Compare commits

...

108 commits

Author SHA1 Message Date
Lukas Brübach
8fcf04d42d [PrintingSelector] Load the pin badge through the themed icon engine
The badge rendered `theme:icons/pin` through the pixmap generator, which
resolved `currentColor` once and cached the result, so the glyph stayed at its
first palette and was rasterized at DPR 1.

- Render the glyph through `loadThemedIcon`, at the label's device pixel ratio,
  and re-render it on palette and theme changes.
- Compose it onto a rounded backdrop filled with `Window` and outlined with
  `WindowText`. The badge floats on card art rather than on a palette surface,
  so a bare outline vanishes into art of the same lightness; the backdrop keeps
  it readable on every printing, and both roles still follow the palette.
2026-11-02 18:29:45 +01:00
Lukas Brübach
2dcf1f2c69 [Game] Follow the palette in judge message tags
Judge tags hardcoded a black prefix and a `theme:icons/scales` image inside rich
text, where `currentColor` cannot resolve and a palette change leaves the tag
unreadable. Render the scales glyph through the themed icon engine, register it
as a document image resource, and repaint the log when the palette or theme
changes.
2026-11-02 18:29:42 +01:00
Lukas Brübach
70f9947c0f [Settings] Delete update channels at shutdown
SettingsCache owns the stable and beta update channels as raw pointers, and
each owns a QNetworkAccessManager, so the process leaves QtNetwork objects
alive past QApplication teardown.

Delete them from a QCoreApplication::aboutToQuit handler instead of the
destructor: SettingsCache is a Q_GLOBAL_STATIC, so ~SettingsCache() runs
during static teardown, after QApplication is gone, and destroying the
network managers at that point is the post-application window that ASan
reports. The hook is installed on the first instance() call that has an
application object, since the first access may predate it.
2026-11-02 15:52:36 +01:00
Lukas Brübach
8551e22b2d [Tests] Drop the empty icon baseline
The legacy icon set is fully paid down, so the ratchet had nothing left to
ratchet: BaselineIsWellFormed required the baseline to be empty, which made
the baseline file, the stale-entry diff and the entry-format regex
unreachable. The rules are enforced directly now.

- AssetsFollowTheRules fails on any violation of collectViolations().
- tests/icon_assets/icon-baseline.txt is gone with its reader.
2026-11-02 15:52:33 +01:00
Lukas Brübach
a87c55e741 [Icons] Add an icon asset ratchet test
The icon rules were enforced by review only, so the next Inkscape export could
reintroduce a baked fill or a physical size without anyone noticing.

Add a test that rejects non-24 viewBoxes, physical sizes, editor metadata,
hardcoded paints, missing tokens, color-coded filenames, and rasters. Keep the
legacy baseline empty so the ratchet can only tighten.
2026-11-02 15:52:33 +01:00
Lukas Brübach
a7d93ad089 [Icons] Render lock and dropdown glyphs through the icon engine
Both generators rendered the sentinel SVG to a fixed height x height pixmap
at DPR 1. The pre-migration path rendered larger and let QIcon scale it, so
on a 2x display the games-list lock (13px) and the banner dropdown arrow
(24px) came back crisp; the new path hands the widget a DPR-1 bitmap that
gets upscaled and blurred.

- The games list asks the themed engine for `icons/lock` directly, so the
  item view paints it at the device pixel ratio and the lock also follows
  HighlightedText on a selected row.
- The dropdown goes through `loadThemedIcon(...).pixmap(size, dpr)`, which
  keeps the glyph's aspect ratio and renders at the requested ratio.
- LockPixmapGenerator has no consumer left, so it and its cache are gone.
2026-11-02 15:52:31 +01:00
Lukas Brübach
005a2cc131 [Tests] Keep the icon render test QApplication alive until exit
Creating it as a function-local static tears it down before Qt's library statics
at exit, and libQt6Network then runs QObject destructors against freed memory —
a SEGV the sanitizer leg reports after the tests have already passed. Leak the
application instead, the usual pattern for a test binary.
2026-11-02 15:52:31 +01:00
Lukas Brübach
cec1579ebf [Icons] Migrate UI glyphs to palette-token SVGs
Runtime inversion is not a theming system: it rotates hue, breaks duotone art
and mishandles alpha, and a QPixmap snapshot cannot follow a palette change.
Redraw the top-level UI glyph set on a 24x24 grid with `currentColor` as the
paint token, drop Inkscape/Sodipodi cruft, and delete the icons whose metaphor
was duplicated (cogwheel/gear -> settings, scale_balanced -> scales,
update.png -> reload).

Load the glyphs through `loadThemedIcon` so the engine resolves the token from
the palette on every request, and let `themePixmap` use the same resolution for
one-shot pixmaps. `loadColorAdjustedPixmap` is gone; every caller now keeps a
QIcon, which `SettingsButtonWidget::setButtonIcon` accepts instead of a QPixmap.

Content art (mana, counters, countries) keeps its authored colors.

Add a render test covering aspect ratio, palette flips, icon modes and
high-DPI pixmaps.
2026-11-02 15:52:31 +01:00
Lukas Brübach
d789f7c3ad [Icons] Add palette-aware themed icon engine
A QPixmap snapshot cannot follow palette changes, so expose a QIcon whose
engine resolves the `currentColor` sentinel from the live palette on every
pixmap request. Icons stay legible across light/dark switches without
recreating actions or buttons.

- Resolve the asset, its bytes and its intrinsic size once, and drop them on
  ThemeManager::themeChanged/paletteChanged. A repaint does no file I/O and
  no theme.cfg parse; the palette color stays part of the render cache key.
- Centre the glyph on QRectF(rect).center(): QRect::center() floors and uses
  right = left + width - 1, which shifted every 16x16 item-view glyph up and
  left by a logical pixel and clipped its last row and column.
- Take a raster override's intrinsic size from QImageReader instead of the
  24x24 SVG default, so a non-square override reports the box it draws.
- Set the device pixel ratio before inserting into the render cache, so a
  cache hit no longer detaches the pixmap on every paint.
2026-11-02 15:51:58 +01:00
Lukas Brübach
b0a642df75 [Icons] Add SVG currentColor sentinel resolver
Qt's SVG renderer has no CSS cascade, so a `currentColor` fill has to be
substituted before the bytes reach QSvgRenderer.

- Match and replace on bytes: both the sentinel and the replacement are
  ASCII, so the document never goes through a UTF-16 round trip, and files
  that are not valid UTF-8 survive unchanged.
- Document that the match is a plain case-insensitive substring, so an
  identifier that merely starts with the sentinel gets rewritten too.
2026-11-02 15:51:55 +01:00
sentry[bot]
9f30892dff
[Client] Fix crash when local game commands are sent after shutdown (#7714)
Some checks are pending
CodeQL / Analyze (cpp) (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
Build Desktop / Configure (push) Waiting to run
Build Desktop / vcpkg baseline (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 cover (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 26 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Desktop / Prune caches (push) Waiting to run
Build Docker / Servatrice (arm) (push) Waiting to run
Build Docker / Servatrice (x86) (push) Waiting to run
Build Docker / Publish multi-platform Servatrice image (push) Blocked by required conditions
* [Client] Fix crash when local game commands are sent after shutdown

* [Network] Fix formatting in local client debug log

* [CI] Keep the vcpkg submodule pointer on the manifest baseline

vcpkg.json asks for builtin-baseline 9eec002 (vcpkg 2026.10.16), but the
submodule gitlink was still at 9e593bb. The runners check submodules out
shallowly, so vcpkg-tool cannot read versions/baseline.json out of the baseline
commit and every vcpkg leg (Windows and all macOS) fails in CMake configure
with:

  failed to `git show` versions/baseline.json

git phrases that as "path ... exists on disk, but not in <sha>" even when the
commit is simply absent from the shallow clone, so it reads like a tooling or
network failure rather than a mismatched pointer. Point the submodule back at
9eec002, and add a cheap job that fails when the gitlink and builtin-baseline
disagree, before the five build legs pay for it.

---------

Co-authored-by: sentry[bot] <39604003+sentry[bot]@users.noreply.github.com>
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-11-02 13:28:23 +01:00
sentry[bot]
8b0c980e85
[Client] Guard dragged card ghost from painting or dropping deleted cards (#7688)
Some checks are pending
CodeQL / Analyze (cpp) (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
Build Desktop / Configure (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 cover (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 26 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Desktop / Prune caches (push) Waiting to run
Build Docker / Servatrice (arm) (push) Waiting to run
Build Docker / Servatrice (x86) (push) Waiting to run
Build Docker / Publish multi-platform Servatrice image (push) Blocked by required conditions
* [Client] Guard dragged card ghost from painting or dropping deleted cards

* [Game] Revert handling for cards destroyed mid-drag

Co-authored-by: sentry[bot] <39604003+sentry[bot]@users.noreply.github.com>

* [DeckView] Access pointer through QPointer in DeckViewCardDragItem

---------

Co-authored-by: sentry[bot] <39604003+sentry[bot]@users.noreply.github.com>
Co-authored-by: zeldazach <7460172+zeldazach@users.noreply.github.com>
2026-11-02 08:39:07 +01:00
RickyRister
62e590d300
[ServerGame] Refactor out spectator/judge bools into RoleInfo (#7761) 2026-11-02 00:37:05 -07:00
BruebachL
a1a8a59f4a
[VisualDatabase] Draw the card grid with a model/view (#7701)
* [VisualDatabase] Draw the card grid with a model/view instead of a widget per card

The visual card database built one CardInfoPictureWithTextOverlayWidget per
card, 100 per page, and tore them down on every search, resize and scroll
page. It also looked each card up again by name from the model row, kept a
shadow QList<ExactCard>, and carried paging state plus a 5 s timer that only
existed to defer the first page.

Replace that with a real view on a flattened model:

- CardDatabaseDisplayModel gains CardInfoRole and cardInfoAt(), so a view can
  get the CardInfoPtr behind a proxy row without a name round trip.
- New CardDatabaseVisualDisplayModel (libcockatrice_models) flattens the
  filtered and sorted proxy into one entry per displayed card picture: the
  preferred printing normally, every printing of the selected sets while set
  filters are active. Proxy changes rebuild it on a 30 ms coalescing timer.
- New CardDatabaseVisualView (QListView IconMode) paints only visible rows
  through the new CardPictureDelegate, keeps the old interaction contract
  (left/right/middle press -> cardClicked, hover -> cardHovered, Ctrl+wheel
  resize, no selection, no focus stealing, scroll to top on a new result) and
  repaints when CardPictureLoader reports an async image.
- CardSizeWidget::enableCtrlScrollResize() also watches scroll-area viewports,
  which is what makes Ctrl+wheel work over a QListView.
- VisualDatabaseDisplayWidget drops the paging, the shadow list, the dead
  members and the 5 s timer.

Behaviour-preserving: no gameplay change, no new user-facing strings.

* [VisualDatabase] Fix the card grid wheel step

QListView hands the delegate's item height to the scroll bar as its single step under ScrollPerPixel, so QAbstractSlider moved wheelScrollLines() whole card rows per notch. Handle the wheel in the view instead: one line is an eighth of the grid cell, so a notch moves about a third of a card row at any card size and still follows the OS line count.

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-11-02 08:35:58 +01:00
BruebachL
94e6281d87
[Logs] Browse room history without filters with paginated infinite scroll (#7531)
* [Logs] Browse room history without filters with paginated infinite scroll

* [Logs] Continue pagination when switching log tabs

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-11-02 07:36:49 +01:00
BruebachL
3cf8bdb00e
[Tests] Add a headless game logic regression suite (#7702)
* [Tests] Add headless game logic regression suite

Cover CardState, CardZoneLogic and the Command_MoveCard protobufs PlayerActions emits, against libcockatrice_game with a recording AbstractClient and no graphics. The old game_smoke_test cases are migrated into the new suite.

* [Tests] Cover game event application through GameEventHandler

Feeds GameEventContainers through the real dispatcher and asserts the resulting zone and card state: move (including face down), the set-card-attr attributes plus the all-cards and does-not-untap branches, card counters, attach/detach, zone reveal properties, and drawing named cards from the deck.

* [Tests] Replay a synthetic game state through the dispatcher

Builds a GameReplay in code, feeds its containers through the same GameEventHandler path the client uses, and asserts the materialized players, zones, cards and attachments plus event ordering for move, attributes and counters. A small headless zone view stands in for the graphics side where processPlayerInfo asks for card items.

* [Tests] Cover card flip, destroy, token and turn events

Adds the remaining state-mutating event handlers: flip (face down keeps the ref, face up adopts the printing), destroy (removes the card and un-attaches its attached cards), create token (database P/T unless provided or face down) and player properties changed under the concede/unconcede contexts, plus active player and phase.

* [Tests] Cover player lifecycle and counter events

Adds the player-level events that mutate session state: leave removes the player from the manager, kicked emits gameClosed, game closed flips the closed flag and clears the started flag, host changed moves the host role to another player, and create/set/delete update the player counters with unknown ids ignored.

* [Tests] Drive the zone view request through addCard

The test emitted createCardRequested itself and then asserted it was emitted. Registering a ZoneViewZoneLogic on the zone and adding a card exercises the real prepareAddCard -> signal path, so the assertion now fails if addCard stops asking the graphics side to build the card.

* [Tests] Skip the card database when listing tests

gtest_discover_tests runs the binary with --gtest_list_tests during the build. That process built the card database and replaced its default path provider, leaving allocations that the sanitizer leg's default LeakSanitizer check reports at exit, so discovery failed on Ubuntu 26.04. No test runs in list mode, so return before the database setup.

* [Tests] Fix fixture comment nit

Wraps the RecordingClient::sent member name in backticks in the comment.

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-11-02 07:35:41 +01:00
BruebachL
5134e72eb4
[Settings] Store server profiles with QSettings arrays (#7629)
The server list used hand-numbered saveName%1/server%1 keys and an O(n)
shift loop to delete entries. Store the profiles with beginReadArray and
beginWriteArray instead, and migrate the legacy keys once in the
constructor so existing profiles and saved passwords survive.

SettingsManager::batchWrite no longer disables atomic sync, so a batch is
still written through QSettings' atomic save. Add tests for add, update,
remove, password updates and the legacy migration.

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-11-02 07:30:29 +01:00
BruebachL
b37c8b828f
[Utility] Budget scrypt's XY array in the derivation memory limit (#7712)
deriveKey passes maxmem = 128nr + 128rp + 4096 to EVP_PBE_scrypt, but scrypt
also allocates XY at 256r bytes. costParamsAreSane accepts r up to 32, so any
server asking for r >= 17 made derivation fail and the client report a login
abort it could never recover from. Cover the XY array and add a regression test
at the accepted-range boundary.

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-11-02 07:29:15 +01:00
BruebachL
719863e43d
[CI] Lint only .sh files in the shell formatting pass (#7715)
The changed-file matcher reused the `*.sh` glob as a regular expression,
where the leading `*` applies to the `(^|/)` group instead of the file
name. Every path ending in "sh" matched, so NSIS include files (.nsh) were
handed to shellcheck and failed the format leg.

Match the suffix explicitly and keep the glob for the find(1) branch.

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-11-02 07:29:05 +01:00
BruebachL
d021f20d14
[Version] Bump to 3.2.0 (#7762)
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-11-02 07:28:14 +01:00
BruebachL
ce543896f5
[Tests] Use QtTest for model contracts and signal spies (#7630)
Qt6::Test was linked into every test but never used. Add a small RAII
QAbstractItemModelTester helper and apply it to the deck list model, the card
database model and display proxy, and the sets model. Add QSignalSpy coverage
for the card-added and download-settings signals, and assert explicitly that a
card row is a leaf with no child columns (the tester does not check that).

The contract checker immediately found four model bugs, fixed here:
- DeckListModel allowed children below non-zero columns.
- CardDatabaseModel reported every card as a child of every card row.
- CardDatabaseModel reported six columns for a valid (leaf) card index.
- CardDatabaseDisplayModel claimed more rows were fetchable while rowCount
  already exposed them all, so fetchMore() inserted duplicates.

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-11-02 07:27:43 +01:00
BruebachL
429eb2a1fd
[Servatrice] Use compile-time checked connections (#7631)
* [Servatrice] Use compile-time checked connections

Replace the remaining SIGNAL/SLOT string connects in servatrice.cpp,
smtpclient.cpp, serversocketinterface.cpp and isl_interface.cpp with
pointer-to-member or lambda connects, and convert the string invokeMethod
calls to the functor overload.

QxtSmtp has overloaded signals, so those need qOverload. Slots inherited as
protected members and the QWebSocket error connection owned by the ISL fix
are left on lambdas/strings as appropriate; the vendored qxtsmtp.cpp is
untouched.

* Fix remaining review threads on the connection syntax

- Connect the IslInterface signals straight to the inherited Server slots
  instead of forwarding lambdas.
- Capture servatrice explicitly in the queued admin lambdas so they do not
  read this->servatrice after teardown.
- Move the websocket newConnection connect out of the per-pool loop.
- Terminate the logging category and restore pendingKey's indentation.

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-11-02 07:13:21 +01:00
BruebachL
a74dfeef6e
[Build] Configure AUTOMOC, AUTOUIC and AUTORCC once (#7637)
The root already set CMAKE_AUTOMOC; add CMAKE_AUTOUIC and CMAKE_AUTORCC
next to it and drop the per-directory copies from 18 CMakeLists files.
These variables are inherited by the subdirectories, so the duplicates
never changed anything.

qt_standard_project_setup is not used: besides the AUTO* variables it
sets CMAKE_RUNTIME_OUTPUT_DIRECTORY on Windows, which breaks the
install(DIRECTORY "$<TARGET_FILE_DIR:...>") copies and the per-app
symbol paths, and appends to CMAKE_INSTALL_RPATH on Linux.

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-11-02 07:06:47 +01:00
BruebachL
5fe7f186d3
[CI] Make the hdiutil retry wrapper report failure (#7643)
* [CI] Make the hdiutil retry wrapper report failure

CPack reads the wrapper's exit status to decide whether the disk image was
created, so a zero exit turns a failed hdiutil into a later "Problem copying
the package" error that hides hdiutil's own message.

- Propagate hdiutil's real status instead of collapsing every failure to 1.
- Name the failing subcommand (create/attach/detach/convert) so the message
  says which CPack step gave up.
- Count attempts rather than failures in the retry line.

* Update .ci/compile.sh

Co-authored-by: tooomm <tooomm@users.noreply.github.com>

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
Co-authored-by: tooomm <tooomm@users.noreply.github.com>
2026-11-02 07:01:55 +01:00
BruebachL
50a2ae9cc8
[Server/Client] Enforce and complete the forced password change at login (#7680)
checkUserPassword ignored force_password_change on the challenge-response
path, so a reset password stayed valid. Returning PasswordChangeRequired
was not enough on its own: the session was dropped and the client told the
user to ask the administrator for the temporary password they had just used.

The pending session now keeps its identity without registering a user
session or announcing a join, may only ping and change its password, and
the client completes the change in-session before reconnecting.

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-11-02 07:01:29 +01:00
BruebachL
ef4574d2b9
[Server] Store a scrypt verifier when an admin resets a password (#7679)
The temporary password was written as a legacy salt+hash row, which makes the
next login look like an authentication downgrade. A client holding a saved
verifier refuses that downgrade, so the reset locked the account out of every
modern client.

Store the verifier and, where security/legacy_backup_key is configured, keep a
sealed legacy hash of the same temporary password as the downgrade backup, so
pre-challenge clients keep the credential path the reset used to provide.

Without the key no row shape serves both: the verifier and the legacy hash
cannot share one column, so those clients have no path at all. Warn at reset
time that the new password has no pre-challenge path, and say so in
servatrice.ini.example instead of promising that a reset gets them back in.

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-11-02 07:00:48 +01:00
tooomm
e08402ac94
bump vcpkg submodule (#7690)
Some checks are pending
CodeQL / Analyze (cpp) (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
Build Desktop / Configure (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 cover (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 26 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Desktop / Prune caches (push) Waiting to run
Build Docker / Servatrice (arm) (push) Waiting to run
Build Docker / Servatrice (x86) (push) Waiting to run
Build Docker / Publish multi-platform Servatrice image (push) Blocked by required conditions
2026-11-01 16:22:51 +01:00
BruebachL
ff393b8990
[Game] Connect zone dump response before sending the request (#7711)
ZoneViewZone::initializeCards() connected PendingCommand::finished only after ZoneViewZoneLogic::requestZoneDump() had already sent the command. Local games process the dump synchronously, so finished was emitted before the view connected and the library/sideboard view stayed empty.

Split requestZoneDump() into prepareZoneDump() and sendZoneDump(), and connect before sending, matching the TabRoom prepare/send convention.

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-11-01 12:49:35 +01:00
BruebachL
00151380e3
[CardDB] Break the CardInfo <-> CardSet cycle on reload (#7645)
Some checks are pending
CodeQL / Analyze (cpp) (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
Build Desktop / Configure (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 cover (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 26 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Desktop / Prune caches (push) Waiting to run
Build Docker / Servatrice (arm) (push) Waiting to run
Build Docker / Servatrice (x86) (push) Waiting to run
Build Docker / Publish multi-platform Servatrice image (push) Blocked by required conditions
* [CardDB] Drop the CardInfo self pointer

The weak self pointer had to be assigned right after every construction,
and a missed assignment silently stopped change notifications. CardInfo
is always owned by a QSharedPointer, so it now derives from
QEnableSharedFromThis<CardInfo> and asks for sharedFromThis() instead:
nothing to initialize, and the CardSet cycle stays broken.

CardSet::newInstance() also loses the commented-out self-pointer
assignment left over from the same design.

* [CardDB] Pin the cardInfoChanged contract without the self pointer

Dropping CardInfo's self pointer moved change notifications onto
QEnableSharedFromThis, so the signal now rests on the card being owned by
a QSharedPointer. Two tests pin that down:

- A property change on a card owned by a CardDatabase still emits
  cardInfoChanged() carrying that card, which is what the card database
  views and models listen to.
- clone() starts out unowned, so a change to the clone is reported as the
  clone's and must not reach the original's observers.

* [CardDB] Treat an unowned CardInfo as a bug, not a no-op

Every CardInfo is built inside a QSharedPointer (both factory overloads
and clone()), and no constructor notifies anyone, so sharedFromThis() is
always available by the time addToSet() or a setter runs. Assert that and
warn in a released build, instead of silently skipping the notification
or the set append.

The copy constructor keeps its explicit QEnableSharedFromThis
initializer: GCC's -Wextra warns about the uninitialized base in every
translation unit that copies a CardInfo otherwise. A comment there
records that the clone deliberately starts unowned.

* [CardDB] Break the CardInfo <-> CardSet cycle on reload

CardSet is a QList<CardInfoPtr> and CardInfo::addToSet() appends the card
to its sets, while a card keeps a CardSetPtr per printing in
setsToPrintings. The sets therefore hold strong references back to the
cards, and the previous database snapshot stayed alive after a reload, so
RSS grew by roughly a second database on every reload.

Empty the sets before the cards are dropped: CardDatabase::clear() and
swapInDatabaseData() clear the sets before replacing the containers, and
removeCard() detaches the card from its sets, so nothing keeps a card
alive on behalf of a set once the database lets go of it.

Two tests pin the behaviour: a reload and a clear() must drop the last
strong reference to a card from the previous snapshot.

* [CardDB] Keep the set detach in one place

clear() and swapInDatabaseData() both emptied every set before dropping the
cards, so share that as detachSetMembership() instead of two copies that have
to stay in sync.

removeCard() now detaches through the first printing of each set directly, the
same way CardInfo::newInstance() appends, instead of an inner loop that always
breaks after the first item.

Because clear() empties the sets up front, its per-card detach was walking
every card's printings to remove it from sets that were already empty. Split
removeCard() into the per-card detach and unindexCard(), and let clear() call
only the latter.

* [CardDB] Test that removeCard detaches the card from its set

removeCard() is the one teardown path a caller can trigger for a single card
(the token editor uses it), and it now detaches the card from its sets as
well. Without that detach the set's strong CardInfoPtr keeps the removed card
alive forever, which is exactly what the reload and clear tests pin for the
whole-snapshot paths.

The test loads the fixture, removes Cat, and requires the card to be gone from
the CAT set and to be destroyed once the test drops its own reference.

* [Servatrice] Drop the settings cache from the logger

#7602 removed #include "settingscache.h" from server_logger.cpp but left
isLoggingEnabled() reading settingsCache, so master no longer compiles: the
servatrice target fails on the undeclared global and server_logger_test, which
compiles the same file without main.cpp, fails to link it.

The same commit made reloadConfig() the single place that stores writelog and
the log filters, precisely so logging threads stop reading the global QSettings.
isLoggingEnabled() now mirrors logMessage() and reads those members instead: the
console is a sink of its own, and the logfile needs an open file plus writelog.
The mutex is mutable so the const query can take it.

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-31 19:37:15 +01:00
BruebachL
344dbd2caa
[Servatrice] Fix silently broken socket error connections (#7626)
* [Servatrice] Fix silently broken socket error connections

QAbstractSocket::error() was removed in Qt 6 in favour of errorOccurred(). The ISL interface connected to the old name through SIGNAL(), which compiles but fails at runtime, so catchSocketError never ran. The WebSocket interface used the same name on QWebSocket, where it still exists but is deprecated since 6.5.

Use errorOccurred for both. The WebSocket connect needs a lambda because catchSocketError is a protected base-class slot and a base pointer-to-member is not accessible from the derived class.

* [Servatrice] Guard the WebSocket error connect against Qt 6.4

QWebSocket gained errorOccurred in 6.5 and dropped the error signal with it, so
the typed connect cannot compile against the 6.4 floor that Debian 12 and
Ubuntu 24.04 still use. Keep the typed connect on 6.5+ and fall back to the
old-style connect below it, which is what the code did before.

Verified both branches compile: forcing the guard to the else path and
rebuilding serversocketinterface.cpp succeeds, so the 6.4 spelling is intact.

* [Servatrice] Initialize ISL serverId before authentication

catchSocketError() removes islInterfaces[serverId], but the incoming
connection constructor left serverId uninitialized until initServer()
set it after the SSL handshake and certificate check. A socket error
during waitForEncrypted() therefore read an indeterminate key.

* [Servatrice] Correct the QWebSocket error signal note

error() was deprecated in 6.5, not removed; errorOccurred() was added in
6.5.

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-31 19:02:55 +01:00
BruebachL
825aba953a
[Servatrice] Fail loudly when startup initialization fails (#7602)
* [Servatrice] Exit non-zero when server initialization fails

initServer() reported every startup failure through a zero exit code: the
database could not be opened, the server printed nothing of its own, and the
process looked like a clean shutdown. Log the two refusal reasons at critical
level and return 1 so supervisors and the Docker exit status can tell the
difference.

* [Servatrice] Keep console logging independent of the logfile

logMessage() returned before the console echo unless a logfile was open and
server/writelog was true, so --log-to-console produced nothing when
server/logfile was empty or could not be opened. That is how a refused database
connection could end in a silent exit.

Print to the console before the logfile gates, drop the duplicate echo from
flushBuffer(), and read writelog/logfilters once in main instead of calling the
non-thread-safe global QSettings from every logging thread.

* [Servatrice] Uninstall the log handler before tearing down globals

The handler reaches into the global logger and settingsCache. Leaving it
installed while main deletes those objects turns any Qt warning emitted during
QCoreApplication/QFactoryLoader teardown into a use-after-free; with
QT_DEBUG_PLUGINS=1 that warning exists, and Servatrice died with SIGSEGV in
QSettings::value() on the way out.

* [Servatrice] Buffer console logs on the logger thread

Address review feedback on the startup failure change:

- Append console lines to a buffer drained by the logger thread, so a
  stalled stdout reader cannot block game threads.
- Report islServer->errorString() instead of the literal call text.
- Let the constructor reuse reloadConfig() instead of parsing the filter
  list twice.

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-31 19:02:49 +01:00
BruebachL
ae43659b91
[Build] Use versionless Qt CMake commands (#7639)
* [Build] Use versionless Qt CMake commands

Replace the versioned qt6_add_executable, qt6_add_resources, qt6_add_shaders,\nqt6_add_translations and qt6_wrap_cpp calls with their unversioned forms.\nAll five are documented as available at the project's 6.4 minimum and accept\nthe same arguments.\n\nVerification: full client, Oracle, server and test build passed.

* versionless qt_finalize_target and _project

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
Co-authored-by: tooomm <tooomm@users.noreply.github.com>
2026-10-31 18:53:00 +01:00
BruebachL
d4002dc52b
[Build] Reject APIs deprecated before Qt 6.4 (#7632)
Add the deprecation cutoff after FindQtRuntime so the compiler rejects any
API deprecated before the project's minimum Qt version. Qt 6.5 renamed the
switch, so the fallback name is used on 6.4.

The full client, Oracle, server and test build passes with the cutoff
enabled.

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-31 18:52:11 +01:00
BruebachL
f2c359ba9f
[CI] Keep the vcpkg cache directory guard unconditional (#7527)
The cache action creates its directory only when a prefix matches an entry, and it reads that directory unguarded when it saves, so a scope nobody has written to yet fails the job. Create it up front on every outcome, and fall back to the workspace path when the cache step was skipped and set no path output.

Co-authored-by: opencode <opencode@local>
2026-10-31 18:49:45 +01:00
BruebachL
52d3978f84
[Build] Let AUTOMOC process library headers (#7638)
The 13 libraries using qt6_wrap_cpp(MOC_SOURCES ${HEADERS}) listed their\nheaders twice and depended on a generated source list. Add the headers to the\ntarget sources directly and delete the qt6_wrap_cpp call; AUTOMOC scans them\nand generates the same moc output.\n\nThe change exposed that server_card_counter_test never defined the rng global\nthat the server remote library references; every sibling server test does.\nGive the test the same definition so the target links.\n\nVerification: full client, Oracle, server and test build passed.

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-31 18:49:05 +01:00
BruebachL
345b0e8ba9
[Refactor] Move game logic into libcockatrice_game (#7437)
* [Refactor] Move game logic into libcockatrice_game

* [Refactor] Include card_state.h in player_actions.h

* [Game] Inject settings providers into libcockatrice_game, drop Widgets

* [Game] Follow base rename to createCardRequested after rebase

* [Game] Drop unused CardItem forward declaration

* [Game] Fix includes after moving game logic into libcockatrice_game

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-31 18:44:15 +01:00
BruebachL
78964779c6
[Refactor] Move card item creation out of game logic (#7436)
* [Refactor] Move card item creation out of game logic

* [Game] Rename signal to createCardRequested per review

* [Game] Move attachment bookkeeping onto CardState

CardState::setAttachedTo now maintains the attachedCards graph, resets the
grid point and emits the zone events itself, so game logic no longer needs
to reach into the CardItem graphics item. CardItem::setAttachedTo delegates
to the state and keeps only the view teardown (deleteLater).

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-31 18:44:15 +01:00
BruebachL
7ca23430cd
[Refactor] Retype PlayerActions onto CardState (#7435)
* [Refactor] Retype card containers and zone logic onto CardState

* [Refactor] Retype PlayerActions onto CardState

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-31 18:44:14 +01:00
BruebachL
65e9f1b370
[Refactor] Retype card containers and zone logic onto CardState (#7434)
* [Refactor] Retype card containers and zone logic onto CardState

* [Game] Restore attach bookkeeping via CardItem and repaint on state change

* [Refactor] Give custom zones a hidden graphics owner

Custom PileZoneLogic zones had no CardZone, so moving a card into one
left the CardItem drawn at its old spot. Create a hidden PileZone in
onCustomZoneAdded so cards are reparented and hidden.

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-31 18:44:14 +01:00
BruebachL
5d0d466930
[Refactor] Add card name, printing id, and color to CardState (#7433)
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-31 18:44:13 +01:00
BruebachL
edb5caec8a
[Refactor] Hold zone views and card view teardown outside game graphics (#7429)
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-31 18:44:13 +01:00
BruebachL
2335e064ac
[Refactor] Move the attachment graph and card view teardown onto CardState (#7428)
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-31 18:44:13 +01:00
BruebachL
47c90cda10
[Refactor] Give graphics zones a card item cache and own card placement (#7427)
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-31 18:44:12 +01:00
BruebachL
4879ddbd0f
[Refactor] Move card selection actions to GameScene and p/t parsing to CardState (#7426)
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-31 18:44:12 +01:00
BruebachL
c9853734ad
[Refactor] Move card identity and card data into CardState (#7425)
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-31 18:44:12 +01:00
BruebachL
6f0c5dca12
[Refactor] Move LoadedDeck and DeckFileFormat data types into libcockatrice_deck_list (#7424)
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-31 18:44:11 +01:00
BruebachL
85fd052fdb
[Refactor] Move ArrowRegistry out of game/ into game_graphics/board (#7423)
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-31 18:44:11 +01:00
BruebachL
3ccd44155d
[Refactor] Build arrow and attach commands in game/ instead of ArrowItem (#7422)
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-31 18:44:11 +01:00
BruebachL
77f882ca37
[Refactor] Build deck setup commands in GameEventHandler instead of DeckViewContainer (#7421)
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-31 18:44:10 +01:00
BruebachL
674a607960
[Refactor] Build player counter commands in game/ instead of AbstractCounter (#7420)
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-31 18:44:10 +01:00
BruebachL
73d5a2a0ab
[Refactor] Emit phase toolbar intent instead of protobuf commands (#7419)
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-31 18:44:10 +01:00
BruebachL
095b135640
[Refactor] Move the remaining zone commands out of game_graphics/zones/ (#7418)
* [Refactor] Move the remaining zone commands out of game_graphics/zones/

* [Game] Move zone dump request onto ZoneViewZoneLogic per review

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-31 18:44:09 +01:00
BruebachL
563833a88a
[Refactor] Build Command_MoveCard in game/ instead of the zone views (#7417)
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-31 18:44:09 +01:00
BruebachL
4972ebcb97
[Refactor] Move the active card from AbstractGame into GameScene (#7416)
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-31 18:44:08 +01:00
BruebachL
94b91be5a2
[Refactor] Pass the target card into PlayerActions instead of reading activeCard (#7415)
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-31 18:44:08 +01:00
BruebachL
93c5d85996
[Refactor] Move attach and arrow previews from game logic into CardMenu (#7414)
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-31 18:44:08 +01:00
BruebachL
52c5bd2ea3
[Refactor] Move table row mapping from TableZone into TableZoneLogic (#7413)
* [Refactor] Move table row mapping from TableZone into TableZoneLogic

* [Game] Use TableZoneLogic::ROW_COUNT directly per review

* [Format] Match clang-format line breaking in table_zone

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-31 18:44:07 +01:00
BruebachL
d30d275296
[Refactor] Move AnnotationDialog and action data types into game/ (#7411)
Folds in the closed #7410 (Move AnnotationDialog from game/ logic to
game_graphics/) now that layers 1-2 are closed and this stack bottoms on
master directly:

- Add game_graphics/dialogs/dlg_annotation.{h,cpp} and move the
  QInputDialog subclass there; game/ no longer declares any widget type.
- Add game/player/token_info.h and game/player/move_top_cards_until_options.h.
- Move CardMenuActionType to game/player/card_menu_action_type.h.
- Graphics dialog headers include the new game/ headers instead of
  defining the structs themselves.

No behavior change.

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-31 18:44:07 +01:00
sentry[bot]
bbc7e462ff
[Installer] Graceful close and a way out of a stuck update (#7687)
Some checks are pending
CodeQL / Analyze (cpp) (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
Build Desktop / Configure (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 cover (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 26 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Desktop / Prune caches (push) Waiting to run
Build Docker / Servatrice (arm) (push) Waiting to run
Build Docker / Servatrice (x86) (push) Waiting to run
Build Docker / Publish multi-platform Servatrice image (push) Blocked by required conditions
* [Installer] Stop calling the payload free while an executable is locked

The guard answered "nothing is holding the payload" from two lookups that can
both miss a running instance: Restart Manager does not reliably report a
program's own image or the modules it mapped, and the image path of a process
running under another account cannot be read from the probe at all. A user log
showed exactly that: the first guard passed while cockatrice.exe was running
from the directory, the old uninstaller silently skipped the file it could not
delete, and the update aborted half an uninstall later with "cancelled by user"
after a close attempt the running window ignored.

Ask the file itself. A running image is opened without write sharing, so the
write open replacing it needs is refused with ERROR_SHARING_VIOLATION for as
long as the program runs, while a file that is merely being read still accepts
it. When neither lookup named anybody and a payload executable refuses that
open, the probe answers that the file is in use and that the program holding it
could not be identified - the guard's "could not confirm" dialog, whose Retry
works once the user has closed it - instead of passing the payload as free.

Only the payload executables are tested, not every file the purge removes: a
locked executable proves a program is running and a mapped DLL belongs to a
running executable, while a locked DLL or qt.conf can be the asking process
itself, which is the loop the guard already had. The open is retried once after
300 ms, and only for the files that refused, so a scanner holding a file for a
moment cannot stop an install for nothing.

The Windows probe check now covers that answer: a payload executable held by
the asking process, so that it cannot be named, has to come back as in use
rather than as free.

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>

* [Installer] Close running clients over a local socket

The installer could only ask a running client to close with WM_CLOSE, which an instance hidden in the notification area or sitting on its own confirmation cannot answer usefully. Give every client a per-process local socket and have the holder probe ask it there first, falling back to WM_CLOSE for clients from before the socket.

* [Installer] Offer to check again or update by hand when files stay locked

Replace the two-answer guard prompt with force close, close by hand and check again, or cancel. Retry the automatic close while the set of holders changes, and point a cancelled run at the latest release so a user who does not want anything killed has a way forward that is not cancelling the update again.

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-31 15:32:59 +01:00
tooomm
720adf5410
[Settings] Rename UI language selector & move translator hint (#7656)
* Update general_settings_page.cpp

* lint
2026-10-31 09:28:52 +01:00
sentry[bot]
0369aaffa9
[Installer] Name only the payload programs installed in the directory (#7684)
Some checks failed
CodeQL / Analyze (cpp) (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
Build Desktop / Configure (push) Has been cancelled
Build Desktop / Prune caches (push) Has been cancelled
Build Docker / Servatrice (arm) (push) Has been cancelled
Build Docker / Servatrice (x86) (push) Has been cancelled
Build Desktop / Debian 13 (push) Has been cancelled
Build Desktop / Debian 12 (push) Has been cancelled
Build Desktop / Fedora 44 (push) Has been cancelled
Build Desktop / Fedora 43 (push) Has been cancelled
Build Desktop / Servatrice_Debian 12 (push) Has been cancelled
Build Desktop / Ubuntu 24.04 (push) Has been cancelled
Build Desktop / Ubuntu 26.04 (push) Has been cancelled
Build Desktop / Arch (push) Has been cancelled
Build Desktop / Ubuntu 26.04 cover (push) Has been cancelled
Build Desktop / macOS 13 Intel (push) Has been cancelled
Build Desktop / macOS 14 (push) Has been cancelled
Build Desktop / macOS 15 (push) Has been cancelled
Build Desktop / macOS 26 Debug (push) Has been cancelled
Build Desktop / Windows 10 (push) Has been cancelled
Build Docker / Publish multi-platform Servatrice image (push) Has been cancelled
The running-instance lookup named every process whose image path began with the
install directory, subfolders included. Installing into a folder that holds
another application in a subfolder therefore reported that application as
holding the previous version, and nothing the guard offers could clear it: the
close asks cockatrice.exe only, and the end answer refuses anything that is not
a payload program. Both answers were no-ops, so the update could only abort and
tell the user to close a program that was never touching the files.

Name only the programs the payload installs, and only when the image lies in the
install directory itself. A program below the directory that really does hold a
payload file is still named by the Restart Manager lookup, which is the lookup
for that question.

The Windows probe check now covers a payload-named program in a subfolder and a
program the payload does not install; both have to come back as nothing.

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-30 13:16:50 +01:00
sentry[bot]
ded83aaab5
[Installer] Ask a hidden instance to close, then offer to end it once (#7683)
Some checks are pending
CodeQL / Analyze (cpp) (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
Build Desktop / Configure (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 cover (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 26 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Desktop / Prune caches (push) Waiting to run
Build Docker / Servatrice (arm) (push) Waiting to run
Build Docker / Servatrice (x86) (push) Waiting to run
Build Docker / Publish multi-platform Servatrice image (push) Blocked by required conditions
* [Installer] Request quit for hidden Cockatrice instances and record holders in abort telemetry

* [Installer] Fix compiler warnings in holder probe and installer quit handler

* [VisualDeckStorage] Order the includes the way clang-format wants them

* [Installer] Ask a hidden instance to close, then offer to end it once

The previous attempt had the client answer a registered window message, which
cannot work for the update it was reported on: the instance being replaced is a
client from before that message exists, so it never answers, and the user is
left with "Cockatrice is still running" exactly as reported. Every step that can
free the files has to be the installer's, so the client side is reverted.

The probe now posts WM_CLOSE to the instance's own window whether that window is
on screen or only in the notification area: the request does not need a visible
window, an instance in the tray is the one this update has no other way to
reach, and the confirmation Cockatrice answers with is a window Qt shows itself,
so it is painted - unlike one restored from outside. A visible window is brought
forward first, and Qt's bookkeeping windows stay excluded, because a close to the
notification-area one terminates the instance without its confirmation.

A question of the instance's own no longer suppresses the close. Withholding it
protected nobody: the installer asked the user to close a program it had never
asked, and a current client refuses the close while its confirmation is pending
anyway, leaving the question where it is. The launcher mode keeps the
visible-only rule, because a launcher without a window has already answered its
own close and the wait ends it after a grace instead of asking a user who is not
there.

The guard asked the same question until the user gave up: after the automatic
close failed it offered to end the programs, then re-ran the probe and showed
the same dialog word for word when the answer was No, which is how an abort was
reported three times over. It now asks once - Yes ends the Cockatrice, Oracle
and Servatrice programs the payload installs and says what that costs, No
cancels - and what survives an end is named in the abort instead of being put to
the user as the same question again. The uninstaller's guard and the recovery
path after a failed purge follow the same shape.

Kept: the abort telemetry that records the holders, the close result and the end
result as event data.

---------

Co-authored-by: sentry[bot] <39604003+sentry[bot]@users.noreply.github.com>
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-29 21:01:16 +01:00
sentry[bot]
9e50c5ad6e
[Installer] Recover payload files when previous uninstaller is missing or fails to launch (#7682)
Some checks are pending
CodeQL / Analyze (cpp) (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
Build Desktop / Configure (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 cover (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 26 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Desktop / Prune caches (push) Waiting to run
Build Docker / Servatrice (arm) (push) Waiting to run
Build Docker / Servatrice (x86) (push) Waiting to run
Build Docker / Publish multi-platform Servatrice image (push) Blocked by required conditions
Co-authored-by: sentry[bot] <39604003+sentry[bot]@users.noreply.github.com>
2026-10-29 12:10:18 +01:00
sentry[bot]
06da7f815a
[Installer] End a launcher that has no window to ask instead of prompting (#7681)
Some checks are pending
CodeQL / Analyze (cpp) (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
Build Desktop / Configure (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 cover (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 26 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Desktop / Prune caches (push) Waiting to run
Build Docker / Servatrice (arm) (push) Waiting to run
Build Docker / Servatrice (x86) (push) Waiting to run
Build Docker / Publish multi-platform Servatrice image (push) Blocked by required conditions
* [Installer] End a launcher that has no window to ask instead of prompting

The in-app updater starts this installer detached and then closes itself. A
client that accepts that close hides its window before it exits, and if it
then hangs in shutdown there is nothing left to ask: the holder probe
deliberately never posts WM_CLOSE to an instance it cannot see a window for,
so the "ask it to close again" answer only repeated itself until the user
picked Cancel and the installation aborted (Sentry COCKATRICE-DESKTOP-J).

The launcher wait now asks the launcher itself before asking the user. A new
probe mode, --close-launcher, answers whether that one process has a window a
close could reach at all; it is limited to a pid that still runs from the
directory being replaced, so a reused process id cannot be hit. When there is
no window, the installer gives the shutdown it already started one full grace
and then ends it through the handle it waited on, which is what the dialog's
Yes answer did. The prompt remains for the case it exists for: a window is up,
the instance may be waiting on its own question, and No now means only "keep
waiting".

The client is left alone: an already-installed version runs the installer
during its own update, so a change there cannot reach the run that aborts.

* [libcockatrice_rng] Include immintrin.h for AVX2 builds in SFMT

---------

Co-authored-by: sentry[bot] <39604003+sentry[bot]@users.noreply.github.com>
2026-10-29 04:00:42 +01:00
BruebachL
5cf3358c99
[Client] Stop reporting local login aborts as missing client features (#7678)
Some checks are pending
CodeQL / Analyze (cpp) (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
Build Desktop / Configure (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 cover (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 26 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Desktop / Prune caches (push) Waiting to run
Build Docker / Servatrice (arm) (push) Waiting to run
Build Docker / Servatrice (x86) (push) Waiting to run
Build Docker / Publish multi-platform Servatrice image (push) Blocked by required conditions
* [Client] Stop reporting local login aborts as missing client features

Local aborts (unusable saved verifier, refused authentication downgrade,
failed scrypt derivation) reuse RespClientUpdateRequired with an empty
feature list, and the handler discarded the reason and advised a client
update. Report the abort with the cause instead, and report a strict
server's challenge_response_auth answer to a credential-less login as the
missing password it is.

* [Client] Keep the login abort messages in one named set

The local login aborts each carried their wording inline at the emit site, so
changing the tone or the remedy meant editing several functions. Collect them
as named constants next to RemoteClient instead, translated at the use sites
with the RemoteClient context so lupdate still picks them up.

* [Client] Reword the login abort explanations to match what happens

The first wording sent users to a server operator to 'migrate' an account,
which operators cannot do, and told them to 'save' a login the client saves by
itself. It also blamed the device for a derivation failure the server's
parameters can cause, and the dialog led with a line that said nothing while
the reason sat in the informative slot.

Say what the client actually does in each case, give the step that works, and
show the reason as the dialog's main text. The unreachable fallback sentence
about the login not reaching the server is gone.

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-28 09:48:37 +01:00
BruebachL
d89b502342
[Client] Report password-reset rate limits instead of a generic failure (#7677)
* [Client] Report password-reset rate limits instead of a generic failure

sigForgotPasswordError carried no response code, so rate limiting, a
disabled reset feature, an unknown user and a bad token all produced
"contact the server operator". Users who were only rate limited retried,
which kept them rate limited.

* [Client] Move the reset-password warning out of the response switch

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-28 09:19:42 +01:00
sentry[bot]
a83d82b5e8
[Installer] Recover leftover payload files when previous uninstaller leaves them behind (#7676)
* [Installer] Recover leftover payload files when previous uninstaller leaves them behind

* [Installer] Fix leftover recovery on the 64-bit auto-uninstall path

- Record the 64-bit uninstaller exit code after ExecWait returns. It was
  captured before the call (always empty), so WaitForOldPayloadToDisappear
  always aborted before RemoveOldPayloadLeftovers could run.
- Restore the pre-uninstall user-data backup before aborting out of the wait,
  including the guard's cancel and probe-failure prompts, so the only copy
  cannot be stranded in %TEMP% for the next run to wipe.
- Report the leftover removal as done only when every payload executable is
  gone and RetryDllPurge reports no stale DLLs, instead of checking
  cockatrice.exe alone.
- Return directly after a successful recovery instead of reusing the poll
  counter, so the log stops claiming the directory "was already clear" and
  the normal settle delay is kept.

* [Installer] Delete the old uninstaller only after recovery succeeds

RemoveOldPayloadLeftovers cleared the attribute and deleted
$INSTDIR\uninstall.exe on every attempt, before the attempt was known to
work. On failure the installer aborts telling the user to run it again, but
UninstallString then points at a missing uninstaller: ExecWait leaves the
exit code empty, WaitForOldPayloadToDisappear takes the "cancelled or
failed" branch, and RemoveOldPayloadLeftovers is gated on exit code 0, so
no later run can ever get past it - a half-removed old install the previous
revision never produced.

Delete it in rop_done instead, after $OldPayloadRemoved is set.
WriteUninstaller recreates it on success anyway, and nothing in the
success verdict depends on it being gone.

---------

Co-authored-by: sentry[bot] <39604003+sentry[bot]@users.noreply.github.com>
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-28 09:08:54 +01:00
sentry[bot]
bf3562a85a
[Installer] Offer to end running Cockatrice immediately when auto-close fails (#7675)
Some checks are pending
CodeQL / Analyze (cpp) (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
Build Desktop / Configure (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 cover (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 26 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Desktop / Prune caches (push) Waiting to run
Build Docker / Servatrice (arm) (push) Waiting to run
Build Docker / Servatrice (x86) (push) Waiting to run
Build Docker / Publish multi-platform Servatrice image (push) Blocked by required conditions
* [Installer] Offer to end running Cockatrice immediately when auto-close fails

* [Installer] Keep the way out that costs nothing in the first prompt

The prompt now offers to end Cockatrice, so what the deleted close-again text
said has to survive in it: an instance the probe reports as waiting for an
answer to a question of its own has been brought forward, and answering that
window is the way out that ends nothing. Say so, and say where to go when Yes
leaves it listed - Task Manager - so an end that cannot take effect does not
loop on the same dialog.

* [Installer] Bring the comments back in line with the code

GuardCloseTried no longer counts closes, and the file header, CloseHolders and
GuardAppsNotRunning still described an escalation after a second close, as did
the probe's --end-holders note.

* [Installer] End Oracle and Servatrice too when the guard's end answer is confirmed

The guard's end answer only ever stopped cockatrice.exe, so an Oracle holding
the card database or a Servatrice service kept the payload locked and the
prompt came back with nothing left that could free it.

The probe now ends every program the payload installs, services included:
isPayloadProgram() - the list restart_manager_holders already used for its
parent walk - decides the set, so a scanner holding a DLL or a program the
user keeps in the install directory is still named and left to the user. A
service is terminated rather than sent a stop through the SCM, which notices
the process exit and marks it stopped afterwards.

The guard prompt now says what ending costs: an unsaved deck, an unwritten
setting, players on a running Servatrice, and an Oracle mid-way through the
card database. It also keeps the notification-area hint, which the probe's
"has no window to ask" answer depends on, and drops the claim that Oracle
and Servatrice had been brought forward.

* [Installer] Give every running-program prompt the same end-or-retry answers

Four prompts meet a running program and each offered a different set: the
guard ended it, the launcher wait only kept waiting, and the recovery prompt
after a failed purge could only ask Cockatrice to close. With Oracle or
Servatrice holding the files, that last one had no answer that could free
anything - Yes and No both retried the purge and Cancel aborted an install
whose old version was already gone.

All four now follow the guard's shape: one automatic attempt, then a prompt
whose Yes ends the programs it names and whose No retries, with Cancel to
give up.

- RecoverFromHolders closes once and purges before it asks anything, then
  offers EndHolders - the same end answer as the guard - instead of a close
  the user had to trigger himself.
- WaitForLauncherToExit can end the launcher by pid, the one process it
  holds a pid for, rather than looping 60 s waits with Cancel as the only
  way out.
- END_COST and AFTER_CLOSING_GUIDANCE are !defines, so the cost of ending
  and the guidance for the answers that end nothing read the same in every
  prompt.

* [Installer] End the launcher through the handle it was waited on

The "end it" answer used to look the launcher's pid up again after a dialog that
can stay open as long as the user takes, so a pid that had been reused in the
meantime - or a /PID= that was never the launcher - would be terminated instead.
The handle the wait already holds names that process and cannot be handed to
another, so the terminate answer now acts on it.

PROCESS_TERMINATE is requested along with PROCESS_SYNCHRONIZE; when only the
synchronize right is granted the launcher is still waited on and the answer falls
back to asking it to close, instead of reporting a live launcher as gone and
writing the payload over it.

* [Installer] Say what the end answer ends, and report a failed end

The prompt offered "end every program listed above", but EndHolders only ends the
programs the payload installs: a scanner holding a payload DLL, or a service the
Restart Manager names by its long name, was listed and then silently left alone, so
Yes looked like it did nothing and the same dialog came back unchanged.

The wording now says which programs Yes ends and that anything else has to be closed
by hand, and the round after an end that did not free the files says so, so the same
dialog no longer reappears word for word. The three prompts are one macro so they
cannot drift apart again.

The added sentences eat into the 1024 characters one NSIS string holds, so the
holder line's budget drops from 400 to 320 characters to keep the longest message
(cancel line included) inside it: 977 characters, measured against the worst case
the probe can produce.

---------

Co-authored-by: sentry[bot] <39604003+sentry[bot]@users.noreply.github.com>
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-27 19:09:21 +01:00
sentry[bot]
30d3afc7b4
[Updater] Close a running Cockatrice when the installer asks (#7672)
Some checks are pending
CodeQL / Analyze (cpp) (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
Build Desktop / Configure (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 cover (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 26 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Desktop / Prune caches (push) Waiting to run
Build Docker / Servatrice (arm) (push) Waiting to run
Build Docker / Servatrice (x86) (push) Waiting to run
Build Docker / Publish multi-platform Servatrice image (push) Blocked by required conditions
* [Updater] Refuse a close that arrives while one is already asking

MainWindow::closeEvent() had a re-entrancy guard that returned without touching
the event. A QCloseEvent is accepted unless something ignores it, so a second
close request - an installer replacing our files posts one every 30 s - accepted
the close while the first one was still blocked on its own confirmation. close()
then hid this window, hid the confirmation dialog with it, and left the process
running inside the nested loop that dialog had opened: no window, no way to
answer it, and every later close request accepted into the same dead end. That
is what an update looked like when it could not close a running client, and it
is why the installer could name the process, bring it forward and ask it to
close for minutes without anything happening.

Track how far the shutdown has got instead. While a confirmation is up, a close
from anywhere else is refused, which leaves the question in front of the user;
once the shutdown has been accepted, a duplicate close (Qt delivers the event
twice on some platforms) is accepted again so it cannot cancel the quit.

* [Installer] Leave an instance that is asking a question alone

An instance that answered a close by hiding rather than quitting - the state the
client used to get into - has no visible window left, and the confirmation it is
waiting on is hidden with the window that owns it. The close probe only ever
looked at visible windows, so it restored the main window, posted WM_CLOSE into
the same dead end, and reported "still running" without saying why.

Show every window the instance left hidden before choosing the one to close, and
skip the close when the window it would reach is disabled: a modal dialog of the
instance's own is up, and posting the close then only hides the question again.
Name what is left of the window in the report as well - gone, still open, hidden
again, and whether the thread answers at all - so the log tells a refused close
from one that was never delivered.

* [Installer] Offer to end a Cockatrice that will not close

A close is a request, and an instance that does not answer it - waiting on a
question nobody is looking at, or stuck where a close cannot reach - leaves the
user with no way forward: the files cannot be replaced while it runs, and
clicking Yes again only repeats the request.

After a second close that changed nothing, offer the only thing that can free
the files: end it. The prompt says what it costs - an unsaved deck, a running
game or a setting it has not written yet - the default button is the safe one,
and it is a separate answer rather than a relabelled "Yes", so it is not
reached by clicking through the close prompt. Only cockatrice.exe is ever
ended: Oracle writes the card database in place and Servatrice is a service, so
both are named and left to the user, exactly as they are for the close.

The probe gains an --end-holders mode for it, and the uninstaller's guard gets
the same offer.

* [Installer] Never name the process that is doing the asking

The old uninstaller is started with _?= so it runs in place, from the very
directory it is emptying, and an installer can be downloaded into the folder it
installs to. Both are then processes running from the directory, so the probe
named them - and the guard asked the user to close the program that was asking.
That question cannot be answered: a close and the end offer both skip anything
that is not cockatrice.exe, so the guard repeated itself until the update or the
uninstall was cancelled.

The probe and the processes that started it are now never named, by either
lookup. The walk up the parent chain stops at the first program the payload
installs, because in an in-app update the installer's own parent is the
Cockatrice instance being replaced - the one the guard exists to name.

The Windows check held its locked file in the script that starts the probe, so
that holder is excluded by design now and the check read it as "nothing found".
It holds the file from a process of its own instead, and asserts the exclusion
itself: a file that only the asking process holds comes back as nothing.

* [Installer] Restore only the windows a user could answer

Showing every hidden window an instance owns put Qt's own bookkeeping windows on
screen: the tray icon keeps one to receive the TaskbarCreated message, styled
WS_OVERLAPPED and titled QTrayIconMessageWindow. Restored, it is an empty white
rectangle in the taskbar with no title bar to close it - it has no window
procedure that would hide it again, and the process is busy in the very loop the
restore is meant to break, so it stayed until the process was force-ended.

Only framed, non-empty windows are restored and considered for the close now.
That also keeps the close off Qt's tray window, which answers WM_CLOSE by asking
the application to terminate - a quit that skips the confirmation the close is
supposed to reach.

* [Installer] Uninstall the previous version before installing over it

A regular install over an existing one asked "a previous version must be
uninstalled", then ran the old uninstaller interactively. That uninstaller
put its confirmation page behind the installer window, where it could not be
answered, and it only removed the installation after the installer had
already written the new one over it.

Run the previous version's uninstaller silently instead. The installer has
already asked the question the user answered, so a second, hidden confirmation
is pure risk: with /S there is no window to be behind, and ExecWait is then
waiting for something that cannot outlive it. QuietUninstallString is used
when the old installation has one, otherwise /S is appended.

ExecWait only waits while the uninstaller runs in place: one that did not get
a usable _?= copies itself to %TEMP% and returns at once, while the copy keeps
deleting - which is how an uninstall can finish after the install it was
supposed to precede. Log the exit code and wait for the old cockatrice.exe to
disappear before restoring user data or writing anything, and abort with a
message instead of installing into a directory that is still being emptied.

Cancelling the "must be uninstalled" prompt now quits the installer; it used
to skip the page and install over the old version anyway.

* [Installer] Do not show windows the application has hidden

The guard restored every hidden window an instance owned before asking it to
close, so that a confirmation hidden together with its window would come back.
Windows does as it is told and shows them; the application does not, because Qt
still believes they are hidden and never paints them. What the user gets is a
blank white rectangle, on screen and on the taskbar, that answers nothing - and
the question it was meant to bring back is not answerable in it either.

An instance with no window a user could answer is named and left to the user
instead, and the prompt says what to do about it: open it from the notification
area. Ending it stays the last resort, offered once a close has been asked for
twice.

The abort after a failed uninstall now says what it saw - the old version is
still there after its uninstaller ran - instead of promising a removal that is
not happening, which is the state a cancelled old uninstaller leaves behind.

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-27 11:19:49 +01:00
sentry[bot]
92d082e735
[VisualDeckStorage] Guard against widget deletion during tag edit dialog (#7674)
Co-authored-by: sentry[bot] <39604003+sentry[bot]@users.noreply.github.com>
2026-10-27 09:14:52 +01:00
sentry[bot]
aa42cfbccc
[VisualDeckEditor] Create menus before central frame to prevent Windows crash in setParent_sys (#7673)
Co-authored-by: sentry[bot] <39604003+sentry[bot]@users.noreply.github.com>
2026-10-27 09:12:37 +01:00
sentry[bot]
d42b9607c5
[Installer] Check for running instances with the Restart Manager probe (#7671)
Some checks are pending
CodeQL / Analyze (cpp) (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
Build Desktop / Configure (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 cover (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 26 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Desktop / Prune caches (push) Waiting to run
Build Docker / Servatrice (arm) (push) Waiting to run
Build Docker / Servatrice (x86) (push) Waiting to run
Build Docker / Publish multi-platform Servatrice image (push) Blocked by required conditions
* [Installer] Check for running instances with the Restart Manager probe

The running-instance guard was built on powershell.exe started from the
32-bit NSIS stub, which is the 32-bit Windows PowerShell: its Get-Process
cannot read the path of a 64-bit process, so a running 64-bit Cockatrice
was reported as not running, the update went ahead, and the purge then
failed on the DLLs that instance still had mapped.

Use tools/installer-holder-probe instead - the same Restart Manager lookup
the abort path already had - before anything is replaced and in the
uninstaller as well. It is bitness-agnostic, so the Sysnative and WMI
fallbacks are gone.

The guard looks only at the payload, asks Cockatrice to close once by
itself (WM_CLOSE, the same request as the window's close button) and then
offers close again / retry after closing by hand / cancel for whatever the
close cannot reach - Oracle writes the card database in place, Servatrice
has no window - without force-stopping anything. A failed purge offers the
same close-and-retry, tries one last purge when nobody is named, and every
dialog shows in every mode: a silent reinstall stays silent until
something goes wrong.

* [Installer] Name processes running from the install directory

The running-instance guard answers from the Restart Manager, which reports
who has a file open. A running instance does not have to have one open: its
own image and the modules it loaded are mapped into it rather than opened by
it, and a mapping is not reliably reported. That is the state the probe was
added for - every DLL still on disk, an instance running from the directory,
and "nothing is holding them any more" as the answer.

A guard built on file handles alone is blind to exactly that instance, so it
passes, the purge fails, the holder lookup after it names nobody either, and
the install ends in a warning that no running program was found: no close is
attempted and no retry is offered. A manual install with another instance
open never asks it to close at all.

Name every process whose image lives in the directory being replaced as
well, with the same bitness-safe QueryFullProcessImageNameW the probe
already uses to label its holders. The image lookup is listed first - it is
the instance the user is asked to close - and the Restart Manager entries
follow with the pids already named dropped, so the close still reaches
everything that holds a file. A Restart Manager call that fails only makes
the probe unable to answer when the image lookup named nobody either.

Ask instead of dead-ending when the probe cannot answer at all: Retry checks
again, Ignore carries on, Abort cancels, in the installer and the uninstaller
alike, and the abort dialog says the check failed instead of claiming no
running program was found.

The Windows CI probe check covers the new lookup with a process started from
the directory that holds no file open.

* [Installer] Offer to wait again when the launcher has not exited

A client that is still closing after 60 s is usually not hung: it is showing
its own "quit anyway?" confirmation for an unsaved deck, an open game or a
card database update, and the user is the one who has to answer it. The
installer answered that with a plain warning and stopped, so the only way
forward was to close Cockatrice by hand and run the update again - which on
an in-app update means finding the downloaded installer.

Ask instead: Retry brings the client to the front, asks it to close again
(WM_CLOSE, nothing forced) and keeps waiting on its handle, Cancel stops as
before. There is no "install anyway" answer because a live process has its
image and Qt DLLs mapped, so writing the payload over them is the broken
install this wait exists to prevent - and the guard that runs right after
names the same process by its image path and stops there, so ignoring would
only move the same question a moment later.

* [Installer] Ask about a launcher that has not exited after ten seconds

A minute of silence is a long time to sit in front of an installer that has no
window yet, and the case it is waiting for is not a slow flush: a client that
started an update exits in well under a second, so a minute means it is almost
always showing its own "quit anyway?" confirmation with nobody looking at it.

Wait ten seconds for the first question instead, and the full grace for the
ones after it. The normal path is untouched - WaitForSingleObject returns as
soon as the handle signals, so a client that exits in 200 ms still costs 200
ms - and answering the first question once does not turn into a stream of
prompts while the user is in Cockatrice's window.

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-26 19:25:10 +01:00
sentry[bot]
4793c1fc04
[Installer] Offer to close blocking processes and retry purge on upgrade (#7664)
Some checks are pending
CodeQL / Analyze (cpp) (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
Build Desktop / Configure (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 cover (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 26 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Desktop / Prune caches (push) Waiting to run
Build Docker / Servatrice (arm) (push) Waiting to run
Build Docker / Servatrice (x86) (push) Waiting to run
Build Docker / Publish multi-platform Servatrice image (push) Blocked by required conditions
* [Installer] Offer to close blocking processes and retry purge on upgrade

* [Installer] Retry the purge after closing only our own applications

The first version of this fix closed every Restart Manager holder through
RmShutdown, forcing what refused to close. RmShutdown also stops services, and
the only API that brings them back is RmRestart, which would restart Cockatrice
itself into the files that are about to be replaced; the forced pass also
contradicts the running-instance guard, which never force-closes Cockatrice
because it may be holding an unsaved deck. The guard ran first anyway, so for
the case the fix exists for - a Cockatrice restarted during the update - the
probe never got to run: the guard waited 60 s and aborted.

Keep the prompt and the retry, but ask only Cockatrice, Oracle and Servatrice to
close, with WM_CLOSE and nothing else, and leave every other holder named by the
probe to the user. Repeat the prompt while the user keeps saying Yes, refresh
the names after a failed retry, and keep the /R abort message pointing at the
downloaded installer.

Also clear the read-only attribute before every purge attempt. Delete and RMDir
leave such a file in place, so the retry could never make progress, and the
diagnostics branch that named the cause had no action behind it.

The holder probe goes back to being diagnostic-only, so its Restart Manager
code and the --close argument are dropped.

* [Installer] Make an accepted close of the running client actually land

WM_CLOSE is a request, and Cockatrice answers it: while a card database
update is running, a game is open or a deck is unsaved it puts up its own
"are you sure?" confirmation. That dialog opened behind the installer's
prompt, so the user saw nothing happen; the next Yes was posted to a main
window the app's own modal dialog had disabled, so it was ignored as well,
and the identical yes/no prompt came back with no hint of why.

- Activate the matching window before posting WM_CLOSE, so the app's own
  confirmation is in front where it can be answered.
- Wait up to 30 s for cockatrice.exe to exit instead of purging after a
  fixed 2 s, so the purge measures the app gone rather than its dialog.
- On the second and later rounds ask with Retry/Cancel and say what is
  needed, instead of repeating the same offer that just did nothing.
- Stop promising Oracle and Servatrice: they are console applications, so
  CloseMainWindow() has nothing to send WM_CLOSE to. They are not
  force-stopped either - Oracle writes the card database in place.

* [Installer] Close the client from the holder probe, not PowerShell

Accepting the offer to close did nothing on a real machine: the instance stayed
up, never came forward, and the same prompt came back.

The prompt names its holders from the Restart Manager probe, but the close itself
went through powershell.exe: Get-Process -Name, a strict "path starts with
$INSTDIR" filter, then Process.CloseMainWindow() and a WScript.Shell AppActivate.
Every step of that is silent. A process whose path cannot be read is filtered
out, a process .NET finds no main window for makes CloseMainWindow() return
false without posting anything, and AppActivate is refused for a background
caller - so an attempted close, a missed close and a close request the client
ignored all looked the same in the log: nothing.

Ask the probe instead. installer-holder-probe --close-holders closes exactly the
processes Restart Manager just named as holding a file of the version being
replaced, so no executable path has to be guessed and a third party application
that merely shares the image name is never in the set. Per instance it restores
and brings the top-level window forward (AttachThreadInput, so the client's own
"really quit?" confirmation is on screen rather than behind the installer), posts
WM_CLOSE to the main window, and waits up to 30 s for the process to exit. Its
report names every holder with what happened to it, including the ones left to
the user, and goes into the installer log as one line.

That also removes the separate PowerShell polling loop that used to wait for the
close: the probe holds a handle on the process it asked, so the purge that
follows measures a settled directory.

Oracle and Servatrice are still never closed, and nothing is force-stopped.

---------

Co-authored-by: sentry[bot] <39604003+sentry[bot]@users.noreply.github.com>
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-26 09:45:52 +01:00
BruebachL
675e1f7447
[Translation] Name languages without reading the translation files (#7662)
Some checks are pending
CodeQL / Analyze (cpp) (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
Build Desktop / Configure (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 cover (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 26 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Desktop / Prune caches (push) Waiting to run
Build Docker / Servatrice (arm) (push) Waiting to run
Build Docker / Servatrice (x86) (push) Waiting to run
Build Docker / Publish multi-platform Servatrice image (push) Blocked by required conditions
* [Translation] Name languages without reading the translation files

The language selector derived every label from the language's own .qm file:
it loaded the file and translated the literal "English" in the "i18n"
context. lupdate could never extract that literal from the callers, which
pass the DEFAULT_LANG_NAME macro, so a dummy QT_TRANSLATE_NOOP in
cache_settings.cpp existed to give it something to extract. #7050 deleted
that dummy, the next lupdate push dropped the string from Transifex, and
the following pull rewrote the .ts files without it. lrelease only emits
translated messages, so 22 of 25 .qm files returned an empty name.

The names are data, not translations: a selector has to be readable before
any translation is loaded, and a label must not depend on the translation
of the language it names. TranslationLoader::languageDisplayName now holds
them next to availableLanguages, falling back to Qt's native language name
and then to the code, so a language added later still gets a label.

Also select the configured language by item data instead of by matching the
translated "English" string, which pointed at the wrong row whenever the
lookup came back empty, and restore that English entry's own name: en_US is
"English (United States)" so it can no longer be confused with the
untranslated default.

Oracle shared the code path, so its wizard language page is fixed too.

* [Translation] Name the default language selection once

Review follow-up: log the unresolvable language through the page's own
category, and move the en_US entry both selectors fall back to for an unset
setting into TranslationLoader::defaultLanguageCode.

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-26 02:39:26 +01:00
sentry[bot]
858b270fa9
[Installer] Retry locked DLL purge before aborting upgrade (#7657)
Some checks are pending
CodeQL / Analyze (cpp) (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
Build Desktop / Configure (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 cover (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 26 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Desktop / Prune caches (push) Waiting to run
Build Docker / Servatrice (arm) (push) Waiting to run
Build Docker / Servatrice (x86) (push) Waiting to run
Build Docker / Publish multi-platform Servatrice image (push) Blocked by required conditions
* [Installer] Retry locked DLL purge before aborting upgrade

* [Installer] Keep the purge verdict when the portable purge runs

$IsUpgrade was read from IsExistingCockatriceInstall after the portable purge,
which deletes the very markers that function looks for. A purge whose only
survivors were non-Qt DLLs (abseil_dll.dll, libssl-3-x64.dll) or content under
Plugins therefore reported "not an install", $IsUpgrade became 0 and the abort
was skipped - the mixed DLL set the retry exists to prevent. Measure the
directory before either purge block, where it still describes the directory as
it arrived, and let RetryDllPurge's own verdict decide the abort.

A portable install into a directory without portable.dat is neither purge
block, so $StaleRuntimeAfterPurge was never assigned there and the abort could
not fire either. Track whether a purge ran and measure that directory with
HasStaleRuntimeFiles instead, which is what every upgrade did before the retry.

---------

Co-authored-by: sentry[bot] <39604003+sentry[bot]@users.noreply.github.com>
Co-authored-by: BruebachL <44814898+BruebachL@users.noreply.github.com>
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-25 20:40:57 +01:00
ebbit1q
4d8ab54313
Revert "[Version] Bump to 3.2.0 for beta release. (#7653)" (#7660)
This reverts commit e6b4c51585.
2026-10-25 20:19:23 +01:00
BruebachL
e6b4c51585
[Version] Bump to 3.2.0 for beta release. (#7653)
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-25 20:14:21 +01:00
sentry[bot]
4ab875be48
[VisualDeckStorage] Keep databaseLoadIndicator alive when swapping in folder widget (#7651)
Co-authored-by: sentry[bot] <39604003+sentry[bot]@users.noreply.github.com>
2026-10-25 17:35:46 +01:00
sentry[bot]
f3fb3331d1
[Cards] Guard against null QScreen when positioning enlarged pixmap (#7650)
Co-authored-by: sentry[bot] <39604003+sentry[bot]@users.noreply.github.com>
2026-10-25 17:35:10 +01:00
BruebachL
93309e01a2
[Server/Client/Protocol] Let moderators clear banner cards (#7546)
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-25 13:19:20 +01:00
BruebachL
b4e24f958a
[Network] Do not format discarded debug messages, parse without memmove (#7606)
Some checks are pending
CodeQL / Analyze (cpp) (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
Build Desktop / Configure (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 cover (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 26 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Desktop / Prune caches (push) Waiting to run
Build Docker / Servatrice (arm) (push) Waiting to run
Build Docker / Servatrice (x86) (push) Waiting to run
Build Docker / Publish multi-platform Servatrice image (push) Blocked by required conditions
* [Network] Do not format discarded debug messages, parse without memmove

Protocol debug logging gets the full protobuf message rendered through
TextFormat and reflection. On the server this happened before every
session/room/game/moderator/admin/developer command, even though the
default Server_ProtocolHandler::logDebugMessage() is a no-op and even
when servatrice has no log file configured. On the clients the same
string was built as an argument to qCDebug(), which evaluates its
arguments regardless of whether the category is enabled.

Server_ProtocolHandler now exposes a virtual logsDebugMessages() hook.
The base implementation returns false, so handlers without a log
destination spend nothing. AbstractServerSocketInterface overrides it
with ServerLogger::isLoggingEnabled(), which checks the log file and the
server/writelog setting that logMessage() itself consults. All debug
message call sites check the hook before formatting. The client
send/receive paths check QLoggingCategory::isDebugEnabled() first, the
same pattern AbstractClient already uses for its slow-command warning.
ISL message decoding does the same.

Byte stream decoding called inputBuffer.remove(0, n) for the length
header and then again for every message. Each call shifts all remaining
bytes, so a read carrying k messages cost O(k * bytes remaining). The
three receive loops (remote client, TCP server interface, ISL interface)
now parse at a read offset and compact the consumed prefix once, when
they stop because a full message is not buffered yet. No buffering or
size-limit behavior changes.

Also in this batch:
- Server_ProtocolHandler::processGameCommandContainer() copied the whole
  games map under gameListMutex just to look up one game id. A new
  getGameInfo() performs the single lookup and returns the room/player
  ids.
- The TCP receive loop's `ok` flag is initialized, so a ParseFromArray
  exception can no longer leave it indeterminate before `if (ok)`.
- The exception log prints only the message being parsed instead of
  hex-dumping the entire pending buffer.

Full build and ctest (628 tests) pass, including the server tests.

* [Network] Address review comments

- Move getGameInfo() out of the header into server_abstractuserinterface.cpp.
- Drop the consumed prefix once after the parse loop instead of on every
  early return: the two "not enough data" exits now break out of the loop.
  Applied to the remote client, TCP server and ISL receive loops.

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-25 12:49:24 +01:00
Neel Jogani
a4c4c67674
Fix tab retranslation (#7580)
* Retranslate all open tabs on language change

* Address review: deeper Visual DB retranslation, index-based Archidekt size logic

In Qt 6, setItemText() on the current item emits currentTextChanged but not
currentIndexChanged, so connecting the Archidekt combos to currentTextChanged
fired a search on every language change. Both combos now use currentIndexChanged,
and buildSearchUrl() compares the size-logic combo by index so translated labels
cannot drop sizeLogic.

* Derive display mode button text in one place
2026-10-25 12:30:17 +01:00
BruebachL
f33cfcb288
[UI] Show 'Password saved' placeholder when verifier is stored (#7649)
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-25 10:34:56 +01:00
BruebachL
5fbc636f93
[Models] Use QCollator for natural, cached sorting (#7633)
Some checks are pending
CodeQL / Analyze (cpp) (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
Build Desktop / Configure (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 cover (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 26 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Desktop / Prune caches (push) Waiting to run
Build Docker / Servatrice (arm) (push) Waiting to run
Build Docker / Servatrice (x86) (push) Waiting to run
Build Docker / Publish multi-platform Servatrice image (push) Blocked by required conditions
* [Models] Use QCollator for natural, cached sorting

QString::localeAwareCompare rebuilds its collation data for every
comparison, and it compares numbers as text. Keep one QCollator per model,
enable numeric mode, and use it for the card name, set and user name sorts.

Add a test that sorts "Forest 1", "Forest 2", "Forest 10" through
DeckListSortFilterProxyModel and checks the natural order.

* [Models] Sort naturally under the C locale too

Numeric mode only takes effect through a real locale: under the C locale,
which headless CI processes run in, QCollator silently falls back to string
order and sorts "Forest 10" before "Forest 2". That made collator_sort_test
fail on every Linux leg while passing locally.

Add makeNaturalSortCollator(), which enables numeric mode and pins English
only when the process locale is the degenerate one, and build the models'
collators through it. Users with a real locale keep their own collation.

* [Models] Fix compile of natural sorting (QStringView mismatch)

* nit: initialize collators in member initializer lists

* nit: namespace makeNaturalSortCollator under NaturalSort

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-25 01:01:04 +02:00
BruebachL
5ddfcd7ead
[Pictures] Watch the custom picture folder instead of polling (#7635)
The local picture loader walked the whole custom picture tree every ten
seconds on the GUI thread. Watch the root and every subdirectory with
QFileSystemWatcher, debounce bursts of events into a single 500 ms refresh,
and keep a five-minute fallback poll for filesystems where watching fails.

Add an explicit-path constructor and indexedPaths() so the indexing can be
tested without SettingsCache, and emit indexChanged() after a rebuild.

Verification: cockatrice built.

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-25 00:36:14 +02:00
BruebachL
518c7e6125
[Network] Add a configured QNetworkAccessManager factory (#7628)
* [Network] Add a configured QNetworkAccessManager factory

Every HTTP caller built its own QNetworkAccessManager, so the system proxy
and a transfer timeout were easy to omit. Add NetworkManagerFactory::create()
as the single place that applies the process-wide proxy configuration and a
transfer timeout, and use it at all 14 construction sites.

Per-site settings such as disk caches and manual redirect policies stay with
their callers.

* [Tests] Link libcockatrice_network into the tests that compile its headers

release_channel.cpp and card_picture_loader_worker.cpp now include
libcockatrice/network/network_manager.h, but the test targets that compile
them only linked libcockatrice_settings, so the include directory never
reached them and every platform failed with "file not found":
loader_local_matching_test and picture_loader_benchmark_test.

libcockatrice_network is an INTERFACE library, so linking it costs these
targets nothing but hands over the include path.

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-25 00:33:43 +02:00
BruebachL
3b07b10b19
[Avatar] Respect EXIF orientation and decode at target size (#7634)
Read the avatar with setAutoTransform(true) so camera orientation is
applied, and ask QImageReader for a scaled decode at MAX_AVATAR_DIMENSION
instead of decoding a full-resolution photo and scaling it afterwards.

Verification: cockatrice built.

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-25 00:11:09 +02:00
BruebachL
66b9338c90
[QtUtils] Use makeScrollArea() for the remaining scroll areas (#7625)
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-24 22:50:25 +02:00
BruebachL
77a3875c25
[VisualDatabase] Debounce filter refreshes with QtUtils::Debouncer (#7624)
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-24 22:48:11 +02:00
BruebachL
28c8474f03
[QtUtils] Add Debouncer helper (#7623)
* [QtUtils] Add Debouncer helper

* Extract long message to variable before confirm() call

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-24 22:43:10 +02:00
BruebachL
11e2bb0d2f
[QtUtils] Adopt window fade, path, bold font and confirmation helpers (#7622)
Some checks are pending
CodeQL / Analyze (cpp) (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
Build Desktop / Configure (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 cover (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 26 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Desktop / Prune caches (push) Waiting to run
Build Docker / Servatrice (arm) (push) Waiting to run
Build Docker / Servatrice (x86) (push) Waiting to run
Build Docker / Publish multi-platform Servatrice image (push) Blocked by required conditions
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-24 21:43:50 +02:00
BruebachL
eac149656b
[QtUtils] Add window fade, path opening, bold font and confirmation helpers (#7621)
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-24 21:38:54 +02:00
BruebachL
e806085681
[QtUtils] Use makeLayout() for zero-margin layouts (#7620)
* [QtUtils] Add parent lookup, layout clearing, scroll area and monospace helpers

* [QtUtils] Adopt shared Qt helpers across the client

* [QtUtils] Add layout creation and relayout helpers

* Swap parameter order (spacing before margin) and remove static from relayout()

* [QtUtils] Use relayout() after rebuilding dynamic layouts

* [QtUtils] Use makeLayout() for zero-margin layouts

* Consolidate setSpacing() calls into makeLayout() using new parameter order

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-24 19:06:18 +02:00
BruebachL
06b9ca368f
[QtUtils] Add layout creation and relayout helpers (#7619)
* [QtUtils] Add layout creation and relayout helpers

* Swap parameter order (spacing before margin) and remove static from relayout()

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-24 19:01:56 +02:00
BruebachL
67a212d677
[Theme] Drop stale pixmap caches on palette-only preview (#7600)
Some checks are pending
CodeQL / Analyze (cpp) (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
Build Desktop / Configure (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 cover (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 26 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Desktop / Prune caches (push) Waiting to run
Build Docker / Servatrice (arm) (push) Waiting to run
Build Docker / Servatrice (x86) (push) Waiting to run
Build Docker / Publish multi-platform Servatrice image (push) Blocked by required conditions
A palette preview repaints widgets through applyStyleAndPalette without running
themeChangedSlot, so generator-owned pixmaps stayed at the previous palette
until the next full theme switch. Clear them where the palette is applied.

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-24 10:40:20 +02:00
BruebachL
4028606bd9
[CardDB] Clear CardInfo relations before deferred deletion (#7615)
removeCard() and swapInDatabaseData() schedule CardRelation deletion with deleteLater(), but the owning CardInfo could outlive them through an external shared pointer and kept returning the freed pointers from getAllRelatedCards(). Add CardInfo::clearDirectRelations() and call it after scheduling deletion so the UI can no longer dereference dangling relations.

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-24 10:28:24 +02:00
Neel Jogani
6e770eb7b2
Retranslate Home tab when the language changes (#7579)
* Retranslate Home tab when the language changes

TabSupervisor::retranslateUi() never included the Home tab, and
HomeWidget set its button text only once, when the buttons were
created. Switching languages left the Home tab in the old language
until it was reopened.

Store the Home buttons as members, add HomeWidget::retranslateUi()
to set their text, and call it from TabHome and TabSupervisor. The
connect button text still only changes for the Connecting,
Disconnected and LoggedIn statuses, as before.

* Address review: plain ClientStatus, drop optional and placeholder
2026-10-24 08:35:31 +02:00
Neel Jogani
e73dd2b520
Refactor display type toggler and add language change handling in Vis… (#7581)
* Refactor display type toggler and add language change handling in VisualDeckDisplayOptionsWidget

* Address review: extract updateDisplayTypeButton(), document changeEvent

* Restore trailing newline in visual_deck_display_options_widget.cpp
2026-10-24 08:34:19 +02:00
BruebachL
ab13a6748f
[QtUtils] Adopt shared Qt helpers across the client (#7618)
* [QtUtils] Add parent lookup, layout clearing, scroll area and monospace helpers

* [QtUtils] Adopt shared Qt helpers across the client

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-24 08:26:21 +02:00
BruebachL
1e0fc35d94
[QtUtils] Add parent lookup, layout clearing, scroll area and monospace helpers (#7617)
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-24 08:26:02 +02:00
BruebachL
bbc6003f0a
[CrashReporting] Name the files and processes behind a failed installer purge (#7590)
Some checks are pending
CodeQL / Analyze (cpp) (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
Build Desktop / Configure (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 cover (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 26 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Desktop / Prune caches (push) Waiting to run
Build Docker / Servatrice (arm) (push) Waiting to run
Build Docker / Servatrice (x86) (push) Waiting to run
Build Docker / Publish multi-platform Servatrice image (push) Blocked by required conditions
* [CrashReporting] Log which files and processes blocked the installer purge

A purge that fails aborts the upgrade with a message that can only guess
at the cause, and the log only listed which DLLs survived. Record what
Windows reports for each survivor and which processes still have the
install directory mapped, then repeat the holder list in the abort
message.

The diagnostics are additive and run only on the abort path: they open
each survivor for DELETE access and close it again without deleting, so a
failed upgrade can never end up half-removed. The purge itself is
unchanged.

* [CrashReporting] Name the holders of a failed purge with Restart Manager

The process-and-module scan could only name a holder whose image lives in the
install directory or that loaded one of its DLLs, so the case this diagnostic
exists for - an antivirus scanner holding a plain handle - was reported as "no
holder named, only a code". Reaching the Restart Manager from the NSIS script
would have meant marshalling RM_PROCESS_INFO through System::Call as a table of
hand-computed offsets, which cannot be checked without a Windows toolchain, and
that is why it was dropped when this diagnostics was written.

Move the call into tools/installer-holder-probe: a small executable the same
Windows build compiles, linking nothing from this project so it still starts
when the installed runtime is what the purge could not replace. It rides inside
the installer and is extracted to $PLUGINSDIR only when the purge has already
failed, so the successful path is unchanged and nothing new is installed.

.ci/compile.sh runs it against a file held with FileShare.None on the Windows
runners, so the lookup is exercised on real Windows instead of only compiled.

* [CrashReporting] Fix the holder probe check and cap the holder line

The probe block ran after the package steps, where the working directory is
already the build dir, so its $BUILD_DIR-prefixed paths named build/build and
the PowerShell file could not be written. Move it ahead of install/package,
where the build dir is still the cwd, and name both files relative to it.
Guard it on MAKE_NO_CLIENT, since the probe is only built with the client.

Cap the rendered holder line at HOLDER_LINE_CHAR_MAX: the count limit alone
does not keep long service names inside the NSIS string that also carries the
abort text and the log path. Whole entries are kept and the rest counted, with
the first holder always shown.

Also run cmake-format on the probe's CMakeLists so the lint job accepts it.

* [CrashReporting] Report a read-only purge survivor and bound the probe check

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-24 00:46:54 +02:00
BruebachL
ad4320cd7b
[CardDB] Stream card properties from blobs (#7608)
* [CardDB] Stream card properties from blobs

Parsed and cached cards used to keep a materialized QHash<QString,
QString> for their properties: LazyPropertiesHash only deferred building
that hash until the first query, and the cache writer re-serialized it on
save.

- LazyPropertiesHash answers value(), contains(), size(), isEmpty() and
  keys() straight out of the serialized blob, so a property query no
  longer builds a hash.
- serialize() is public, and the cache writer passes the stored blob
  through instead of serializing a hash it just rebuilt.
- CardInfo and PrintingInfo expose getPropertiesBlob() and
  getPropertyCount(); PrintingInfo::operator== compares key by key
  without materializing either side.
- The XML parsers build cards via newInstanceFromPropertiesBlob(), which
  derives the simple name and the alternate names that the parser used
  to keep next to the hash.

The reload cycle fix stays out of this change; it depends on changing
the CardInfo self pointer and is reviewed separately.

* [CardDB] Address review comments on streaming properties

* [CardDB] Address final review nits on property streaming

Move BlobReader and the blob accessors into LazyPropertiesHash as private
members so the parsing helper is declared with the class instead of hiding
in the translation unit.

Add LazyPropertiesHash::serializedFrom() and use it where a PrintingInfo is
built from a fresh property hash, replacing the nested
LazyPropertiesHash(LazyPropertiesHash::serialize(props)) construction.

The pre-materialized QHash constructor stays: CardInfo's non-blob factory
still uses it for the oracle import path, and the tests cover it directly.

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-24 00:17:31 +02:00
BruebachL
c25a2c5c3b
[CardDB] Avoid copying printing maps and property strings (#7605)
Some checks are pending
CodeQL / Analyze (cpp) (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
Build Desktop / Configure (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 cover (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 26 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Desktop / Prune caches (push) Waiting to run
Build Docker / Servatrice (arm) (push) Waiting to run
Build Docker / Servatrice (x86) (push) Waiting to run
Build Docker / Publish multi-platform Servatrice image (push) Blocked by required conditions
* [CardDB] Avoid copying printing maps and property strings

Reading a card's sets was a measured hotspot: `SetToPrintingsMap setMap =
card->getSets();` copies the whole QMap, and then iterating it with a
non-const iterator detaches and deep-copies every PrintingInfo, including
its property hash, on first use. A micro-benchmark of that exact pattern
(copy plus non-const iteration) came out about 19x slower than a const
reference over the same data.

The querier, the cache writer, the XML writer, the picture loader and the
printing/set selection widgets now take `getSets()` by const reference and
only use const iterators. The tests that iterate generated data are
covered by the existing card database and picture loader suites.

String accessors were also returning by value where the value lives in a
hash that has already been materialized:
- CardInfo::getProperty() and the legacy getCardType()/getColors()/
  getManaCost()/getCmc()/getPowTough()/getLoyalty() accessors,
- PrintingInfo::getProperty(), getUuid(), getFlavorName(), getArtist(),
  and getSet(),
- ExactCard::getPrinting() and getCardPtr(),
- CardSet::getShortName(), getLongName() and getSetType().

getPrinting() in particular copied a PrintingInfo on every call, and a
copy of an unmaterialized PrintingInfo has to take the properties mutex.
Callers that need an owned copy still get one; the rest just read.

Other allocation removals in the same path:
- LazyPropertiesHash::ensureMaterialized() checks an atomic flag before
  taking the mutex, so property reads after the first one do not lock.
  The flag is release-stored after materialization and acquire-loaded by
  readers/copies, preserving the existing locking for the first read.
- CardSet::getCorrectedShortName() no longer rebuilds its QSet of
  reserved Windows file names on every call.
- CardSet::getIsKnownIgnored() no longer formats the release date into a
  throwaway string just to check its length.
- The querier builds its card-type/format count caches without
  `cards.values()` or a properties key list, reserves its result lists,
  and picks a random card without materializing `cards.keys()`.
- The querier's pinned-printing path reuses the CardInfoPtr it already
  has instead of looking the card up again by name.
- CardDatabaseCache/XML serialization copy the alt-name QSet by
  reference.
- The picture loader compiles its !prop!/!set! regular expressions once
  instead of per URL template, and walks the transform map with an
  iterator instead of keys() plus operator[].

Full build and ctest (628 tests) pass.

* [CardDB] Address review comments

PrintingInfo is a value type: it is stored in QLists and returned by value
from the querier, so a const-ref getter can hand out a reference into a
temporary. Return the QStrings and the CardSetPtr by value again.

The constFind lookup stays, so a property read still never materializes the
lazy property hash - only the last shared-data refcount is paid.

* [CardDB] Undo the const-ref QString return changes

QString is implicitly shared, so returning by value costs only a refcount
and avoids handing out references into a lazily materialized hash. The
constFind lookups stay, so a property read still never materializes the
hash.

* [CardDB] Use QMap::asKeyValueRange() in transformUrl

The range is a view over the map's own iterators and yields references to
the stored key and value, so it keeps the no-allocation property of the
manual const iteration.

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-23 11:58:58 +02:00
BruebachL
b85436461e
[Filters] Precompute term data instead of redoing it per card (#7603)
* [Filters] Precompute term data instead of redoing it per card

Card filters are evaluated once per card in the database, and several
attributes derived constant values from the filter term on every single
evaluation:

- acceptColor() ran up to twelve case-insensitive string replacements and
  a space strip for each card, then called getColors() again for every
  character of the term.
- acceptRarity() ran the rarity abbreviation expansion loop per card.
- acceptManaCost() uppercased and sorted the term per card, before
  sorting the card's own cost.
- acceptLoyalty() and acceptFormat() trimmed/lowercased the term per card.
- relationCheck() re-parsed the numeric operator and operand per card,
  for every cmc/power/toughness/loyalty comparison.

The term of a FilterItem never changes, so these values are now computed
once in the constructor and only the card-dependent part remains in the
accept path. For colors this also removes the repeat getColors() call,
which materializes the printing properties hash.

Additionally:
- CardInfoPtr is passed by const reference through FilterItemList,
  FilterItem and FilterTree instead of by value, removing an atomic
  refcount pair per card per filter node.
- Main/sub type filtering no longer allocates a QStringList via split();
  it looks the " - " separator up directly and compares QStringViews.
- acceptSet() and acceptPowerToughness() fetch the printing/set or the
  power/toughness string once instead of once per branch/accessor.

No filtering behavior is intended to change. Invalid numeric terms (for
example a bare "<") now return false instead of indexing trimmedTerm[1]
past the end.

Verified with filter_string_test (42 tests) and a full client build.

* [Filters] Address review comments

- Replace the main/sub type separator accessor function with a plain
  namespace-scope constant.
- Take card type, colors, cmc, loyalty, power/toughness and the printing's
  set by value; those getters already return by value.

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-23 11:23:17 +02:00
BruebachL
f4b4365464
[Search] Stop allocating per card in card-name completion (#7604)
* [Search] Stop allocating per card in card-name completion

CardSearchModel::updateSearchResults() runs on every textEdited()
signal, walks the whole card database and runs Levenshtein against every
matching name. Three costs dominated that path:

1. Every candidate built a QStringList of its searchable names, then
   lowercased each name into another QString, only to break out of the
   loop after the first hit.
2. The sort comparator called sortableName() for each comparison, which
   re-fetched the name (QMap lookup plus QString construction) O(n log n)
   times.
3. levenshteinDistance() allocated a full len1 x len2 vector of vectors.

The search model now lowercases the one name it tests directly, stores
the tie-breaking name length once per result, and the comparator only
compares integers. levenshteinDistance() uses the standard two-row
formulation: same result, O(len2) memory instead of O(len1*len2), with
early exits for empty and equal strings.

FilterString query closures get the same treatment:
- Set queries iterate the set map directly instead of materializing
  keys()/values() lists for every card.
- Rarity queries iterate printings in place instead of copying them into
  a QList<PrintingInfo> first.
- Power/toughness split the string with indexOf and compare QStringViews
  instead of allocating a QStringList.
- Field queries do one hash lookup instead of contains() followed by
  value().
- Color queries bind the colors string by reference instead of copying.

Verified with filter_string_test (42 tests) and a full client build.

* [Search] Address review comments

- Use std::any_of/std::none_of over the set map's key/value iterators
  instead of hand-rolled loops.
- Extract the name matching into matchingLowercaseName() returning
  std::optional<QString>.
- Reuse the matched name's length for the distance tie-break instead of
  looking the name up again, removing one getLocalizedName() call per card.
- Take the color strings by value; the getters already return by value.

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-23 11:23:04 +02:00
BruebachL
4980f88a7a
[CardDB] Sort power/toughness without splitting every comparison (#7607)
* [CardDB] Sort power/toughness without splitting every comparison

When the card database is sorted by the P/T column, lessThan() runs
O(n log n) times over the whole view, and each call split both strings
into a QStringList ("power/toughness") and then read the two elements
back. For the roughly 36k cards in the database that is millions of
list and string allocations, all for a value that contains at most one
separator.

The comparator now locates the single '/' with indexOf and passes the
two halves as QStringView to lessThanNumerically(), which is changed
from QString to QStringView. The numeric parsing, the "1+*" fallback and
the locale-aware tie-break are unchanged, and strings with no separator
or more than one still fall through to the plain string comparison,
exactly as split()-based size checks did before.

lessThanNumerically() also initializes its two bool out-parameters; they
were declared uninitialized, which only worked because toFloat() always
assigns them.

Compared old and new comparator over a corpus of 2024 power/toughness
strings (4096576 ordered pairs, including malformed values): zero
differences. Full build and ctest (628 tests) pass.

* Extract well-formedness checks in P/T comparator

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-23 10:34:13 +02:00
BruebachL
e666a4978d
[VisualDatabase] Use scoped QSignalBlockers for filter updates (#7641)
* [VisualDatabase] Use scoped QSignalBlockers for filter updates

updateFilterModel() blocked signals on the filter model and its filter tree,\nthen unblocked each of them twice. The second pair was a no-op only because\nthe first pair had already restored the default. Use two scoped\nQSignalBlockers instead, so the models are unblocked exactly once before the\nexplicit changed()/layoutChanged() notifications.\n\nVerification: cockatrice built.

* Drop stale typo note from QSignalBlocker comment

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-23 10:33:29 +02:00
tooomm
c4c7cc0253
[README] Small tweaks (#7585)
Some checks are pending
CodeQL / Analyze (cpp) (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
Build Docker / Servatrice (arm) (push) Waiting to run
Build Docker / Servatrice (x86) (push) Waiting to run
Build Docker / Publish multi-platform Servatrice image (push) Blocked by required conditions
2026-10-22 20:13:43 +02:00
542 changed files with 16022 additions and 14157 deletions

View file

@ -311,16 +311,24 @@ if [[ $RUNNER_OS == macOS ]]; then
if [[ $MAKE_PACKAGE ]]; then
# Workaround https://github.com/actions/runner-images/issues/7522
# have hdiutil repeat the command 10 times in hope of success
# have hdiutil repeat the command 10 times in hope of success.
# The wrapper has to exit non-zero once it gives up: CPack reads that status to
# decide whether the disk image was created, so a zero exit turns a failed hdiutil
# into a much later, misleading "Problem copying the package" error that hides
# hdiutil's own message.
hdiutil_script="/tmp/hdiutil.sh"
# shellcheck disable=SC2016
echo '#!/bin/bash
attempts=10
i=0
while ! hdiutil "$@"; do
if (( ++i >= 10 )); then
echo "Error: hdiutil failed $i times!" >&2
break
while true; do
hdiutil "$@" && exit 0
rc=$?
if (( ++i >= attempts )); then
echo "::error::hdiutil $1 failed $i times (last status $rc), giving up" >&2
exit "$rc"
fi
echo "hdiutil $1 attempt $i/$attempts failed (status $rc), retrying" >&2
sleep 1
done' >"$hdiutil_script"
chmod +x "$hdiutil_script"
@ -459,6 +467,206 @@ if [[ $MAKE_COVERAGE ]]; then
echo "::endgroup::"
fi
if [[ $RUNNER_OS == Windows && ! $MAKE_NO_CLIENT ]]; then
echo "::group::Probe the installer's holder lookup"
# The working directory is still the build dir here: the package steps below are what
# leave and re-enter it, and that is what made a $BUILD_DIR-prefixed path name
# build/build. Both paths are relative to the dir the probe was built into.
probe="./installer-holder-probe.exe"
if [[ ! -f $probe ]]; then
echo "::error file=$0::installer-holder-probe.exe was not built"
exit 1
fi
# The probe exists to name a holder that a process-and-module scan cannot see: one
# that has a file open without having loaded it. Holding a temporary DLL with
# FileShare.None is exactly that case, so this asserts the reason the probe was
# added instead of only that the Restart Manager answers at all. It needs no NSIS
# and no packaging, so it runs on every Windows build that gets this far.
# The holder is a process of its own: the probe never names the process that started it,
# which is what keeps an in-place uninstaller from being named as a holder of the
# directory it is emptying. The same DLL held by the script that starts the probe
# therefore has to come back as nothing, and that is the second case below.
probe_check="./holder-probe-check.ps1"
cat >"$probe_check" <<'POWERSHELL'
$ErrorActionPreference = "Stop"
$dir = Join-Path ([IO.Path]::GetTempPath()) "cockatrice-holder-probe-$PID"
Remove-Item -Recurse -Force $dir -ErrorAction SilentlyContinue
New-Item -ItemType Directory -Force $dir | Out-Null
$probe = (Resolve-Path -LiteralPath $env:PROBE_EXE).Path
function Invoke-Probe([string] $guardDir) {
$start = New-Object System.Diagnostics.ProcessStartInfo
$start.FileName = $probe
$start.UseShellExecute = $false
$start.RedirectStandardOutput = $true
$start.EnvironmentVariables["COCKATRICE_GUARD_DIR"] = $guardDir
$process = [System.Diagnostics.Process]::Start($start)
$read = $process.StandardOutput.ReadToEndAsync()
if (-not $process.WaitForExit(20000)) {
try { $process.Kill() } catch { }
throw "the holder probe did not finish within 20 s for $guardDir"
}
$output = $read.Result
$code = $process.ExitCode
$process.Dispose()
return @{ Code = $code; Output = $output }
}
function Wait-UntilLocked([string] $path) {
$deadline = (Get-Date).AddSeconds(15)
while ((Get-Date) -lt $deadline) {
try {
$open = [IO.File]::Open($path, "Open", "ReadWrite", "None")
$open.Dispose()
} catch {
return
}
Start-Sleep -Milliseconds 100
}
throw "the holder never locked $path"
}
try {
$file = Join-Path $dir "locked.dll"
[IO.File]::WriteAllText($file, "x")
# The holder is a process of its own, not this script: the probe never names the process
# that started it (the case below asserts that), so a file held here would be left out on
# purpose and the check would pass for the wrong reason.
$holderScript = Join-Path $dir "hold.ps1"
Set-Content -LiteralPath $holderScript -Value @'
param([string] $Path)
$handle = [IO.File]::Open($Path, "Open", "ReadWrite", "None")
Start-Sleep -Seconds 120
'@
$powershell = Join-Path $env:SystemRoot "System32\WindowsPowerShell\v1.0\powershell.exe"
$holder = Start-Process -FilePath $powershell -PassThru -ArgumentList @(
"-NoProfile", "-ExecutionPolicy", "Bypass", "-File", "`"$holderScript`"", "-Path", "`"$file`"")
try {
Wait-UntilLocked $file
$locked = Invoke-Probe $dir
if ($locked.Code -ne 1) { throw "expected exit 1 for a locked file, got $($locked.Code) : $($locked.Output)" }
if ($locked.Output -notmatch "pid\s+$($holder.Id)\b") {
throw "the lookup did not name the process holding the file: $($locked.Output)"
}
} finally {
try { $holder.Kill() } catch { }
try { $holder.WaitForExit(5000) | Out-Null } catch { }
}
# The probe is started by the installer, or by an uninstaller that runs in place from the
# directory it is emptying, so the asking process holds files there itself. Naming it would
# ask the user to close the program that is asking - a question neither the close nor the
# end offer can answer, so the guard repeated it until the update was cancelled. A holder
# that is only the asking process has to come back as nothing.
$handle = [IO.File]::Open($file, "Open", "ReadWrite", "None")
try {
$self = Invoke-Probe $dir
} finally {
$handle.Dispose()
}
if ($self.Code -ne 0) { throw "expected exit 0 when the asking process is the only holder, got $($self.Code) : $($self.Output)" }
if ($self.Output -match "pid\s+$PID\b") { throw "the lookup named the process that started it: $($self.Output)" }
# A payload executable that refuses to be replaced is running, whether or not this probe
# may name it: the Restart Manager does not report every mapping, and the image path of a
# process under another account cannot be read from here, so both process lookups can
# come back empty while the program is still there. Held here by the asking process, so
# that it cannot be named - the answer has to be "could not name it", never "nothing is
# holding it", which is what sent an update into an uninstall that could only fail
# halfway. Exit 3 is the code the guard answers by asking the user to close it and retry.
$image = Join-Path $dir "oracle.exe"
[IO.File]::WriteAllText($image, "x")
$handle = [IO.File]::Open($image, "Open", "ReadWrite", "None")
try {
$unnameable = Invoke-Probe $dir
} finally {
$handle.Dispose()
}
if ($unnameable.Code -ne 3) {
throw "expected exit 3 for a payload executable that is in use but cannot be named, got $($unnameable.Code) : $($unnameable.Output)"
}
if ($unnameable.Output -notmatch "oracle\.exe is in use") {
throw "the answer did not name the executable it could not replace: $($unnameable.Output)"
}
$empty = Join-Path $dir "empty"
New-Item -ItemType Directory -Force $empty | Out-Null
$nothing = Invoke-Probe $empty
if ($nothing.Code -ne 0) { throw "expected exit 0 for a directory with nothing open, got $($nothing.Code) : $($nothing.Output)" }
# A process running from the directory is a holder even when it has no file open: an
# instance holds its payload as mapped images, not as handles, and that is the state
# the guard used to miss - it passed, the purge failed, and the install ended in a
# warning with no offer to close and try again. The image is a copy of a native
# Windows program, so it starts without its usual directory next to it, and it carries
# one of the payload's own names because that is what the lookup names.
$copy = Join-Path $dir "cockatrice.exe"
Copy-Item -LiteralPath (Join-Path $env:SystemRoot "System32\cmd.exe") -Destination $copy
$running = Start-Process -FilePath $copy -ArgumentList "/c", "ping -n 20 127.0.0.1 >nul" -PassThru
try {
Start-Sleep -Milliseconds 1500
$byImage = Invoke-Probe $dir
} finally {
try { $running.Kill() } catch { }
# Wait for the image to be released, or the cleanup below leaves the copy behind.
try { $running.WaitForExit(5000) | Out-Null } catch { }
}
if ($byImage.Code -ne 1) { throw "expected exit 1 for a process running from the directory, got $($byImage.Code) : $($byImage.Output)" }
if ($byImage.Output -notmatch "cockatrice\.exe \(pid\s+$($running.Id)") {
throw "the lookup did not name the process running from the directory: $($byImage.Output)"
}
# A program in a folder below the directory is not an instance of the installation, even
# when it carries a payload program's name: the install directory can be a folder the
# user keeps other applications in, each in its own subfolder, and naming one of those
# asked for a close the probe never sends and an end it refuses to perform, so the guard
# could only abort the update. A program that really does hold a payload file is still
# named, by the Restart Manager lookup exercised above.
$nested = Join-Path $dir "other"
New-Item -ItemType Directory -Force $nested | Out-Null
$nestedImage = Join-Path $nested "cockatrice.exe"
Copy-Item -LiteralPath (Join-Path $env:SystemRoot "System32\cmd.exe") -Destination $nestedImage
$nestedRunning = Start-Process -FilePath $nestedImage -ArgumentList "/c", "ping -n 20 127.0.0.1 >nul" -PassThru
try {
Start-Sleep -Milliseconds 1500
$inSubfolder = Invoke-Probe $dir
} finally {
try { $nestedRunning.Kill() } catch { }
try { $nestedRunning.WaitForExit(5000) | Out-Null } catch { }
}
if ($inSubfolder.Code -ne 0) {
throw "expected exit 0 for a program in a folder below the directory, got $($inSubfolder.Code) : $($inSubfolder.Output)"
}
# A program the user keeps in the directory itself is not a payload program either: the
# guard ends only what the payload installs, and naming anything else asks for an answer
# that cannot free a single file.
$foreign = Join-Path $dir "tool.exe"
Copy-Item -LiteralPath (Join-Path $env:SystemRoot "System32\cmd.exe") -Destination $foreign
$foreignRunning = Start-Process -FilePath $foreign -ArgumentList "/c", "ping -n 20 127.0.0.1 >nul" -PassThru
try {
Start-Sleep -Milliseconds 1500
$ignored = Invoke-Probe $dir
} finally {
try { $foreignRunning.Kill() } catch { }
try { $foreignRunning.WaitForExit(5000) | Out-Null } catch { }
}
if ($ignored.Code -ne 0) {
throw "expected exit 0 for a program the payload does not install, got $($ignored.Code) : $($ignored.Output)"
}
Write-Host "holder lookup named pid $($holder.Id) for a file another process holds, named nothing for a file only the asking process holds, reported a payload executable it could not name as in use instead of free, named nothing for an empty directory, named pid $($running.Id) for a payload program running from the directory, and named nothing for a payload program in a folder below it or for a program the payload does not install"
} finally {
Remove-Item -Recurse -Force $dir -ErrorAction SilentlyContinue
}
POWERSHELL
if ! PROBE_EXE="$probe" powershell -NoProfile -File "$probe_check"; then
rm -f "$probe_check"
exit 1
fi
rm -f "$probe_check"
echo "::endgroup::"
fi
if [[ $MAKE_INSTALL ]]; then
echo "::group::Install"
cmake --build . --target install --config "$BUILDTYPE"

View file

@ -101,6 +101,36 @@ jobs:
--title "$release_name" \
--notes-file "$body_path"
vcpkg-baseline:
name: vcpkg baseline
runs-on: ubuntu-slim
steps:
- name: "Checkout"
uses: actions/checkout@v7
# vcpkg-tool reads versions/baseline.json out of the commit named by
# `builtin-baseline`, through the `vcpkg` submodule's git history. A submodule
# pointer that lags the manifest - e.g. a stale `vcpkg/` worktree captured by
# `git add` in a PR - makes every vcpkg leg fail in configure with "failed to
# `git show` versions/baseline.json". That reads like a baseline or network
# problem, when the pointer is what has to move. Check the two agree here in
# seconds instead of on five build legs.
- name: "Check the submodule pointer against the manifest baseline"
shell: bash
run: |
pointer="$(git rev-parse HEAD:vcpkg 2>/dev/null || true)"
baseline="$(sed -nE 's/.*"builtin-baseline"[[:space:]]*:[[:space:]]*"([0-9a-f]{40})".*/\1/p' vcpkg.json)"
if [[ -z "$pointer" || -z "$baseline" ]]; then
echo "::error file=vcpkg.json::could not read the vcpkg submodule pointer or the builtin-baseline"
exit 1
fi
if [[ "$pointer" != "$baseline" ]]; then
echo "::error file=vcpkg.json::vcpkg submodule is at $pointer but builtin-baseline is $baseline"
echo "Move them together: git -C vcpkg checkout $baseline && git add vcpkg"
exit 1
fi
echo "vcpkg submodule and builtin-baseline agree on $baseline"
build-linux:
strategy:
fail-fast: false
@ -466,7 +496,7 @@ jobs:
vcpkg_upload: 1 # only one leg per vcpkg_scope hands its archives over
name: ${{ matrix.os }} ${{ matrix.target }}${{ matrix.soc == 'Intel' && ' Intel' || '' }}${{ matrix.type == 'Debug' && ' Debug' || '' }}
needs: configure
needs: [configure, vcpkg-baseline]
runs-on: ${{ matrix.runner }}
timeout-minutes: 100
env:
@ -584,11 +614,17 @@ jobs:
# job. A scope nobody has written to yet therefore leaves the directory missing
# and fails the job, which is exactly the state every scope starts in. Make the
# directory up front so an empty scope is a cache miss instead of an error.
# always() covers the cache step itself failing: the action's post save still runs
# then, and it should report the real error instead of ENOENT. It cannot rescue a
# failure before the cache step, since a post step only runs for an action whose
# main step did. The fallback keeps this guard from failing when the cache step was
# skipped and left no path output.
- name: "Create vcpkg cache directory"
if: always()
shell: bash
env:
CACHE_DIR: '${{ steps.vcpkg-cache.outputs.path }}'
run: mkdir -p "$CACHE_DIR"
run: mkdir -p "${CACHE_DIR:-$GITHUB_WORKSPACE/.vcpkg-cache}"
# Uses environment variables, see compile.sh for more details
- name: "Build Cockatrice"

View file

@ -90,7 +90,7 @@ endif()
# A project name is needed for CPack
# Version can be overriden by git tags, see cmake/getversion.cmake
project("Cockatrice" VERSION 3.1.2)
project("Cockatrice" VERSION 3.2.0)
# Set release name if not provided via env/cmake var
if(NOT DEFINED GIT_TAG_RELEASENAME)
@ -250,7 +250,22 @@ message(STATUS "Update Translations: ${UPDATE_TRANSLATIONS}")
include(FindQtRuntime)
# Reject APIs that were deprecated before the oldest Qt release we support
# (6.4). Qt 6.5 renamed the switch, so use whichever spelling the found
# version understands while still compiling everywhere.
if(Qt6_VERSION VERSION_GREATER_EQUAL 6.5)
add_compile_definitions(QT_DISABLE_DEPRECATED_UP_TO=0x060400)
else()
add_compile_definitions(QT_DISABLE_DEPRECATED_BEFORE=0x060400)
endif()
# Set once here for every target: these variables are inherited by the
# subdirectories, so the per-directory copies were redundant. Only the
# variables are set; qt_standard_project_setup would also change the runtime
# output directories and the install RPATH.
set(CMAKE_AUTOMOC TRUE)
set(CMAKE_AUTOUIC TRUE)
set(CMAKE_AUTORCC TRUE)
# Find other needed libraries
find_package(Protobuf CONFIG)
@ -420,6 +435,9 @@ if(WITH_ORACLE OR WITH_CLIENT)
add_subdirectory(${CMAKE_SOURCE_DIR}/libcockatrice_models ${CMAKE_BINARY_DIR}/libcockatrice_models)
add_subdirectory(${CMAKE_SOURCE_DIR}/libcockatrice_filters ${CMAKE_BINARY_DIR}/libcockatrice_filters)
endif()
if(WITH_CLIENT)
add_subdirectory(${CMAKE_SOURCE_DIR}/libcockatrice_game ${CMAKE_BINARY_DIR}/libcockatrice_game)
endif()
if(WITH_SERVER)
add_subdirectory(servatrice)
@ -431,6 +449,13 @@ if(WITH_CLIENT)
set(CPACK_INSTALL_CMAKE_PROJECTS "Cockatrice;Cockatrice;ALL;/" ${CPACK_INSTALL_CMAKE_PROJECTS})
endif()
if(WIN32 AND WITH_CLIENT)
# Runs from the installer's $PLUGINSDIR when a purge fails, and is never installed
# (see LogProcessesUsingInstallDir in cmake/NSIS.template.in), so it has no install
# rules and is not part of the client's staged tree.
add_subdirectory(${CMAKE_SOURCE_DIR}/tools/installer-holder-probe ${CMAKE_BINARY_DIR}/tools/installer-holder-probe)
endif()
if(WITH_ORACLE)
add_subdirectory(oracle)
set(CPACK_INSTALL_CMAKE_PROJECTS "Oracle;Oracle;ALL;/" ${CPACK_INSTALL_CMAKE_PROJECTS})
@ -443,5 +468,5 @@ endif()
if(Qt6_FOUND AND Qt6_VERSION_MINOR GREATER_EQUAL 3)
# Qt6.3+ requires project finalization to support translations
qt6_finalize_project()
qt_finalize_project()
endif()

View file

@ -15,9 +15,10 @@
---
<br><pre><p align='center'>
<b>To get started with Cockatrice &#8674; [view our webpage](https://cockatrice.github.io/)</b><br>
<b>To get support, or suggest changes to the app &#8674; [file an issue](https://github.com/Cockatrice/Cockatrice/issues) ([How?](https://github.com/Cockatrice/Cockatrice/wiki/How-to-Create-a-GitHub-Ticket-Regarding-Cockatrice))</b>
<b>To help with development &#8674; learn [how to contribute](#contribute-)</b>
<b>To get started with Cockatrice &#8674; [view our webpage](https://cockatrice.github.io/)</b>
<b>To get support, or suggest changes to the app &#8674; [file an issue](https://github.com/Cockatrice/Cockatrice/issues) ([How?](https://github.com/Cockatrice/Cockatrice/wiki/How-to-Create-a-GitHub-Ticket-Regarding-Cockatrice))</b><br>
<b>To learn about the app and its code &#8674; [read our code documentation](https://cockatrice.github.io/docs/)</b>
<b>To help with development &#8674; learn [how to contribute](#contribute)</b>
</pre><p><br>
@ -83,7 +84,7 @@ Join our [Discord community](https://discord.gg/3Z9yzmA) to connect with other p
### Code
To contribute code to the project, please review our [guidelines](https://github.com/Cockatrice/Cockatrice/blob/master/.github/CONTRIBUTING.md) first.<br>
To commit code to the project, please review our [Contribution Guidelines](https://github.com/Cockatrice/Cockatrice/blob/master/.github/CONTRIBUTING.md) first.<br>
We maintain two tags for contributors to easier find issues to potentially work on:
- [![Good first issue](https://img.shields.io/github/issues/cockatrice/cockatrice/Good%20First%20Issue)](https://github.com/Cockatrice/Cockatrice/issues?utf8=%E2%9C%93&q=is%3Aopen%20is%3Aissue%20label%3A%22Good%20first%20issue%22%20)<br>
Issues tagged in this way provide a simple way to get started. They don't require much experience to be worked on.
@ -95,7 +96,7 @@ We'll happily advice on how best to implement a feature, or we can show you wher
You can also have a look at our `Todo List` in our [Code Documentation](https://cockatrice.github.io/docs) or search the repo for [`\todo` comments](https://github.com/search?q=repo%3ACockatrice%2FCockatrice%20%5Ctodo&type=code).
### Documentation [![CI Docs](https://github.com/Cockatrice/Cockatrice/actions/workflows/documentation-build.yml/badge.svg?event=push)](https://github.com/Cockatrice/Cockatrice/actions/workflows/documentation-build.yml?query=event%3Apush)
### Documentation [![CI Docs](https://github.com/Cockatrice/Cockatrice/actions/workflows/documentation-build.yml/badge.svg?event=push)](https://github.com/Cockatrice/Cockatrice/actions/workflows/documentation-build.yml?query=event%3Arelease+event%3Aworkflow_dispatch)
There are various places where useful information for different needs are maintained:
- [Official Code Documentation](https://cockatrice.github.io/docs/)
@ -104,7 +105,8 @@ There are various places where useful information for different needs are mainta
- [Official README](https://github.com/Cockatrice/Cockatrice/blob/master/README.md) `This file`
- [Official CONTRIBUTING](https://github.com/Cockatrice/Cockatrice/blob/master/.github/CONTRIBUTING.md)
Cockatrice tries to use the [Google Developer Documentation Style Guide](https://developers.google.com/style/) to ensure consistent documentation. We encourage you to improve the documentation by suggesting edits based on this guide.
Cockatrice tries to use the [Google Developer Documentation Style Guide](https://developers.google.com/style/) to ensure consistent documentation.
We encourage everybody to improve the documentation by suggesting edits based on this guide.
### Translation [![Transifex Project](https://img.shields.io/badge/translate-on%20transifex-brightgreen)](https://explore.transifex.com/cockatrice/cockatrice/)

File diff suppressed because it is too large Load diff

View file

@ -57,6 +57,29 @@ try {
}
}
# --- What was holding the files, read from the log as well -------------------
# The guard and the close attempt each log one line naming every holder and what
# happened to it. Carrying the last of each as event data keeps an abort caused by
# a running instance actionable without opening the attachment. Kept out of the
# message so the issue still groups on the reason alone.
$Holders = ''
$CloseResult = ''
$EndResult = ''
if (Test-Path -LiteralPath $LogPath) {
$holderLine = Select-String -LiteralPath $LogPath -Pattern 'guard: still in use by (.*)$' | Select-Object -Last 1
if ($holderLine) {
$Holders = $holderLine.Matches[0].Groups[1].Value
}
$closeLine = Select-String -LiteralPath $LogPath -Pattern '(close-holders: .*)$' | Select-Object -Last 1
if ($closeLine) {
$CloseResult = $closeLine.Matches[0].Groups[1].Value
}
$endLine = Select-String -LiteralPath $LogPath -Pattern '(end-holders: .*)$' | Select-Object -Last 1
if ($endLine) {
$EndResult = $endLine.Matches[0].Groups[1].Value
}
}
# --- Event ---------------------------------------------------------------
$eventId = [guid]::NewGuid().ToString('N')
$now = (Get-Date).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ssZ')
@ -75,6 +98,9 @@ try {
extra = @{
reason = $Reason
os = [System.Environment]::OSVersion.VersionString
holders = $Holders
close_result = $CloseResult
end_result = $EndResult
}
}
$eventJson = $sentryEvent | ConvertTo-Json -Compress -Depth 6

View file

@ -25,9 +25,7 @@ set(cockatrice_SOURCES
src/client/settings/shortcut_treeview.cpp
src/client/settings/shortcuts_settings.cpp
src/interface/deck_loader/card_node_function.cpp
src/interface/deck_loader/deck_file_format.cpp
src/interface/deck_loader/deck_loader.cpp
src/interface/deck_loader/loaded_deck.cpp
src/interface/widgets/dialogs/dlg_connect.cpp
src/interface/widgets/dialogs/dlg_convert_deck_to_cod_format.cpp
src/interface/widgets/dialogs/dlg_create_game.cpp
@ -71,36 +69,27 @@ set(cockatrice_SOURCES
src/filters/filter_builder.cpp
src/filters/filter_tree_model.cpp
src/filters/syntax_help.cpp
src/game/abstract_game.cpp
src/game/arrow_registry.cpp
src/game_graphics/board/abstract_card_drag_item.cpp
src/game_graphics/board/abstract_card_item.cpp
src/game_graphics/board/abstract_counter.cpp
src/game/board/arrow_data.cpp
src/game_graphics/board/arrow_item.cpp
src/game_graphics/board/arrow_registry.cpp
src/game_graphics/board/arrow_target.cpp
src/game_graphics/board/card_drag_item.cpp
src/game_graphics/board/card_item.cpp
src/game/board/card_list.cpp
src/game/board/card_state.cpp
src/game_graphics/board/counter_general.cpp
src/game/board/counter_state.cpp
src/game_graphics/board/translate_counter_name.cpp
src/game_graphics/deckview/deck_view.cpp
src/game_graphics/deckview/deck_view_container.cpp
src/game_graphics/deckview/tabbed_deck_view_container.cpp
src/game_graphics/dialogs/dlg_annotation.cpp
src/game_graphics/dialogs/dlg_create_token.cpp
src/game_graphics/dialogs/dlg_move_top_cards_until.cpp
src/game_graphics/dialogs/dlg_roll_dice.cpp
src/game/game.cpp
src/game/game_event_handler.cpp
src/game/game_meta_info.cpp
src/game_graphics/game_scene.cpp
src/game/game_state.cpp
src/game_graphics/game_view.cpp
src/game_graphics/hand_counter.cpp
src/game_graphics/log/message_log_widget.cpp
src/game/phase.cpp
src/game_graphics/phases_toolbar.cpp
src/game_graphics/player/menu/card_menu.cpp
src/game_graphics/player/menu/custom_zone_menu.cpp
@ -118,23 +107,11 @@ set(cockatrice_SOURCES
src/game_graphics/tally/stats_tally.cpp
src/game_graphics/tally/subtype_tally.cpp
src/game_graphics/tally/tally.cpp
src/game/player/player_actions.cpp
src/game_graphics/player/player_area.cpp
src/game_graphics/player/player_dialogs.cpp
src/game/player/player_event_handler.cpp
src/game_graphics/player/player_graphics_item.cpp
src/game/player/player_info.cpp
src/game_graphics/player/player_list_widget.cpp
src/game/player/player_logic.cpp
src/game/player/player_manager.cpp
src/game_graphics/player/player_target.cpp
src/game/replay.cpp
src/game/zones/card_zone_logic.cpp
src/game/zones/hand_zone_logic.cpp
src/game/zones/pile_zone_logic.cpp
src/game/zones/stack_zone_logic.cpp
src/game/zones/table_zone_logic.cpp
src/game/zones/view_zone_logic.cpp
src/game_graphics/zones/card_zone.cpp
src/game_graphics/zones/hand_zone.cpp
src/game_graphics/zones/pile_zone.cpp
@ -172,6 +149,7 @@ set(cockatrice_SOURCES
src/interface/widgets/utility/reversed_completer_model.cpp
src/interface/pixel_map_generator.cpp
src/interface/theme_config.cpp
src/interface/theme_icon.cpp
src/interface/theme_manager.cpp
src/interface/palette_editor/color_button.cpp
src/interface/palette_editor/palette_generator.cpp
@ -194,6 +172,7 @@ set(cockatrice_SOURCES
src/interface/widgets/cards/card_info_picture_widget.cpp
src/interface/widgets/cards/card_info_picture_with_text_overlay_widget.cpp
src/interface/widgets/cards/card_info_text_widget.cpp
src/interface/widgets/cards/card_picture_delegate.cpp
src/interface/widgets/cards/card_size_widget.cpp
src/interface/widgets/cards/deck_card_zone_display_widget.cpp
src/interface/widgets/cards/deck_preview_card_picture_widget.cpp
@ -313,6 +292,7 @@ set(cockatrice_SOURCES
src/interface/widgets/utility/sequence_edit.cpp
src/interface/widgets/utility/visibility_change_listener.cpp
src/interface/widgets/utility/visibility_change_listener.h
src/interface/widgets/visual_database_display/card_database_visual_view.cpp
src/interface/widgets/visual_database_display/visual_database_display_color_filter_widget.cpp
src/interface/widgets/visual_database_display/visual_database_display_filter_save_load_widget.cpp
src/interface/widgets/visual_database_display/visual_database_display_filter_toolbar_widget.cpp
@ -345,6 +325,7 @@ set(cockatrice_SOURCES
src/interface/widgets/visual_deck_storage/visual_deck_storage_tag_filter_widget.cpp
src/interface/widgets/visual_deck_storage/visual_deck_storage_widget.cpp
src/interface/window_main.cpp
src/installer_close_server.cpp
src/main.cpp
src/single_instance_manager.cpp
src/interface/widgets/tabs/abstract_tab_deck_editor.cpp
@ -450,6 +431,7 @@ set(cockatrice_SOURCES
src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_commander_api_response_budget_navigation_widget.h
src/interface/widgets/utility/compact_push_button.cpp
src/interface/widgets/utility/compact_push_button.h
src/installer_close_server.h
src/single_instance_manager.h
src/client/url_scheme_event_filter.h
src/interface/intents/intent_connect_to_server.cpp
@ -511,7 +493,7 @@ if(APPLE)
set(cockatrice_SOURCES ${cockatrice_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/resources/appicon.icns)
endif(APPLE)
qt6_add_resources(cockatrice_RESOURCES_RCC ${cockatrice_RESOURCES})
qt_add_resources(cockatrice_RESOURCES_RCC ${cockatrice_RESOURCES})
# Declare path variables
set(ICONDIR
@ -532,7 +514,7 @@ set(COCKATRICE_MAC_QM_INSTALL_DIR "cockatrice.app/Contents/Resources/translation
set(COCKATRICE_UNIX_QM_INSTALL_DIR "share/cockatrice/translations")
set(COCKATRICE_WIN32_QM_INSTALL_DIR "translations")
qt6_add_executable(
qt_add_executable(
cockatrice
WIN32
MACOSX_BUNDLE
@ -544,7 +526,7 @@ qt6_add_executable(
target_precompile_headers(cockatrice PRIVATE "${CMAKE_SOURCE_DIR}/cmake/pch/qtwidgets_pch.h")
qt6_add_shaders(
qt_add_shaders(
cockatrice
"onboarding_shaders"
PREFIX
@ -556,7 +538,7 @@ qt6_add_shaders(
src/interface/widgets/onboarding/shaders/brand_plate.frag
)
qt6_add_resources(
qt_add_resources(
cockatrice
"onboarding_qml"
PREFIX
@ -572,6 +554,7 @@ target_link_libraries(
PUBLIC libcockatrice_card
libcockatrice_deck_list
libcockatrice_filters
libcockatrice_game
libcockatrice_utility
libcockatrice_network
libcockatrice_models
@ -788,7 +771,7 @@ endif()
if(Qt6LinguistTools_FOUND)
#Qt6 Translations happen after the executable is built up
if(UPDATE_TRANSLATIONS)
qt6_add_translations(
qt_add_translations(
cockatrice
TS_FILES
${cockatrice_TS}
@ -798,7 +781,7 @@ if(Qt6LinguistTools_FOUND)
cockatrice_QM
)
else()
qt6_add_translations(cockatrice TS_FILES ${cockatrice_TS} QM_FILES_OUTPUT_VARIABLE cockatrice_QM)
qt_add_translations(cockatrice TS_FILES ${cockatrice_TS} QM_FILES_OUTPUT_VARIABLE cockatrice_QM)
endif()
if(UNIX)
@ -824,4 +807,4 @@ if(Qt6LinguistTools_FOUND)
endforeach()
endif()
qt6_finalize_target(cockatrice)
qt_finalize_target(cockatrice)

View file

@ -6,19 +6,18 @@
<file>resources/hand.svg</file>
<file>resources/hr.jpg</file>
<file>resources/icons/arrow_bottom_green.svg</file>
<file>resources/icons/arrow_down_green.svg</file>
<file>resources/icons/arrow_down.svg</file>
<file>resources/icons/arrow_history.svg</file>
<file>resources/icons/arrow_left_green.svg</file>
<file>resources/icons/arrow_left.svg</file>
<file>resources/icons/arrow_redo.svg</file>
<file>resources/icons/arrow_right_blue.svg</file>
<file>resources/icons/arrow_right_green.svg</file>
<file>resources/icons/arrow_top_green.svg</file>
<file>resources/icons/arrow_up_green.svg</file>
<file>resources/icons/arrow_right.svg</file>
<file>resources/icons/arrow_right_sideboard.svg</file>
<file>resources/icons/arrow_to_bottom.svg</file>
<file>resources/icons/arrow_to_top.svg</file>
<file>resources/icons/arrow_up.svg</file>
<file>resources/icons/arrow_undo.svg</file>
<file>resources/icons/circle_half_stroke.svg</file>
<file>resources/icons/clearsearch.svg</file>
<file>resources/icons/cogwheel.svg</file>
<file>resources/icons/conceded.svg</file>
<file>resources/icons/decrement.svg</file>
<file>resources/icons/delete.svg</file>
@ -28,7 +27,6 @@
<file>resources/icons/filter.svg</file>
<file>resources/icons/floppy_disk.svg</file>
<file>resources/icons/forgot_password.svg</file>
<file>resources/icons/gear.svg</file>
<file>resources/icons/increment.svg</file>
<file>resources/icons/info.svg</file>
<file>resources/icons/lock.svg</file>
@ -41,7 +39,6 @@
<file>resources/icons/reload.svg</file>
<file>resources/icons/remove_row.svg</file>
<file>resources/icons/rename.svg</file>
<file>resources/icons/scale_balanced.svg</file>
<file>resources/icons/scales.svg</file>
<file>resources/icons/scroll.svg</file>
<file>resources/icons/search.svg</file>
@ -52,7 +49,6 @@
<file>resources/icons/swap.svg</file>
<file>resources/icons/sync.svg</file>
<file>resources/icons/tab_changed.svg</file>
<file>resources/icons/update.png</file>
<file>resources/icons/view.svg</file>
<file>resources/icons/mana/B.svg</file>

View file

@ -1,793 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64"
height="64"
id="svg2646"
sodipodi:version="0.32"
inkscape:version="0.48.4 r9943 custom"
version="1.0"
sodipodi:docname="arrow_down_green.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
<defs
id="defs2648">
<linearGradient
id="linearGradient3169">
<stop
style="stop-color:#0000ff;stop-opacity:1;"
offset="0"
id="stop3171" />
<stop
style="stop-color:#000067;stop-opacity:1;"
offset="1"
id="stop3173" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient3175"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient4766">
<stop
style="stop-color:#784421;stop-opacity:1;"
offset="0"
id="stop4768" />
<stop
style="stop-color:#3d2210;stop-opacity:0;"
offset="1"
id="stop4770" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2396"
gradientUnits="userSpaceOnUse"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)" />
<linearGradient
id="linearGradient4758">
<stop
style="stop-color:#a05a2c;stop-opacity:1;"
offset="0"
id="stop4760" />
<stop
style="stop-color:#3d2210;stop-opacity:1;"
offset="1"
id="stop4762" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2399"
gradientUnits="userSpaceOnUse"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)" />
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective2654" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2691"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2693"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2695"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2707"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2709"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2711"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient3508"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient3510"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient3512"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient3514"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient3516"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient3518"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient3520"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient3522"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient3524"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2444"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2446"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2448"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2450"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2452"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2454"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2456"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2458"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2460"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2478"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2480"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2482"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2484"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2486"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2488"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2490"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2492"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2494"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2527"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2529"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2531"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2533"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2535"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2537"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2539"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2541"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2543"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2545"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2547"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2549"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2561"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2563"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2565"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2594"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2596"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2598"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2600"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2602"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2604"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2606"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2608"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2610"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2612"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2614"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2616"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2618"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2620"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2622"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="7.625"
inkscape:cx="8.25663"
inkscape:cy="31.788561"
inkscape:document-units="px"
inkscape:current-layer="layer2"
showgrid="false"
inkscape:window-width="1272"
inkscape:window-height="723"
inkscape:window-x="0"
inkscape:window-y="23"
inkscape:window-maximized="0" />
<metadata
id="metadata2651">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
style="display:inline" />
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Pfeil"
style="display:inline">
<path
style="fill:#96ff96;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:3;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 52.71118,29.086208 -12.351931,0 12.852459,-18.346676 -42.685714,0 12.327869,18.346676 -12.351929,0 21.104622,25.485735 z"
id="rect2714"
sodipodi:nodetypes="cccccccc"
inkscape:connector-curvature="0" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 25 KiB

View file

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M12 5v13"/>
<path d="M18 12l-6 6-6-6"/>
</svg>

After

Width:  |  Height:  |  Size: 219 B

View file

@ -1,793 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64"
height="64"
id="svg2646"
sodipodi:version="0.32"
inkscape:version="0.48.4 r9943 custom"
version="1.0"
sodipodi:docname="arrow_up_green.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
<defs
id="defs2648">
<linearGradient
id="linearGradient3169">
<stop
style="stop-color:#0000ff;stop-opacity:1;"
offset="0"
id="stop3171" />
<stop
style="stop-color:#000067;stop-opacity:1;"
offset="1"
id="stop3173" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient3175"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient4766">
<stop
style="stop-color:#784421;stop-opacity:1;"
offset="0"
id="stop4768" />
<stop
style="stop-color:#3d2210;stop-opacity:0;"
offset="1"
id="stop4770" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2396"
gradientUnits="userSpaceOnUse"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)" />
<linearGradient
id="linearGradient4758">
<stop
style="stop-color:#a05a2c;stop-opacity:1;"
offset="0"
id="stop4760" />
<stop
style="stop-color:#3d2210;stop-opacity:1;"
offset="1"
id="stop4762" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2399"
gradientUnits="userSpaceOnUse"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)" />
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective2654" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2691"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2693"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2695"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2707"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2709"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2711"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient3508"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient3510"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient3512"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient3514"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient3516"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient3518"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient3520"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient3522"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient3524"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2444"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2446"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2448"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2450"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2452"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2454"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2456"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2458"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2460"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2478"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2480"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2482"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2484"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2486"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2488"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2490"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2492"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2494"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2527"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2529"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2531"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2533"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2535"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2537"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2539"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2541"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2543"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2545"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2547"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2549"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2561"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2563"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2565"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2594"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2596"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2598"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2600"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2602"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2604"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2606"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2608"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2610"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2612"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2614"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2616"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2618"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2620"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2622"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="7.625"
inkscape:cx="8.25663"
inkscape:cy="31.788561"
inkscape:document-units="px"
inkscape:current-layer="layer2"
showgrid="false"
inkscape:window-width="1272"
inkscape:window-height="723"
inkscape:window-x="0"
inkscape:window-y="23"
inkscape:window-maximized="0" />
<metadata
id="metadata2651">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
style="display:inline" />
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Pfeil"
style="display:inline">
<path
style="fill:#96ff96;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:3;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 53.104623,35.38129 -12.351931,0 0,-32.248315 -17.505386,0 0,32.248315 -12.351929,0 21.104622,25.485735 21.104624,-25.485735 z"
id="rect2714"
sodipodi:nodetypes="cccccccc"
inkscape:connector-curvature="0" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 25 KiB

View file

@ -1,8 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<title>
history
</title>
<path d="M9 6v5h.06l2.48 2.47 1.41-1.41L11 10.11V6H9z"/>
<path d="M10 1a9 9 0 0 0-7.85 13.35L.5 16H6v-5.5l-2.38 2.38A7 7 0 1 1 10 17v2a9 9 0 0 0 0-18z"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M3 12a9 9 0 1 0 3-6.7"/>
<path d="M3 4v5h5"/>
<path d="M12 7v5l3 2"/>
</svg>

Before

Width:  |  Height:  |  Size: 332 B

After

Width:  |  Height:  |  Size: 249 B

Before After
Before After

View file

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M19 12H6"/>
<path d="M12 6l-6 6 6 6"/>
</svg>

After

Width:  |  Height:  |  Size: 218 B

View file

@ -1,791 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64"
height="64"
id="svg2646"
sodipodi:version="0.32"
inkscape:version="0.47pre4 r22446"
version="1.0"
sodipodi:docname="test.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
<defs
id="defs2648">
<linearGradient
id="linearGradient3169">
<stop
style="stop-color:#0000ff;stop-opacity:1;"
offset="0"
id="stop3171" />
<stop
style="stop-color:#000067;stop-opacity:1;"
offset="1"
id="stop3173" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient3175"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient4766">
<stop
style="stop-color:#784421;stop-opacity:1;"
offset="0"
id="stop4768" />
<stop
style="stop-color:#3d2210;stop-opacity:0;"
offset="1"
id="stop4770" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2396"
gradientUnits="userSpaceOnUse"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)" />
<linearGradient
id="linearGradient4758">
<stop
style="stop-color:#a05a2c;stop-opacity:1;"
offset="0"
id="stop4760" />
<stop
style="stop-color:#3d2210;stop-opacity:1;"
offset="1"
id="stop4762" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2399"
gradientUnits="userSpaceOnUse"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)" />
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective2654" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2691"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2693"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2695"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2707"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2709"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2711"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient3508"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient3510"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient3512"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient3514"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient3516"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient3518"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient3520"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient3522"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient3524"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2444"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2446"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2448"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2450"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2452"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2454"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2456"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2458"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2460"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2478"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2480"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2482"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2484"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2486"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2488"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2490"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2492"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2494"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2527"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2529"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2531"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2533"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2535"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2537"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2539"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2541"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2543"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2545"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2547"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2549"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2561"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2563"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2565"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2594"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2596"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2598"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2600"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2602"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2604"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2606"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2608"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2610"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2612"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2614"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2616"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2618"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2620"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2622"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="7.203125"
inkscape:cx="3.6095445"
inkscape:cy="32"
inkscape:document-units="px"
inkscape:current-layer="layer2"
showgrid="false"
inkscape:window-width="1272"
inkscape:window-height="718"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="0" />
<metadata
id="metadata2651">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
style="display:inline" />
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Pfeil"
style="display:inline">
<path
style="fill:#96ff96;fill-opacity:1;stroke:#000000;stroke-width:3;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="M 28.802264,8.8785925 2.0835141,31.441092 l 26.7187499,22.5625 0,-13.40625 31.59375,0 0,-18.3125 -31.59375,0 0,-13.4062495 z"
id="rect4156" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 25 KiB

View file

@ -1,40 +1,4 @@
<?xml version="1.0" encoding="windows-1252"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" x="0px"
y="0px" width="485.212px" height="485.212px" viewBox="0 0 485.212 485.212"
style="enable-background:new 0 0 485.212 485.212;" xml:space="preserve">
<g>
<path d="M242.607,424.559c-75.252,0-136.468-61.209-136.468-136.465c0-75.252,61.216-136.466,136.468-136.466v90.978 l151.629-121.302L242.607,0v90.978c-108.687,0-197.117,88.432-197.117,197.117c0,108.691,88.43,197.118,197.117,197.118 c108.687,0,197.114-88.427,197.114-197.118h-60.645C379.077,363.35,317.859,424.559,242.607,424.559z"/>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M15 14l5-5-5-5"/>
<path d="M20 9H9.5A5.5 5.5 0 0 0 4 14.5a5.5 5.5 0 0 0 5.5 5.5H13"/>
</svg>

Before

Width:  |  Height:  |  Size: 1,018 B

After

Width:  |  Height:  |  Size: 263 B

Before After
Before After

View file

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M5 12h13"/>
<path d="M12 6l6 6-6 6"/>
</svg>

After

Width:  |  Height:  |  Size: 217 B

View file

@ -1,789 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64"
height="64"
id="svg2646"
sodipodi:version="0.32"
inkscape:version="0.46"
version="1.0"
sodipodi:docname="add_to_sideboard.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
<defs
id="defs2648">
<linearGradient
id="linearGradient3169">
<stop
style="stop-color:#0000ff;stop-opacity:1;"
offset="0"
id="stop3171" />
<stop
style="stop-color:#000067;stop-opacity:1;"
offset="1"
id="stop3173" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient3175"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient4766">
<stop
style="stop-color:#784421;stop-opacity:1;"
offset="0"
id="stop4768" />
<stop
style="stop-color:#3d2210;stop-opacity:0;"
offset="1"
id="stop4770" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2396"
gradientUnits="userSpaceOnUse"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)" />
<linearGradient
id="linearGradient4758">
<stop
style="stop-color:#a05a2c;stop-opacity:1;"
offset="0"
id="stop4760" />
<stop
style="stop-color:#3d2210;stop-opacity:1;"
offset="1"
id="stop4762" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2399"
gradientUnits="userSpaceOnUse"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)" />
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective2654" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2691"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2693"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2695"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2707"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2709"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2711"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient3508"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient3510"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient3512"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient3514"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient3516"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient3518"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient3520"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient3522"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient3524"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2444"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2446"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2448"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2450"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2452"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2454"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2456"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2458"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2460"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2478"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2480"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2482"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2484"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2486"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2488"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2490"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2492"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2494"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2527"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2529"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2531"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2533"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2535"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2537"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2539"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2541"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2543"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2545"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2547"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2549"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2561"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2563"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2565"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2594"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2596"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2598"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2600"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2602"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2604"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2606"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2608"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2610"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2612"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2614"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2616"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2618"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2620"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2622"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="7.625"
inkscape:cx="-15.396123"
inkscape:cy="31.722987"
inkscape:document-units="px"
inkscape:current-layer="layer2"
showgrid="false"
inkscape:window-width="1272"
inkscape:window-height="723"
inkscape:window-x="0"
inkscape:window-y="25" />
<metadata
id="metadata2651">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
style="display:inline" />
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Pfeil"
style="display:inline">
<path
style="fill:#64c0ff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 35.38129,10.895377 L 35.38129,23.247308 L 3.1329751,23.247308 L 3.1329751,40.752694 L 35.38129,40.752694 L 35.38129,53.104623 L 60.867025,32.000001 L 35.38129,10.895377 z"
id="rect2714"
sodipodi:nodetypes="cccccccc" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 25 KiB

View file

@ -1,789 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64"
height="64"
id="svg2646"
sodipodi:version="0.32"
inkscape:version="0.46"
version="1.0"
sodipodi:docname="add_to_deck.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
<defs
id="defs2648">
<linearGradient
id="linearGradient3169">
<stop
style="stop-color:#0000ff;stop-opacity:1;"
offset="0"
id="stop3171" />
<stop
style="stop-color:#000067;stop-opacity:1;"
offset="1"
id="stop3173" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient3175"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient4766">
<stop
style="stop-color:#784421;stop-opacity:1;"
offset="0"
id="stop4768" />
<stop
style="stop-color:#3d2210;stop-opacity:0;"
offset="1"
id="stop4770" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2396"
gradientUnits="userSpaceOnUse"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)" />
<linearGradient
id="linearGradient4758">
<stop
style="stop-color:#a05a2c;stop-opacity:1;"
offset="0"
id="stop4760" />
<stop
style="stop-color:#3d2210;stop-opacity:1;"
offset="1"
id="stop4762" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2399"
gradientUnits="userSpaceOnUse"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)" />
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective2654" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2691"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2693"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2695"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2707"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2709"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2711"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient3508"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient3510"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient3512"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient3514"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient3516"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient3518"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient3520"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient3522"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient3524"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2444"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2446"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2448"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2450"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2452"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2454"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2456"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2458"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2460"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2478"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2480"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2482"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2484"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2486"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2488"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2490"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2492"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2494"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2527"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2529"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2531"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2533"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2535"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2537"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2539"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2541"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2543"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2545"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2547"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2549"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2561"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2563"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2565"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2594"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2596"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2598"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2600"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2602"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2604"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2606"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2608"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2610"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2612"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2614"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2616"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2618"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2620"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2622"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="7.625"
inkscape:cx="-45.970664"
inkscape:cy="31.722987"
inkscape:document-units="px"
inkscape:current-layer="layer2"
showgrid="false"
inkscape:window-width="1272"
inkscape:window-height="723"
inkscape:window-x="0"
inkscape:window-y="25" />
<metadata
id="metadata2651">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
style="display:inline" />
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Pfeil"
style="display:inline">
<path
style="fill:#96ff96;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 35.38129,10.895377 L 35.38129,23.247308 L 3.1329751,23.247308 L 3.1329751,40.752694 L 35.38129,40.752694 L 35.38129,53.104623 L 60.867025,32.000001 L 35.38129,10.895377 z"
id="rect2714"
sodipodi:nodetypes="cccccccc" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 25 KiB

View file

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M3 12h9"/>
<path d="M8 7l5 5-5 5"/>
<path d="M16 7h4v10h-4"/>
</svg>

After

Width:  |  Height:  |  Size: 243 B

View file

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M12 4v11"/>
<path d="M6 9l6 6 6-6"/>
<path d="M5 20h14"/>
</svg>

After

Width:  |  Height:  |  Size: 239 B

View file

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M12 20V9"/>
<path d="M6 15l6-6 6 6"/>
<path d="M5 4h14"/>
</svg>

After

Width:  |  Height:  |  Size: 239 B

View file

@ -1,793 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64"
height="64"
id="svg2646"
sodipodi:version="0.32"
inkscape:version="0.48.4 r9943 custom"
version="1.0"
sodipodi:docname="arrow_bottom_green.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
<defs
id="defs2648">
<linearGradient
id="linearGradient3169">
<stop
style="stop-color:#0000ff;stop-opacity:1;"
offset="0"
id="stop3171" />
<stop
style="stop-color:#000067;stop-opacity:1;"
offset="1"
id="stop3173" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient3175"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient4766">
<stop
style="stop-color:#784421;stop-opacity:1;"
offset="0"
id="stop4768" />
<stop
style="stop-color:#3d2210;stop-opacity:0;"
offset="1"
id="stop4770" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2396"
gradientUnits="userSpaceOnUse"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)" />
<linearGradient
id="linearGradient4758">
<stop
style="stop-color:#a05a2c;stop-opacity:1;"
offset="0"
id="stop4760" />
<stop
style="stop-color:#3d2210;stop-opacity:1;"
offset="1"
id="stop4762" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2399"
gradientUnits="userSpaceOnUse"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)" />
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective2654" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2691"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2693"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2695"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2707"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2709"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2711"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient3508"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient3510"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient3512"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient3514"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient3516"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient3518"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient3520"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient3522"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient3524"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2444"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2446"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2448"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2450"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2452"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2454"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2456"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2458"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2460"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2478"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2480"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2482"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2484"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2486"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2488"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2490"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2492"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2494"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2527"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2529"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2531"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2533"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2535"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2537"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2539"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2541"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2543"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2545"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2547"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2549"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2561"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2563"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2565"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2594"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2596"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2598"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2600"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2602"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2604"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2606"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2608"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2610"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2612"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2614"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2616"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2618"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2620"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2622"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="7.625"
inkscape:cx="8.25663"
inkscape:cy="31.788561"
inkscape:document-units="px"
inkscape:current-layer="layer2"
showgrid="false"
inkscape:window-width="1272"
inkscape:window-height="723"
inkscape:window-x="0"
inkscape:window-y="23"
inkscape:window-maximized="0" />
<metadata
id="metadata2651">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
style="display:inline" />
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Pfeil"
style="display:inline">
<path
style="fill:#96ff96;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:3;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 11.002462,36.225266 12.351931,0 -12.852459,18.346676 42.685714,0 -12.327869,-18.346676 12.351929,0 -21.104622,-25.485734 z"
id="rect2714"
sodipodi:nodetypes="cccccccc"
inkscape:connector-curvature="0" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 25 KiB

View file

@ -1,40 +1,4 @@
<?xml version="1.0" encoding="windows-1252"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" x="0px"
y="0px" width="512px" height="512px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;"
xml:space="preserve">
<g>
<path d="M256,448c79.406,0,144-64.594,144-144s-64.594-144-144-144v96L96,128L256,0v96c114.688,0,208,93.313,208,208 c0,114.688-93.312,208-208,208c-114.687,0-208-93.312-208-208h64C112,383.406,176.594,448,256,448z"/>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M9 14 4 9l5-5"/>
<path d="M4 9h10.5A5.5 5.5 0 0 1 20 14.5a5.5 5.5 0 0 1-5.5 5.5H11"/>
</svg>

Before

Width:  |  Height:  |  Size: 874 B

After

Width:  |  Height:  |  Size: 263 B

Before After
Before After

View file

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M12 19V6"/>
<path d="M6 12l6-6 6 6"/>
</svg>

After

Width:  |  Height:  |  Size: 217 B

View file

@ -1,792 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64"
height="64"
id="svg2646"
sodipodi:version="0.32"
inkscape:version="0.48.4 r9943 custom"
version="1.0"
sodipodi:docname="arrow_up_green.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
<defs
id="defs2648">
<linearGradient
id="linearGradient3169">
<stop
style="stop-color:#0000ff;stop-opacity:1;"
offset="0"
id="stop3171" />
<stop
style="stop-color:#000067;stop-opacity:1;"
offset="1"
id="stop3173" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient3175"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient4766">
<stop
style="stop-color:#784421;stop-opacity:1;"
offset="0"
id="stop4768" />
<stop
style="stop-color:#3d2210;stop-opacity:0;"
offset="1"
id="stop4770" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2396"
gradientUnits="userSpaceOnUse"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)" />
<linearGradient
id="linearGradient4758">
<stop
style="stop-color:#a05a2c;stop-opacity:1;"
offset="0"
id="stop4760" />
<stop
style="stop-color:#3d2210;stop-opacity:1;"
offset="1"
id="stop4762" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2399"
gradientUnits="userSpaceOnUse"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)" />
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective2654" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2691"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2693"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2695"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2707"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2709"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2711"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient3508"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient3510"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient3512"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient3514"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient3516"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient3518"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient3520"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient3522"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient3524"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2444"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2446"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2448"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2450"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2452"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2454"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2456"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2458"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2460"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2478"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2480"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2482"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2484"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2486"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2488"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2490"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2492"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2494"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2527"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2529"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2531"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2533"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2535"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2537"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2539"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2541"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2543"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2545"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2547"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2549"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2561"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2563"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2565"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2594"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2596"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2598"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2600"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2602"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2604"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2606"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2608"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2610"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2612"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2614"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2616"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2618"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2620"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2622"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="7.625"
inkscape:cx="8.25663"
inkscape:cy="31.788561"
inkscape:document-units="px"
inkscape:current-layer="layer2"
showgrid="false"
inkscape:window-width="1272"
inkscape:window-height="723"
inkscape:window-x="0"
inkscape:window-y="23"
inkscape:window-maximized="0" />
<metadata
id="metadata2651">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
style="display:inline" />
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Pfeil"
style="display:inline">
<path
style="fill:#96ff96;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:3;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 10.895377,28.61871 12.351931,0 0,32.248315 17.505386,0 0,-32.248315 12.351929,0 L 32.000001,3.132975 10.895377,28.61871 z"
id="rect2714"
sodipodi:nodetypes="cccccccc"
inkscape:connector-curvature="0" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 25 KiB

View file

@ -1 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.--><path d="M512 320C512 214 426 128 320 128L320 512C426 512 512 426 512 320zM64 320C64 178.6 178.6 64 320 64C461.4 64 576 178.6 576 320C576 461.4 461.4 576 320 576C178.6 576 64 461.4 64 320z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<circle cx="12" cy="12" r="9" fill="none" stroke="currentColor" stroke-width="2"/>
<path d="M12 3a9 9 0 0 1 0 18z" fill="currentColor"/>
</svg>

Before

Width:  |  Height:  |  Size: 410 B

After

Width:  |  Height:  |  Size: 209 B

Before After
Before After

View file

@ -1,276 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64"
height="64"
id="svg2"
version="1.1"
inkscape:version="0.48.5 r10040"
sodipodi:docname="icon_clearsearch.svg">
<defs
id="defs4">
<linearGradient
id="linearGradient3709">
<stop
style="stop-color:#4d4d4d;stop-opacity:1;"
offset="0"
id="stop3711" />
<stop
style="stop-color:white;stop-opacity:1;"
offset="1"
id="stop3713" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient3699">
<stop
style="stop-color:#ececec;stop-opacity:1;"
offset="0"
id="stop3701" />
<stop
style="stop-color:#ececec;stop-opacity:0;"
offset="1"
id="stop3703" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient3632">
<stop
style="stop-color:#c87137;stop-opacity:1;"
offset="0"
id="stop3634" />
<stop
style="stop-color:#c87137;stop-opacity:0;"
offset="1"
id="stop3636" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient3622">
<stop
style="stop-color:#f9f9f9;stop-opacity:1;"
offset="0"
id="stop3624" />
<stop
style="stop-color:#f9f9f9;stop-opacity:0;"
offset="1"
id="stop3626" />
</linearGradient>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective10" />
<inkscape:perspective
id="perspective3685"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3709"
id="linearGradient3726"
gradientUnits="userSpaceOnUse"
x1="22.288248"
y1="35.505978"
x2="49.488647"
y2="49.106178" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3622"
id="linearGradient3728"
gradientUnits="userSpaceOnUse"
x1="30.59761"
y1="8.9243031"
x2="30.59761"
y2="21.545816" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3632"
id="linearGradient3730"
gradientUnits="userSpaceOnUse"
x1="28.430279"
y1="47.808765"
x2="29.960159"
y2="47.808765" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3699"
id="linearGradient3732"
gradientUnits="userSpaceOnUse"
x1="29.215645"
y1="1021.9559"
x2="31.852083"
y2="1021.9559" />
<inkscape:perspective
id="perspective3766"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective3797"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective3896"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3699"
id="linearGradient3911"
gradientUnits="userSpaceOnUse"
x1="29.215645"
y1="1021.9559"
x2="31.852083"
y2="1021.9559"
gradientTransform="translate(713.20829,-318.19428)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3709"
id="linearGradient3928"
gradientUnits="userSpaceOnUse"
x1="22.288248"
y1="35.505978"
x2="49.488647"
y2="49.106178" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3622"
id="linearGradient3930"
gradientUnits="userSpaceOnUse"
x1="30.59761"
y1="8.9243031"
x2="30.59761"
y2="21.545816" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3632"
id="linearGradient3932"
gradientUnits="userSpaceOnUse"
x1="28.430279"
y1="47.808765"
x2="29.960159"
y2="47.808765" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3699"
id="linearGradient3934"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(713.20829,-318.19428)"
x1="29.215645"
y1="1021.9559"
x2="31.852083"
y2="1021.9559" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="7.84375"
inkscape:cx="11.205704"
inkscape:cy="35.993597"
inkscape:document-units="px"
inkscape:current-layer="layer2"
showgrid="false"
inkscape:window-width="1920"
inkscape:window-height="1028"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-988.36218)" />
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Verbot">
<g
sodipodi:type="inkscape:box3d"
style="fill:red;fill-opacity:1;stroke:black;stroke-width:0.30000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="g3936"
inkscape:perspectiveID="#perspective10"
inkscape:corner0="-32.72006 : 181.09419 : 0 : 1"
inkscape:corner7="-365.7807 : 14.86007 : 0.25 : 1">
<path
sodipodi:type="inkscape:box3dside"
id="path3946"
style="fill:#afafde;fill-rule:evenodd;stroke:none"
inkscape:box3dsidetype="13"
d="M -11.729084,0.76495424 L -1.0199203,-421.92491 L -1.5309297,-421.89731 L -17.73339,4.4426247 z" />
<path
sodipodi:type="inkscape:box3dside"
id="path3942"
style="fill:#8686bf;fill-rule:evenodd;stroke:none"
inkscape:box3dsidetype="3"
d="M -11.729084,5241.4272 L -1.0199203,33.784832 L -1.0199203,-421.92491 L -11.729084,0.76495424 z" />
<path
sodipodi:type="inkscape:box3dside"
id="path3938"
style="fill:#353564;fill-rule:evenodd;stroke:none"
inkscape:box3dsidetype="6"
d="M -11.729084,5241.4272 L -11.729084,0.76495424 L -17.73339,4.4426247 L -17.73339,5286.737 z" />
<path
sodipodi:type="inkscape:box3dside"
id="path3940"
style="fill:#4d4d9f;fill-rule:evenodd;stroke:none"
inkscape:box3dsidetype="5"
d="M -11.729084,5241.4272 L -1.0199203,33.784832 L -1.5309297,34.124972 L -17.73339,5286.737 z" />
<path
sodipodi:type="inkscape:box3dside"
id="path3948"
style="fill:#e9e9ff;fill-rule:evenodd;stroke:none"
inkscape:box3dsidetype="11"
d="M -17.73339,5286.737 L -1.5309297,34.124972 L -1.5309297,-421.89731 L -17.73339,4.4426247 z" />
<path
sodipodi:type="inkscape:box3dside"
id="path3944"
style="fill:#d7d7ff;fill-rule:evenodd;stroke:none"
inkscape:box3dsidetype="14"
d="M -1.0199203,33.784832 L -1.0199203,-421.92491 L -1.5309297,-421.89731 L -1.5309297,34.124972 z" />
</g>
<path
style="fill:#ff0000;fill-opacity:1;stroke:#cd3535;stroke-width:5.84793520000000020;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="M 52.385908,50.646333 C 62.721799,39.279033 61.886144,21.695001 50.518842,11.359112 39.151542,1.0232223 21.567509,1.8588773 11.231623,13.22618 0.89573232,24.593479 1.7313874,42.177512 13.098689,52.5134 c 11.3673,10.335889 28.951332,9.500234 39.287219,-1.867067 z M 49.738687,48.239307 C 41.198715,57.631478 26.946973,58.753059 17.056847,51.15466 L 49.541588,15.428288 c 8.502064,9.124975 8.737071,23.418851 0.197099,32.811019 z M 46.560682,12.717855 14.075941,48.444228 C 5.5738777,39.31925 5.3388704,25.025377 13.878842,15.633206 22.418813,6.2410344 36.670557,5.1194531 46.560682,12.717855 z"
id="path3787"
inkscape:connector-curvature="0" />
</g>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="8"/>
<path d="M9 9l6 6M15 9l-6 6"/>
</svg>

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 231 B

Before After
Before After

View file

@ -1,29 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" width="102.5024mm" height="102.24421mm"
viewBox="0 0 102.5024 102.24421" version="1.1"
id="svg1"
inkscape:version="1.4 (e7c3feb100, 2024-10-09)" sodipodi:docname="cog_wheel.svg"
xmlns="http://www.w3.org/2000/svg">
<sodipodi:namedview id="namedview1" pagecolor="#ffffff" bordercolor="#000000" borderopacity="0.25"
inkscape:showpageshadow="2" inkscape:pageopacity="0.0" inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1" inkscape:document-units="mm" inkscape:zoom="0.66101291"
inkscape:cx="146.74449" inkscape:cy="193.64221" inkscape:window-width="1829"
inkscape:window-height="951" inkscape:window-x="0" inkscape:window-y="0"
inkscape:window-maximized="1" inkscape:current-layer="layer1"/>
<defs id="defs1"/>
<g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" transform="translate(-66.148059,-97.377896)">
<g id="g1" transform="translate(-165.09777,-82.009607)">
<g id="g2" transform="matrix(0.26458333,0,0,0.26458333,64.983323,161.37858)">
<path style="fill:#333333;stroke-width:94.4882"
d="m 721.34301,94.413051 40.00966,29.763289 29.51933,-9.27053 14.63768,-46.840589 36.83817,0.48792 13.41787,46.108699 28.29952,9.5145 40.74155,-28.299519 29.0314,21.468599 -15.85748,47.08454 16.58937,23.66426 48.30432,-2.68358 12.93,34.88648 -41.71741,27.07971 -0.48792,29.27536 40.49763,26.10387 -10.2464,34.15459 -48.54834,-0.97584 -18.78502,23.42029 15.85749,45.37681 -28.29952,21.71256 -41.22947,-29.27536 -28.54348,9.75846 -13.66184,47.57246 -38.30194,-0.73188 -14.63768,-48.30435 -27.07971,-9.27054 -40.00966,29.27537 -30.25121,-20.49276 17.32125,-46.35266 -17.80918,-24.64009 -49.76812,3.17149 -11.22222,-34.64251 40.74155,-27.07971 0.48792,-30.00725 -41.71739,-27.32367 12.19807,-32.93479 48.30435,2.68358 20.24879,-24.6401 -17.32126,-47.08455 z"
id="path1"/>
<circle style="fill:#f9f9f9;stroke-width:72.1317" id="path2" cx="822.09906" cy="261.28262"
r="83.434792"/>
<circle style="fill:#4d4d4d;stroke-width:40.5147" id="circle2" cx="822.09906" cy="261.28262"
r="46.863361"/>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.5 KiB

View file

@ -1,103 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="48"
height="48"
id="svg2"
sodipodi:version="0.32"
inkscape:version="0.47pre4 r22446"
sodipodi:docname="skull.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
version="1.0">
<defs
id="defs4">
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective10" />
<inkscape:perspective
id="perspective2447"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 526.18109 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective2687"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 526.18109 : 1"
sodipodi:type="inkscape:persp3d" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="18.217407"
inkscape:cx="23.789126"
inkscape:cy="21.065041"
inkscape:document-units="px"
inkscape:current-layer="g2551"
showgrid="false"
inkscape:window-width="1274"
inkscape:window-height="725"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="0" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1">
<g
id="g2547">
<g
id="g2551"
transform="translate(0.2014828,0.2890558)">
<path
style="fill:#000000"
d="m 23.0625,7.875 c -2.309245,0.049099 -4.522809,0.469358 -6.125,1.28125 l -1.625,0.8125 -3,2.9375 c -4.4036271,4.810187 -5.7159942,14.310988 -2.03289,16.192421 0.470391,0.240289 2.475497,1.006426 3.728817,1.227998 2.521045,0.445688 2.327223,0.322567 2.787218,1.340469 0.238995,0.528863 0.09446,1.428157 -0.0144,3.364112 -0.222151,3.951055 -0.06236,4.424776 1.59375,4.75 1.098431,0.21571 1.347302,-0.472438 1.21875,-3.15625 -0.115618,-2.413774 0.583332,-2.187741 1.1875,0.375 0.547478,2.322281 0.410725,2.936824 1.34375,2.9375 0.919623,6.65e-4 1.076314,-0.818043 1.34375,-3 0.353869,-2.887142 1.125,-3.139658 1.125,-0.375 0,2.08688 -0.222077,3.589602 1.6875,3.40625 1.132862,-0.108774 1.082149,-3.370508 0.9375,-4.09375 -0.121253,-0.606271 -0.04263,-0.84375 0.25,-0.84375 0.538278,0 0.77605,0.936782 0.78125,3.0625 0.0023,0.939922 0.100607,1.819357 0.21875,1.9375 0.257103,0.257101 1.968476,-0.05495 2.375,-0.4375 0.16137,-0.151853 0.01366,-2.350878 0.21875,-5 0.35428,-4.576122 1.366108,-2.962194 4.245673,-3.85919 4.126605,-1.285455 4.289077,-3.901867 4.285577,-7.64081 -0.0033,-3.474911 -1.444977,-7.288916 -3.75,-9.9375 l -1.0625,-1.21875 -1.875,-1.5 C 31.003675,8.7156929 26.911241,7.7931682 23.0625,7.875 z M 15.625,19.03125 c 3.394247,0 7.005748,2.293983 4.9375,3.96875 -0.883048,0.715048 -6.772942,-0.473271 -8.34375,-1.15625 -2.8401606,-1.234886 -0.0067,-2.8125 3.40625,-2.8125 z M 30.40625,19.625 c 0.636388,-0.004 1.310094,0.03125 1.9375,0.03125 3.145949,0 6.024182,0.340703 3.875,2.03125 -0.761324,0.598858 -1.605395,1.78125 -5.125,1.78125 -4.382431,0 -4.28125,0.0393 -4.28125,-1.625 0,-1.934908 1.684585,-2.206867 3.59375,-2.21875 z M 24,26.086963 24.75,27.59375 25.46711,29.015215 23.96875,28.875 22.336963,28.850537 23.25,27.5625 24,26.086963 z"
transform="translate(-0.2014828,-0.2890558)"
id="path2693"
sodipodi:nodetypes="ccccssssssssssssssssssscccccssccsssscccccccc" />
<rect
style="fill:#ffffff;fill-opacity:1;stroke:none"
id="rect3702"
width="3.0739832"
height="9.9355526"
x="41.498772"
y="27.689754"
transform="translate(-0.2014828,-0.2890558)" />
</g>
</g>
<g
id="g2471"
transform="matrix(4.0064997,0,0,4.0064997,-232.82633,-1139.1808)" />
</g>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M5 21V4"/>
<path d="M5 4h12l-2 4 2 4H5"/>
</svg>

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 219 B

Before After
Before After

View file

@ -1,205 +1,3 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64"
height="64"
id="svg2646"
sodipodi:version="0.32"
inkscape:version="0.48.5 r10040"
version="1.0"
sodipodi:docname="deck_editor_decrement.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
<defs
id="defs2648">
<linearGradient
id="linearGradient3169">
<stop
style="stop-color:#0000ff;stop-opacity:1;"
offset="0"
id="stop3171" />
<stop
style="stop-color:#000067;stop-opacity:1;"
offset="1"
id="stop3173" />
</linearGradient>
<linearGradient
id="linearGradient4766">
<stop
style="stop-color:#784421;stop-opacity:1;"
offset="0"
id="stop4768" />
<stop
style="stop-color:#3d2210;stop-opacity:0;"
offset="1"
id="stop4770" />
</linearGradient>
<linearGradient
id="linearGradient4758">
<stop
style="stop-color:#a05a2c;stop-opacity:1;"
offset="0"
id="stop4760" />
<stop
style="stop-color:#3d2210;stop-opacity:1;"
offset="1"
id="stop4762" />
</linearGradient>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective2654" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient3508"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient3510"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient3512"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient3514"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient3516"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient3518"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient3520"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient3522"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient3524"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="7.625"
inkscape:cx="26.34754"
inkscape:cy="29.107677"
inkscape:document-units="px"
inkscape:current-layer="layer2"
showgrid="false"
inkscape:window-width="1445"
inkscape:window-height="893"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="0" />
<metadata
id="metadata2651">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
style="display:inline" />
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Pfeil"
style="display:inline">
<rect
style="fill:#ff7672;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline"
id="rect3548"
width="14.386732"
height="59.259636"
x="24.806633"
y="-61.629818"
transform="matrix(0,1,-1,0,0,0)" />
</g>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M5 12h14"/>
</svg>

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 189 B

Before After
Before After

View file

@ -1,357 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64"
height="64"
id="svg2646"
sodipodi:version="0.32"
inkscape:version="0.47pre4 r22446"
version="1.0"
sodipodi:docname="remove_row.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
<defs
id="defs2648">
<linearGradient
id="linearGradient3169">
<stop
style="stop-color:#0000ff;stop-opacity:1;"
offset="0"
id="stop3171" />
<stop
style="stop-color:#000067;stop-opacity:1;"
offset="1"
id="stop3173" />
</linearGradient>
<linearGradient
id="linearGradient4766">
<stop
style="stop-color:#784421;stop-opacity:1;"
offset="0"
id="stop4768" />
<stop
style="stop-color:#3d2210;stop-opacity:0;"
offset="1"
id="stop4770" />
</linearGradient>
<linearGradient
id="linearGradient4758">
<stop
style="stop-color:#a05a2c;stop-opacity:1;"
offset="0"
id="stop4760" />
<stop
style="stop-color:#3d2210;stop-opacity:1;"
offset="1"
id="stop4762" />
</linearGradient>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective2654" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient3508"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient3510"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient3512"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient3514"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient3516"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient3518"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient3520"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient3522"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient3524"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2442"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2444"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2446"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2470"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2472"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2474"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2476"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2478"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2480"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2482"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2484"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2486"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2488"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2490"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2492"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="7.625"
inkscape:cx="12.656427"
inkscape:cy="31.784541"
inkscape:document-units="px"
inkscape:current-layer="layer2"
showgrid="false"
inkscape:window-width="1280"
inkscape:window-height="725"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="1" />
<metadata
id="metadata2651">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
style="display:inline" />
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Pfeil"
style="display:inline">
<path
style="fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline"
d="M 6.433227,14.50946 L 23.923767,32 L 6.433227,49.490541 L 14.50946,57.566773 L 32,40.076233 L 49.490541,57.566773 L 57.566773,49.490541 L 40.076233,32 L 57.566773,14.50946 L 49.490541,6.433227 L 32,23.923767 L 14.50946,6.433227 L 6.433227,14.50946 z"
id="rect3548" />
</g>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M4 7h16"/>
<path d="M9 7V4h6v3"/>
<path d="M6 7l1 13h10l1-13"/>
</svg>

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 245 B

Before After
Before After

View file

@ -1 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.--><path d="M352 188.5L300.1 175.5C293.6 173.9 288.8 168.4 288.1 161.7C287.4 155 290.9 148.6 296.8 145.6L337.6 125.2L294.3 92.7C288.8 88.6 286.5 81.4 288.7 74.8C290.9 68.2 297.1 64 304 64L464 64C494.2 64 522.7 78.2 540.8 102.4L598.4 179.2C604.6 187.5 608 197.6 608 208C608 234.5 586.5 256 560 256L538.5 256C521.5 256 505.2 249.3 493.2 237.3L479.9 224L447.9 224L447.9 245.5C447.9 270.3 460.7 293.4 481.7 306.6L588.3 373.2C620.4 393.3 639.9 428.4 639.9 466.3C639.9 526.9 590.8 576.1 530.1 576.1L32.3 576C29 576 25.7 575.6 22.7 574.6C13.5 571.8 6 565 2.3 556C1 552.7 .1 549.1 0 545.3C-.2 541.6 .3 538 1.3 534.6C4.1 525.4 10.9 517.9 19.9 514.2C22.9 513 26.1 512.2 29.4 512L433.3 476C441.6 475.3 448 468.3 448 459.9C448 455.6 446.3 451.5 443.3 448.5L398.9 404.1C368.9 374.1 352 333.4 352 291L352 188.5zM512 136.3C512 136.2 512 136.1 512 136C512 135.9 512 135.8 512 135.7L512 136.3zM510.7 143.7L464.3 132.1C464.1 133.4 464 134.7 464 136C464 149.3 474.7 160 488 160C498.6 160 507.5 153.2 510.7 143.7zM130.9 180.5C147.2 166 171.3 164.3 189.4 176.4L320 263.4L320 290.9C320 323.7 328.4 355.7 344 383.9L112 383.9C105.3 383.9 99.3 379.7 97 373.5C94.7 367.3 96.5 360.2 101.6 355.8L171 296.3L18.4 319.8C11.4 320.9 4.5 317.2 1.5 310.8C-1.5 304.4 .1 296.8 5.4 292L130.9 180.5z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
<!-- Font Awesome Free 7.1.0, CC BY 4.0 / MIT; https://fontawesome.com/license/free -->
<g transform="translate(2 2) scale(0.03125)">
<path d="M352 188.5L300.1 175.5C293.6 173.9 288.8 168.4 288.1 161.7C287.4 155 290.9 148.6 296.8 145.6L337.6 125.2L294.3 92.7C288.8 88.6 286.5 81.4 288.7 74.8C290.9 68.2 297.1 64 304 64L464 64C494.2 64 522.7 78.2 540.8 102.4L598.4 179.2C604.6 187.5 608 197.6 608 208C608 234.5 586.5 256 560 256L538.5 256C521.5 256 505.2 249.3 493.2 237.3L479.9 224L447.9 224L447.9 245.5C447.9 270.3 460.7 293.4 481.7 306.6L588.3 373.2C620.4 393.3 639.9 428.4 639.9 466.3C639.9 526.9 590.8 576.1 530.1 576.1L32.3 576C29 576 25.7 575.6 22.7 574.6C13.5 571.8 6 565 2.3 556C1 552.7 .1 549.1 0 545.3C-.2 541.6 .3 538 1.3 534.6C4.1 525.4 10.9 517.9 19.9 514.2C22.9 513 26.1 512.2 29.4 512L433.3 476C441.6 475.3 448 468.3 448 459.9C448 455.6 446.3 451.5 443.3 448.5L398.9 404.1C368.9 374.1 352 333.4 352 291L352 188.5zM512 136.3C512 136.2 512 136.1 512 136C512 135.9 512 135.8 512 135.7L512 136.3zM510.7 143.7L464.3 132.1C464.1 133.4 464 134.7 464 136C464 149.3 474.7 160 488 160C498.6 160 507.5 153.2 510.7 143.7zM130.9 180.5C147.2 166 171.3 164.3 189.4 176.4L320 263.4L320 290.9C320 323.7 328.4 355.7 344 383.9L112 383.9C105.3 383.9 99.3 379.7 97 373.5C94.7 367.3 96.5 360.2 101.6 355.8L171 296.3L18.4 319.8C11.4 320.9 4.5 317.2 1.5 310.8C-1.5 304.4 .1 296.8 5.4 292L130.9 180.5z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Before After
Before After

View file

@ -1,10 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 12.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
]>
<svg version="1.1" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="460.5" height="531.74"
viewBox="0 0 460.5 531.74" overflow="visible" enable-background="new 0 0 460.5 531.74" xml:space="preserve">
<polygon fill="#918d8d" points="0.5,0.866 459.5,265.87 0.5,530.874 "/>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M9 6l6 6-6 6"/>
</svg>

Before

Width:  |  Height:  |  Size: 657 B

After

Width:  |  Height:  |  Size: 191 B

Before After
Before After

View file

@ -1,10 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 12.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
]>
<svg version="1.1" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="531.74" height="460.5"
viewBox="0 0 531.74 460.5" overflow="visible" enable-background="new 0 0 531.74 460.5" xml:space="preserve">
<polygon fill="#918d8d" points="530.874,0.5 265.87,459.5 0.866,0.5 "/>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M6 9l6 6 6-6"/>
</svg>

Before

Width:  |  Height:  |  Size: 657 B

After

Width:  |  Height:  |  Size: 191 B

Before After
Before After

View file

@ -1,12 +1,3 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg fill="#000000" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg"
width="800px" height="800px" viewBox="0 0 971.986 971.986"
xml:space="preserve">
<g>
<path d="M370.216,459.3c10.2,11.1,15.8,25.6,15.8,40.6v442c0,26.601,32.1,40.101,51.1,21.4l123.3-141.3
c16.5-19.8,25.6-29.601,25.6-49.2V500c0-15,5.7-29.5,15.8-40.601L955.615,75.5c26.5-28.8,6.101-75.5-33.1-75.5h-873
c-39.2,0-59.7,46.6-33.1,75.5L370.216,459.3z"/>
</g>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M3 5h18l-7 8v6l-4 2v-8z"/>
</svg>

Before

Width:  |  Height:  |  Size: 676 B

After

Width:  |  Height:  |  Size: 202 B

Before After
Before After

View file

@ -1 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.--><path d="M160 96C124.7 96 96 124.7 96 160L96 480C96 515.3 124.7 544 160 544L480 544C515.3 544 544 515.3 544 480L544 237.3C544 220.3 537.3 204 525.3 192L448 114.7C436 102.7 419.7 96 402.7 96L160 96zM192 192C192 174.3 206.3 160 224 160L384 160C401.7 160 416 174.3 416 192L416 256C416 273.7 401.7 288 384 288L224 288C206.3 288 192 273.7 192 256L192 192zM320 352C355.3 352 384 380.7 384 416C384 451.3 355.3 480 320 480C284.7 480 256 451.3 256 416C256 380.7 284.7 352 320 352z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M5 3h11l3 3v15H5z"/>
<path d="M8 3v6h8V3"/>
<path d="M8 14h8v7H8z"/>
</svg>

Before

Width:  |  Height:  |  Size: 693 B

After

Width:  |  Height:  |  Size: 248 B

Before After
Before After

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="48pt" height="48pt" viewBox="0 0 48 48" version="1.1">
<g id="surface1">
<path style=" stroke:none;fill-rule:nonzero;fill:#000000;fill-opacity:1;" d="M 24 2 C 17.398438 2 12 7.398438 12 14 L 12 16 C 9.789063 16 8 17.789063 8 20 L 8 40 C 8 42.210938 9.789063 44 12 44 L 36 44 C 38.210938 44 40 42.210938 40 40 L 40 20 C 40 17.789063 38.210938 16 36 16 L 36 14 C 36 7.398438 30.601563 2 24 2 Z M 24 6 C 28.4375 6 32 9.5625 32 14 L 32 16 L 16 16 L 16 14 C 16 9.5625 19.554688 6 24 6 Z M 23.9375 19.9375 C 29.929688 19.9375 30 24.398438 30 25.25 C 30 29.71875 25.125 29.96875 25.375 33.875 L 21.875 33.875 C 21.578125 28.632813 26.0625 28.398438 26.0625 25.4375 C 26.0625 23.3125 24.632813 23.125 23.9375 23.125 C 21.859375 23.125 21.757813 25.09375 21.75 25.5 L 17.8125 25.5 C 17.820313 24.554688 18.015625 19.9375 23.9375 19.9375 Z M 23.6875 35.9375 C 25.671875 35.9375 25.875 37.765625 25.875 38.0625 C 25.875 38.351563 25.671875 40.125 23.6875 40.125 C 21.632813 40.125 21.5 38.351563 21.5 38.0625 C 21.5 37.765625 21.671875 35.9375 23.6875 35.9375 Z "/>
</g>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="7.5" cy="15.5" r="3.5"/>
<path d="M10 13l9-9"/>
<path d="M16 4l4 4"/>
<path d="M14 6l3 3"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 276 B

Before After
Before After

View file

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.--><path d="M259.1 73.5C262.1 58.7 275.2 48 290.4 48L350.2 48C365.4 48 378.5 58.7 381.5 73.5L396 143.5C410.1 149.5 423.3 157.2 435.3 166.3L503.1 143.8C517.5 139 533.3 145 540.9 158.2L570.8 210C578.4 223.2 575.7 239.8 564.3 249.9L511 297.3C511.9 304.7 512.3 312.3 512.3 320C512.3 327.7 511.8 335.3 511 342.7L564.4 390.2C575.8 400.3 578.4 417 570.9 430.1L541 481.9C533.4 495 517.6 501.1 503.2 496.3L435.4 473.8C423.3 482.9 410.1 490.5 396.1 496.6L381.7 566.5C378.6 581.4 365.5 592 350.4 592L290.6 592C275.4 592 262.3 581.3 259.3 566.5L244.9 496.6C230.8 490.6 217.7 482.9 205.6 473.8L137.5 496.3C123.1 501.1 107.3 495.1 99.7 481.9L69.8 430.1C62.2 416.9 64.9 400.3 76.3 390.2L129.7 342.7C128.8 335.3 128.4 327.7 128.4 320C128.4 312.3 128.9 304.7 129.7 297.3L76.3 249.8C64.9 239.7 62.3 223 69.8 209.9L99.7 158.1C107.3 144.9 123.1 138.9 137.5 143.7L205.3 166.2C217.4 157.1 230.6 149.5 244.6 143.4L259.1 73.5zM320.3 400C364.5 399.8 400.2 363.9 400 319.7C399.8 275.5 363.9 239.8 319.7 240C275.5 240.2 239.8 276.1 240 320.3C240.2 364.5 276.1 400.2 320.3 400z"/></svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -1,199 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64"
height="64"
id="svg2646"
sodipodi:version="0.32"
inkscape:version="0.46"
version="1.0"
sodipodi:docname="increment.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
<defs
id="defs2648">
<linearGradient
id="linearGradient3169">
<stop
style="stop-color:#0000ff;stop-opacity:1;"
offset="0"
id="stop3171" />
<stop
style="stop-color:#000067;stop-opacity:1;"
offset="1"
id="stop3173" />
</linearGradient>
<linearGradient
id="linearGradient4766">
<stop
style="stop-color:#784421;stop-opacity:1;"
offset="0"
id="stop4768" />
<stop
style="stop-color:#3d2210;stop-opacity:0;"
offset="1"
id="stop4770" />
</linearGradient>
<linearGradient
id="linearGradient4758">
<stop
style="stop-color:#a05a2c;stop-opacity:1;"
offset="0"
id="stop4760" />
<stop
style="stop-color:#3d2210;stop-opacity:1;"
offset="1"
id="stop4762" />
</linearGradient>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective2654" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient3508"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient3510"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient3512"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient3514"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient3516"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient3518"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient3520"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient3522"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient3524"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="7.625"
inkscape:cx="-58.636066"
inkscape:cy="33.549415"
inkscape:document-units="px"
inkscape:current-layer="layer2"
showgrid="false"
inkscape:window-width="1272"
inkscape:window-height="723"
inkscape:window-x="0"
inkscape:window-y="248" />
<metadata
id="metadata2651">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
style="display:inline" />
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Pfeil"
style="display:inline">
<path
style="fill:#96ff96;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 25.592359,5.717815 L 25.592359,25.62856 L 5.681613,25.62856 L 5.681613,38.371435 L 25.592359,38.371435 L 25.592359,58.282185 L 38.40764,58.282185 L 38.40764,38.371435 L 58.318387,38.371435 L 58.318387,25.62856 L 38.40764,25.62856 L 38.40764,5.717815 L 25.592359,5.717815 z"
id="rect3546" />
</g>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M12 5v14"/>
<path d="M5 12h14"/>
</svg>

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 212 B

Before After
Before After

View file

@ -1,43 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="100"
height="100"
id="svg2858"
version="1.1"
inkscape:version="0.48.5 r10040"
sodipodi:docname="info.svg">
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Triangle"
style="display:inline">
<path
sodipodi:type="arc"
style="fill:#aaaaaa;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
id="path3758-1"
sodipodi:cx="53.900002"
sodipodi:cy="78.5"
sodipodi:rx="46.5"
sodipodi:ry="46.5"
d="M 100.4,78.5 A 46.5,46.5 0 1 1 7.4000015,78.5 46.5,46.5 0 1 1 100.4,78.5 z"
transform="matrix(1.05866,0,0,1.05866,-7.0617752,-32.704809)" />
<g
style="font-size:133.49534607px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.06498075;stroke-opacity:1;font-family:'Magic:the Gathering';-inkscape-font-specification:'Magic:the Gathering'"
id="text3759">
<path
d="m 46.854005,16.085692 c 0.977733,-2.411704 1.683885,-4.193378 2.118456,-5.345028 0.369355,-1.1514901 0.771318,-1.9988718 1.205891,-2.5421482 0.456264,-0.4344718 1.347101,-0.825571 2.672514,-1.1732989 1.23846,-0.2823765 2.705082,-0.4670623 4.399871,-0.5540578 0.369346,8.46e-5 0.727854,8.46e-5 1.075524,0 1.694737,8.46e-5 2.672485,0.5758696 2.933248,1.7273567 -3e-5,0.1956326 -3e-5,0.3803183 0,0.5540579 -3e-5,1.3254743 -0.662726,2.9224633 -1.98809,4.7909703 -1.520969,2.238035 -3.43301,4.24785 -5.736128,6.029453 -2.32489,1.760018 -4.551983,2.781222 -6.681286,3.063614 -1.260224,-0.543125 -1.977239,-1.075454 -2.151048,-1.59699 -1.3e-5,-0.08684 -1.3e-5,-0.184616 0,-0.293325 -1.3e-5,-0.434484 0.228128,-1.010269 0.684424,-1.727357 0.521453,-0.890765 1.010327,-1.868513 1.466624,-2.933247 z M 31.372977,37.856906 c 2.650785,-0.716962 6.159814,-1.651255 10.527099,-2.802881 4.280354,-1.173242 7.398284,-1.803346 9.3538,-1.890315 0.08689,5.8e-5 0.173803,5.8e-5 0.260733,0 1.06464,5.8e-5 1.82511,0.358566 2.281415,1.075524 0.260711,0.630161 0.391077,1.520998 0.391099,2.672514 -2.2e-5,0.260787 -2.2e-5,0.532384 0,0.814791 -0.173844,1.586178 -0.260755,2.781204 -0.260733,3.58508 l 0,39.533656 c 1.238459,1e-5 2.976678,-0.673549 5.214662,-2.020681 1.673009,-0.977736 2.868034,-1.46661 3.58508,-1.466624 0.173791,1.4e-5 0.304158,0.04347 0.3911,0.130367 0.543162,0.369385 0.814759,0.771348 0.814791,1.20589 -3.2e-5,1.151583 -1.868617,2.66166 -5.605762,4.530238 -1.238507,0.717023 -3.063637,1.922912 -5.475395,3.617671 -2.49871,1.781679 -4.769259,3.204846 -6.811652,4.269505 -0.347658,0.347644 -0.923443,0.662696 -1.727357,0.945157 -0.260745,0.08691 -0.532342,0.130366 -0.814791,0.130367 -0.521477,-10e-7 -1.010351,-0.271598 -1.466623,-0.814791 C 41.856611,91.111641 41.7697,81.594892 41.76971,62.8221 c -1e-5,-1.955468 -1e-5,-4.008739 0,-6.15982 -1e-5,-2.129283 -0.08692,-4.128235 -0.260734,-5.996861 -0.260742,-1.781634 -0.706161,-3.204801 -1.336257,-4.269504 -0.717023,-1.347075 -1.60786,-2.368279 -2.672514,-3.063614 -1.151576,-0.630057 -2.357465,-1.260161 -3.617672,-1.890315 -1.325394,-0.521416 -2.161911,-1.053746 -2.509556,-1.59699 -0.195549,-0.173771 -0.293324,-0.434504 -0.293324,-0.7822 -0.08691,-0.369319 0.01086,-0.771282 0.293324,-1.20589 z"
style=""
id="path2993" />
</g>
</g>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="9"/>
<path d="M12 11v6"/>
<path d="M12 7.5h.01"/>
</svg>

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 247 B

Before After
Before After

View file

@ -1,750 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
height="128.00000"
id="svg1931"
version="1.0"
width="128.00000"
x="0.00000000"
y="0.00000000"
sodipodi:version="0.32"
inkscape:version="0.48.5 r10040"
sodipodi:docname="lock.svg">
<sodipodi:namedview
inkscape:window-height="933"
inkscape:window-width="1163"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
guidetolerance="10.0"
gridtolerance="10.0"
objecttolerance="10.0"
borderopacity="1.0"
bordercolor="#666666"
pagecolor="#ffffff"
id="base"
inkscape:zoom="4"
inkscape:cx="-26.577351"
inkscape:cy="72.426878"
inkscape:window-x="204"
inkscape:window-y="90"
inkscape:current-layer="g5908"
showgrid="false"
inkscape:window-maximized="0" />
<metadata
id="metadata3">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:title>padlock</dc:title>
<dc:description />
<dc:subject>
<rdf:Bag>
<rdf:li>icon</rdf:li>
<rdf:li />
<rdf:li>lock</rdf:li>
<rdf:li>security</rdf:li>
<rdf:li>secure</rdf:li>
<rdf:li>padlock</rdf:li>
<rdf:li>signs_and_symbols</rdf:li>
</rdf:Bag>
</dc:subject>
<dc:publisher>
<cc:Agent
rdf:about="http://www.openclipart.org">
<dc:title>AJ Ashton</dc:title>
</cc:Agent>
</dc:publisher>
<dc:creator>
<cc:Agent>
<dc:title>AJ Ashton</dc:title>
</cc:Agent>
</dc:creator>
<dc:rights>
<cc:Agent>
<dc:title>AJ Ashton</dc:title>
</cc:Agent>
</dc:rights>
<dc:date />
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<cc:license
rdf:resource="http://web.resource.org/cc/PublicDomain" />
<dc:language>en</dc:language>
</cc:Work>
<cc:License
rdf:about="http://web.resource.org/cc/PublicDomain">
<cc:permits
rdf:resource="http://web.resource.org/cc/Reproduction" />
<cc:permits
rdf:resource="http://web.resource.org/cc/Distribution" />
<cc:permits
rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
</cc:License>
</rdf:RDF>
</metadata>
<defs
id="defs3">
<linearGradient
id="linearGradient3057">
<stop
id="stop3059"
offset="0.00000000"
style="stop-color:#282828;stop-opacity:1.0000000;" />
<stop
id="stop3061"
offset="1.0000000"
style="stop-color:#282828;stop-opacity:0.00000000;" />
</linearGradient>
<linearGradient
id="linearGradient2834">
<stop
id="stop2836"
offset="0"
style="stop-color:#e59a00;stop-opacity:1;" />
<stop
id="stop2838"
offset="1"
style="stop-color:#faff7d;stop-opacity:0.18367347;" />
</linearGradient>
<linearGradient
id="linearGradient2780">
<stop
id="stop2782"
offset="0.00000000"
style="stop-color:#ffffff;stop-opacity:1.0000000;" />
<stop
id="stop2784"
offset="1.0000000"
style="stop-color:#ffffff;stop-opacity:0.00000000;" />
</linearGradient>
<linearGradient
id="linearGradient2713">
<stop
id="stop2715"
offset="0.00000000"
style="stop-color:#000000;stop-opacity:1.0000000;" />
<stop
id="stop2717"
offset="1.0000000"
style="stop-color:#ffffff;stop-opacity:1.0000000;" />
</linearGradient>
<linearGradient
id="linearGradient2701">
<stop
id="stop2703"
offset="0"
style="stop-color:#db9300;stop-opacity:1;" />
<stop
id="stop2770"
offset="0.75"
style="stop-color:#fac700;stop-opacity:1;" />
<stop
id="stop2705"
offset="1"
style="stop-color:#fff363;stop-opacity:1;" />
</linearGradient>
<linearGradient
gradientTransform="matrix(2.151801,0.000000,0.000000,1.770850,-5.130350e-2,4.351838)"
gradientUnits="userSpaceOnUse"
id="linearGradient2707"
spreadMethod="reflect"
x1="29.613848"
x2="44.723549"
xlink:href="#linearGradient2701"
y1="52.608921"
y2="52.608921" />
<linearGradient
gradientTransform="matrix(1.121224,0.000000,0.000000,0.891883,0.000000,4.000000)"
gradientUnits="userSpaceOnUse"
id="linearGradient2719"
spreadMethod="reflect"
x1="28.071486"
x2="28.071486"
xlink:href="#linearGradient2713"
y1="40.272228"
y2="42.645634" />
<linearGradient
gradientTransform="matrix(2.218790,0.000000,0.000000,1.825981,-5.130350e-2,-1.012826)"
gradientUnits="userSpaceOnUse"
id="linearGradient2732"
spreadMethod="reflect"
x1="29.093641"
x2="29.093641"
xlink:href="#linearGradient2713"
y1="46.357063"
y2="47.295517" />
<linearGradient
gradientTransform="matrix(2.218790,0.000000,0.000000,1.825981,-5.130350e-2,-1.012826)"
gradientUnits="userSpaceOnUse"
id="linearGradient2736"
spreadMethod="reflect"
x1="24.261463"
x2="24.605862"
xlink:href="#linearGradient2713"
y1="44.011002"
y2="45.887836" />
<linearGradient
gradientTransform="scale(1.102326,0.907173)"
gradientUnits="userSpaceOnUse"
id="linearGradient2740"
spreadMethod="reflect"
x1="17.681860"
x2="17.425413"
xlink:href="#linearGradient2713"
y1="60.433849"
y2="62.779984" />
<radialGradient
cx="20.360580"
cy="22.546398"
fx="20.360580"
fy="22.546396"
gradientTransform="matrix(0.433337,0.000000,0.000000,1.434961,6.409890,-0.113137)"
gradientUnits="userSpaceOnUse"
id="radialGradient2788"
r="15.156592"
xlink:href="#linearGradient2780" />
<radialGradient
cx="20.360580"
cy="22.546398"
fx="20.360580"
fy="22.546396"
gradientTransform="matrix(0.500069,0.000000,0.000000,1.675192,5.002970,-5.108149)"
gradientUnits="userSpaceOnUse"
id="radialGradient2792"
r="15.156592"
xlink:href="#linearGradient2780" />
<radialGradient
cx="20.360580"
cy="22.546398"
fx="20.360580"
fy="22.546396"
gradientTransform="matrix(0.621397,0.000000,0.000000,1.882058,2.388831,-9.409409)"
gradientUnits="userSpaceOnUse"
id="radialGradient2796"
r="15.156592"
xlink:href="#linearGradient2780" />
<radialGradient
cx="20.360580"
cy="22.546398"
fx="20.360580"
fy="22.546396"
gradientTransform="matrix(0.433337,0.000000,0.000000,1.434961,6.409890,-0.113137)"
gradientUnits="userSpaceOnUse"
id="radialGradient2811"
r="15.156592"
xlink:href="#linearGradient2780" />
<radialGradient
cx="20.360580"
cy="22.546398"
fx="20.360580"
fy="22.546396"
gradientTransform="matrix(0.500069,0.000000,0.000000,1.675192,5.002970,-5.108149)"
gradientUnits="userSpaceOnUse"
id="radialGradient2813"
r="15.156592"
xlink:href="#linearGradient2780" />
<radialGradient
cx="20.360580"
cy="22.546398"
fx="20.360580"
fy="22.546396"
gradientTransform="matrix(0.621397,0.000000,0.000000,1.882058,2.388831,-9.409409)"
gradientUnits="userSpaceOnUse"
id="radialGradient2815"
r="15.156592"
xlink:href="#linearGradient2780" />
<radialGradient
cx="20.360580"
cy="22.546398"
fx="20.360580"
fy="22.546396"
gradientTransform="matrix(0.433337,0.000000,0.000000,1.434961,6.409890,-0.113137)"
gradientUnits="userSpaceOnUse"
id="radialGradient2817"
r="15.156592"
xlink:href="#linearGradient2780" />
<radialGradient
cx="20.360580"
cy="22.546398"
fx="20.360580"
fy="22.546396"
gradientTransform="matrix(0.500069,0.000000,0.000000,1.675192,5.002970,-5.108149)"
gradientUnits="userSpaceOnUse"
id="radialGradient2819"
r="15.156592"
xlink:href="#linearGradient2780" />
<radialGradient
cx="20.360580"
cy="22.546398"
fx="20.360580"
fy="22.546396"
gradientTransform="matrix(0.621397,0.000000,0.000000,1.882058,2.388831,-9.409409)"
gradientUnits="userSpaceOnUse"
id="radialGradient2821"
r="15.156592"
xlink:href="#linearGradient2780" />
<radialGradient
cx="17.191872"
cy="14.639010"
fx="17.191872"
fy="14.639010"
gradientTransform="scale(1.896245,0.527358)"
gradientUnits="userSpaceOnUse"
id="radialGradient2840"
r="3.5649405"
xlink:href="#linearGradient2834" />
<radialGradient
cx="21.595108"
cy="8.9813547"
fx="21.595108"
fy="8.9813547"
gradientTransform="matrix(2.366562,0,0,1.726511,-0.404355,-1.2826e-2)"
gradientUnits="userSpaceOnUse"
id="radialGradient2869"
r="6.0678878"
xlink:href="#linearGradient2834" />
<radialGradient
cx="21.595108"
cy="8.9813547"
fx="21.595108"
fy="8.9813547"
gradientTransform="matrix(-2.366562,0,0,1.726511,129.1226,-0.112925)"
gradientUnits="userSpaceOnUse"
id="radialGradient2873"
r="6.0678878"
xlink:href="#linearGradient2834" />
<linearGradient
gradientTransform="matrix(2.161083,0,0,1.804543,-5.13035e-2,2.267068)"
gradientUnits="userSpaceOnUse"
id="linearGradient2895"
x1="33.184048"
x2="33.184048"
xlink:href="#linearGradient2780"
y1="24.384579"
y2="-13.170087" />
<radialGradient
cx="27.270315"
cy="16.278088"
fx="27.270315"
fy="16.278088"
gradientTransform="scale(0.973329,1.027402)"
gradientUnits="userSpaceOnUse"
id="radialGradient2929"
r="13.638700"
xlink:href="#linearGradient2780" />
<linearGradient
gradientTransform="matrix(2.210222,0,0,1.964283,-1.515862,-2.171324)"
gradientUnits="userSpaceOnUse"
id="linearGradient2935"
x1="33.184048"
x2="33.184048"
xlink:href="#linearGradient2780"
y1="24.384579"
y2="-13.170087" />
<linearGradient
gradientTransform="matrix(1.632005,0,0,2.482509,-5.13035e-2,-1.2826e-2)"
gradientUnits="userSpaceOnUse"
id="linearGradient2943"
x1="38.781849"
x2="38.781849"
xlink:href="#linearGradient2780"
y1="9.5745525"
y2="7.5863166" />
<linearGradient
gradientTransform="matrix(1.63752,0,0,2.47415,-5.13035e-2,-1.2826e-2)"
gradientUnits="userSpaceOnUse"
id="linearGradient2951"
x1="38.362892"
x2="39.723621"
xlink:href="#linearGradient2780"
y1="11.170151"
y2="6.0918369" />
<radialGradient
cx="21.595108"
cy="8.9813547"
fx="21.595108"
fy="8.9813547"
gradientTransform="matrix(3.085042,0,0,2.052895,-15.9848,-3.14928)"
gradientUnits="userSpaceOnUse"
id="radialGradient2955"
r="6.0678878"
xlink:href="#linearGradient2834" />
<radialGradient
cx="21.595108"
cy="8.9813547"
fx="21.595108"
fy="8.9813547"
gradientTransform="matrix(-2.846279,0,0,2.087943,139.5254,-3.586178)"
gradientUnits="userSpaceOnUse"
id="radialGradient2959"
r="6.0678878"
xlink:href="#linearGradient2834" />
<radialGradient
cx="8.0178375"
cy="231.98276"
fx="8.0178375"
fy="231.98276"
gradientTransform="scale(3.741657,0.267261)"
gradientUnits="userSpaceOnUse"
id="radialGradient3063"
r="7.4833150"
xlink:href="#linearGradient3057" />
<radialGradient
cx="8.0178375"
cy="231.98276"
fx="8.0178375"
fy="231.98276"
gradientTransform="scale(3.741657,0.267261)"
gradientUnits="userSpaceOnUse"
id="radialGradient3069"
r="7.4833150"
xlink:href="#linearGradient3057" />
<radialGradient
cx="8.0178375"
cy="231.98276"
fx="8.0178375"
fy="231.98276"
gradientTransform="scale(3.741657,0.267261)"
gradientUnits="userSpaceOnUse"
id="radialGradient3071"
r="7.4833150"
xlink:href="#linearGradient3057" />
<linearGradient
gradientTransform="matrix(2.136116,0.000000,0.000000,1.825981,2.348697,-1.012826)"
gradientUnits="userSpaceOnUse"
id="linearGradient3080"
spreadMethod="pad"
x1="26.974447"
x2="26.974447"
xlink:href="#linearGradient2780"
y1="68.680031"
y2="44.981197" />
<linearGradient
gradientTransform="matrix(1.632005,0,0,2.436073,-5.13035e-2,2.009678)"
gradientUnits="userSpaceOnUse"
id="linearGradient3084"
x1="35.995708"
x2="35.995708"
xlink:href="#linearGradient2780"
y1="1.6246380"
y2="11.710631" />
<linearGradient
gradientTransform="matrix(2.218790,0.000000,0.000000,1.825981,-5.130350e-2,-1.012826)"
gradientUnits="userSpaceOnUse"
id="linearGradient3086"
spreadMethod="reflect"
x1="17.681860"
x2="17.425413"
xlink:href="#linearGradient2713"
y1="60.433849"
y2="62.779984" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2701"
id="linearGradient3106"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(2.151801,0,0,1.77085,-5.13035e-2,4.351838)"
spreadMethod="reflect"
x1="29.613848"
y1="52.608921"
x2="44.723549"
y2="52.608921" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2713"
id="linearGradient3108"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(2.21879,0,0,1.825981,-5.13035e-2,-1.012826)"
spreadMethod="reflect"
x1="29.093641"
y1="46.357063"
x2="29.093641"
y2="47.295517" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2713"
id="linearGradient3110"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(2.21879,0,0,1.825981,-5.13035e-2,-1.012826)"
spreadMethod="reflect"
x1="24.261463"
y1="44.011002"
x2="24.605862"
y2="45.887836" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2713"
id="linearGradient3112"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(2.21879,0,0,1.825981,-5.13035e-2,-1.012826)"
spreadMethod="reflect"
x1="17.681860"
y1="60.433849"
x2="17.425413"
y2="62.779984" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2780"
id="radialGradient3114"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.433337,0,0,1.434961,6.40989,-0.113137)"
cx="20.360580"
cy="22.546398"
fx="20.360580"
fy="22.546396"
r="15.156592" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2780"
id="radialGradient3116"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.500069,0,0,1.675192,5.00297,-5.108149)"
cx="20.360580"
cy="22.546398"
fx="20.360580"
fy="22.546396"
r="15.156592" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2780"
id="radialGradient3118"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.621397,0,0,1.882058,2.388831,-9.409409)"
cx="20.360580"
cy="22.546398"
fx="20.360580"
fy="22.546396"
r="15.156592" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2780"
id="radialGradient3120"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.433337,0,0,1.434961,6.40989,-0.113137)"
cx="20.360580"
cy="22.546398"
fx="20.360580"
fy="22.546396"
r="15.156592" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2780"
id="radialGradient3122"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.500069,0,0,1.675192,5.00297,-5.108149)"
cx="20.360580"
cy="22.546398"
fx="20.360580"
fy="22.546396"
r="15.156592" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2780"
id="radialGradient3124"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.621397,0,0,1.882058,2.388831,-9.409409)"
cx="20.360580"
cy="22.546398"
fx="20.360580"
fy="22.546396"
r="15.156592" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2780"
id="linearGradient3126"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(2.136116,0,0,1.825981,2.348697,-1.012826)"
spreadMethod="pad"
x1="26.974447"
y1="68.680031"
x2="26.974447"
y2="44.981197" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2780"
id="linearGradient3130"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(2.136116,0,0,1.825981,-87.401303,-67.012826)"
spreadMethod="pad"
x1="26.974447"
y1="68.680031"
x2="26.974447"
y2="44.981197" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2713"
id="linearGradient3142"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(2.21879,0,0,1.825981,-54.801304,-67.512826)"
spreadMethod="reflect"
x1="17.681860"
y1="60.433849"
x2="17.425413"
y2="62.779984" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2713"
id="linearGradient3145"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(2.21879,0,0,1.825981,-70.051304,-58.262826)"
spreadMethod="reflect"
x1="24.261463"
y1="44.011002"
x2="24.605862"
y2="45.887836" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2713"
id="linearGradient3148"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(2.21879,0,0,1.825981,-62.551304,-52.512826)"
spreadMethod="reflect"
x1="29.093641"
y1="46.357063"
x2="29.093641"
y2="47.295517" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3057"
id="radialGradient4946"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(7.531304,0,0,0.53795,-15.775652,-129.52565)"
cx="8.0178375"
cy="231.98276"
fx="8.0178375"
fy="231.98276"
r="7.4833150" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3057"
id="radialGradient4949"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(7.531304,0,0,0.672437,-18.025652,-149.23087)"
cx="8.0178375"
cy="231.98276"
fx="8.0178375"
fy="231.98276"
r="7.4833150" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3057"
id="radialGradient4952"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(7.531304,0,0,0.53795,-11.275652,-137.01283)"
cx="8.0178375"
cy="231.98276"
fx="8.0178375"
fy="231.98276"
r="7.4833150" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2834"
id="radialGradient4955"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-2.846279,0,0,2.087943,139.5254,-3.586178)"
cx="21.595108"
cy="8.9813547"
fx="21.595108"
fy="8.9813547"
r="6.0678878" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2834"
id="radialGradient4958"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(3.085042,0,0,2.052895,-15.9848,-3.14928)"
cx="21.595108"
cy="8.9813547"
fx="21.595108"
fy="8.9813547"
r="6.0678878" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2834"
id="radialGradient4974"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-2.366562,0,0,1.726511,129.1226,-0.112925)"
cx="21.595108"
cy="8.9813547"
fx="21.595108"
fy="8.9813547"
r="6.0678878" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2834"
id="radialGradient4977"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(2.366562,0,0,1.726511,-0.404355,-1.2826e-2)"
cx="21.595108"
cy="8.9813547"
fx="21.595108"
fy="8.9813547"
r="6.0678878" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2834"
id="linearGradient6992"
x1="-229"
y1="36.5"
x2="-134"
y2="36.5"
gradientUnits="userSpaceOnUse" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2834"
id="radialGradient7002"
cx="-118.5"
cy="-41"
fx="-118.5"
fy="-41"
r="30.5"
gradientTransform="matrix(1,0,0,0.655738,0,-14.11475)"
gradientUnits="userSpaceOnUse" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2834"
id="radialGradient7014"
cx="-35"
cy="-163"
fx="-35"
fy="-163"
r="59"
gradientTransform="matrix(1,0,0,0.576271,0,-69.0678)"
gradientUnits="userSpaceOnUse" />
</defs>
<g
id="g5908">
<g
id="g5889"
style="fill:#989898;fill-opacity:1;stroke:#000000;stroke-opacity:1;stroke-width:2.4;stroke-miterlimit:4;stroke-dasharray:none">
<path
style="fill:#989898;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;stroke-dasharray:none"
id="rect2723"
d="M 64.359126,2 C 44.287226,2 28.128259,18.158966 28.128259,38.230867 L 28.128259,78.487385 L 38.192389,78.487385 L 38.192389,38.230867 C 38.192389,23.734494 49.862754,12.06413 64.359126,12.06413 C 78.855498,12.06413 90.525863,23.734494 90.525863,38.230867 L 90.525863,78.487385 L 100.58999,78.487385 L 100.58999,38.230867 C 100.58999,18.158966 84.431026,2 64.359126,2 z " />
</g>
<g
id="g4928"
style="fill:#edbb15;fill-opacity:1;stroke:#000000;stroke-width:2.8;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
transform="translate(0,-0.25)">
<rect
y="57.359127"
x="24.102608"
width="80.513039"
style="fill:#edbb15;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2.8;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
ry="0.5"
rx="0.49999997"
id="rect1941"
height="66.259109" />
</g>
</g>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<rect x="5" y="11" width="14" height="10" rx="2"/>
<path d="M9 11V8a3 3 0 0 1 6 0v3"/>
</svg>

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 255 B

Before After
Before After

View file

@ -1,368 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64"
height="64"
id="svg2646"
sodipodi:version="0.32"
inkscape:version="0.48.5 r10040"
version="1.0"
sodipodi:docname="icon_not_ready_start.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
<defs
id="defs2648">
<linearGradient
id="linearGradient3169">
<stop
style="stop-color:#0000ff;stop-opacity:1;"
offset="0"
id="stop3171" />
<stop
style="stop-color:#000067;stop-opacity:1;"
offset="1"
id="stop3173" />
</linearGradient>
<linearGradient
id="linearGradient4766">
<stop
style="stop-color:#784421;stop-opacity:1;"
offset="0"
id="stop4768" />
<stop
style="stop-color:#3d2210;stop-opacity:0;"
offset="1"
id="stop4770" />
</linearGradient>
<linearGradient
id="linearGradient4758">
<stop
style="stop-color:#a05a2c;stop-opacity:1;"
offset="0"
id="stop4760" />
<stop
style="stop-color:#3d2210;stop-opacity:1;"
offset="1"
id="stop4762" />
</linearGradient>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective2654" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient3508"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient3510"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient3512"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient3514"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient3516"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient3518"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient3520"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient3522"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient3524"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2442"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2444"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2446"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2470"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2472"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2474"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2476"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2478"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2480"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2482"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2484"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2486"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2488"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2490"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2492"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="7.625"
inkscape:cx="-7.5402943"
inkscape:cy="36.374705"
inkscape:document-units="px"
inkscape:current-layer="layer2"
showgrid="false"
inkscape:window-width="1920"
inkscape:window-height="1028"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1" />
<metadata
id="metadata2651">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
style="display:inline" />
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Pfeil"
style="display:inline">
<path
sodipodi:type="arc"
style="fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.37689075;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="path3018"
sodipodi:cx="-25.967213"
sodipodi:cy="12.852459"
sodipodi:rx="9.04918"
sodipodi:ry="9.04918"
d="m -16.918033,12.852459 a 9.04918,9.04918 0 1 1 -18.09836,0 9.04918,9.04918 0 1 1 18.09836,0 z"
transform="matrix(3.392487,0,0,3.392487,120.35572,-11.470653)" />
<path
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
d="M 12.146996,18.3904 25.952237,32.195642 12.146996,46.000885 18.521547,52.375436 32.326789,38.570194 46.132032,52.375436 52.506582,46.000885 38.701341,32.195642 52.506582,18.3904 46.132032,12.015849 32.326789,25.82109 18.521547,12.015849 12.146996,18.3904 z"
id="rect3548"
inkscape:connector-curvature="0" />
</g>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M6 6l12 12"/>
<path d="M18 6L6 18"/>
</svg>

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 214 B

Before After
Before After

View file

@ -1 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.--><path d="M535.6 85.7C513.7 63.8 478.3 63.8 456.4 85.7L432 110.1L529.9 208L554.3 183.6C576.2 161.7 576.2 126.3 554.3 104.4L535.6 85.7zM236.4 305.7C230.3 311.8 225.6 319.3 222.9 327.6L193.3 416.4C190.4 425 192.7 434.5 199.1 441C205.5 447.5 215 449.7 223.7 446.8L312.5 417.2C320.7 414.5 328.2 409.8 334.4 403.7L496 241.9L398.1 144L236.4 305.7zM160 128C107 128 64 171 64 224L64 480C64 533 107 576 160 576L416 576C469 576 512 533 512 480L512 384C512 366.3 497.7 352 480 352C462.3 352 448 366.3 448 384L448 480C448 497.7 433.7 512 416 512L160 512C142.3 512 128 497.7 128 480L128 224C128 206.3 142.3 192 160 192L256 192C273.7 192 288 177.7 288 160C288 142.3 273.7 128 256 128L160 128z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M11 4H6a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-5"/>
<path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4z"/>
</svg>

Before

Width:  |  Height:  |  Size: 899 B

After

Width:  |  Height:  |  Size: 299 B

Before After
Before After

View file

@ -1,123 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
width="64"
height="64"
id="svg2"
inkscape:version="0.47 r22583"
sodipodi:docname="pencil.svg">
<metadata
id="metadata18">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1280"
inkscape:window-height="752"
id="namedview16"
showgrid="false"
inkscape:zoom="38.985767"
inkscape:cx="49.593625"
inkscape:cy="9.752988"
inkscape:window-x="-4"
inkscape:window-y="-3"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" />
<defs
id="defs4">
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 32 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="64 : 32 : 1"
inkscape:persp3d-origin="32 : 21.333333 : 1"
id="perspective20" />
</defs>
<path
style="fill:#f2f2f2;stroke:black;stroke-width:0.36091354;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="rect4310"
d="M 10.735636,2.7007755 L 10.735636,59.759195 L 47.991073,59.759195 L 53.259135,54.575403 L 53.259135,2.7007755 L 10.735636,2.7007755 z" />
<path
style="opacity:0.43930634;fill:black;stroke:none"
id="rect4314-9-2"
d="M 47.539263,54.178486 L 53.43341,54.178486 L 47.539263,59.914352 L 47.539263,54.178486 z" />
<path
style="fill:#f2f2f2;stroke:black;stroke-width:0.33989298;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="rect4314-9-5"
d="M 48.080899,54.683517 L 53.016926,54.683517 L 48.080899,59.569868 L 48.080899,54.683517 z" />
<path
style="opacity:0.43930634;fill:black;stroke:none"
id="rect4120-3"
d="M 7.8062475,55.039312 L 7.8339835,55.072982 L 4.5689682,57.65671 L 5.2398545,58.476426 L 6.3020905,59.774252 L 6.9450675,60.559879 L 10.210081,57.976151 L 35.079771,38.295796 L 35.107506,38.329466 L 37.205296,34.249681 L 32.67559,35.358116 L 7.8059005,55.03861 z" />
<rect
style="fill:#fc0;stroke:black;stroke-width:0.28297317;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="rect4120"
transform="matrix(0.78188456,-0.62342324,0.63622425,0.77150419,0,0)"
y="46.463638"
x="-29.50437"
height="3.7814219"
width="31.701616" />
<rect
style="fill:#4d4d4d;stroke:black;stroke-width:0.28297317;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="rect4122"
transform="matrix(0.78188456,-0.62342324,0.63622425,0.77150419,0,0)"
y="46.477345"
x="-33.674004"
height="3.7620518"
width="4.171114" />
<path
style="fill:#ffe680;stroke:black;stroke-width:0.28295398;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="rect4124"
d="M 31.271515,34.459836 L 35.787845,33.312261 L 33.712851,37.420244 L 31.271515,34.459836 z" />
<path
style="fill:black;stroke:black;stroke-width:0.28295398;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="rect4127"
d="M 34.451031,33.663829 L 35.778335,33.329236 L 35.171353,34.537276 L 34.451031,33.663829 z" />
<rect
style="fill:#333;stroke:black;stroke-width:0.28297317;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="rect4122-4"
transform="matrix(0.78188456,-0.62342324,0.63622425,0.77150419,0,0)"
y="47.533978"
x="-33.669418"
height="1.698899"
width="4.171114" />
<rect
style="fill:#4d4d4d;stroke:black;stroke-width:0.28297317;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="rect4122-8"
transform="matrix(0.78188456,-0.62342324,0.63622425,0.77150419,0,0)"
y="49.239918"
x="-33.669418"
height="1.0045688"
width="4.171114" />
<rect
style="fill:#a80;stroke:black;stroke-width:0.28297317;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="rect4122-4-7"
transform="matrix(0.78188456,-0.62342324,0.63622425,0.77150419,0,0)"
y="47.53389"
x="-29.508781"
height="1.698899"
width="31.643009" />
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M12 20h9"/>
<path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4z"/>
</svg>

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 250 B

Before After
Before After

View file

@ -1,24 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="64" height="64">
<g transform="matrix(0 1 -1 0 99.465813 0)" opacity="0.7">
<path fill="#000000" fill-rule="evenodd" clip-rule="evenodd"
stroke="#ffffff"
stroke-width="4"
stroke-linejoin="round"
stroke-linecap="round"
d="M65.5 62
L78 49
C73.5 44.5 69.5 42 63 44
L45 31 C47 25 46 22 41.5 18
L19 41.5
C23 45.5 25 46.5 31 45
L44 62.5
C42.3 69 45 73.5 49 78
L61.5 65.5
L84 87
L87 87
L87.5 86.5
L87.5 83.5 Z" />
</g>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M9 4h6l-1 6 3 3v2H7v-2l3-3z"/>
<path d="M12 15v6"/>
</svg>

Before

Width:  |  Height:  |  Size: 736 B

After

Width:  |  Height:  |  Size: 229 B

Before After
Before After

View file

@ -1,142 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64px"
height="64px"
id="svg2508"
sodipodi:version="0.32"
inkscape:version="0.48.5 r10040"
sodipodi:docname="icon_player.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
version="1.1">
<defs
id="defs2510">
<linearGradient
id="linearGradient5717">
<stop
style="stop-color:#003580;stop-opacity:1;"
offset="0"
id="stop5719" />
<stop
id="stop5727"
offset="0.25297618"
style="stop-color:#055897;stop-opacity:1;" />
<stop
id="stop5725"
offset="0.5"
style="stop-color:#00a4ff;stop-opacity:1;" />
<stop
id="stop5733"
offset="0.75"
style="stop-color:#055897;stop-opacity:1;" />
<stop
style="stop-color:#003580;stop-opacity:1;"
offset="1"
id="stop5721" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5717"
id="linearGradient5723"
x1="339.93985"
y1="482.58844"
x2="459.27341"
y2="355.50766"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0,0.1263349,-0.1263349,0,74.367722,-7.5042832)" />
<linearGradient
id="linearGradient3234">
<stop
style="stop-color:#6f6f6f;stop-opacity:1;"
offset="0"
id="stop3236" />
<stop
id="stop3242"
offset="0.47999999"
style="stop-color:#e6e6e6;stop-opacity:1;" />
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0.5"
id="stop3244" />
<stop
id="stop3286"
offset="0.75"
style="stop-color:#bebebe;stop-opacity:1;" />
<stop
style="stop-color:#494949;stop-opacity:1;"
offset="1"
id="stop3238" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3234"
id="linearGradient5120"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(8.9332267e-2,8.9332267e-2,8.9332267e-2,-8.9332267e-2,-16.525693,40.126552)"
x1="202.99225"
y1="395.23221"
x2="251.27765"
y2="395.23221" />
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 32 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="64 : 32 : 1"
inkscape:persp3d-origin="32 : 21.333333 : 1"
id="perspective2516" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="7.7781746"
inkscape:cx="35.570639"
inkscape:cy="33.231713"
inkscape:current-layer="g2536"
showgrid="true"
inkscape:document-units="px"
inkscape:grid-bbox="true"
inkscape:window-width="1280"
inkscape:window-height="725"
inkscape:window-x="619"
inkscape:window-y="35"
inkscape:window-maximized="0" />
<metadata
id="metadata2513">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<g
id="g2536"
transform="translate(-0.1818183,-3.0952293e-8)">
<path
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:3.4920001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:60.01653385"
d="m 60.100711,4.0811082 -8.925773,4.066985 C 41.14173,19.502755 31.186489,31.772714 19.035138,42.39632 16.923235,39.989095 14.162681,36.349247 12.592568,33.629733 L 7.4098614,38.84843 c 0,0 4.1855936,1.798155 5.3626626,2.627344 1.177067,0.829192 3.640464,3.136411 3.640464,3.136411 0,0 -6.9973489,9.844274 -12.8181741,11.40396 -1.8723058,0.501682 4.0691751,6.443164 4.5708593,4.570859 1.5576526,-5.813242 11.1468308,-13.589562 11.1468308,-13.589562 0,0 2.672321,3.126813 3.501514,4.30388 0.82919,1.177069 2.519371,5.470634 2.519371,5.470634 L 30.552085,51.58925 C 27.830216,50.017778 24.343721,47.501755 21.950055,45.40381 32.445673,33.693842 43.199214,24.522178 56.033726,13.00688 z"
id="path5116"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccscsscsccccc" />
</g>
</g>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M14.5 17.5 3 6V3h3l11.5 11.5"/>
<path d="M13 19l6-6"/>
<path d="M16 16l4 4"/>
<path d="M19 21l2-2"/>
<path d="M5 14l4 4"/>
<path d="M7 17l-3 3"/>
</svg>

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 331 B

Before After
Before After

View file

@ -1,81 +1,3 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="500"
height="500"
id="svg2"
version="1.1"
inkscape:version="0.48.5 r10040"
sodipodi:docname="icon_ready_start.svg">
<defs
id="defs4">
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective10" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.4339754"
inkscape:cx="281.46845"
inkscape:cy="299.09369"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1600"
inkscape:window-height="1178"
inkscape:window-x="1912"
inkscape:window-y="-8"
inkscape:window-maximized="1"
showguides="true"
inkscape:guide-bbox="true" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-552.36218)">
<path
sodipodi:type="arc"
style="fill:#0dc700;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-opacity:1;stroke-width:5.46761148;stroke-miterlimit:4;stroke-dasharray:none"
id="path2984"
sodipodi:cx="-137.08441"
sodipodi:cy="104.52625"
sodipodi:rx="182.45049"
sodipodi:ry="182.45049"
d="m 45.366074,104.52625 c 0,100.76462 -81.685865,182.45049 -182.450484,182.45049 -100.76462,0 -182.45049,-81.68587 -182.45049,-182.45049 0,-100.7646178 81.68587,-182.450482 182.45049,-182.450482 100.764619,0 182.450484,81.6858642 182.450484,182.450482 z"
transform="matrix(1.3351351,0,0,1.3351351,434.51202,663.29215)" />
<path
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 375.18246,681.4936 -180.66822,156.20036 -62.11391,-71.84189 -57.207882,49.50276 110.831342,128.16069 0.15088,-0.11694 0.7485,0.87896 237.72517,-205.58619 -49.46594,-57.19777 z"
id="rect3754"
inkscape:connector-curvature="0" />
</g>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M4 12l5 5L20 6"/>
</svg>

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 193 B

Before After
Before After

View file

@ -1,7 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
viewBox="0 0 1000 1000" enable-background="new 0 0 1000 1000" xml:space="preserve">
<metadata> Svg Vector Icons : http://www.onlinewebfonts.com/icon </metadata>
<g><path d="M586.9,373.6l95.6-84.4c-49.6-39.2-129.4-79.1-198.2-79.1c-134.9,0-248.2,90.5-280.2,212.8L10.6,374.5C64.4,168.3,255.2,15.8,482.5,15.8c126.7,0,258.8,63.7,345.4,141.4l90.8-80.1L990,479.6L586.9,373.6z M317.5,710.8c49.6,39.2,129.4,79.1,198.2,79.1c134.9,0,248.2-90.5,280.2-212.8l193.5,48.5c-53.7,206.2-244.6,358.7-471.9,358.7c-126.7,0-258.8-63.7-345.4-141.4l-90.8,80.1L10,520.4l403.1,106L317.5,710.8z"/></g>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M20 12a8 8 0 1 1-2.3-5.7"/>
<path d="M20 4v5h-5"/>
</svg>

Before

Width:  |  Height:  |  Size: 797 B

After

Width:  |  Height:  |  Size: 228 B

Before After
Before After

View file

@ -1,356 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64"
height="64"
id="svg2646"
sodipodi:version="0.32"
inkscape:version="0.48.5 r10040"
version="1.0"
sodipodi:docname="deck_editor_remove_row.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
<defs
id="defs2648">
<linearGradient
id="linearGradient3169">
<stop
style="stop-color:#0000ff;stop-opacity:1;"
offset="0"
id="stop3171" />
<stop
style="stop-color:#000067;stop-opacity:1;"
offset="1"
id="stop3173" />
</linearGradient>
<linearGradient
id="linearGradient4766">
<stop
style="stop-color:#784421;stop-opacity:1;"
offset="0"
id="stop4768" />
<stop
style="stop-color:#3d2210;stop-opacity:0;"
offset="1"
id="stop4770" />
</linearGradient>
<linearGradient
id="linearGradient4758">
<stop
style="stop-color:#a05a2c;stop-opacity:1;"
offset="0"
id="stop4760" />
<stop
style="stop-color:#3d2210;stop-opacity:1;"
offset="1"
id="stop4762" />
</linearGradient>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective2654" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient3508"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient3510"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient3512"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient3514"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient3516"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient3518"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient3520"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient3522"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient3524"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2442"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2444"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2446"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2470"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2472"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2474"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2476"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2478"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2480"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2482"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2484"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2486"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient2488"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="590.62201"
y1="434.7522"
x2="698.54004"
y2="517.79218" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient2490"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9650128,0,0,0.9948433,-449.70565,-312.80927)"
x1="661.24402"
y1="602.90814"
x2="431.5"
y2="201.5482" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient2492"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="7.625"
inkscape:cx="-27.27273"
inkscape:cy="30.210771"
inkscape:document-units="px"
inkscape:current-layer="layer2"
showgrid="false"
inkscape:window-width="1272"
inkscape:window-height="723"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="0" />
<metadata
id="metadata2651">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
style="display:inline" />
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Pfeil"
style="display:inline">
<path
style="fill:#ff7672;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline"
d="M 6.433227,14.50946 L 23.923767,32 L 6.433227,49.490541 L 14.50946,57.566773 L 32,40.076233 L 49.490541,57.566773 L 57.566773,49.490541 L 40.076233,32 L 57.566773,14.50946 L 49.490541,6.433227 L 32,23.923767 L 14.50946,6.433227 L 6.433227,14.50946 z"
id="rect3548" />
</g>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M6 6l12 12"/>
<path d="M18 6L6 18"/>
</svg>

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 216 B

Before After
Before After

View file

@ -1,10 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="1200pt" height="1200pt" version="1.1" viewBox="0 0 1200 1200" xmlns="http://www.w3.org/2000/svg">
<path transform="scale(50)" d="m17 16h4v-8h-4" fill="none" stroke="#000" stroke-miterlimit="10" stroke-width="2"/>
<path transform="scale(50)" d="m12 8h-9v8h9" fill="none" stroke="#000" stroke-miterlimit="10" stroke-width="2"/>
<path transform="scale(50)" d="m6 12h5" fill="none" stroke="#000" stroke-miterlimit="10" stroke-width="2"/>
<path transform="scale(50)" d="m20 4h-2c-1.1 0-2 0.9-2 2v12c0 1.1 0.9 2 2 2h2" fill="none" stroke="#000"
stroke-linejoin="round" stroke-miterlimit="10" stroke-width="2"/>
<path transform="scale(50)" d="m12 20h2c1.1 0 2-0.9 2-2v-12c0-1.1-0.9-2-2-2h-2" fill="none" stroke="#000"
stroke-linejoin="round" stroke-miterlimit="10" stroke-width="2"/>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linejoin="round">
<path d="M17 16h4V8h-4"/>
<path d="M12 8H3v8h9"/>
<path d="M6 12h5"/>
<path d="M20 4h-2c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h2"/>
<path d="M12 20h2c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2h-2"/>
</svg>

Before

Width:  |  Height:  |  Size: 875 B

After

Width:  |  Height:  |  Size: 335 B

Before After
Before After

View file

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.--><path d="M384 96L512 96C529.7 96 544 110.3 544 128C544 145.7 529.7 160 512 160L398.4 160C393.2 185.8 375.5 207.1 352 217.3L352 512L512 512C529.7 512 544 526.3 544 544C544 561.7 529.7 576 512 576L128 576C110.3 576 96 561.7 96 544C96 526.3 110.3 512 128 512L288 512L288 217.3C264.5 207 246.8 185.7 241.6 160L128 160C110.3 160 96 145.7 96 128C96 110.3 110.3 96 128 96L256 96C270.6 76.6 293.8 64 320 64C346.2 64 369.4 76.6 384 96zM439.6 384L584.4 384L512 259.8L439.6 384zM512 480C449.1 480 396.8 446 386 401.1C383.4 390.1 387 378.8 392.7 369L487.9 205.8C492.9 197.2 502.1 192 512 192C521.9 192 531.1 197.3 536.1 205.8L631.3 369C637 378.8 640.6 390.1 638 401.1C627.2 445.9 574.9 480 512 480zM126.8 259.8L54.4 384L199.3 384L126.8 259.8zM.9 401.1C-1.7 390.1 1.9 378.8 7.6 369L102.8 205.8C107.8 197.2 117 192 126.9 192C136.8 192 146 197.3 151 205.8L246.2 369C251.9 378.8 255.5 390.1 252.9 401.1C242.1 445.9 189.8 480 126.9 480C64 480 11.7 446 .9 401.1z"/></svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="52pt" height="52pt" viewBox="0 0 52 52" version="1.1">
<g id="surface1">
<path style=" stroke:none;fill-rule:nonzero;fill:#000000;fill-opacity:1;" d="M 25.605469 0.125 C 25.605469 0.125 23.265625 3.140625 23.265625 4.433594 C 23.265625 5.316406 23.765625 6.070313 24.5 6.464844 C 23.898438 6.65625 23.375 6.992188 22.960938 7.449219 C 22.011719 6.640625 20.628906 5.910156 18.710938 5.910156 C 16.640625 5.910156 14.863281 6.753906 13.355469 7.507813 C 12.601563 7.886719 11.925781 8.25 11.324219 8.496094 C 10.964844 8.09375 10.425781 7.878906 9.847656 7.878906 C 8.75 7.878906 7.878906 8.75 7.878906 9.847656 C 7.878906 10.949219 8.75 11.816406 9.847656 11.816406 C 10.757813 11.816406 11.519531 11.234375 11.757813 10.402344 C 12.578125 10.078125 13.386719 9.648438 14.21875 9.234375 C 15.671875 8.507813 17.179688 7.878906 18.710938 7.878906 C 20.496094 7.878906 21.519531 8.679688 22.097656 9.355469 C 22.074219 9.519531 22.035156 9.6875 22.035156 9.847656 C 22.035156 11.816406 23.636719 13.417969 25.605469 13.417969 C 27.574219 13.417969 29.175781 11.816406 29.175781 9.847656 C 29.175781 9.6875 29.136719 9.519531 29.113281 9.355469 C 29.691406 8.679688 30.714844 7.878906 32.5 7.878906 C 34.03125 7.878906 35.539063 8.507813 36.992188 9.234375 C 37.824219 9.648438 38.632813 10.078125 39.457031 10.402344 C 39.695313 11.234375 40.457031 11.816406 41.363281 11.816406 C 42.464844 11.816406 43.332031 10.949219 43.332031 9.847656 C 43.332031 8.75 42.464844 7.878906 41.363281 7.878906 C 40.785156 7.878906 40.246094 8.09375 39.886719 8.496094 C 39.285156 8.25 38.609375 7.886719 37.855469 7.507813 C 36.347656 6.753906 34.570313 5.910156 32.5 5.910156 C 30.585938 5.910156 29.199219 6.640625 28.253906 7.449219 C 27.835938 6.992188 27.3125 6.65625 26.714844 6.464844 C 27.445313 6.070313 27.945313 5.316406 27.945313 4.433594 C 27.945313 3.140625 25.605469 0.125 25.605469 0.125 Z M 9.539063 13.234375 C 9.25 13.332031 9.023438 13.558594 8.925781 13.847656 L 2.277344 31.515625 L 0 31.515625 C 1.445313 35.578125 5.285156 38.53125 9.847656 38.53125 C 14.410156 38.53125 18.25 35.578125 19.695313 31.515625 L 17.417969 31.515625 L 10.773438 13.847656 C 10.601563 13.402344 10.132813 13.140625 9.664063 13.234375 C 9.625 13.234375 9.578125 13.234375 9.539063 13.234375 Z M 41.054688 13.234375 C 40.761719 13.332031 40.539063 13.558594 40.441406 13.847656 L 33.792969 31.515625 L 31.515625 31.515625 C 32.960938 35.578125 36.800781 38.53125 41.363281 38.53125 C 45.925781 38.53125 49.765625 35.578125 51.210938 31.515625 L 48.933594 31.515625 L 42.285156 13.847656 C 42.117188 13.402344 41.648438 13.140625 41.179688 13.234375 C 41.140625 13.234375 41.09375 13.234375 41.054688 13.234375 Z M 21.914063 15.757813 C 21.914063 17.082031 22.589844 18.242188 23.636719 18.898438 L 23.636719 41.980469 C 21.429688 42.773438 19.796875 44.816406 19.695313 47.273438 L 15.757813 47.273438 C 14.671875 47.273438 13.789063 48.15625 13.789063 49.242188 L 13.789063 51.210938 L 37.425781 51.210938 L 37.425781 49.242188 C 37.425781 48.15625 36.539063 47.273438 35.453125 47.273438 L 31.515625 47.273438 C 31.414063 44.816406 29.785156 42.773438 27.574219 41.980469 L 27.574219 18.898438 C 28.621094 18.242188 29.300781 17.082031 29.300781 15.757813 Z M 9.847656 17.050781 L 15.328125 31.515625 L 4.371094 31.515625 Z M 41.363281 17.050781 L 46.84375 31.515625 L 35.886719 31.515625 Z "/>
</g>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M12 3v18"/>
<path d="M5 7h14"/>
<path d="M5 7l-3 6a3 3 0 0 0 6 0z"/>
<path d="M19 7l3 6a3 3 0 0 1-6 0z"/>
<path d="M8 21h8"/>
</svg>

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 309 B

Before After
Before After

View file

@ -1 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.--><path d="M32 176C32 134.5 63.6 100.4 104 96.4L104 96L384 96C437 96 480 139 480 192L480 368L304 368C264.2 368 232 400.2 232 440L232 500C232 524.3 212.3 544 188 544C163.7 544 144 524.3 144 500L144 272L80 272C53.5 272 32 250.5 32 224L32 176zM268.8 544C275.9 530.9 280 515.9 280 500L280 440C280 426.7 290.7 416 304 416L552 416C565.3 416 576 426.7 576 440L576 464C576 508.2 540.2 544 496 544L268.8 544zM112 144C94.3 144 80 158.3 80 176L80 224L144 224L144 176C144 158.3 129.7 144 112 144z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/>
<path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/>
<path d="M8 7h8"/>
<path d="M8 11h8"/>
</svg>

Before

Width:  |  Height:  |  Size: 704 B

After

Width:  |  Height:  |  Size: 332 B

Before After
Before After

View file

@ -1,198 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64"
height="64"
id="svg2"
version="1.1"
inkscape:version="0.48.5 r10040"
sodipodi:docname="icon_search_black.svg">
<defs
id="defs4">
<linearGradient
inkscape:collect="always"
id="linearGradient3709">
<stop
style="stop-color:#4d4d4d;stop-opacity:1;"
offset="0"
id="stop3711" />
<stop
style="stop-color:#4d4d4d;stop-opacity:0;"
offset="1"
id="stop3713" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient3699">
<stop
style="stop-color:#ececec;stop-opacity:1;"
offset="0"
id="stop3701" />
<stop
style="stop-color:#ececec;stop-opacity:0;"
offset="1"
id="stop3703" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient3632">
<stop
style="stop-color:#c87137;stop-opacity:1;"
offset="0"
id="stop3634" />
<stop
style="stop-color:#c87137;stop-opacity:0;"
offset="1"
id="stop3636" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient3622">
<stop
style="stop-color:#f9f9f9;stop-opacity:1;"
offset="0"
id="stop3624" />
<stop
style="stop-color:#f9f9f9;stop-opacity:0;"
offset="1"
id="stop3626" />
</linearGradient>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective10" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3622"
id="linearGradient3628"
x1="30.59761"
y1="8.9243031"
x2="30.59761"
y2="21.545816"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3632"
id="linearGradient3638"
x1="28.430279"
y1="47.808765"
x2="29.960159"
y2="47.808765"
gradientUnits="userSpaceOnUse" />
<inkscape:perspective
id="perspective3685"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3699"
id="linearGradient3705"
x1="29.215645"
y1="1021.9559"
x2="31.852083"
y2="1021.9559"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3709"
id="linearGradient3715"
x1="22.288248"
y1="35.505978"
x2="49.488647"
y2="49.106178"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3632"
id="linearGradient3730"
gradientUnits="userSpaceOnUse"
x1="28.430279"
y1="47.808765"
x2="29.960159"
y2="47.808765" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3699"
id="linearGradient3732"
gradientUnits="userSpaceOnUse"
x1="29.215645"
y1="1021.9559"
x2="31.852083"
y2="1021.9559" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="7.84375"
inkscape:cx="6.0725518"
inkscape:cy="32"
inkscape:document-units="px"
inkscape:current-layer="g3717"
showgrid="false"
inkscape:window-width="1920"
inkscape:window-height="1028"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-988.36218)">
<g
id="g3717"
transform="matrix(0.70710678,0.70710678,-0.70710678,0.70710678,729.31175,279.31708)">
<path
transform="matrix(1.7216859,0,0,1.7216859,-37.751505,955.72849)"
d="m 49.338646,35.505978 a 13.450199,13.450199 0 1 1 -26.900398,0 13.450199,13.450199 0 1 1 26.900398,0 z"
sodipodi:ry="13.450199"
sodipodi:rx="13.450199"
sodipodi:cy="35.505978"
sodipodi:cx="35.888447"
id="path2816"
style="fill:#222326;fill-opacity:0;stroke:#222326;stroke-width:1.90745997;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
sodipodi:type="arc" />
<path
transform="matrix(-0.08671958,-1.1164509,1.1164509,-0.08671958,2.9138372,1039.7631)"
d="m 18.613546,52.207172 a 2.5498009,12.302789 0 1 1 -5.099601,0 2.5498009,12.302789 0 1 1 5.099601,0 z"
sodipodi:ry="12.302789"
sodipodi:rx="2.5498009"
sodipodi:cy="52.207172"
sodipodi:cx="16.063745"
id="path2826"
style="fill:#222326;fill-opacity:1;stroke:#222326;stroke-width:0.30000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
sodipodi:type="arc" />
</g>
</g>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="10.5" cy="10.5" r="6.5"/>
<path d="M15.5 15.5 21 21"/>
</svg>

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 237 B

Before After
Before After

View file

@ -1,280 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 12.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
height="133.078"
id="Layer_1"
inkscape:version="0.48.5 r10040"
sodipodi:docname="icon_settings.svg"
sodipodi:version="0.32"
space="preserve"
style="overflow:visible;enable-background:new 0 0 132.882 133.078;"
version="1.1"
viewBox="0 0 132.882 133.078"
width="132.882">
<metadata
id="metadata3">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:title>Ruota dentata grigia</dc:title>
<dc:description />
<dc:subject>
<rdf:Bag>
<rdf:li>unsorted</rdf:li>
</rdf:Bag>
</dc:subject>
<dc:publisher>
<cc:Agent
rdf:about="http://www.openclipart.org/">
<dc:title>Open Clip Art Library</dc:title>
</cc:Agent>
</dc:publisher>
<dc:creator>
<cc:Agent>
<dc:title>Architetto Francesco Rollandin</dc:title>
</cc:Agent>
</dc:creator>
<dc:rights>
<cc:Agent>
<dc:title>Architetto Francesco Rollandin</dc:title>
</cc:Agent>
</dc:rights>
<dc:date />
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<cc:license
rdf:resource="http://web.resource.org/cc/PublicDomain" />
<dc:language>en</dc:language>
</cc:Work>
<cc:License
rdf:about="http://web.resource.org/cc/PublicDomain">
<cc:permits
rdf:resource="http://web.resource.org/cc/Reproduction" />
<cc:permits
rdf:resource="http://web.resource.org/cc/Distribution" />
<cc:permits
rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
</cc:License>
</rdf:RDF>
</metadata>
<defs
id="defs88" />
<sodipodi:namedview
bordercolor="#666666"
borderopacity="1.0"
id="base"
inkscape:current-layer="Layer_1"
inkscape:cx="11.842486"
inkscape:cy="69.252383"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:window-height="928"
inkscape:window-width="1411"
inkscape:window-x="191"
inkscape:window-y="47"
inkscape:zoom="5.4103608"
pagecolor="#ffffff"
showgrid="false"
inkscape:window-maximized="0" />
<g
id="g3"
style="fill:#007aff;fill-opacity:1;stroke:none;stroke-opacity:1">
<radialGradient
cx="66.5674"
cy="66.3169"
gradientUnits="userSpaceOnUse"
id="XMLID_5_"
r="65.835">
<stop
id="stop6"
offset="0"
style="stop-color:#F8F8F8" />
<stop
id="stop8"
offset="1"
style="stop-color:#7F7F7F" />
</radialGradient>
<path
d="M125.144,56.349c-3.771,0-7.545,0.045-11.314,0.186c-0.897-4.456-2.482-8.765-4.657-12.756 c-1.116-2.051-3.152-3.094-1.176-4.893c1.351-1.228,2.674-2.482,3.984-3.751c2.54-2.458,7.481-6.071,5.054-10.111 c-2.409-4.008-9.553-12.402-14.613-8.778c-3.259,2.332-6.025,5.805-8.753,8.728c-1.839,1.972-10.072-3.345-13.153-4.284 c-2.29-0.697-4.424-0.006-4.282-2.731c0.099-1.899,0.151-3.802,0.183-5.704c0.046-2.924,0.872-7.681-1.602-9.949 c-2.693-2.47-13.091-2.182-16.192-0.591c-2.902,1.487-2.505,5.529-2.49,8.222c0.011,2.005,0.038,4.011,0.09,6.017 c0.076,2.895,1.006,3.128-2.148,3.853c-4.414,1.016-8.685,2.631-12.661,4.795c-2.706,1.474-2.19,0.776-4.07-1.242 c-1.784-1.917-3.619-3.792-5.471-5.644c-5.942-5.942-11.491,1.433-15.473,6.153c-2.454,2.908-1.425,5.693,1.093,8.212 c1.554,1.552,3.121,3.095,4.703,4.618c3.003,2.895,2.475,2.563,0.439,6.089c-2.106,3.649-3.704,7.589-4.729,11.678 c-0.889,3.547-6.993,1.883-10.459,1.883c-8.083,0-6.575,7.183-6.646,13.097c-0.099,8.381,6.687,7.291,13.357,7.167 c3.019-0.057,3.419-1.006,4.392,2.141c0.679,2.203,1.527,4.354,2.533,6.43c0.999,2.063,2.151,4.05,3.442,5.944 c1.956,2.872-0.17,3.17-2.443,5.329c-2.402,2.283-7.031,5.432-7.215,9.075c-0.154,3.043,3.263,5.365,5.149,7.252 s4.212,5.316,7.26,5.158c3.995-0.206,7.724-5.77,10.257-8.424c1.112-1.164,2.211-2.339,3.291-3.532 c2.416,1.359,4.945,2.514,7.554,3.451c2.667,0.961,5.417,1.691,8.207,2.191c-0.196,2.286-0.295,4.58-0.357,6.873 c-0.093,3.384-1.316,9.583,1.551,12.215c2.403,2.205,7.079,1.192,10.013,1.252c2.549,0.054,6.151,0.456,7.717-2.1 c2.355-3.849,0.94-10.923,0.786-15.24c-0.107-2.931-1.017-3.003,2.18-3.832c3.045-0.79,6.019-1.861,8.864-3.205 c3.503-1.651,3.52-2.752,6.156,0.172c1.791,1.988,3.646,3.92,5.522,5.826c2.889,2.937,6.048,6.091,9.923,2.818 c2.688-2.271,7.617-6.12,8.636-9.61c1.223-4.195-4.952-8.343-7.479-10.767c-2.237-2.148-4.737-2.782-2.863-5.64 c1.603-2.441,2.973-5.036,4.082-7.737c0.839-2.045,1.528-4.15,2.061-6.296c2.411,0.156,4.826,0.234,7.239,0.275 c3.483,0.061,9.652,1.05,10.868-3.456C133.132,67.049,133.389,56.349,125.144,56.349 M65.631,84.78 c-10.628,0-20.194-8.436-20.194-19.325c0-10.889,9.565-19.324,20.194-19.324c10.627,0,20.195,8.435,20.195,19.324 C85.826,76.344,76.259,84.78,65.631,84.78"
id="path10"
style="fill:#007aff;fill-opacity:1;stroke:none;stroke-opacity:1" />
<linearGradient
gradientTransform="matrix(776.0099 550.007 550.007 -776.0099 -66856.1797 490158.2813)"
gradientUnits="userSpaceOnUse"
id="XMLID_6_"
x1="-241.1641"
x2="-239.5807"
y1="461.063"
y2="461.063">
<stop
id="stop13"
offset="0"
style="stop-color:#FFFFFF" />
<stop
id="stop15"
offset="1"
style="stop-color:#000000" />
</linearGradient>
<path
d="M66.287,1.853c2.222-0.034,4.739-0.403,6.857,0.365c3.572,1.299,2.531,7.112,2.485,9.961 c-0.025,1.531-1.121,6.786-0.321,8.029c0.813,1.265,9.244,2.709,11.056,3.537c6.891,3.14,5.463,4.316,10.604-1.013 c2.665-2.76,6.867-9.078,11.128-5.777c2.658,2.06,9.874,8.281,8.585,11.593c-1.303,3.346-5.354,6.176-7.92,8.567 c-2.921,2.722-3.367,1.872-1.364,5.159c2.313,3.799,4.064,7.936,5.156,12.25c0.605,2.394-0.082,2.838,2.033,2.802 c4.069-0.069,10.315-1.296,14.178,0.4c3.522,1.548,2.268,9.16,2.229,12.543c-0.096,8.456-12.104,5.645-17.898,5.283 c0.156,0.011-6.795,14.843-7.944,16.447c-0.547,0.763,7.359,7.556,8.381,8.538c4.944,4.761,2.824,7.329-1.513,11.69 c-6.039,6.069-7.887,5.521-13.935-0.731c-2.149-2.219-4.261-4.48-6.246-6.85c-0.521-0.625-6.012,2.776-6.994,3.185 c-1.476,0.614-8.901,1.845-9.535,2.872c-1.004,1.622,0.309,8.013,0.33,9.982c0.096,8.526-0.896,10.481-9.352,10.481 c-2.232,0-4.709,0.411-6.843-0.365c-4-1.453-2.523-9.013-2.438-12.174c0.04-1.498,1.174-6.406,0.431-7.654 c-0.568-0.956-8.392-2.117-9.829-2.669c-0.787-0.303-6.762-3.507-7.049-3.207c-1.525,1.591-3.051,3.181-4.578,4.771 c-1.979,2.064-5.734,7.388-8.932,7.289c-2.806-0.048-9.959-7.553-11.098-10.111c-2.792-6.279,10.07-9.389,10.988-13.959 c0.043-0.212-9.882-17.351-8.595-17.368c-3.593,0.05-7.317,0.41-10.899,0.153c-6.971,0-5.875-6.05-5.83-11.202 c-0.16-7.395,3.619-7.569,9.824-7.444c2.137,0.043,4.276,0.086,6.414,0.128c0.444,0.01,2.333-7.586,2.722-8.551 c1.339-3.326,3.101-6.425,5.146-9.363c0.438-0.629-1.932-2.346-2.398-2.799c-3.363-3.273-10.421-7.872-5.851-12.794 c2.096-2.259,6.541-7.985,9.6-7.985c3.747,0,8.376,6.755,10.672,9.161c3.036,3.181,6.353-1.095,10.14-2.528 c3.945-1.491,9.292-0.362,9.213-4.943c-0.058-3.255-0.396-6.637-0.172-9.884C56.925,1.449,61.375,1.775,66.287,1.853 M69.694,0.223 c-3.688,0-9.813-1.099-12.571,1.586c-3.116,3.085-1.696,10.736-1.63,14.678c0.059,3.6-3.022,2.813-6.17,3.854 c-1.466,0.484-9.462,4.621-10.028,4.025c-2.892-3.043-6.707-8.735-10.962-9.909c-4.166-1.15-7.581,3.806-10.172,6.478 c-5.742,5.518-4.111,8.898,0.979,13.844c1.579,1.533,3.153,3.07,4.737,4.598c-2.533,3.705-4.533,7.768-5.897,12.042 c-1.361,4.257-0.689,4.336-4.944,4.254c-2.461-0.048-5.048-0.305-7.504,0.003c-6.472,0.811-5.456,7.242-5.495,12.174 c-0.062,8.137,3.169,9.687,10.582,9.567c2.239-0.035,4.479-0.076,6.717-0.105c1.116,4.185,2.831,8.202,5.067,11.91 c1.376,2.284,3.278,2.844,1.032,4.902c-1.601,1.465-3.171,2.964-4.72,4.482c-2.292,2.248-5.735,5.252-4.299,8.88 c1.176,2.967,7.935,9.732,10.902,10.908c4.637,1.839,8.851-4.352,11.594-7.205c1.362-1.417,2.717-2.845,4.093-4.25 c3.94,2.146,8.163,3.761,12.527,4.799c3.048,0.725,2.151,0.836,2.018,3.6c-0.091,1.868-0.145,3.736-0.175,5.606 c-0.057,3.465-0.923,9.161,2.917,11.094c3.094,1.558,9.554,0.977,13.091,0.706c8.238-0.634,5.907-11.882,5.715-17.565 c-0.093-2.766-0.968-2.98,2.009-3.78c2.121-0.57,4.206-1.277,6.235-2.116c2.025-0.838,3.997-1.808,5.898-2.898 c1.049,1.227,2.131,2.424,3.23,3.604c4.327,4.647,9.567,12.294,15.874,6.219c2.729-2.633,8.092-6.614,8.172-10.478 c0-4.122-5.587-7.971-8.271-10.553c-2.079-1.999-3.72-2.262-2.068-4.844c2.22-3.474,3.976-7.236,5.207-11.169 c1.902-6.08,17.526,3.361,19.05-6.681c0.542-3.585,1.057-12.592-1.447-15.135c-2.997-3.071-10.253-1.718-14.098-1.652 c-3.809,0.065-3-2.746-4.229-6.091c-1.123-3.054-5.727-8.679-3.43-10.785c6.34-5.817,12.979-10.456,5.196-17.885 c-2.6-2.681-6.001-7.617-10.181-6.482c-3.963,1.077-7.582,6.327-10.301,9.135c-2.466,2.545-4.07,0.031-7.078-1.328 c-2.639-1.192-9.949-2.184-9.821-4.885C77.38,10.375,79.38,0.223,69.694,0.223"
id="path17"
style="fill:#007aff;fill-opacity:1;stroke:none;stroke-opacity:1" />
<linearGradient
gradientTransform="matrix(0 -214.9991 -214.9991 0 102181.7813 -51529.3086)"
gradientUnits="userSpaceOnUse"
id="XMLID_7_"
x1="-240.6104"
x2="-239.069"
y1="474.9624"
y2="474.9624">
<stop
id="stop20"
offset="0"
style="stop-color:#FFFFFF" />
<stop
id="stop22"
offset="1"
style="stop-color:#000000" />
</linearGradient>
<path
d="M44.65,65.457c0,26.066,41.962,26.066,41.962,0S44.65,39.39,44.65,65.457 M46.234,65.457 c0-24.025,38.794-24.025,38.794,0S46.234,89.482,46.234,65.457"
id="path24"
style="fill:#007aff;fill-opacity:1;stroke:none;stroke-opacity:1" />
<radialGradient
cx="65.6309"
cy="65.4565"
gradientUnits="userSpaceOnUse"
id="XMLID_8_"
r="34.9484">
<stop
id="stop27"
offset="0"
style="stop-color:#F3F3F3" />
<stop
id="stop29"
offset="0.4367"
style="stop-color:#F1F1F1" />
<stop
id="stop31"
offset="0.594"
style="stop-color:#EAEAEA" />
<stop
id="stop33"
offset="0.7061"
style="stop-color:#DEDEDE" />
<stop
id="stop35"
offset="0.7968"
style="stop-color:#CDCDCD" />
<stop
id="stop37"
offset="0.8745"
style="stop-color:#B7B7B7" />
<stop
id="stop39"
offset="0.9419"
style="stop-color:#9D9D9D" />
<stop
id="stop41"
offset="1"
style="stop-color:#7F7F7F" />
</radialGradient>
<path
d="M65.631,31.895c-18.581,0-36.284,14.164-36.284,33.56c0,19.402,17.697,33.563,36.284,33.563 c18.586,0,36.283-14.16,36.283-33.563C101.914,46.058,84.212,31.895,65.631,31.895 M65.631,93.859 c-15.729,0-30.71-11.983-30.71-28.404c0-16.42,14.981-28.401,30.71-28.401c15.729,0,30.711,11.979,30.711,28.401 C96.343,81.877,81.362,93.859,65.631,93.859"
id="path43"
style="fill:#007aff;fill-opacity:1;stroke:none;stroke-opacity:1" />
<path
d="M24.022,47.759c1.389-2.133,2.794-4.254,4.284-6.319C26.071,40.979,24.669,46.14,24.022,47.759 M107.988,19.272c-1.503-5.967-10.331,4.207-11.839,5.825c-0.454,0.487-3.053,4-3.867,3.761c-4.902-3.622-10.62-6.063-16.557-7.381 c-1.076,3.631,8.287,4.644,11.055,6.028c2.139,1.068,4.24,4.338,6.308,2.435c3.427-3.154,6.553-6.757,10.268-9.576 c0.894-0.678,5.101-1.062,4.814,0.303C108.109,20.202,108.049,19.738,107.988,19.272 M40.692,28.996 c3.305-2.111,6.968-3.595,10.795-4.437c2.593-0.569,6.13,0.171,5.04-3.526C53.526,21.596,39.653,24.832,40.692,28.996"
id="path45"
style="fill:#007aff;fill-opacity:1;stroke:none;stroke-opacity:1" />
<path
d="M73.152,3.636c0,2.344-14.251,2.344-14.251,0S73.152,1.292,73.152,3.636"
id="path47"
style="fill:#007aff;fill-opacity:1;stroke:none;stroke-opacity:1" />
<path
d="M66.03,128.431c-0.671,0-7.125-0.13-7.125,1.282c0,1.931,14.251,1.933,14.251,0 C73.155,128.301,66.701,128.431,66.03,128.431"
id="path49"
style="fill:#007aff;fill-opacity:1;stroke:none;stroke-opacity:1" />
<path
d="M11.008,72.88c-0.671,0-7.125-0.131-7.125,1.282c0,1.916,14.251,1.913,14.251,0 C18.134,72.75,11.679,72.88,11.008,72.88"
id="path51"
style="fill:#007aff;fill-opacity:1;stroke:none;stroke-opacity:1" />
<path
d="M121.58,72.88c-0.671,0-7.125-0.13-7.125,1.282c0,1.914,14.251,1.914,14.251,0 C128.706,72.75,122.252,72.88,121.58,72.88"
id="path53"
style="fill:#007aff;fill-opacity:1;stroke:none;stroke-opacity:1" />
<path
d="M17.557,106.256c-1.294,0,2.25,4.292,2.338,4.391c1.444,1.629,4.758,5.852,7.256,5.852 c0.034,0.022-1.976-3.976-2.431-4.485C23.285,110.405,20.025,106.251,17.557,106.256"
id="path55"
style="fill:#007aff;fill-opacity:1;stroke:none;stroke-opacity:1" />
<path
d="M94.355,104.674c-0.578,0,7.519,12.467,9.826,10.159C105.671,113.348,96.25,104.674,94.355,104.674"
id="path57"
style="fill:#007aff;fill-opacity:1;stroke:none;stroke-opacity:1" />
<path
d="M26.671,16.666c1.05,1.051-9.306,11.41-10.357,10.358C15.267,25.972,25.62,15.62,26.671,16.666"
id="path59"
style="fill:#007aff;fill-opacity:1;stroke:none;stroke-opacity:1" />
<path
d="M115.199,27.97c-1.964,0-11.219,9.358-10.206,10.408C106.838,40.223,115.24,27.97,115.199,27.97"
id="path61"
style="fill:#007aff;fill-opacity:1;stroke:none;stroke-opacity:1" />
<path
d="M115.726,106.081c-1.962,0-11.194,9.419-10.205,10.408 C107.472,118.347,115.713,106.081,115.726,106.081"
id="path63"
style="fill:#007aff;fill-opacity:1;stroke:none;stroke-opacity:1" />
<path
d="M37.346,106.081c-1.842,0-4.608,3.414-5.731,4.537c-0.465,0.462-4.612,5.885-4.463,5.881 C29.433,118.323,37.092,106.081,37.346,106.081"
id="path65"
style="fill:#007aff;fill-opacity:1;stroke:none;stroke-opacity:1" />
<path
d="M27.347,115.672c-0.07,0.271-0.138,0.545-0.207,0.816C27.825,117.173,26.743,114.15,27.347,115.672"
id="path67"
style="fill:#007aff;fill-opacity:1;stroke:none;stroke-opacity:1" />
<path
d="M17.435,58.462c0,1.339-12.324-0.53-12.924,1.248c-0.368,1.084-0.489,11.103-1.228,11.024 c-1.711-0.183-0.224-10.043-0.08-11.327C3.558,56.244,17.435,57.476,17.435,58.462"
id="path69"
style="fill:#007aff;fill-opacity:1;stroke:none;stroke-opacity:1" />
<path
d="M23.478,100.129c-0.358,0.358-4.58,4.749-5.319,4.013c-0.977-0.977,8.35-10.312,9.332-9.33 C28.226,95.548,23.835,99.773,23.478,100.129"
id="path71"
style="fill:#007aff;fill-opacity:1;stroke:none;stroke-opacity:1" />
<path
d="M128.573,58.66c0,1.19-14.846,1.19-14.846,0S128.573,57.47,128.573,58.66"
id="path73"
style="fill:#007aff;fill-opacity:1;stroke:none;stroke-opacity:1" />
<path
d="M101.119,74.258c-7.886,24.178-41.95,33.291-60.554,15.481c0,3.725,7.864,8.189,10.455,9.559 c9.041,4.776,19.717,4.771,29.24,1.414C92.282,96.476,99.202,86.506,101.119,74.258 M101.58,72.276 c-0.306,0.617-0.461,1.277-0.461,1.982C100.85,75.084,101.843,72.276,101.58,72.276"
id="path75"
style="fill:#007aff;fill-opacity:1;stroke:none;stroke-opacity:1" />
<path
d="M90.129,90.213c-8.308,6.802-19.974,9.833-30.567,8.335C70.359,100.232,81.753,97.307,90.129,90.213 "
id="path77"
style="fill:#007aff;fill-opacity:1;stroke:none;stroke-opacity:1" />
<path
d="M35.812,60.705c0-9.224,8.177-18.148,16.011-21.707c8.522-3.872,17.985-3.937,26.437,0.105 c1.084,0.518,13.452,7.704,11.891,9.714c0.415-0.534-7.813-6.607-8.427-6.956c-7.797-4.435-17.463-4.583-25.884-1.935 C48.108,42.359,35.812,51.58,35.812,60.705"
id="path79"
style="fill:#007aff;fill-opacity:1;stroke:none;stroke-opacity:1" />
<path
d="M29.221,60.477c0-11.246,10.8-22.154,20.227-26.36c10.268-4.583,21.688-4.81,31.842,0.146 c3.762,1.836,7.336,4.222,10.343,7.144c0.161,0.158,3.231,3.874,2.678,3.895c-0.649,0.027-2.156-2.297-2.538-2.712 c-2.223-2.406-4.743-4.534-7.549-6.232c-9.406-5.692-21.297-5.859-31.503-2.277c-8.237,2.891-15.042,8.673-19.335,16.251 C31.957,52.851,29.221,57.912,29.221,60.477"
id="path81"
style="fill:#007aff;fill-opacity:1;stroke:none;stroke-opacity:1" />
<path
d="M96.321,66.114c0.076-0.002-1.774,6.544-1.93,6.928c-2.031,5.045-5.354,9.536-9.722,12.801 c-14.182,10.598-33.677,7.999-44.948-5.131c15.231,22.079,55.698,13.75,56.604-14.6"
id="path83"
style="fill:#007aff;fill-opacity:1;stroke:none;stroke-opacity:1" />
<path
d="M87.782,85.129c-0.864,0.83-1.773,1.606-2.729,2.329C86.015,86.743,86.926,85.967,87.782,85.129 M39.057,80.084c-0.394,0,5.06,5.707,5.491,6.023C43.611,85.29,40.002,80.084,39.057,80.084"
id="path85"
style="fill:#007aff;fill-opacity:1;stroke:none;stroke-opacity:1" />
</g>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.38a2 2 0 0 0-.73-2.73l-.15-.09a2 2 0 0 1-1-1.74v-.51a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"/>
<circle cx="12" cy="12" r="3"/>
</svg>

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 779 B

Before After
Before After

View file

@ -1,25 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg height="800"
width="800"
version="1.1"
id="_x32_"
viewBox="0 0 512 512"
xml:space="preserve"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs id="defs1"/>
<style type="text/css"
id="style1">
.st0{fill:#64C0FF;stroke:black;stroke-width:3;stroke-miterlimit:4;stroke-opacity:1}
</style>
<g id="g1"
transform="matrix(0.87097097,0,0,1.0008579,38.609049,-0.21963163)"
style="stroke-width:3.42738;stroke-dasharray:none">
<path class="st0"
d="M 512,255.995 277.045,65.394 v 103.574 c -17.255,0 -36.408,0 -57.542,0 -208.59,0 -249.35,153.44 -201.394,266.128 9.586,-103.098 142.053,-100.701 237.358,-100.701 7.247,0 14.446,0 21.578,0 v 112.211 z"
id="path1"
style="stroke-width:20;stroke:#000000;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"/>
</g>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="6" cy="12" r="2.5"/>
<circle cx="18" cy="6" r="2.5"/>
<circle cx="18" cy="18" r="2.5"/>
<path d="M8.2 10.8l7.6-3.6"/>
<path d="M8.2 13.2l7.6 3.6"/>
</svg>

Before

Width:  |  Height:  |  Size: 1 KiB

After

Width:  |  Height:  |  Size: 334 B

Before After
Before After

View file

@ -1 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.--><path d="M278.6 438.6L182.6 534.6C170.1 547.1 149.8 547.1 137.3 534.6L41.3 438.6C28.8 426.1 28.8 405.8 41.3 393.3C53.8 380.8 74.1 380.8 86.6 393.3L128 434.7L128 128C128 110.3 142.3 96 160 96C177.7 96 192 110.3 192 128L192 434.7L233.4 393.3C245.9 380.8 266.2 380.8 278.7 393.3C291.2 405.8 291.2 426.1 278.7 438.6zM352 544C334.3 544 320 529.7 320 512C320 494.3 334.3 480 352 480L384 480C401.7 480 416 494.3 416 512C416 529.7 401.7 544 384 544L352 544zM352 416C334.3 416 320 401.7 320 384C320 366.3 334.3 352 352 352L448 352C465.7 352 480 366.3 480 384C480 401.7 465.7 416 448 416L352 416zM352 288C334.3 288 320 273.7 320 256C320 238.3 334.3 224 352 224L512 224C529.7 224 544 238.3 544 256C544 273.7 529.7 288 512 288L352 288zM352 160C334.3 160 320 145.7 320 128C320 110.3 334.3 96 352 96L576 96C593.7 96 608 110.3 608 128C608 145.7 593.7 160 576 160L352 160z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M4 6h10"/>
<path d="M4 12h7"/>
<path d="M4 18h4"/>
<path d="M18 8v10"/>
<path d="M15 15l3 3 3-3"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 282 B

Before After
Before After

View file

@ -1,106 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="500"
height="500"
id="svg2825"
version="1.1"
inkscape:version="0.48.5 r10040"
sodipodi:docname="icon_spectator.svg">
<defs
id="defs2827">
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective2833" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3170"
id="linearGradient3176"
x1="348.1423"
y1="241.25623"
x2="362.82382"
y2="226.27509"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
id="linearGradient3170">
<stop
style="stop-color: rgb(255, 255, 255); stop-opacity: 1;"
offset="0"
id="stop3172" />
<stop
style="stop-color: rgb(255, 255, 255); stop-opacity: 0;"
offset="1"
id="stop3174" />
</linearGradient>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.7"
inkscape:cx="161.90734"
inkscape:cy="313.43022"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="784"
inkscape:window-height="1162"
inkscape:window-x="2720"
inkscape:window-y="0"
inkscape:window-maximized="0" />
<metadata
id="metadata2830">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-552.36218)">
<path
sodipodi:type="arc"
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:10;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="path3609"
sodipodi:cx="382.85715"
sodipodi:cy="549.50507"
sodipodi:rx="71.428574"
sodipodi:ry="71.428574"
d="m 454.28572,549.50507 a 71.428574,71.428574 0 1 1 -142.85715,0 71.428574,71.428574 0 1 1 142.85715,0 z"
transform="matrix(1.278781,0,0,1.278781,-239.59045,89.665546)" />
<g
transform="matrix(4.0314732,0,0,4.0314732,-693.67321,-408.8113)"
id="g3178">
<path
inkscape:connector-curvature="0"
sodipodi:nodetypes="csssc"
id="path3159"
d="m 234.78774,331.58001 c -31.87684,0.0325 -57.71719,-31.08607 -58.23077,-32.66642 -1.24408,-3.82817 25.38817,-32.75179 57.265,-32.78433 31.87683,-0.0325 58.68772,30.04142 58.23076,32.66642 -0.17904,1.02851 -24.29715,32.20961 -55.54932,32.76812"
style="fill:none;stroke:#000000;stroke-width:6.60500002;stroke-linecap:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
</g>
</g>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7-10-7-10-7z"/>
<circle cx="12" cy="12" r="3"/>
</svg>

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 261 B

Before After
Before After

View file

@ -1,12 +1,6 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns:xlink="http://www.w3.org/1999/xlink" fill="#000000" version="1.1" id="Capa_1"
xmlns="http://www.w3.org/2000/svg"
width="800px" height="800px" viewBox="0 0 71.753 71.753"
xml:space="preserve">
<g>
<path d="M39.798,20.736H28.172v20.738L11.625,41.47V20.736H0L19.899,0.839L39.798,20.736z M51.855,70.914l19.897-19.896H60.129
V30.282l-16.547-0.004v20.74H31.957L51.855,70.914z"/>
</g>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M4 8h13"/>
<path d="M14 5l3 3-3 3"/>
<path d="M20 16H7"/>
<path d="M10 13l-3 3 3 3"/>
</svg>

Before

Width:  |  Height:  |  Size: 648 B

After

Width:  |  Height:  |  Size: 269 B

Before After
Before After

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="520pt" height="520pt" viewBox="0 0 520 520" version="1.1">
<g id="surface1">
<path style=" stroke:none;fill-rule:nonzero;fill:#000000;fill-opacity:1;" d="M 240 0 L 240 45 C 130.078125 55.234375 43.75 147.421875 43.75 260 C 43.75 318.671875 67.03125 371.640625 105 410.625 L 159.375 361.875 C 133.203125 335.859375 116.875 299.765625 116.875 260 C 116.875 187.8125 170.46875 127.96875 240 118.125 L 240 160 L 368.125 80 Z M 415 109.375 L 361.25 158.125 C 387.421875 184.140625 403.125 220.3125 403.125 260 C 403.125 332.265625 349.609375 391.484375 280 401.25 L 280 360 L 151.875 440 L 280 520 L 280 475 C 389.921875 464.765625 476.25 372.578125 476.25 260 C 476.25 201.328125 452.96875 148.359375 415 109.375 Z "/>
</g>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M20 11a8 8 0 0 0-13.7-5.7L4 8"/>
<path d="M4 4v4h4"/>
<path d="M4 13a8 8 0 0 0 13.7 5.7L20 16"/>
<path d="M20 20v-4h-4"/>
</svg>

Before

Width:  |  Height:  |  Size: 856 B

After

Width:  |  Height:  |  Size: 303 B

Before After
Before After

View file

@ -1,116 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="100"
height="100"
id="svg2858"
version="1.1"
inkscape:version="0.48.5 r10040"
sodipodi:docname="icon_tab_changed.svg">
<defs
id="defs2860">
<linearGradient
id="linearGradient3753">
<stop
style="stop-color:#02db0e;stop-opacity:1;"
offset="0"
id="stop3755" />
<stop
style="stop-color:#02db0e;stop-opacity:1;"
offset="1"
id="stop3757" />
</linearGradient>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective2866" />
<inkscape:perspective
id="perspective2853"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3753"
id="linearGradient3766"
x1="103.53491"
y1="132.64713"
x2="-1.5473157"
y2="33.224445"
gradientUnits="userSpaceOnUse" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="5"
inkscape:cx="-9.896878"
inkscape:cy="42.810059"
inkscape:document-units="px"
inkscape:current-layer="layer2"
showgrid="false"
inkscape:window-width="1920"
inkscape:window-height="1028"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1" />
<metadata
id="metadata2863">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Triangle"
style="display:inline">
<path
sodipodi:type="arc"
style="fill:#007aff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
id="path3758-1"
sodipodi:cx="53.900002"
sodipodi:cy="78.5"
sodipodi:rx="46.5"
sodipodi:ry="46.5"
d="M 100.4,78.5 A 46.5,46.5 0 1 1 7.4000015,78.5 46.5,46.5 0 1 1 100.4,78.5 z"
transform="matrix(1.05866,0,0,1.05866,-7.0617752,-32.704809)" />
<g
style="font-size:133.49534607px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.06498075;stroke-opacity:1;font-family:'Magic:the Gathering';-inkscape-font-specification:'Magic:the Gathering'"
id="text3759">
<path
d="m 46.854005,16.085692 c 0.977733,-2.411704 1.683885,-4.193378 2.118456,-5.345028 0.369355,-1.1514901 0.771318,-1.9988718 1.205891,-2.5421482 0.456264,-0.4344718 1.347101,-0.825571 2.672514,-1.1732989 1.23846,-0.2823765 2.705082,-0.4670623 4.399871,-0.5540578 0.369346,8.46e-5 0.727854,8.46e-5 1.075524,0 1.694737,8.46e-5 2.672485,0.5758696 2.933248,1.7273567 -3e-5,0.1956326 -3e-5,0.3803183 0,0.5540579 -3e-5,1.3254743 -0.662726,2.9224633 -1.98809,4.7909703 -1.520969,2.238035 -3.43301,4.24785 -5.736128,6.029453 -2.32489,1.760018 -4.551983,2.781222 -6.681286,3.063614 -1.260224,-0.543125 -1.977239,-1.075454 -2.151048,-1.59699 -1.3e-5,-0.08684 -1.3e-5,-0.184616 0,-0.293325 -1.3e-5,-0.434484 0.228128,-1.010269 0.684424,-1.727357 0.521453,-0.890765 1.010327,-1.868513 1.466624,-2.933247 z M 31.372977,37.856906 c 2.650785,-0.716962 6.159814,-1.651255 10.527099,-2.802881 4.280354,-1.173242 7.398284,-1.803346 9.3538,-1.890315 0.08689,5.8e-5 0.173803,5.8e-5 0.260733,0 1.06464,5.8e-5 1.82511,0.358566 2.281415,1.075524 0.260711,0.630161 0.391077,1.520998 0.391099,2.672514 -2.2e-5,0.260787 -2.2e-5,0.532384 0,0.814791 -0.173844,1.586178 -0.260755,2.781204 -0.260733,3.58508 l 0,39.533656 c 1.238459,1e-5 2.976678,-0.673549 5.214662,-2.020681 1.673009,-0.977736 2.868034,-1.46661 3.58508,-1.466624 0.173791,1.4e-5 0.304158,0.04347 0.3911,0.130367 0.543162,0.369385 0.814759,0.771348 0.814791,1.20589 -3.2e-5,1.151583 -1.868617,2.66166 -5.605762,4.530238 -1.238507,0.717023 -3.063637,1.922912 -5.475395,3.617671 -2.49871,1.781679 -4.769259,3.204846 -6.811652,4.269505 -0.347658,0.347644 -0.923443,0.662696 -1.727357,0.945157 -0.260745,0.08691 -0.532342,0.130366 -0.814791,0.130367 -0.521477,-10e-7 -1.010351,-0.271598 -1.466623,-0.814791 C 41.856611,91.111641 41.7697,81.594892 41.76971,62.8221 c -1e-5,-1.955468 -1e-5,-4.008739 0,-6.15982 -1e-5,-2.129283 -0.08692,-4.128235 -0.260734,-5.996861 -0.260742,-1.781634 -0.706161,-3.204801 -1.336257,-4.269504 -0.717023,-1.347075 -1.60786,-2.368279 -2.672514,-3.063614 -1.151576,-0.630057 -2.357465,-1.260161 -3.617672,-1.890315 -1.325394,-0.521416 -2.161911,-1.053746 -2.509556,-1.59699 -0.195549,-0.173771 -0.293324,-0.434504 -0.293324,-0.7822 -0.08691,-0.369319 0.01086,-0.771282 0.293324,-1.20589 z"
style=""
id="path2993" />
</g>
</g>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-952.36218)"
style="display:inline" />
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="8"/>
<circle cx="12" cy="12" r="3.5" fill="currentColor" stroke="none"/>
</svg>

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 268 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

View file

@ -1,29 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="122.14841" height="72.055801" id="svg2" sodipodi:version="0.32" inkscape:version="0.46" sodipodi:docname="swerty_eye.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape" version="1.0">
<defs id="defs4">
<linearGradient inkscape:collect="always" id="linearGradient3170">
<stop style="stop-color: rgb(255, 255, 255); stop-opacity: 1;" offset="0" id="stop3172"/>
<stop style="stop-color: rgb(255, 255, 255); stop-opacity: 0;" offset="1" id="stop3174"/>
</linearGradient>
<inkscape:perspective sodipodi:type="inkscape:persp3d" inkscape:vp_x="0 : 526.18109 : 1" inkscape:vp_y="0 : 1000 : 0" inkscape:vp_z="744.09448 : 526.18109 : 1" inkscape:persp3d-origin="372.04724 : 350.78739 : 1" id="perspective10"/>
<linearGradient inkscape:collect="always" xlink:href="#linearGradient3170" id="linearGradient3176" x1="348.1423" y1="241.25623" x2="362.82382" y2="226.27509" gradientUnits="userSpaceOnUse"/>
</defs>
<sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" gridtolerance="10000" guidetolerance="10" objecttolerance="10" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="1.9163562" inkscape:cx="296.89701" inkscape:cy="743.73197" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="false" showguides="true" inkscape:guide-bbox="true" inkscape:window-width="1024" inkscape:window-height="712" inkscape:window-x="-4" inkscape:window-y="-4"/>
<metadata id="metadata7">
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
</cc:Work>
</rdf:RDF>
</metadata>
<g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" transform="translate(-173.21257,-262.82673)">
<g id="g3178">
<path sodipodi:open="true" transform="matrix(1.7416,0,0,1.7416,-381.027,-111.162)" sodipodi:end="10.935153" sodipodi:start="4.6610829" d="M 352.96016,223.72064 A 11.219209,10.958297 0 1 1 352.85806,223.72622" sodipodi:ry="10.958297" sodipodi:rx="11.219209" sodipodi:cy="234.66452" sodipodi:cx="353.53552" id="path3166" style="opacity:1;fill:#0000de;fill-opacity:1;stroke:none;stroke-width:6.60500002;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" sodipodi:type="arc"/>
<path sodipodi:nodetypes="csssc" id="path3159" d="M 234.78774,331.58001 C 202.9109,331.61255 177.07055,300.49394 176.55697,298.91359 C 175.31289,295.08542 201.94514,266.1618 233.82197,266.12926 C 265.6988,266.09672 292.50969,296.17068 292.05273,298.79568 C 291.87369,299.82419 267.75558,331.00529 236.50341,331.5638" style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:6.60500002;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"/>
<path sodipodi:open="true" transform="matrix(1.7416,0,0,1.7416,-380.897,-111.409)" sodipodi:end="10.935153" sodipodi:start="4.6610829" d="M 352.96016,223.72064 A 11.219209,10.958297 0 1 1 352.85806,223.72622" sodipodi:ry="10.958297" sodipodi:rx="11.219209" sodipodi:cy="234.66452" sodipodi:cx="353.53552" id="path3168" style="opacity:1;fill:url(#linearGradient3176);fill-opacity:1;stroke:none;stroke-width:6.60500002;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" sodipodi:type="arc"/>
<path sodipodi:open="true" transform="matrix(1.38447,0,0,1.38447,-254.533,-26.8231)" sodipodi:end="4.6519677" sodipodi:start="0.53396878" d="M 363.19295,240.24179 A 11.219209,10.958297 0 1 1 352.85806,223.72622" sodipodi:ry="10.958297" sodipodi:rx="11.219209" sodipodi:cy="234.66452" sodipodi:cx="353.53552" id="path3162" style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:6.60500002;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" sodipodi:type="arc"/>
</g>
</g>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7-10-7-10-7z"/>
<circle cx="12" cy="12" r="3"/>
</svg>

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 261 B

Before After
Before After

View file

@ -14,6 +14,7 @@
#include <QObject>
#include <QPoint>
#include <QVBoxLayout>
#include <libcockatrice/utility/qt_utils.h>
#include <qnamespace.h>
LatencyStatusWidget::LatencyStatusWidget(QWidget *parent) : QWidget(parent)
@ -24,9 +25,7 @@ LatencyStatusWidget::LatencyStatusWidget(QWidget *parent) : QWidget(parent)
latencyGraph = new LatencyGraphWidget(this);
latencyGraph->setFixedSize(90, 14);
auto *layout = new QHBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(4);
auto *layout = QtUtils::makeLayout<QHBoxLayout>(this, 4);
layout->addWidget(latencyGraph);
layout->addWidget(pingLabel);

View file

@ -3,6 +3,7 @@
#include "../../../interface/pixel_map_generator.h"
#include "../../settings/cache_settings.h"
#include "../interface/widgets/dialogs/dlg_connect.h"
#include "../interface/widgets/dialogs/dlg_edit_password.h"
#include "../interface/widgets/dialogs/dlg_forgot_password_challenge.h"
#include "../interface/widgets/dialogs/dlg_forgot_password_request.h"
#include "../interface/widgets/dialogs/dlg_forgot_password_reset.h"
@ -24,6 +25,7 @@
#include <libcockatrice/network/client/remote/remote_client.h>
#include <libcockatrice/protocol/pb/response.pb.h>
#include <libcockatrice/settings/servers_settings.h>
#include <libcockatrice/utility/qt_utils.h>
#include <qnamespace.h>
class QWidget;
@ -98,6 +100,10 @@ void ConnectionController::wireClientSignals()
connect(remoteClient, &RemoteClient::sigPasswordVerifierReady, this,
&ConnectionController::onPasswordVerifierReady);
connect(remoteClient, &RemoteClient::sigPasswordChangeSuccess, this,
&ConnectionController::onPasswordChangeSuccess);
connect(remoteClient, &RemoteClient::sigPasswordChangeError, this, &ConnectionController::onPasswordChangeError);
}
void ConnectionController::connectToServer()
@ -243,17 +249,27 @@ void ConnectionController::onLoginError(int r,
{
switch (static_cast<Response::ResponseCode>(r)) {
case Response::RespClientUpdateRequired: {
QString formatted = "Missing Features: ";
for (int i = 0; i < missingFeatures.size(); ++i) {
formatted.append(QString("\n %1").arg(QChar(0x2022)) + " " + missingFeatures.value(i));
}
QMessageBox msgBox(dialogParent);
msgBox.setIcon(QMessageBox::Critical);
msgBox.setWindowTitle(tr("Failed Login"));
msgBox.setText(tr("Your client seems to be missing features this server requires for connection.") +
"\n\n" + tr("To update your client, go to 'Help -> Check for Client Updates'."));
msgBox.setDetailedText(formatted);
if (missingFeatures.isEmpty()) {
// Without a feature list this is either a login the client stopped itself or a
// strict server asking for a password; the reason string already says which and
// what to do. No client update can fix any of those causes, so show it instead of
// the update advice.
msgBox.setText(reasonStr.isEmpty() ? tr("The login did not complete.") : reasonStr);
} else {
QString formatted = tr("Missing Features:");
for (const QString &feature : missingFeatures) {
formatted.append(QString("\n %1 ").arg(QChar(0x2022)) + feature);
}
msgBox.setText(tr("Your client seems to be missing features this server requires for connection.") +
"\n\n" + tr("To update your client, go to 'Help -> Check for Client Updates'."));
msgBox.setDetailedText(formatted);
}
msgBox.exec();
break;
}
@ -300,9 +316,8 @@ void ConnectionController::onLoginError(int r,
}
case Response::RespRegistrationRequired: {
if (QMessageBox::question(dialogParent, tr("Error"),
tr("This server requires user registration. Do you want to register now?"),
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
if (QtUtils::confirm(dialogParent, tr("Error"),
tr("This server requires user registration. Do you want to register now?"))) {
registerToServer();
}
return; // don't re-prompt connect
@ -341,10 +356,16 @@ void ConnectionController::onLoginError(int r,
}
case Response::RespPasswordChangeRequired: {
QMessageBox::information(
dialogParent, tr("Password Change Required"),
tr("An administrator has reset your password. Please contact your server administrator to obtain "
"your temporary password, then log in and change it via Account -> Change Password."));
// The credentials were right, but the account may not be used until a new password
// is chosen. Let the user complete the change here: sending them off to "ask the
// administrator for your temporary password" sends them in circles, since they just
// logged in with it and the session ends without a way to comply.
DlgEditPassword dlg(dialogParent);
dlg.setWindowTitle(tr("Password Change Required"));
if (dlg.exec()) {
remoteClient->changePasswordToServer(dlg.getOldPassword(), dlg.getNewPassword());
return; // onPasswordChangeSuccess/onPasswordChangeError decides the next step
}
remoteClient->disconnectFromServer();
return;
}
@ -507,6 +528,43 @@ void ConnectionController::onNotifyUserAboutUpdate()
"To update your client, go to Help -> Check for Updates."));
}
void ConnectionController::onPasswordChangeSuccess()
{
// The credential saved for this profile is stale now: drop it so the next login asks for
// the new password instead of replaying the old verifier.
if (!pendingSaveName.isEmpty()) {
SettingsCache::instance().servers().setServerPassword(pendingSaveName, "");
}
QMessageBox::information(dialogParent, tr("Password Changed"),
tr("Your password has been changed. Please log in again with your new password."));
remoteClient->disconnectFromServer();
connectToServer();
}
void ConnectionController::onPasswordChangeError(int responseCode)
{
QString reason;
switch (static_cast<Response::ResponseCode>(responseCode)) {
case Response::RespWrongPassword:
reason = tr("The current password is incorrect.");
break;
case Response::RespPasswordTooShort:
reason = tr("The new password is too short.");
break;
case Response::RespClientUpdateRequired:
reason = tr("The server does not accept the new password format.");
break;
default:
reason = tr("The password could not be changed (error %1).").arg(responseCode);
break;
}
QMessageBox::critical(dialogParent, tr("Password Change Failed"), reason);
remoteClient->disconnectFromServer();
connectToServer();
}
void ConnectionController::onForgotPasswordSuccess()
{
QMessageBox::information(
@ -517,14 +575,38 @@ void ConnectionController::onForgotPasswordSuccess()
SettingsCache::instance().servers().setFPPlayerName("");
}
void ConnectionController::onForgotPasswordError()
void ConnectionController::onForgotPasswordError(int responseCode)
{
QMessageBox::warning(
dialogParent, tr("Reset Password"),
tr("Failed to reset user account password, please contact the server operator to reset your password."));
SettingsCache::instance().servers().setFPHostName("");
SettingsCache::instance().servers().setFPPort("");
SettingsCache::instance().servers().setFPPlayerName("");
// Rate limiting is retryable, so it must not clear the prefill.
bool keepPrefill = false;
QString message;
switch (static_cast<Response::ResponseCode>(responseCode)) {
case Response::RespTooManyRequests:
// Retryable: keep the host/port/user prefill so the user can try again. The window
// is server-configured (an hour by default), so do not promise a shorter wait.
keepPrefill = true;
message = tr("Too many password reset attempts from your address. Please wait before "
"requesting a new reset.");
break;
case Response::RespFunctionNotAllowed:
// Also returned for an unknown user, a banned user, and an expired token or
// challenge, so the message must not claim a single cause.
message = tr("The server did not accept the reset request. Check the user name, or contact "
"the server operator to reset your password.");
break;
default:
message = tr("Failed to reset user account password, please contact the server operator to reset your "
"password.");
break;
}
QMessageBox::warning(dialogParent, tr("Reset Password"), message);
if (!keepPrefill) {
SettingsCache::instance().servers().setFPHostName("");
SettingsCache::instance().servers().setFPPort("");
SettingsCache::instance().servers().setFPPlayerName("");
}
}
void ConnectionController::onPromptForgotPasswordReset()

View file

@ -87,13 +87,17 @@ private slots:
// Forgot-password flow
void onForgotPasswordSuccess();
void onForgotPasswordError();
void onForgotPasswordError(int responseCode);
void onPromptForgotPasswordReset();
void onPromptForgotPasswordChallenge();
// Persists the derived scrypt verifier after a successful challenge-response login
void onPasswordVerifierReady(const QString &verifier);
// Completes the forced password change the server demanded at login
void onPasswordChangeSuccess();
void onPasswordChangeError(int responseCode);
private:
void wireClientSignals();
void updateWindowTitle();

View file

@ -20,11 +20,12 @@
#include <libcockatrice/card/database/card_database_manager.h>
#include <libcockatrice/deck_list/deck_list.h>
#include <libcockatrice/deck_list/tree/deck_list_card_node.h>
#include <libcockatrice/network/network_manager.h>
#include <version_string.h>
DeckStatsInterface::DeckStatsInterface(QObject *parent) : QObject(parent)
{
manager = new QNetworkAccessManager(this);
manager = NetworkManagerFactory::create(this);
connect(manager, &QNetworkAccessManager::finished, this, &DeckStatsInterface::queryFinished);
}

View file

@ -26,11 +26,12 @@
#include <libcockatrice/card/database/card_database_manager.h>
#include <libcockatrice/deck_list/deck_list.h>
#include <libcockatrice/deck_list/tree/deck_list_card_node.h>
#include <libcockatrice/network/network_manager.h>
#include <version_string.h>
TappedOutInterface::TappedOutInterface(QObject *parent) : QObject(parent)
{
manager = new QNetworkAccessManager(this);
manager = NetworkManagerFactory::create(this);
connect(manager, &QNetworkAccessManager::finished, this, &TappedOutInterface::queryFinished);
}

View file

@ -27,6 +27,7 @@
#include <functional>
#include <libcockatrice/card/database/card_database.h>
#include <libcockatrice/card/database/card_database_manager.h>
#include <libcockatrice/network/network_manager.h>
#include <libcockatrice/settings/download_settings.h>
#include <libcockatrice/settings/paths_settings.h>
#include <tuple>
@ -56,7 +57,7 @@ void SpoilerBackgroundUpdater::startSpoilerDownloadProcess(QString url, bool sav
void SpoilerBackgroundUpdater::downloadFromURL(QUrl url, bool saveResults)
{
auto *nam = new QNetworkAccessManager(this);
auto *nam = NetworkManagerFactory::create(this);
auto request = QNetworkRequest(url);
request.setHeader(QNetworkRequest::UserAgentHeader, QString("Cockatrice %1").arg(VERSION_STRING));
QNetworkReply *reply = nam->get(request);

View file

@ -20,6 +20,7 @@
#include <QVariant>
#include <QVariantMap>
#include <QtGlobal>
#include <libcockatrice/network/network_manager.h>
#include <optional>
#include <qnamespace.h>
#include <qprocessordetection.h>
@ -62,7 +63,7 @@ std::optional<int> getProductVersionMajor()
} // namespace
ReleaseChannel::ReleaseChannel() : netMan(new QNetworkAccessManager(this)), response(nullptr), lastRelease(nullptr)
ReleaseChannel::ReleaseChannel() : netMan(NetworkManagerFactory::create(this)), response(nullptr), lastRelease(nullptr)
{
}

View file

@ -9,10 +9,11 @@
#include <QNetworkRequest>
#include <QUrl>
#include <QVariant>
#include <libcockatrice/network/network_manager.h>
UpdateDownloader::UpdateDownloader(QObject *parent) : QObject(parent), response(nullptr)
{
netMan = new QNetworkAccessManager(this);
netMan = NetworkManagerFactory::create(this);
}
void UpdateDownloader::beginDownload(QUrl downloadUrl)

View file

@ -6,6 +6,7 @@
#include "shortcuts_settings.h"
#include <QApplication>
#include <QCoreApplication>
#include <QDebug>
#include <QDir>
#include <QFile>
@ -47,7 +48,32 @@ Q_GLOBAL_STATIC(SettingsCache, settingsCache)
SettingsCache &SettingsCache::instance()
{
return *settingsCache; // returns a QT managed singleton reference
SettingsCache &cache = *settingsCache; // returns a QT managed singleton reference
// The release channels own QNetworkAccessManagers, which must be destroyed
// while the application object is alive. ~SettingsCache() runs during
// static teardown, after QApplication is gone, so hook the application's
// shutdown instead. Retried here because the first access may predate the
// application object.
cache.installShutdownHook();
return cache;
}
void SettingsCache::installShutdownHook()
{
if (shutdownHookInstalled) {
return;
}
QCoreApplication *application = QCoreApplication::instance();
if (application == nullptr) {
return;
}
connect(application, &QCoreApplication::aboutToQuit, this, [this] {
for (ReleaseChannel *releaseChannel : std::as_const(releaseChannels)) {
delete releaseChannel;
}
releaseChannels.clear();
});
shutdownHookInstalled = true;
}
QString SettingsCache::getDataPath()

View file

@ -19,7 +19,6 @@ inline Q_LOGGING_CATEGORY(SettingsCacheLog, "settings_cache");
class ReleaseChannel;
#define DEFAULT_LANG_NAME "English"
#define CLIENT_INFO_NOT_SET "notset"
#define DEFAULT_FONT_SIZE 12
@ -91,8 +90,13 @@ private:
QString themeName;
QList<ReleaseChannel *> releaseChannels;
bool shutdownHookInstalled = false;
bool isPortableBuild;
// Connects the aboutToQuit handler that deletes the release channels while
// the application object is still alive; a no-op before it exists.
void installShutdownHook();
[[nodiscard]] QString getSafeConfigPath(QString configEntry, QString defaultPath) const;
[[nodiscard]] QString getSafeConfigFilePath(QString configEntry, QString defaultPath) const;
void loadPaths();

View file

@ -2,13 +2,18 @@
#define COCKATRICE_SETTINGS_CARD_PREFERENCE_PROVIDER_H
#include "../../client/settings/cache_settings.h"
#include <QObject>
#include <libcockatrice/interfaces/interface_card_preference_provider.h>
#include <libcockatrice/settings/card_override_settings.h>
#include <libcockatrice/settings/cards_display_settings.h>
class SettingsCardPreferenceProvider : public ICardPreferenceProvider
class SettingsCardPreferenceProvider : public QObject, public ICardPreferenceProvider
{
public:
explicit SettingsCardPreferenceProvider(QObject *parent = nullptr) : QObject(parent)
{
}
[[nodiscard]] QString getCardPreferenceOverride(const QString &cardName) const override
{
return SettingsCache::instance().cardOverrides().getCardPreferenceOverride(cardName);

View file

@ -1,6 +1,5 @@
#include "deck_filter_string.h"
#include "../interface/deck_loader/loaded_deck.h"
#include "libcockatrice/card/card_localization.h"
#include "libcockatrice/card/database/card_database_querier.h"
#include "libcockatrice/deck_list/deck_list.h"
@ -15,6 +14,7 @@
#include <algorithm>
#include <any>
#include <libcockatrice/card/database/card_database_manager.h>
#include <libcockatrice/deck_list/loaded_deck.h>
#include <libcockatrice/filters/filter_string.h>
#include <libcockatrice/utility/peglib.h>
#include <mutex>

View file

@ -11,6 +11,7 @@
#include <QString>
#include <functional>
#include <libcockatrice/card/card_localization.h>
#include <libcockatrice/deck_list/loaded_deck.h>
struct CardSearchLanguage;
struct LoadedDeck;

View file

@ -1,6 +1,6 @@
#include "filter_builder.h"
#include "../interface/pixel_map_generator.h"
#include "../interface/theme_icon.h"
#include "../interface/widgets/utility/custom_line_edit.h"
#include <QComboBox>
@ -13,6 +13,7 @@
#include <QVariant>
#include <QtGlobal>
#include <libcockatrice/filters/filter_card.h>
#include <libcockatrice/utility/qt_utils.h>
#include <stddef.h>
FilterBuilder::FilterBuilder(QWidget *parent) : QWidget(parent)
@ -29,7 +30,7 @@ FilterBuilder::FilterBuilder(QWidget *parent) : QWidget(parent)
typeCombo->addItem(CardFilter::typeName(static_cast<CardFilter::Type>(i)), QVariant(i));
}
QPushButton *ok = new QPushButton(themePixmap(QStringLiteral("icons/increment")), QString());
QPushButton *ok = new QPushButton(loadThemedIcon(QStringLiteral("icons/increment")), QString());
ok->setObjectName("ok");
ok->setMaximumSize(20, 20);
@ -39,9 +40,8 @@ FilterBuilder::FilterBuilder(QWidget *parent) : QWidget(parent)
edit->setClearButtonEnabled(true);
edit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
QGridLayout *layout = new QGridLayout;
QGridLayout *layout = QtUtils::makeLayout<QGridLayout>();
layout->setObjectName("layout");
layout->setContentsMargins(0, 0, 0, 0);
layout->addWidget(typeCombo, 0, 0, 1, 2);
layout->addWidget(filterCombo, 0, 2, 1, 2);

View file

@ -11,6 +11,27 @@
class QObject;
namespace
{
/**
* @brief Visits every filter item below @p node, depth first.
*/
template <typename Callback> void forEachFilter(const FilterTreeNode *node, const Callback &callback)
{
if (node == nullptr) {
return;
}
if (const auto *filterItem = dynamic_cast<const FilterItem *>(node)) {
callback(filterItem);
}
for (int i = 0; i < node->childCount(); ++i) {
forEachFilter(node->nodeAt(i), callback);
}
}
} // namespace
FilterTreeModel::FilterTreeModel(QObject *parent) : QAbstractItemModel(parent)
{
fTree = new FilterTree;
@ -110,46 +131,31 @@ void FilterTreeModel::clearFiltersOfType(CardFilter::Attr filterType)
QList<const CardFilter *> FilterTreeModel::getFiltersOfType(CardFilter::Attr filterType) const
{
QList<const CardFilter *> filters;
if (!fTree) {
return filters;
}
std::function<void(const FilterTreeNode *)> traverse;
traverse = [&](const FilterTreeNode *node) {
if (const auto *filterItem = dynamic_cast<const FilterItem *>(node)) {
if (filterItem->attr() == filterType) {
QString text = filterItem->text();
filters.append(new CardFilter(text, filterItem->type(), filterItem->attr()));
}
forEachFilter(fTree, [&](const FilterItem *filterItem) {
if (filterItem->attr() == filterType) {
filters.append(new CardFilter(filterItem->text(), filterItem->type(), filterItem->attr()));
}
for (int i = 0; i < node->childCount(); ++i) {
traverse(node->nodeAt(i));
}
};
traverse(fTree);
});
return filters;
}
QStringList FilterTreeModel::getFilterTermsOfType(CardFilter::Attr filterType) const
{
QStringList terms;
forEachFilter(fTree, [&](const FilterItem *filterItem) {
if (filterItem->attr() == filterType) {
terms.append(filterItem->text());
}
});
return terms;
}
QList<const CardFilter *> FilterTreeModel::allFilters() const
{
QList<const CardFilter *> filters;
if (!fTree) {
return filters;
}
std::function<void(const FilterTreeNode *)> traverse;
traverse = [&](const FilterTreeNode *node) {
if (const auto *filterItem = dynamic_cast<const FilterItem *>(node)) {
QString text = filterItem->text();
filters.append(new CardFilter(text, filterItem->type(), filterItem->attr()));
}
for (int i = 0; i < node->childCount(); ++i) {
traverse(node->nodeAt(i));
}
};
traverse(fTree);
forEachFilter(fTree, [&](const FilterItem *filterItem) {
filters.append(new CardFilter(filterItem->text(), filterItem->type(), filterItem->attr()));
});
return filters;
}

View file

@ -28,7 +28,14 @@ public slots:
void addFilter(const CardFilter *f);
void removeFilter(const CardFilter *f);
void clearFiltersOfType(CardFilter::Attr filterType);
/**
* @brief Copies every active filter of one attribute into new CardFilter objects.
*
* The caller owns the returned filters. Prefer getFilterTermsOfType() when only
* the terms are needed.
*/
[[nodiscard]] QList<const CardFilter *> getFiltersOfType(CardFilter::Attr filterType) const;
/// @brief Copies every active filter into new CardFilter objects. The caller owns them.
[[nodiscard]] QList<const CardFilter *> allFilters() const;
private slots:
@ -48,6 +55,13 @@ public:
{
return fTree;
}
/**
* @brief The texts of every active filter of one attribute, without allocating filters.
*
* Prefer this over getFiltersOfType() when only the filter terms are needed.
*/
[[nodiscard]] QStringList getFilterTermsOfType(CardFilter::Attr filterType) const;
[[nodiscard]] int rowCount(const QModelIndex &parent = QModelIndex()) const override;
[[nodiscard]] int columnCount(const QModelIndex & /*parent*/ = QModelIndex()) const override;
[[nodiscard]] QVariant data(const QModelIndex &index, int role) const override;

View file

@ -1,113 +0,0 @@
#include "card_state.h"
#include <QSharedPointer>
void CardState::resetState(bool keepAnnotations)
{
attacking = false;
counters.clear();
pt.clear();
if (!keepAnnotations) {
annotation.clear();
}
attachedTo = nullptr;
}
void CardState::setZone(CardZoneLogic *_zone)
{
if (zone == _zone) {
return;
}
zone = _zone;
emit zoneChanged(this, zone);
emit stateChanged();
}
void CardState::setAttacking(bool _attacking)
{
if (attacking == _attacking) {
return;
}
attacking = _attacking;
emit attackingChanged(_attacking);
emit stateChanged();
}
void CardState::insertCounter(int id, int value)
{
counters.insert(id, value);
emit countersChanged(counters);
emit stateChanged();
}
void CardState::setCounter(int id, int value)
{
if (value) {
counters[id] = value;
} else {
counters.remove(id);
}
emit countersChanged(counters);
emit stateChanged();
}
void CardState::clearCounters()
{
counters.clear();
emit countersChanged(counters);
emit stateChanged();
}
void CardState::setAnnotation(const QString &_annotation)
{
if (annotation == _annotation) {
return;
}
annotation = _annotation;
emit annotationChanged(annotation);
emit stateChanged();
}
void CardState::setPT(const QString &_pt)
{
if (pt == _pt) {
return;
}
pt = _pt;
emit ptChanged(pt);
emit stateChanged();
}
void CardState::setDoesntUntap(bool _doesntUntap)
{
if (doesntUntap == _doesntUntap) {
return;
}
doesntUntap = _doesntUntap;
emit doesntUntapChanged(_doesntUntap);
emit stateChanged();
}
void CardState::setDestroyOnZoneChange(bool _destroyOnZoneChange)
{
if (destroyOnZoneChange == _destroyOnZoneChange) {
return;
}
destroyOnZoneChange = _destroyOnZoneChange;
emit destroyOnZoneChangeChanged(_destroyOnZoneChange);
emit stateChanged();
}
void CardState::setAttachedTo(CardItem *_attachedTo)
{
if (attachedTo == _attachedTo) {
return;
}
attachedTo = _attachedTo;
emit attachedToChanged(_attachedTo);
emit stateChanged();
}

View file

@ -1,106 +0,0 @@
#ifndef COCKATRICE_CARD_STATE_H
#define COCKATRICE_CARD_STATE_H
#include <QMap>
#include <QObject>
#include <QString>
#include <qtmetamacros.h>
class CardZoneLogic;
class CardItem;
class CardState : public QObject
{
Q_OBJECT
private:
bool attacking = false;
QMap<int, int> counters;
QString annotation;
QString pt;
bool doesntUntap = false;
bool destroyOnZoneChange = false;
CardItem *attachedTo = nullptr;
CardZoneLogic *zone = nullptr;
signals:
void stateChanged();
void attackingChanged(bool newValue);
void countersChanged(const QMap<int, int> &newCounters);
void annotationChanged(const QString &newAnnotation);
void ptChanged(const QString &newPt);
void doesntUntapChanged(bool newValue);
void destroyOnZoneChangeChanged(bool newValue);
void attachedToChanged(CardItem *newAttachedTo);
void zoneChanged(CardState *changedCard, CardZoneLogic *newZone);
public:
explicit CardState(QObject *parent, CardZoneLogic *_zone) : QObject(parent), zone(_zone)
{
}
void resetState(bool keepAnnotations);
CardZoneLogic *getZone() const
{
return zone;
}
void setZone(CardZoneLogic *_zone);
bool getAttacking() const
{
return attacking;
}
void setAttacking(bool _attacking);
const QMap<int, int> &getCounters() const
{
return counters;
}
void insertCounter(int id, int value);
void setCounter(int id, int value);
void clearCounters();
QString getAnnotation() const
{
return annotation;
}
void setAnnotation(const QString &_annotation);
QString getPT() const
{
return pt;
}
void setPT(const QString &_pt);
bool getDoesntUntap() const
{
return doesntUntap;
}
void setDoesntUntap(bool _doesntUntap);
bool getDestroyOnZoneChange() const
{
return destroyOnZoneChange;
}
void setDestroyOnZoneChange(bool _destroyOnZoneChange);
CardItem *getAttachedTo() const
{
return attachedTo;
}
void setAttachedTo(CardItem *_attachedTo);
};
#endif // COCKATRICE_CARD_STATE_H

View file

@ -1,26 +0,0 @@
/**
* @file replay.h
* @ingroup GameLogic
* @ingroup Replay
*/
//! \todo Document this file.
#ifndef COCKATRICE_REPLAY_H
#define COCKATRICE_REPLAY_H
#include "abstract_game.h"
#include <qtmetamacros.h>
class GameReplay;
class QObject;
class Replay : public AbstractGame
{
Q_OBJECT
public:
explicit Replay(QObject *_parent, const GameReplay *_replay, bool isLocalGame);
};
#endif // COCKATRICE_REPLAY_H

View file

@ -7,6 +7,7 @@
#include <QBrush>
#include <QColor>
#include <QCursor>
#include <QGraphicsScene>
#include <QGraphicsSceneMouseEvent>
#include <QPainter>
#include <QPainterPath>
@ -51,7 +52,20 @@ AbstractCardDragItem::AbstractCardDragItem(AbstractCardItem *_item,
update();
});
connect(item, &QObject::destroyed, this, &AbstractCardDragItem::deleteLater);
// The source card can be destroyed mid-drag (e.g. moved by a server event). deleteLater() alone is not enough:
// a scene repaint can run before the deferred delete and paint the dead card. Detach from the scene immediately.
connect(_item, &QObject::destroyed, this, [this]() {
hide();
if (QGraphicsScene *sc = scene()) {
sc->removeItem(this);
}
deleteLater();
});
}
AbstractCardItem *AbstractCardDragItem::getItem() const
{
return item.data();
}
QPainterPath AbstractCardDragItem::shape() const
@ -65,6 +79,10 @@ QPainterPath AbstractCardDragItem::shape() const
void AbstractCardDragItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
if (item.isNull()) {
return;
}
item->paint(painter, option, widget);
// adds a mask to the card so it looks like the card hasnt been placed yet

View file

@ -14,6 +14,7 @@
#include <QList>
#include <QObject>
#include <QPointF>
#include <QPointer>
#include <QRectF>
#include <qtmetamacros.h>
@ -24,7 +25,8 @@ class AbstractCardDragItem : public QObject, public QGraphicsItem
Q_OBJECT
Q_INTERFACES(QGraphicsItem)
protected:
AbstractCardItem *item;
/// Guarded pointer: the source card may be destroyed while this drag item still exists.
QPointer<AbstractCardItem> item;
QPointF hotSpot;
QList<AbstractCardDragItem *> childDrags;
@ -44,10 +46,8 @@ public:
}
[[nodiscard]] QPainterPath shape() const override;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
[[nodiscard]] AbstractCardItem *getItem() const
{
return item;
}
/// @return the source card, or nullptr if it has already been destroyed.
[[nodiscard]] AbstractCardItem *getItem() const;
[[nodiscard]] QPointF getHotSpot() const
{
return hotSpot;

View file

@ -34,7 +34,6 @@
#include <QVariant>
#include <QtGlobal>
#include <algorithm>
#include <libcockatrice/card/database/card_database_manager.h>
#include <libcockatrice/settings/appearance_settings.h>
#include <libcockatrice/settings/cards_display_settings.h>
#include <libcockatrice/settings/debug_settings.h>
@ -43,13 +42,23 @@
class QSizeF;
AbstractCardItem::AbstractCardItem(QGraphicsItem *parent, const CardRef &cardRef, PlayerLogic *_owner, int _id)
: ArrowTarget(_owner, parent), id(_id), cardRef(cardRef), tapped(false), facedown(false), tapAngle(0),
bgColor(Qt::transparent), isHovered(false), realZValue(0), pendingSelectionCollapse(false)
: ArrowTarget(_owner, parent), state(new CardState(this, nullptr, cardRef, _id)), tapAngle(0),
bgColor(Qt::transparent), isHovered(false), realZValue(0)
{
setCursor(Qt::OpenHandCursor);
setFlag(ItemIsSelectable);
setCacheMode(DeviceCoordinateCache);
connect(state, &CardState::cardPixmapUpdated, this, &AbstractCardItem::pixmapUpdated);
connect(state, &CardState::cardInfoChanged, this, &AbstractCardItem::onCardInfoChanged);
connect(state, &CardState::cardRefChanged, this, &AbstractCardItem::onCardRefChanged);
connect(state, &CardState::tappedChanged, this, &AbstractCardItem::onTappedChanged);
connect(state, &CardState::facedownChanged, this, [this] { update(); });
connect(state, &CardState::colorChanged, this, [this] {
cacheBgColor();
update();
});
connect(&SettingsCache::instance().cardsDisplay(), &CardsDisplaySettings::displayCardNamesChanged, this,
[this] { update(); });
connect(&SettingsCache::instance().cardsDisplay(), &CardsDisplaySettings::cardLangChanged, this,
@ -67,7 +76,7 @@ AbstractCardItem::AbstractCardItem(QGraphicsItem *parent, const CardRef &cardRef
AbstractCardItem::~AbstractCardItem()
{
emit deleteCardInfoPopup(cardRef.name);
emit deleteCardInfoPopup(state->getCardRef().name);
}
QRectF AbstractCardItem::boundingRect() const
@ -90,30 +99,29 @@ void AbstractCardItem::pixmapUpdated()
emit sigPixmapUpdated();
}
void AbstractCardItem::refreshCardInfo()
void AbstractCardItem::onCardInfoChanged()
{
exactCard = CardDatabaseManager::query()->getCard(cardRef);
if (!exactCard && !cardRef.name.isEmpty()) {
CardInfo::UiAttributes attributes = {.tableRow = -1};
auto info = CardInfo::newInstance(cardRef.name, "", true, {}, {}, {}, {}, attributes);
exactCard = ExactCard(info);
}
if (exactCard) {
connect(exactCard.getCardPtr().data(), &CardInfo::pixmapUpdated, this, &AbstractCardItem::pixmapUpdated);
}
cacheBgColor();
update();
}
void AbstractCardItem::onCardRefChanged(const CardRef &oldCardRef, const CardRef & /*newCardRef*/)
{
emit deleteCardInfoPopup(oldCardRef.name);
}
void AbstractCardItem::refreshCardInfo()
{
state->refreshCardInfo();
}
/**
* Convenience method to get the CardInfo of the exactCard
* @return A const reference to the CardInfo, or an empty CardInfo if card was null
*/
const CardInfo &AbstractCardItem::getCardInfo() const
{
return exactCard.getInfo();
return state->getCardInfo();
}
void AbstractCardItem::setRealZValue(qreal _zValue)
@ -158,13 +166,13 @@ void AbstractCardItem::paintPicture(QPainter *painter, const QSizeF &translatedS
QPixmap translatedPixmap;
bool paintImage = true;
if (facedown || cardRef.name.isEmpty()) {
if (state->getFaceDown() || state->getCardRef().name.isEmpty()) {
// never reveal card color, always paint the card back
CardPictureLoader::getCardBackPixmap(translatedPixmap, translatedSize.toSize());
} else {
// don't even spend time trying to load the picture if our size is too small
if (translatedSize.width() > 10) {
CardPictureLoader::getPixmap(translatedPixmap, exactCard, translatedSize.toSize());
CardPictureLoader::getPixmap(translatedPixmap, state->getCard(), translatedSize.toSize());
if (translatedPixmap.isNull()) {
paintImage = false;
}
@ -185,19 +193,20 @@ void AbstractCardItem::paintPicture(QPainter *painter, const QSizeF &translatedS
painter->drawPath(shape());
}
if (translatedPixmap.isNull() || SettingsCache::instance().cardsDisplay().getDisplayCardNames() || facedown) {
if (translatedPixmap.isNull() || SettingsCache::instance().cardsDisplay().getDisplayCardNames() ||
state->getFaceDown()) {
painter->save();
transformPainter(painter, translatedSize, angle);
painter->setPen(Qt::white);
painter->setBackground(Qt::black);
painter->setBackgroundMode(Qt::OpaqueMode);
QString nameStr;
if (facedown) {
nameStr = "# " + QString::number(id);
if (state->getFaceDown()) {
nameStr = "# " + QString::number(state->getId());
} else {
QString prefix = "";
if (SettingsCache::instance().debug().getShowCardId()) {
prefix = "#" + QString::number(id) + " ";
prefix = "#" + QString::number(state->getId()) + " ";
}
nameStr = prefix + CardLocalization::displayName(getCardInfo());
}
@ -235,21 +244,6 @@ void AbstractCardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *
painter->restore();
}
void AbstractCardItem::setCardRef(const CardRef &_cardRef)
{
if (cardRef == _cardRef) {
return;
}
emit deleteCardInfoPopup(cardRef.name);
if (exactCard) {
disconnect(exactCard.getCardPtr().data(), nullptr, this, nullptr);
}
cardRef = _cardRef;
refreshCardInfo();
}
void AbstractCardItem::setHovered(bool _hovered)
{
if (isHovered == _hovered) {
@ -275,18 +269,17 @@ void AbstractCardItem::setHovered(bool _hovered)
void AbstractCardItem::setColor(const QString &_color)
{
color = _color;
cacheBgColor();
update();
state->setColor(_color);
}
void AbstractCardItem::cacheBgColor()
{
QChar colorChar;
if (color.isEmpty()) {
colorChar = exactCard.getInfo().getColorChar();
const QString cardColor = state->getColor();
if (cardColor.isEmpty()) {
colorChar = state->getCardInfo().getColorChar();
} else {
colorChar = color.at(0);
colorChar = cardColor.at(0);
}
switch (colorChar.toLower().toLatin1()) {
@ -314,17 +307,12 @@ void AbstractCardItem::cacheBgColor()
}
}
void AbstractCardItem::setTapped(bool _tapped, bool canAnimate)
void AbstractCardItem::onTappedChanged(bool newTapped, bool canAnimate)
{
if (tapped == _tapped) {
return;
}
tapped = _tapped;
if (SettingsCache::instance().cardsDisplay().getTapAnimation() && canAnimate) {
static_cast<GameScene *>(scene())->registerAnimationItem(this);
} else {
tapAngle = tapped ? 90 : 0;
tapAngle = newTapped ? 90 : 0;
setTransform(QTransform()
.translate(CardDimensions::WIDTH_HALF_F, CardDimensions::HEIGHT_HALF_F)
.rotate(tapAngle)
@ -338,12 +326,6 @@ bool AbstractCardItem::animationEvent()
return false;
}
void AbstractCardItem::setFaceDown(bool _facedown)
{
facedown = _facedown;
update();
}
void AbstractCardItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
cancelPendingSelectionCollapse();
@ -357,7 +339,7 @@ void AbstractCardItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
}
}
if ((event->modifiers() & Qt::AltModifier) && event->button() == Qt::LeftButton) {
emit cardShiftClicked(cardRef.name);
emit cardShiftClicked(state->getCardRef().name);
} else if ((event->modifiers() & Qt::ControlModifier)) {
setSelected(!isSelected());
} else if (!isSelected()) {
@ -371,7 +353,7 @@ void AbstractCardItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
if (event->button() == Qt::LeftButton) {
setCursor(Qt::ClosedHandCursor);
} else if (event->button() == Qt::MiddleButton) {
emit showCardInfoPopup(event->screenPos(), cardRef);
emit showCardInfoPopup(event->screenPos(), state->getCardRef());
}
event->accept();
}
@ -405,7 +387,7 @@ void AbstractCardItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
}
if (event->button() == Qt::MiddleButton) {
emit deleteCardInfoPopup(cardRef.name);
emit deleteCardInfoPopup(state->getCardRef().name);
}
// This function ensures the parent function doesn't mess around with our selection.

View file

@ -16,8 +16,7 @@
#include <QSizeF>
#include <QString>
#include <QtGlobal>
#include <libcockatrice/card/printing/exact_card.h>
#include <libcockatrice/utility/card_ref.h>
#include <libcockatrice/game/board/card_state.h>
#include <qtmetamacros.h>
class PlayerLogic;
@ -29,13 +28,8 @@ class AbstractCardItem : public ArrowTarget, public IAnimatedItem
{
Q_OBJECT
protected:
ExactCard exactCard;
int id;
CardRef cardRef;
bool tapped;
bool facedown;
CardState *state;
int tapAngle;
QString color;
QColor bgColor;
private:
@ -45,6 +39,9 @@ private:
int selectionCollapseGeneration = 0; ///< Guards the deferred collapse timer against stale firings
private slots:
void pixmapUpdated();
void onCardInfoChanged();
void onCardRefChanged(const CardRef &oldCardRef, const CardRef &newCardRef);
void onTappedChanged(bool newTapped, bool canAnimate);
public slots:
void refreshCardInfo();
@ -80,31 +77,38 @@ public:
QSizeF getTranslatedSize(QPainter *painter) const;
void paintPicture(QPainter *painter, const QSizeF &translatedSize, int angle);
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
[[nodiscard]] CardState *getState() const
{
return state;
}
ExactCard getCard() const
{
return exactCard;
return state->getCard();
}
const CardInfo &getCardInfo() const;
int getId() const
{
return id;
return state->getId();
}
void setId(int _id)
{
id = _id;
state->setId(_id);
}
QString getName() const
{
return cardRef.name;
return state->getCardRef().name;
}
QString getProviderId() const
{
return cardRef.providerId;
return state->getCardRef().providerId;
}
void setCardRef(const CardRef &_cardRef)
{
state->setCardRef(_cardRef);
}
void setCardRef(const CardRef &_cardRef);
CardRef getCardRef() const
{
return cardRef;
return state->getCardRef();
}
qreal getRealZValue() const
{
@ -116,27 +120,33 @@ public:
{
return isHovered;
}
QString getColor() const
[[nodiscard]] QString getColor() const
{
return color;
return state->getColor();
}
void setColor(const QString &_color);
bool getTapped() const
{
return tapped;
return state->getTapped();
}
void setTapped(bool _tapped, bool canAnimate = false)
{
state->setTapped(_tapped, canAnimate);
}
void setTapped(bool _tapped, bool canAnimate = false);
bool getFaceDown() const
{
return facedown;
return state->getFaceDown();
}
void setFaceDown(bool _facedown)
{
state->setFaceDown(_facedown);
}
void setFaceDown(bool _facedown);
void processHoverEvent();
/** @brief Drop a pending collapse and disarm any deferred collapse timer. */
void cancelPendingSelectionCollapse();
void deleteCardInfoPopup()
{
emit deleteCardInfoPopup(cardRef.name);
emit deleteCardInfoPopup(state->getCardRef().name);
}
/** @brief Default: no per-tick animation. Subclasses override to animate. */

View file

@ -2,10 +2,6 @@
#include "../../client/settings/cache_settings.h"
#include "../../client/settings/shortcuts_settings.h"
#include "../../game/board/counter_state.h"
#include "../../game/player/player_actions.h"
#include "../../game/player/player_info.h"
#include "../../game/player/player_logic.h"
#include "../../game_graphics/board/translate_counter_name.h"
#include "../../interface/widgets/menus/tearoff_menu.h"
@ -23,8 +19,10 @@
#include <QString>
#include <QVariant>
#include <QtGlobal>
#include <libcockatrice/protocol/pb/command_inc_counter.pb.h>
#include <libcockatrice/protocol/pb/command_set_counter.pb.h>
#include <libcockatrice/game/board/counter_state.h>
#include <libcockatrice/game/player/player_actions.h>
#include <libcockatrice/game/player/player_info.h>
#include <libcockatrice/game/player/player_logic.h>
#include <libcockatrice/utility/expression.h>
#include <qnamespace.h>
@ -151,10 +149,7 @@ void AbstractCounter::mousePressEvent(QGraphicsSceneMouseEvent *event)
menu->exec(event->screenPos());
}
} else {
Command_IncCounter cmd;
cmd.set_counter_id(id);
cmd.set_delta(event->button() == Qt::LeftButton ? 1 : -1);
player->getPlayerActions()->sendGameCommand(cmd);
player->getPlayerActions()->actIncrementCounter(id, event->button() == Qt::LeftButton ? 1 : -1);
}
event->accept();
}
@ -172,10 +167,7 @@ void AbstractCounter::hoverLeaveEvent(QGraphicsSceneHoverEvent *)
void AbstractCounter::incrementCounter()
{
Command_IncCounter cmd;
cmd.set_counter_id(id);
cmd.set_delta(static_cast<QAction *>(sender())->data().toInt());
player->getPlayerActions()->sendGameCommand(cmd);
player->getPlayerActions()->actIncrementCounter(id, static_cast<QAction *>(sender())->data().toInt());
}
void AbstractCounter::setCounter()
@ -199,10 +191,7 @@ void AbstractCounter::setCounter()
}
Expression exp(value);
Command_SetCounter cmd;
cmd.set_counter_id(id);
cmd.set_value(static_cast<int>(exp.parse(dlg.textValue())));
player->getPlayerActions()->sendGameCommand(cmd);
player->getPlayerActions()->actSetCounter(id, static_cast<int>(exp.parse(dlg.textValue())));
}
AbstractCounterDialog::AbstractCounterDialog(const QString &name, const QString &value, QWidget *parent)

View file

@ -2,11 +2,6 @@
#include "arrow_item.h"
#include "../../client/settings/cache_settings.h"
#include "../../game/board/arrow_data.h"
#include "../../game/player/player_actions.h"
#include "../../game/player/player_info.h"
#include "../../game/player/player_logic.h"
#include "../../game/zones/card_zone_logic.h"
#include "../game_scene.h"
#include "../player/player_target.h"
#include "../z_values.h"
@ -27,12 +22,12 @@
#include <QTransform>
#include <QtGlobal>
#include <QtMath>
#include <libcockatrice/card/card_info.h>
#include <libcockatrice/protocol/pb/command_attach_card.pb.h>
#include <libcockatrice/protocol/pb/command_create_arrow.pb.h>
#include <libcockatrice/game/board/arrow_data.h>
#include <libcockatrice/game/player/player_actions.h>
#include <libcockatrice/game/player/player_info.h>
#include <libcockatrice/game/player/player_logic.h>
#include <libcockatrice/game/zones/card_zone_logic.h>
#include <libcockatrice/settings/cards_display_settings.h>
#include <libcockatrice/settings/interface_settings.h>
#include <libcockatrice/utility/color.h>
#include <libcockatrice/utility/zone_names.h>
#include <math.h>
#include <qnamespace.h>
@ -426,19 +421,19 @@ void ArrowDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
CardZoneLogic *startZone = startCard->getZone();
Command_CreateArrow cmd;
cmd.mutable_arrow_color()->CopyFrom(convertQColorToColor(data->color));
cmd.set_start_player_id(startZone->getPlayer()->getPlayerInfo()->getId());
cmd.set_start_zone(startZone->getName().toStdString());
cmd.set_start_card_id(startCard->getId());
ArrowData arrow;
arrow.color = data->color;
arrow.startPlayerId = startZone->getPlayer()->getPlayerInfo()->getId();
arrow.startZone = startZone->getName();
arrow.startCardId = startCard->getId();
if (auto *targetCard = qgraphicsitem_cast<CardItem *>(targetItem)) {
CardZoneLogic *targetZone = targetCard->getZone();
cmd.set_target_player_id(targetZone->getPlayer()->getPlayerInfo()->getId());
cmd.set_target_zone(targetZone->getName().toStdString());
cmd.set_target_card_id(targetCard->getId());
arrow.targetPlayerId = targetZone->getPlayer()->getPlayerInfo()->getId();
arrow.targetZone = targetZone->getName();
arrow.targetCardId = targetCard->getId();
} else if (auto *targetPlayer = qgraphicsitem_cast<PlayerTarget *>(targetItem)) {
cmd.set_target_player_id(targetPlayer->getOwner()->getPlayerInfo()->getId());
arrow.targetPlayerId = targetPlayer->getOwner()->getPlayerInfo()->getId();
} else {
delArrow();
return;
@ -447,22 +442,9 @@ void ArrowDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
// if the card is in hand then we will move the card to stack or table as part of drawing the arrow
if (startZone->getName() == ZoneNames::HAND) {
startCard->playCard(false);
CardInfoPtr ci = startCard->getCard().getCardPtr();
bool playToStack = SettingsCache::instance().userInterface().getPlayToStack();
if (ci && ((!playToStack && ci->getUiAttributes().tableRow == 3) ||
(playToStack && ci->getUiAttributes().tableRow != 0 &&
startCard->getZone()->getName() != ZoneNames::STACK))) {
cmd.set_start_zone(ZoneNames::STACK);
} else {
cmd.set_start_zone(playToStack ? ZoneNames::STACK : ZoneNames::TABLE);
}
}
if (deleteInPhase != 0) {
cmd.set_delete_in_phase(deleteInPhase);
}
player->getPlayerActions()->sendGameCommand(cmd);
player->getPlayerActions()->createArrow(startCard->getState(), arrow, deleteInPhase);
}
delArrow();
@ -554,7 +536,7 @@ void ArrowAttachItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
auto *startCard = qgraphicsitem_cast<CardItem *>(startItem);
auto *targetCard = qgraphicsitem_cast<CardItem *>(targetItem);
if (startCard && targetCard) {
attachCards(startCard, targetCard);
player->getPlayerActions()->attachCards(startCard->getState(), targetCard->getState());
}
}
@ -563,23 +545,3 @@ void ArrowAttachItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
child->mouseReleaseEvent(event);
}
}
void ArrowAttachItem::attachCards(CardItem *startCard, const CardItem *targetCard)
{
if (targetCard->getAttachedTo() || targetCard->getZone()->getName() != ZoneNames::TABLE) {
return;
}
// move card onto table first if attaching from some other zone
if (startCard->getZone()->getName() != ZoneNames::TABLE) {
player->getPlayerActions()->playCardToTable(startCard, false);
}
Command_AttachCard cmd;
cmd.set_start_zone(ZoneNames::TABLE);
cmd.set_card_id(startCard->getId());
cmd.set_target_player_id(targetCard->getZone()->getPlayer()->getPlayerInfo()->getId());
cmd.set_target_zone(targetCard->getZone()->getName().toStdString());
cmd.set_target_card_id(targetCard->getId());
player->getPlayerActions()->sendGameCommand(cmd);
}

View file

@ -1,7 +1,6 @@
#ifndef ARROWITEM_H
#define ARROWITEM_H
#include "../../game/board/arrow_data.h"
#include "../animated_item.h"
#include "arrow_target.h"
#include "graphics_item_type.h"
@ -18,6 +17,7 @@
#include <QRectF>
#include <QSharedPointer>
#include <QtGlobal>
#include <libcockatrice/game/board/arrow_data.h>
#include <qtmetamacros.h>
class CardItem;
@ -131,7 +131,6 @@ private:
PlayerLogic *player;
QList<ArrowAttachItem *> childArrows;
QMetaObject::Connection positionConnection;
void attachCards(CardItem *startCard, const CardItem *targetCard);
public:
explicit ArrowAttachItem(ArrowTarget *_startItem);

View file

@ -1,9 +1,9 @@
#include "arrow_registry.h"
#include "../game_graphics/board/arrow_item.h"
#include "board/arrow_data.h"
#include "arrow_item.h"
#include <QSharedPointer>
#include <libcockatrice/game/board/arrow_data.h>
void ArrowRegistry::insert(QSharedPointer<ArrowData> data, ArrowItem *arrow)
{

View file

@ -4,6 +4,7 @@
#include <QList>
#include <QMap>
#include <QSet>
#include <libcockatrice/game/board/arrow_data.h>
class ArrowItem;
struct ArrowData;

View file

@ -130,8 +130,9 @@ void CardDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
sc->removeItem(this);
QList<CardDragItem *> dragItemList;
CardZoneLogic *startZone = static_cast<CardItem *>(item)->getZone();
if (currentZone && !(static_cast<CardItem *>(item)->getAttachedTo() && (startZone == currentZone->getLogic()))) {
CardZoneLogic *startZone = static_cast<CardItem *>(item.data())->getZone();
if (currentZone &&
!(static_cast<CardItem *>(item.data())->getAttachedTo() && (startZone == currentZone->getLogic()))) {
if (!occupied) {
dragItemList.append(this);
}
@ -139,7 +140,7 @@ void CardDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
for (int i = 0; i < childDrags.size(); i++) {
CardDragItem *c = static_cast<CardDragItem *>(childDrags[i]);
if (!occupied &&
!(static_cast<CardItem *>(c->item)->getAttachedTo() && (startZone == currentZone->getLogic())) &&
!(static_cast<CardItem *>(c->item.data())->getAttachedTo() && (startZone == currentZone->getLogic())) &&
!c->occupied) {
dragItemList.append(c);
}

View file

@ -1,17 +1,6 @@
#include "card_item.h"
#include "../../client/settings/cache_settings.h"
#include "../../game/abstract_game.h"
#include "../../game/board/card_state.h"
#include "../../game/game_state.h"
#include "../../game/phase.h"
#include "../../game/player/player_actions.h"
#include "../../game/player/player_info.h"
#include "../../game/player/player_logic.h"
#include "../../game/player/player_manager.h"
#include "../../game/zones/card_zone_logic.h"
#include "../../game/zones/table_zone_logic.h"
#include "../../game/zones/view_zone_logic.h"
#include "../card_dimensions.h"
#include "../game_scene.h"
#include "arrow_item.h"
@ -41,6 +30,17 @@
#include <QVariant>
#include <QtGlobal>
#include <libcockatrice/card/card_info.h>
#include <libcockatrice/game/abstract_game.h>
#include <libcockatrice/game/board/card_state.h>
#include <libcockatrice/game/game_state.h>
#include <libcockatrice/game/phase.h>
#include <libcockatrice/game/player/player_actions.h>
#include <libcockatrice/game/player/player_info.h>
#include <libcockatrice/game/player/player_logic.h>
#include <libcockatrice/game/player/player_manager.h>
#include <libcockatrice/game/zones/card_zone_logic.h>
#include <libcockatrice/game/zones/table_zone_logic.h>
#include <libcockatrice/game/zones/view_zone_logic.h>
#include <libcockatrice/protocol/pb/serverinfo_card.pb.h>
#include <libcockatrice/settings/interface_settings.h>
#include <libcockatrice/utility/card_ref.h>
@ -53,8 +53,9 @@ CardItem::CardItem(PlayerLogic *_owner,
const CardRef &cardRef,
int _cardid,
CardZoneLogic *_zone)
: AbstractCardItem(parent, cardRef, _owner, _cardid), state(new CardState(this, _zone)), dragItem(nullptr)
: AbstractCardItem(parent, cardRef, _owner, _cardid), dragItem(nullptr)
{
state->setZone(_zone);
owner->addCard(this);
connect(&SettingsCache::instance().cardCounters(), &CardCounterSettings::colorChanged, this, [this](int counterId) {
@ -62,25 +63,44 @@ CardItem::CardItem(PlayerLogic *_owner,
update();
}
});
connect(state, &CardState::stateReset, this, [this] {
if (scene()) {
static_cast<GameScene *>(scene())->unregisterAnimationItem(this);
}
update();
});
// The retyped logic layer drives CardState setters directly (bypassing the CardItem wrappers that called
// update()), so repaint on every state change: attacking, annotation, doesntUntap, P/T and counters.
connect(state, &CardState::stateChanged, this, [this] { update(); });
connect(state, &CardState::viewDeleteRequested, this, &CardItem::deleteLater);
}
void CardItem::prepareDelete()
{
if (owner != nullptr) {
if (owner->getGame()->getActiveCard() == this) {
auto *gameScene = qobject_cast<GameScene *>(scene());
if (gameScene && gameScene->getActiveCard() == this) {
emit owner->requestCardMenuUpdate(nullptr);
owner->getGame()->setActiveCard(nullptr);
gameScene->setActiveCard(nullptr);
}
owner = nullptr;
}
while (!attachedCards.isEmpty()) {
attachedCards.first()->setZone(nullptr); // so that it won't try to call reorganizeCards()
attachedCards.first()->setAttachedTo(nullptr);
const QList<CardState *> &attachedStates = state->getAttachedCards();
while (!attachedStates.isEmpty()) {
auto *attachedItem = qobject_cast<CardItem *>(attachedStates.first()->parent());
if (attachedItem == nullptr) {
break;
}
attachedItem->setZone(nullptr); // so that it won't try to call reorganizeCards()
attachedItem->setAttachedTo(nullptr);
}
if (state->getAttachedTo() != nullptr) {
state->getAttachedTo()->removeAttachedCard(this);
state->getAttachedTo()->removeAttachedCard(state);
state->setAttachedTo(nullptr);
}
}
@ -127,7 +147,7 @@ void CardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
painter->save();
transformPainter(painter, translatedSize, tapAngle);
if (!getFaceDown() && state->getPT() == exactCard.getInfo().getPowTough()) {
if (!getFaceDown() && state->getPT() == state->getCardInfo().getPowTough()) {
painter->setPen(Qt::white);
} else {
painter->setPen(QColor(255, 150, 0)); // dark orange
@ -209,36 +229,13 @@ void CardItem::setPT(const QString &_pt)
void CardItem::setAttachedTo(CardItem *_attachedTo)
{
if (state->getAttachedTo() != nullptr) {
state->getAttachedTo()->removeAttachedCard(this);
}
CardState *newParent = _attachedTo == nullptr ? nullptr : _attachedTo->getState();
state->setAttachedTo(newParent);
gridPoint.setX(-1);
state->setAttachedTo(_attachedTo);
if (state->getAttachedTo() != nullptr) {
// If the zone is being torn down, it might already be null by the time a card tries to un-attach all its
// attached cards
if (state->getAttachedTo()->getZone() == nullptr) {
deleteLater();
} else {
emit state->getAttachedTo()->getZone()->cardAdded(this);
state->getAttachedTo()->addAttachedCard(this);
if (state->getZone() != state->getAttachedTo()->getZone()) {
state->getAttachedTo()->getZone()->reorganizeCards();
}
}
} else {
// If the zone is being torn down, it might already be null by the time a card tries to un-attach all its
// attached cards
if (state->getZone() == nullptr) {
deleteLater();
} else {
emit state->getZone()->cardAdded(this);
}
}
if (state->getZone() != nullptr) {
state->getZone()->reorganizeCards();
// If the zone is being torn down, it might already be null by the time a card tries to un-attach all its attached
// cards
if (newParent != nullptr ? newParent->getZone() == nullptr : state->getZone() == nullptr) {
deleteLater();
}
}
@ -248,13 +245,6 @@ void CardItem::setAttachedTo(CardItem *_attachedTo)
void CardItem::resetState(bool keepAnnotations)
{
state->resetState(keepAnnotations);
attachedCards.clear();
setTapped(false, false);
setDoesntUntap(false);
if (scene()) {
static_cast<GameScene *>(scene())->unregisterAnimationItem(this);
}
update();
}
void CardItem::processCardInfo(const ServerInfo_Card &_info)
@ -390,7 +380,7 @@ void CardItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
// Use the buttonDownPos to align the hot spot with the position when
// the user originally clicked
createDragItem(id, event->buttonDownPos(Qt::LeftButton), event->scenePos(), forceFaceDown);
createDragItem(state->getId(), event->buttonDownPos(Qt::LeftButton), event->scenePos(), forceFaceDown);
dragItem->grabMouse();
int childIndex = 0;
@ -433,42 +423,11 @@ void CardItem::playCard(bool faceDown)
emit playSelected(this);
}
} else {
state->getZone()->getPlayer()->getPlayerActions()->playCard(this, faceDown);
state->getZone()->getPlayer()->getPlayerActions()->playCard(state, faceDown);
}
}
}
QVariantList CardItem::parsePT(const QString &pt)
{
QVariantList ptList = QVariantList();
if (!pt.isEmpty()) {
int sep = pt.indexOf('/');
if (sep == 0) {
ptList.append(QVariant(pt.mid(1))); // cut off starting '/' and take full string
} else {
int start = 0;
for (;;) {
QString item = pt.mid(start, sep - start);
if (item.isEmpty()) {
ptList.append(QVariant(QString()));
} else if (item[0] == '+') {
ptList.append(QVariant(item.mid(1).toInt())); // add as int
} else if (item[0] == '-') {
ptList.append(QVariant(item.toInt())); // add as int
} else {
ptList.append(QVariant(item)); // add as qstring
}
if (sep == -1) {
break;
}
start = sep + 1;
sep = pt.indexOf('/', start);
}
}
}
return ptList;
}
/**
* @brief returns true if the zone is a unwritable reveal zone view (eg a card reveal window). Will return false if zone
* is nullptr.
@ -493,7 +452,7 @@ void CardItem::handleClickedToPlay(bool shiftHeld)
if (SettingsCache::instance().userInterface().getClickPlaysAllSelected()) {
emit hideSelected(this);
} else {
state->getZone()->removeCard(this);
state->getZone()->removeCard(state);
}
} else {
playCard(shiftHeld);
@ -537,16 +496,16 @@ bool CardItem::animationEvent()
{
int rotation = ROTATION_DEGREES_PER_FRAME;
bool animationIncomplete = true;
if (!tapped) {
if (!state->getTapped()) {
rotation *= -1;
}
tapAngle += rotation;
if (tapped && (tapAngle > 90)) {
if (state->getTapped() && (tapAngle > 90)) {
tapAngle = 90;
animationIncomplete = false;
}
if (!tapped && (tapAngle < 0)) {
if (!state->getTapped() && (tapAngle < 0)) {
tapAngle = 0;
animationIncomplete = false;
}
@ -567,7 +526,9 @@ QVariant CardItem::itemChange(GraphicsItemChange change, const QVariant &value)
bool selected = value.toBool();
if (selected) {
owner->getGame()->setActiveCard(this);
if (auto *gameScene = qobject_cast<GameScene *>(scene())) {
gameScene->setActiveCard(this);
}
}
emit selectionChanged(this, selected);

View file

@ -7,7 +7,6 @@
#ifndef CARDITEM_H
#define CARDITEM_H
#include "../../game/board/card_state.h"
#include "abstract_card_item.h"
#include "graphics_item_type.h"
@ -16,6 +15,7 @@
#include <QPointF>
#include <QString>
#include <QVariantList>
#include <libcockatrice/game/board/card_state.h>
#include <qtmetamacros.h>
class CardDragItem;
@ -33,11 +33,7 @@ class CardItem : public AbstractCardItem
{
Q_OBJECT
private:
CardState *state;
QPoint gridPoint;
CardDragItem *dragItem;
QList<CardItem *> attachedCards;
void prepareDelete();
void handleClickedToPlay(bool shiftHeld);
@ -60,10 +56,6 @@ public:
CardZoneLogic *_zone = nullptr);
void retranslateUi();
[[nodiscard]] CardState *getState() const
{
return state;
}
[[nodiscard]] CardZoneLogic *getZone() const
{
return state->getZone();
@ -72,15 +64,15 @@ public:
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
[[nodiscard]] QPoint getGridPoint() const
{
return gridPoint;
return state->getGridPoint();
}
void setGridPoint(const QPoint &_gridPoint)
{
gridPoint = _gridPoint;
state->setGridPoint(_gridPoint);
}
[[nodiscard]] QPoint getGridPos() const
{
return gridPoint;
return state->getGridPoint();
}
[[nodiscard]] PlayerLogic *getOwner() const
{
@ -123,22 +115,22 @@ public:
{
state->setDestroyOnZoneChange(_destroy);
}
[[nodiscard]] CardItem *getAttachedTo() const
[[nodiscard]] CardState *getAttachedTo() const
{
return state->getAttachedTo();
}
void setAttachedTo(CardItem *_attachedTo);
void addAttachedCard(CardItem *card)
void addAttachedCard(CardState *card)
{
attachedCards.append(card);
state->addAttachedCard(card);
}
void removeAttachedCard(CardItem *card)
void removeAttachedCard(CardState *card)
{
attachedCards.removeOne(card);
state->removeAttachedCard(card);
}
[[nodiscard]] const QList<CardItem *> &getAttachedCards() const
[[nodiscard]] const QList<CardState *> &getAttachedCards() const
{
return attachedCards;
return state->getAttachedCards();
}
void resetState(bool keepAnnotations = false);
void processCardInfo(const ServerInfo_Card &_info);
@ -150,26 +142,6 @@ public:
void drawAttachArrow();
void playCard(bool faceDown);
/**
* @brief Parses a string representing a p/t in order to extract the values from it.
*
* If the string contains '/', the string will be split at the '/' and each side will be parsed separately,
* which means the result list will have two elements.
*
* If '/' is not found, then the entire string is parsed together, which means the result list will
* have a single element.
*
* If either side of the split is empty, there will also only be a single element in the result list.
*
* This function will attempt to parse each substring as an int first, handling plus and minus prefixes.
* If successful, it will put the parsed value into the QVariant as an int.
* If failed, it will just put the substring into the QVariant as a QString.
*
* @param pt The p/t string
* @return A QVariantList that can contain one or two elements, where each QVariant can be either int or QString
*/
static QVariantList parsePT(const QString &pt);
protected:
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;

View file

@ -77,7 +77,7 @@ void DeckViewCardDragItem::updatePosition(const QPointF &cursorScenePos)
void DeckViewCardDragItem::handleDrop(DeckViewCardContainer *target)
{
auto *card = static_cast<DeckViewCard *>(item);
auto *card = static_cast<DeckViewCard *>(item.data());
auto *start = static_cast<DeckViewCardContainer *>(item->parentItem());
start->removeCard(card);
target->addCard(card);

View file

@ -2,13 +2,8 @@
#include "../../client/settings/cache_settings.h"
#include "../../client/settings/shortcuts_settings.h"
#include "../../game/abstract_game.h"
#include "../../game/game_event_handler.h"
#include "../../game/game_state.h"
#include "../../interface/card_picture_loader/card_picture_loader.h"
#include "../../interface/deck_loader/deck_file_format.h"
#include "../../interface/deck_loader/deck_loader.h"
#include "../../interface/deck_loader/loaded_deck.h"
#include "../../interface/widgets/dialogs/dlg_load_deck.h"
#include "../../interface/widgets/dialogs/dlg_load_deck_from_clipboard.h"
#include "../../interface/widgets/dialogs/dlg_load_deck_from_website.h"
@ -33,16 +28,17 @@
#include <QRect>
#include <QVBoxLayout>
#include <libcockatrice/card/database/card_database_manager.h>
#include <libcockatrice/deck_list/deck_file_format.h>
#include <libcockatrice/deck_list/loaded_deck.h>
#include <libcockatrice/deck_list/playmat_resolver.h>
#include <libcockatrice/protocol/pb/command_deck_select.pb.h>
#include <libcockatrice/protocol/pb/command_ready_start.pb.h>
#include <libcockatrice/protocol/pb/command_set_playmat.pb.h>
#include <libcockatrice/protocol/pb/command_set_sideboard_lock.pb.h>
#include <libcockatrice/protocol/pb/command_set_sideboard_plan.pb.h>
#include <libcockatrice/game/abstract_game.h>
#include <libcockatrice/game/game_event_handler.h>
#include <libcockatrice/game/game_state.h>
#include <libcockatrice/protocol/pb/response_deck_download.pb.h>
#include <libcockatrice/protocol/pending_command.h>
#include <libcockatrice/settings/interface_settings.h>
#include <libcockatrice/settings/visual_deck_storage_settings.h>
#include <libcockatrice/utility/qt_utils.h>
#include <libcockatrice/utility/string_limits.h>
#include <optional>
#include <qnamespace.h>
@ -111,10 +107,9 @@ DeckViewContainer::DeckViewContainer(int _playerId, TabGame *parent)
connect(deckView, &DeckView::newCardAdded, this, &DeckViewContainer::newCardAdded);
connect(deckView, &DeckView::sideboardPlanChanged, this, &DeckViewContainer::sideboardPlanChanged);
deckViewLayout = new QVBoxLayout;
deckViewLayout = QtUtils::makeLayout<QVBoxLayout>();
deckViewLayout->addLayout(buttonHBox);
deckViewLayout->addWidget(deckView);
deckViewLayout->setContentsMargins(0, 0, 0, 0);
setLayout(deckViewLayout);
retranslateUi();
@ -314,9 +309,7 @@ void DeckViewContainer::loadDeckFromDeckList(const DeckList &deck)
return;
}
Command_DeckSelect cmd;
cmd.set_deck(deckString.toStdString());
PendingCommand *pend = parentGame->getGame()->getGameEventHandler()->prepareGameCommand(cmd);
PendingCommand *pend = parentGame->getGame()->getGameEventHandler()->prepareDeckSelect(deckString);
connect(pend, &PendingCommand::finished, this, &DeckViewContainer::deckSelectFinished);
parentGame->getGame()->getGameEventHandler()->sendGameCommand(pend, playerId);
@ -345,15 +338,7 @@ void DeckViewContainer::resolveAndSendPlaymat()
lastResolvedPlaymat = resolved;
Command_SetPlaymat playmatCmd;
auto *pp = playmatCmd.mutable_playmat_params();
pp->set_card_name(resolved.card.name.toStdString());
pp->set_card_provider_id(resolved.card.providerId.toStdString());
pp->set_margin_pct_l(resolved.params.marginPctL);
pp->set_margin_pct_r(resolved.params.marginPctR);
pp->set_vertical_offset(resolved.params.verticalOffset);
pp->set_zoom(resolved.params.zoom);
PendingCommand *playmatPend = parentGame->getGame()->getGameEventHandler()->prepareGameCommand(playmatCmd);
PendingCommand *playmatPend = parentGame->getGame()->getGameEventHandler()->prepareSetPlaymat(resolved);
const QString sentName = resolved.card.name;
connect(playmatPend, &PendingCommand::finished, this, [this, sentName](const Response &r) {
// Only RespFunctionNotAllowed signals a card art DENY rule. Older servers that predate
@ -384,9 +369,7 @@ void DeckViewContainer::loadRemoteDeck()
{
DlgLoadRemoteDeck dlg(parentGame->getGame()->getClientForPlayer(playerId), this);
if (dlg.exec()) {
Command_DeckSelect cmd;
cmd.set_deck_id(dlg.getDeckId());
PendingCommand *pend = parentGame->getGame()->getGameEventHandler()->prepareGameCommand(cmd);
PendingCommand *pend = parentGame->getGame()->getGameEventHandler()->prepareDeckSelectId(dlg.getDeckId());
connect(pend, &PendingCommand::finished, this, &DeckViewContainer::deckSelectFinished);
parentGame->getGame()->getGameEventHandler()->sendGameCommand(pend, playerId);
}
@ -442,34 +425,21 @@ void DeckViewContainer::readyStart()
void DeckViewContainer::forceStart()
{
const auto msg = tr("Are you sure you want to force start?\nThis will kick all non-ready players from the game.");
const auto res =
QMessageBox::question(this, tr("Cockatrice"), msg, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
if (res == QMessageBox::No) {
if (!QtUtils::confirm(this, tr("Cockatrice"), msg, QMessageBox::Yes)) {
return;
}
Command_ReadyStart cmd;
cmd.set_force_start(true);
cmd.set_ready(true);
parentGame->getGame()->getGameEventHandler()->sendGameCommand(cmd, playerId);
parentGame->getGame()->getGameEventHandler()->sendForceStart(playerId);
}
void DeckViewContainer::sideboardLockButtonClicked()
{
Command_SetSideboardLock cmd;
cmd.set_locked(sideboardLockButton->getState());
parentGame->getGame()->getGameEventHandler()->sendGameCommand(cmd, playerId);
parentGame->getGame()->getGameEventHandler()->sendSetSideboardLock(sideboardLockButton->getState(), playerId);
}
void DeckViewContainer::sideboardPlanChanged()
{
Command_SetSideboardPlan cmd;
const QList<MoveCard_ToZone> &newPlan = deckView->getSideboardPlan();
for (const auto &i : newPlan) {
cmd.add_move_list()->CopyFrom(i);
}
parentGame->getGame()->getGameEventHandler()->sendGameCommand(cmd, playerId);
parentGame->getGame()->getGameEventHandler()->sendSetSideboardPlan(deckView->getSideboardPlan(), playerId);
}
/**
@ -481,9 +451,7 @@ void DeckViewContainer::sendReadyStartCommand(bool ready)
resolveAndSendPlaymat();
}
Command_ReadyStart cmd;
cmd.set_ready(ready);
parentGame->getGame()->getGameEventHandler()->sendGameCommand(cmd, playerId);
parentGame->getGame()->getGameEventHandler()->sendReadyStart(ready, playerId);
}
/**

View file

@ -0,0 +1,13 @@
#include "dlg_annotation.h"
#include <QKeyEvent>
void AnnotationDialog::keyPressEvent(QKeyEvent *event)
{
if (event->key() == Qt::Key_Return && event->modifiers() & Qt::ControlModifier) {
event->accept();
accept();
return;
}
QInputDialog::keyPressEvent(event);
}

View file

@ -0,0 +1,22 @@
/**
* @file dlg_annotation.h
* @ingroup GameDialogs
*/
#ifndef COCKATRICE_DLG_ANNOTATION_H
#define COCKATRICE_DLG_ANNOTATION_H
#include <QInputDialog>
class AnnotationDialog : public QInputDialog
{
Q_OBJECT
void keyPressEvent(QKeyEvent *e) override;
public:
explicit AnnotationDialog(QWidget *parent = nullptr) : QInputDialog(parent)
{
}
};
#endif // COCKATRICE_DLG_ANNOTATION_H

View file

@ -11,6 +11,7 @@
#include <QList>
#include <QString>
#include <QStringList>
#include <libcockatrice/game/player/token_info.h>
#include <qtmetamacros.h>
class QLabel;
@ -25,17 +26,6 @@ class CardInfoPictureWidget;
class QModelIndex;
class QWidget;
struct TokenInfo
{
QString name;
QString color;
QString pt;
QString annotation;
bool destroy = true;
bool faceDown = false;
QString providerId;
};
class DlgCreateToken : public QDialog
{
Q_OBJECT

View file

@ -11,6 +11,7 @@
#include <QList>
#include <QString>
#include <QStringList>
#include <libcockatrice/game/player/move_top_cards_until_options.h>
#include <qtmetamacros.h>
class FilterString;
@ -21,13 +22,6 @@ class QLabel;
class QSpinBox;
class QWidget;
struct MoveTopCardsUntilOptions
{
QStringList exprs = {};
int numberOfHits = 1;
bool autoPlay = false;
};
class DlgMoveTopCardsUntil : public QDialog
{
Q_OBJECT

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