avios-cli 0.3.0__tar.gz → 0.4.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. {avios_cli-0.3.0 → avios_cli-0.4.1}/CHANGELOG.md +37 -1
  2. {avios_cli-0.3.0 → avios_cli-0.4.1}/PKG-INFO +35 -12
  3. {avios_cli-0.3.0 → avios_cli-0.4.1}/README.md +33 -10
  4. {avios_cli-0.3.0 → avios_cli-0.4.1}/SECURITY.md +2 -0
  5. avios_cli-0.4.1/docs/dashboard.svg +216 -0
  6. avios_cli-0.4.1/docs/reward-flights.svg +223 -0
  7. {avios_cli-0.3.0 → avios_cli-0.4.1}/pyproject.toml +1 -1
  8. avios_cli-0.4.1/scripts/screenshot.py +149 -0
  9. avios_cli-0.4.1/src/avios/__init__.py +6 -0
  10. {avios_cli-0.3.0 → avios_cli-0.4.1}/src/avios/auth.py +20 -0
  11. {avios_cli-0.3.0 → avios_cli-0.4.1}/src/avios/cli.py +287 -0
  12. {avios_cli-0.3.0 → avios_cli-0.4.1}/src/avios/client.py +5 -0
  13. {avios_cli-0.3.0 → avios_cli-0.4.1}/src/avios/endpoints.py +3 -0
  14. {avios_cli-0.3.0 → avios_cli-0.4.1}/src/avios/finnair.py +37 -11
  15. avios_cli-0.4.1/src/avios/rewards.py +370 -0
  16. {avios_cli-0.3.0 → avios_cli-0.4.1}/src/avios/session.py +41 -8
  17. {avios_cli-0.3.0 → avios_cli-0.4.1}/src/avios/tui/app.py +26 -10
  18. avios_cli-0.4.1/src/avios/tui/rewards.py +380 -0
  19. avios_cli-0.4.1/src/avios/tui/styles.tcss +94 -0
  20. avios_cli-0.4.1/tests/fixtures/reward_search.rsc +3 -0
  21. {avios_cli-0.3.0 → avios_cli-0.4.1}/tests/test_auth.py +8 -3
  22. {avios_cli-0.3.0 → avios_cli-0.4.1}/tests/test_cli.py +176 -0
  23. {avios_cli-0.3.0 → avios_cli-0.4.1}/tests/test_finnair.py +32 -0
  24. avios_cli-0.4.1/tests/test_rewards.py +142 -0
  25. {avios_cli-0.3.0 → avios_cli-0.4.1}/tests/test_session.py +13 -0
  26. avios_cli-0.4.1/tests/test_tui.py +280 -0
  27. avios_cli-0.3.0/docs/dashboard.svg +0 -190
  28. avios_cli-0.3.0/scripts/screenshot.py +0 -84
  29. avios_cli-0.3.0/src/avios/__init__.py +0 -6
  30. avios_cli-0.3.0/src/avios/tui/styles.tcss +0 -21
  31. avios_cli-0.3.0/tests/test_tui.py +0 -137
  32. {avios_cli-0.3.0 → avios_cli-0.4.1}/.editorconfig +0 -0
  33. {avios_cli-0.3.0 → avios_cli-0.4.1}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  34. {avios_cli-0.3.0 → avios_cli-0.4.1}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  35. {avios_cli-0.3.0 → avios_cli-0.4.1}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  36. {avios_cli-0.3.0 → avios_cli-0.4.1}/.github/dependabot.yml +0 -0
  37. {avios_cli-0.3.0 → avios_cli-0.4.1}/.github/workflows/ci.yml +0 -0
  38. {avios_cli-0.3.0 → avios_cli-0.4.1}/.github/workflows/publish.yml +0 -0
  39. {avios_cli-0.3.0 → avios_cli-0.4.1}/.gitignore +0 -0
  40. {avios_cli-0.3.0 → avios_cli-0.4.1}/.pre-commit-config.yaml +0 -0
  41. {avios_cli-0.3.0 → avios_cli-0.4.1}/.python-version +0 -0
  42. {avios_cli-0.3.0 → avios_cli-0.4.1}/CONTRIBUTING.md +0 -0
  43. {avios_cli-0.3.0 → avios_cli-0.4.1}/LICENSE +0 -0
  44. {avios_cli-0.3.0 → avios_cli-0.4.1}/src/avios/accounts.py +0 -0
  45. {avios_cli-0.3.0 → avios_cli-0.4.1}/src/avios/aggregate.py +0 -0
  46. {avios_cli-0.3.0 → avios_cli-0.4.1}/src/avios/config.py +0 -0
  47. {avios_cli-0.3.0 → avios_cli-0.4.1}/src/avios/models.py +0 -0
  48. {avios_cli-0.3.0 → avios_cli-0.4.1}/src/avios/programmes.py +0 -0
  49. {avios_cli-0.3.0 → avios_cli-0.4.1}/src/avios/tui/__init__.py +0 -0
  50. {avios_cli-0.3.0 → avios_cli-0.4.1}/src/avios/tui/art.py +0 -0
  51. {avios_cli-0.3.0 → avios_cli-0.4.1}/src/avios/tui/widgets.py +0 -0
  52. {avios_cli-0.3.0 → avios_cli-0.4.1}/tests/conftest.py +0 -0
  53. {avios_cli-0.3.0 → avios_cli-0.4.1}/tests/fixtures/balance.json +0 -0
  54. {avios_cli-0.3.0 → avios_cli-0.4.1}/tests/fixtures/transactions.json +0 -0
  55. {avios_cli-0.3.0 → avios_cli-0.4.1}/tests/test_accounts.py +0 -0
  56. {avios_cli-0.3.0 → avios_cli-0.4.1}/tests/test_aggregate.py +0 -0
  57. {avios_cli-0.3.0 → avios_cli-0.4.1}/tests/test_client.py +0 -0
  58. {avios_cli-0.3.0 → avios_cli-0.4.1}/tests/test_models.py +0 -0
  59. {avios_cli-0.3.0 → avios_cli-0.4.1}/uv.lock +0 -0
@@ -6,6 +6,40 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.4.1] - 2026-07-27
10
+
11
+ ### Fixed
12
+ - **Finnair balance/transactions failed with 403 immediately after login.** Login
13
+ captured the API key from the first `api.finnair.com` request (`getgauth`), which
14
+ uses a *different* `x-api-key` than the loyalty balance/transactions endpoints —
15
+ so every data call sent the wrong key and was refused. Login now captures
16
+ credentials only from a loyalty API request (`/d/loyalty-service/legacy/current/api/`),
17
+ which carries the key those endpoints accept. Fixes #28.
18
+ - A Finnair `403 Forbidden` is no longer mislabelled "session expired"; the message
19
+ now names the real cause (likely a stale/wrong API key) and includes the response.
20
+ Fixes #29.
21
+
22
+ ## [0.4.0] - 2026-07-27
23
+
24
+ ### Added
25
+ - **British Airways reward-flight availability.** `avios flights ORIGIN DEST`
26
+ supports exact-date and month-calendar searches, cabin/passenger filters,
27
+ available-only output by default, `--show-unavailable`, and scriptable JSON.
28
+ - Return journeys run two independent one-way searches with the route reversed
29
+ for the inbound leg.
30
+ - Typed reward calendar, day, flight, and cabin-availability models plus an
31
+ isolated parser for avios.com's authenticated React Server Components stream.
32
+ - The Textual app now has Dashboard and Reward Flights tabs. The search tab keeps
33
+ network work off the event loop and renders outbound/inbound results separately.
34
+
35
+ ### Changed
36
+ - BA browser-assisted login warms the separate `spend-avios` flight-search app
37
+ before saving cookies.
38
+
39
+ ### Security
40
+ - Reward-search action tokens from the private RSC response are ignored and never
41
+ stored; tests use a small sanitized fixture rather than the captured HAR.
42
+
9
43
  ## [0.3.0] - 2026-07-27
10
44
 
11
45
  ### Added
@@ -153,7 +187,9 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
153
187
  - Reward-flight **availability** search is not yet implemented (needs a British
154
188
  Airways capture).
155
189
 
156
- [Unreleased]: https://github.com/alexechoi/avios-cli/compare/v0.3.0...HEAD
190
+ [Unreleased]: https://github.com/alexechoi/avios-cli/compare/v0.4.1...HEAD
191
+ [0.4.1]: https://github.com/alexechoi/avios-cli/compare/v0.4.0...v0.4.1
192
+ [0.4.0]: https://github.com/alexechoi/avios-cli/compare/v0.3.0...v0.4.0
157
193
  [0.3.0]: https://github.com/alexechoi/avios-cli/compare/v0.2.1...v0.3.0
158
194
  [0.2.1]: https://github.com/alexechoi/avios-cli/compare/v0.2.0...v0.2.1
159
195
  [0.2.0]: https://github.com/alexechoi/avios-cli/compare/v0.1.6...v0.2.0
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: avios-cli
3
- Version: 0.3.0
4
- Summary: A CLI and TUI for avios.com — view your Avios balance and transactions from the terminal.
3
+ Version: 0.4.1
4
+ Summary: A CLI and TUI for Avios balances, transactions, and BA reward-flight availability.
5
5
  Project-URL: Homepage, https://github.com/alexechoi/avios-cli
6
6
  Project-URL: Repository, https://github.com/alexechoi/avios-cli
7
7
  Project-URL: Issues, https://github.com/alexechoi/avios-cli/issues
@@ -39,9 +39,10 @@ Description-Content-Type: text/markdown
39
39
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
40
40
  [![Python](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/)
41
41
 
42
- A **CLI and TUI for your Avios programmes** — check balances and browse transactions
43
- without leaving the terminal. British Airways and Iberia use avios.com; Finnair Plus
44
- uses Finnair's own OAuth and loyalty API.
42
+ A **CLI and TUI for your Avios programmes** — check balances, browse transactions,
43
+ and search British Airways reward-flight availability without leaving the terminal.
44
+ British Airways, Iberia, and Aer Lingus use avios.com; Finnair Plus uses Finnair's
45
+ own OAuth and loyalty API.
45
46
 
46
47
  > ⚠️ **Unofficial.** This project is not affiliated with, authorised by, or endorsed by
47
48
  > Avios, British Airways, Finnair or IAG Loyalty. It drives the same private endpoints
@@ -52,6 +53,10 @@ uses Finnair's own OAuth and loyalty API.
52
53
 
53
54
  <sub>The <code>avios tui</code> dashboard (demo data). Regenerate with <code>uv run python scripts/screenshot.py</code>.</sub>
54
55
 
56
+ ![avios reward-flight search](docs/reward-flights.svg)
57
+
58
+ <sub>Direct BA reward-seat availability by date and cabin (synthetic demo data).</sub>
59
+
55
60
  ## Status
56
61
 
57
62
  Early alpha, built in the open. See the [roadmap](#roadmap).
@@ -123,6 +128,8 @@ for Finnair because browser-cookie import cannot read that token.
123
128
  Each programme session is stored at `~/.config/avios/accounts/<programme>.json`
124
129
  (mode `600`). Sessions expire; just log in to that programme again. Use
125
130
  `avios logout <programme>` for one account or `avios logout` for all accounts.
131
+ For BA, browser-assisted login also opens the reward-flight finder briefly so its
132
+ separate `spend-avios` session is captured.
126
133
 
127
134
  ## Usage
128
135
 
@@ -138,11 +145,17 @@ avios balance --account iberia # just one programme
138
145
  avios overview # dashboard summary
139
146
  avios whoami # name, tier, membership, email
140
147
  avios raw /shell/api/users/current/accounts # hit any endpoint directly
148
+
149
+ # Direct British Airways reward-seat availability:
150
+ avios flights LON ABZ --date 2026-11-05
151
+ avios flights LON ABZ --date 2026-11-05 --return-date 2026-11-12
152
+ avios flights LON ABZ --month 2026-11 --cabin economy --cabin business
153
+ avios flights LON ABZ --month 2026-11 --return-month 2026-12 --json
141
154
  ```
142
155
 
143
- Add `--json` to `accounts`, `balance`, `transactions`, `pending` or `whoami` for
144
- scriptable output. With a single account, `balance` keeps the individual/household
145
- breakdown.
156
+ Add `--json` to `accounts`, `balance`, `transactions`, `pending`, `whoami`, or
157
+ `flights` for scriptable output. With a single account, `balance` keeps the
158
+ individual/household breakdown.
146
159
 
147
160
  ## TUI
148
161
 
@@ -150,9 +163,19 @@ breakdown.
150
163
  avios tui
151
164
  ```
152
165
 
153
- A full-screen dashboard across all your accounts: a combined balance header (with a
154
- per-programme breakdown) and a scrollable transactions table with a Programme column,
155
- merged newest-first. Press `r` to refresh, `q` to quit.
166
+ A tabbed full-screen application:
167
+
168
+ - **Dashboard** — combined balance header and transactions across every account.
169
+ - **Reward Flights** — BA date/calendar search with optional reverse-route return,
170
+ cabin/passenger controls, and independent outbound/inbound result tables.
171
+
172
+ Press `r` to refresh the dashboard and `q` to quit. Reward searches run only when
173
+ you press Search or Enter.
174
+
175
+ Reward search is an unofficial, availability-only view. It currently supports
176
+ direct BA flights, three-letter airport/city codes, and seat counts by cabin. It
177
+ does not price, book, or show taxes/fees or connecting flights. Return journeys
178
+ are two independent one-way searches.
156
179
 
157
180
  ## Roadmap
158
181
 
@@ -163,7 +186,7 @@ merged newest-first. Press `r` to refresh, `q` to quit.
163
186
  - [x] CLI commands
164
187
  - [x] Textual TUI dashboard
165
188
  - [x] Multiple accounts (BA, Iberia, Aer Lingus, Finnair) with combined views
166
- - [ ] Reward-flight **availability** search _(coming soon — needs a British Airways capture)_
189
+ - [x] British Airways reward-flight **availability** search (CLI + TUI)
167
190
 
168
191
  ## Development
169
192
 
@@ -4,9 +4,10 @@
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
5
5
  [![Python](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/)
6
6
 
7
- A **CLI and TUI for your Avios programmes** — check balances and browse transactions
8
- without leaving the terminal. British Airways and Iberia use avios.com; Finnair Plus
9
- uses Finnair's own OAuth and loyalty API.
7
+ A **CLI and TUI for your Avios programmes** — check balances, browse transactions,
8
+ and search British Airways reward-flight availability without leaving the terminal.
9
+ British Airways, Iberia, and Aer Lingus use avios.com; Finnair Plus uses Finnair's
10
+ own OAuth and loyalty API.
10
11
 
11
12
  > ⚠️ **Unofficial.** This project is not affiliated with, authorised by, or endorsed by
12
13
  > Avios, British Airways, Finnair or IAG Loyalty. It drives the same private endpoints
@@ -17,6 +18,10 @@ uses Finnair's own OAuth and loyalty API.
17
18
 
18
19
  <sub>The <code>avios tui</code> dashboard (demo data). Regenerate with <code>uv run python scripts/screenshot.py</code>.</sub>
19
20
 
21
+ ![avios reward-flight search](docs/reward-flights.svg)
22
+
23
+ <sub>Direct BA reward-seat availability by date and cabin (synthetic demo data).</sub>
24
+
20
25
  ## Status
21
26
 
22
27
  Early alpha, built in the open. See the [roadmap](#roadmap).
@@ -88,6 +93,8 @@ for Finnair because browser-cookie import cannot read that token.
88
93
  Each programme session is stored at `~/.config/avios/accounts/<programme>.json`
89
94
  (mode `600`). Sessions expire; just log in to that programme again. Use
90
95
  `avios logout <programme>` for one account or `avios logout` for all accounts.
96
+ For BA, browser-assisted login also opens the reward-flight finder briefly so its
97
+ separate `spend-avios` session is captured.
91
98
 
92
99
  ## Usage
93
100
 
@@ -103,11 +110,17 @@ avios balance --account iberia # just one programme
103
110
  avios overview # dashboard summary
104
111
  avios whoami # name, tier, membership, email
105
112
  avios raw /shell/api/users/current/accounts # hit any endpoint directly
113
+
114
+ # Direct British Airways reward-seat availability:
115
+ avios flights LON ABZ --date 2026-11-05
116
+ avios flights LON ABZ --date 2026-11-05 --return-date 2026-11-12
117
+ avios flights LON ABZ --month 2026-11 --cabin economy --cabin business
118
+ avios flights LON ABZ --month 2026-11 --return-month 2026-12 --json
106
119
  ```
107
120
 
108
- Add `--json` to `accounts`, `balance`, `transactions`, `pending` or `whoami` for
109
- scriptable output. With a single account, `balance` keeps the individual/household
110
- breakdown.
121
+ Add `--json` to `accounts`, `balance`, `transactions`, `pending`, `whoami`, or
122
+ `flights` for scriptable output. With a single account, `balance` keeps the
123
+ individual/household breakdown.
111
124
 
112
125
  ## TUI
113
126
 
@@ -115,9 +128,19 @@ breakdown.
115
128
  avios tui
116
129
  ```
117
130
 
118
- A full-screen dashboard across all your accounts: a combined balance header (with a
119
- per-programme breakdown) and a scrollable transactions table with a Programme column,
120
- merged newest-first. Press `r` to refresh, `q` to quit.
131
+ A tabbed full-screen application:
132
+
133
+ - **Dashboard** — combined balance header and transactions across every account.
134
+ - **Reward Flights** — BA date/calendar search with optional reverse-route return,
135
+ cabin/passenger controls, and independent outbound/inbound result tables.
136
+
137
+ Press `r` to refresh the dashboard and `q` to quit. Reward searches run only when
138
+ you press Search or Enter.
139
+
140
+ Reward search is an unofficial, availability-only view. It currently supports
141
+ direct BA flights, three-letter airport/city codes, and seat counts by cabin. It
142
+ does not price, book, or show taxes/fees or connecting flights. Return journeys
143
+ are two independent one-way searches.
121
144
 
122
145
  ## Roadmap
123
146
 
@@ -128,7 +151,7 @@ merged newest-first. Press `r` to refresh, `q` to quit.
128
151
  - [x] CLI commands
129
152
  - [x] Textual TUI dashboard
130
153
  - [x] Multiple accounts (BA, Iberia, Aer Lingus, Finnair) with combined views
131
- - [ ] Reward-flight **availability** search _(coming soon — needs a British Airways capture)_
154
+ - [x] British Airways reward-flight **availability** search (CLI + TUI)
132
155
 
133
156
  ## Development
134
157
 
@@ -11,6 +11,8 @@
11
11
  - `avios logout` deletes stored sessions. They also expire on the server side.
12
12
  - `AVIOS_COOKIE` may be set to supply a cookie via the environment instead of the
13
13
  stored file — avoid committing it or storing it in shell history.
14
+ - Reward-flight search sends the same saved BA cookie only to `www.avios.com`.
15
+ The RSC response's short-lived action tokens are neither exposed nor persisted.
14
16
 
15
17
  ## Unofficial software
16
18
 
@@ -0,0 +1,216 @@
1
+ <svg class="rich-terminal" viewBox="0 0 1190 928.4" xmlns="http://www.w3.org/2000/svg">
2
+ <!-- Generated with Rich https://www.textualize.io -->
3
+ <style>
4
+
5
+ @font-face {
6
+ font-family: "Fira Code";
7
+ src: local("FiraCode-Regular"),
8
+ url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Regular.woff2") format("woff2"),
9
+ url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Regular.woff") format("woff");
10
+ font-style: normal;
11
+ font-weight: 400;
12
+ }
13
+ @font-face {
14
+ font-family: "Fira Code";
15
+ src: local("FiraCode-Bold"),
16
+ url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Bold.woff2") format("woff2"),
17
+ url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Bold.woff") format("woff");
18
+ font-style: bold;
19
+ font-weight: 700;
20
+ }
21
+
22
+ .terminal-1769193694-matrix {
23
+ font-family: Fira Code, monospace;
24
+ font-size: 20px;
25
+ line-height: 24.4px;
26
+ font-variant-east-asian: full-width;
27
+ }
28
+
29
+ .terminal-1769193694-title {
30
+ font-size: 18px;
31
+ font-weight: bold;
32
+ font-family: arial;
33
+ }
34
+
35
+ .terminal-1769193694-r1 { fill: #c5c8c6 }
36
+ .terminal-1769193694-r2 { fill: #e0e0e0 }
37
+ .terminal-1769193694-r3 { fill: #a3a3a3 }
38
+ .terminal-1769193694-r4 { fill: #c6c6c6 }
39
+ .terminal-1769193694-r5 { fill: #a6a6a6;font-weight: bold }
40
+ .terminal-1769193694-r6 { fill: #a9a9a9;font-weight: bold }
41
+ .terminal-1769193694-r7 { fill: #8d8d8d;font-weight: bold }
42
+ .terminal-1769193694-r8 { fill: #707070;font-weight: bold }
43
+ .terminal-1769193694-r9 { fill: #535353;font-weight: bold }
44
+ .terminal-1769193694-r10 { fill: #686868;font-weight: bold }
45
+ .terminal-1769193694-r11 { fill: #9e9e9e;font-style: italic; }
46
+ .terminal-1769193694-r12 { fill: #eaeaea;font-weight: bold }
47
+ .terminal-1769193694-r13 { fill: #7f7f7f }
48
+ .terminal-1769193694-r14 { fill: #585858 }
49
+ .terminal-1769193694-r15 { fill: #656565 }
50
+ .terminal-1769193694-r16 { fill: #e0e0e0;font-weight: bold }
51
+ .terminal-1769193694-r17 { fill: #b9b9b9;font-weight: bold }
52
+ .terminal-1769193694-r18 { fill: #9e9e9e }
53
+ .terminal-1769193694-r19 { fill: #b0b0b0;font-weight: bold }
54
+ .terminal-1769193694-r20 { fill: #515151 }
55
+ </style>
56
+
57
+ <defs>
58
+ <clipPath id="terminal-1769193694-clip-terminal">
59
+ <rect x="0" y="0" width="1170.1999999999998" height="877.4" />
60
+ </clipPath>
61
+ <clipPath id="terminal-1769193694-line-0">
62
+ <rect x="0" y="1.5" width="1171.2" height="24.65"/>
63
+ </clipPath>
64
+ <clipPath id="terminal-1769193694-line-1">
65
+ <rect x="0" y="25.9" width="1171.2" height="24.65"/>
66
+ </clipPath>
67
+ <clipPath id="terminal-1769193694-line-2">
68
+ <rect x="0" y="50.3" width="1171.2" height="24.65"/>
69
+ </clipPath>
70
+ <clipPath id="terminal-1769193694-line-3">
71
+ <rect x="0" y="74.7" width="1171.2" height="24.65"/>
72
+ </clipPath>
73
+ <clipPath id="terminal-1769193694-line-4">
74
+ <rect x="0" y="99.1" width="1171.2" height="24.65"/>
75
+ </clipPath>
76
+ <clipPath id="terminal-1769193694-line-5">
77
+ <rect x="0" y="123.5" width="1171.2" height="24.65"/>
78
+ </clipPath>
79
+ <clipPath id="terminal-1769193694-line-6">
80
+ <rect x="0" y="147.9" width="1171.2" height="24.65"/>
81
+ </clipPath>
82
+ <clipPath id="terminal-1769193694-line-7">
83
+ <rect x="0" y="172.3" width="1171.2" height="24.65"/>
84
+ </clipPath>
85
+ <clipPath id="terminal-1769193694-line-8">
86
+ <rect x="0" y="196.7" width="1171.2" height="24.65"/>
87
+ </clipPath>
88
+ <clipPath id="terminal-1769193694-line-9">
89
+ <rect x="0" y="221.1" width="1171.2" height="24.65"/>
90
+ </clipPath>
91
+ <clipPath id="terminal-1769193694-line-10">
92
+ <rect x="0" y="245.5" width="1171.2" height="24.65"/>
93
+ </clipPath>
94
+ <clipPath id="terminal-1769193694-line-11">
95
+ <rect x="0" y="269.9" width="1171.2" height="24.65"/>
96
+ </clipPath>
97
+ <clipPath id="terminal-1769193694-line-12">
98
+ <rect x="0" y="294.3" width="1171.2" height="24.65"/>
99
+ </clipPath>
100
+ <clipPath id="terminal-1769193694-line-13">
101
+ <rect x="0" y="318.7" width="1171.2" height="24.65"/>
102
+ </clipPath>
103
+ <clipPath id="terminal-1769193694-line-14">
104
+ <rect x="0" y="343.1" width="1171.2" height="24.65"/>
105
+ </clipPath>
106
+ <clipPath id="terminal-1769193694-line-15">
107
+ <rect x="0" y="367.5" width="1171.2" height="24.65"/>
108
+ </clipPath>
109
+ <clipPath id="terminal-1769193694-line-16">
110
+ <rect x="0" y="391.9" width="1171.2" height="24.65"/>
111
+ </clipPath>
112
+ <clipPath id="terminal-1769193694-line-17">
113
+ <rect x="0" y="416.3" width="1171.2" height="24.65"/>
114
+ </clipPath>
115
+ <clipPath id="terminal-1769193694-line-18">
116
+ <rect x="0" y="440.7" width="1171.2" height="24.65"/>
117
+ </clipPath>
118
+ <clipPath id="terminal-1769193694-line-19">
119
+ <rect x="0" y="465.1" width="1171.2" height="24.65"/>
120
+ </clipPath>
121
+ <clipPath id="terminal-1769193694-line-20">
122
+ <rect x="0" y="489.5" width="1171.2" height="24.65"/>
123
+ </clipPath>
124
+ <clipPath id="terminal-1769193694-line-21">
125
+ <rect x="0" y="513.9" width="1171.2" height="24.65"/>
126
+ </clipPath>
127
+ <clipPath id="terminal-1769193694-line-22">
128
+ <rect x="0" y="538.3" width="1171.2" height="24.65"/>
129
+ </clipPath>
130
+ <clipPath id="terminal-1769193694-line-23">
131
+ <rect x="0" y="562.7" width="1171.2" height="24.65"/>
132
+ </clipPath>
133
+ <clipPath id="terminal-1769193694-line-24">
134
+ <rect x="0" y="587.1" width="1171.2" height="24.65"/>
135
+ </clipPath>
136
+ <clipPath id="terminal-1769193694-line-25">
137
+ <rect x="0" y="611.5" width="1171.2" height="24.65"/>
138
+ </clipPath>
139
+ <clipPath id="terminal-1769193694-line-26">
140
+ <rect x="0" y="635.9" width="1171.2" height="24.65"/>
141
+ </clipPath>
142
+ <clipPath id="terminal-1769193694-line-27">
143
+ <rect x="0" y="660.3" width="1171.2" height="24.65"/>
144
+ </clipPath>
145
+ <clipPath id="terminal-1769193694-line-28">
146
+ <rect x="0" y="684.7" width="1171.2" height="24.65"/>
147
+ </clipPath>
148
+ <clipPath id="terminal-1769193694-line-29">
149
+ <rect x="0" y="709.1" width="1171.2" height="24.65"/>
150
+ </clipPath>
151
+ <clipPath id="terminal-1769193694-line-30">
152
+ <rect x="0" y="733.5" width="1171.2" height="24.65"/>
153
+ </clipPath>
154
+ <clipPath id="terminal-1769193694-line-31">
155
+ <rect x="0" y="757.9" width="1171.2" height="24.65"/>
156
+ </clipPath>
157
+ <clipPath id="terminal-1769193694-line-32">
158
+ <rect x="0" y="782.3" width="1171.2" height="24.65"/>
159
+ </clipPath>
160
+ <clipPath id="terminal-1769193694-line-33">
161
+ <rect x="0" y="806.7" width="1171.2" height="24.65"/>
162
+ </clipPath>
163
+ <clipPath id="terminal-1769193694-line-34">
164
+ <rect x="0" y="831.1" width="1171.2" height="24.65"/>
165
+ </clipPath>
166
+ </defs>
167
+
168
+ <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" x="1" y="1" width="1188" height="926.4" rx="8"/><text class="terminal-1769193694-title" fill="#c5c8c6" text-anchor="middle" x="594" y="27">avios</text>
169
+ <g transform="translate(26,22)">
170
+ <circle cx="0" cy="0" r="7" fill="#ff5f57"/>
171
+ <circle cx="22" cy="0" r="7" fill="#febc2e"/>
172
+ <circle cx="44" cy="0" r="7" fill="#28c840"/>
173
+ </g>
174
+
175
+ <g transform="translate(9, 41)" clip-path="url(#terminal-1769193694-clip-terminal)">
176
+ <rect fill="#2d2d2d" x="0" y="1.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#2d2d2d" x="12.2" y="1.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#2d2d2d" x="24.4" y="1.5" width="61" height="24.65" shape-rendering="crispEdges"/><rect fill="#2d2d2d" x="85.4" y="1.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#2d2d2d" x="97.6" y="1.5" width="256.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#2d2d2d" x="353.8" y="1.5" width="61" height="24.65" shape-rendering="crispEdges"/><rect fill="#2d2d2d" x="414.8" y="1.5" width="36.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#2d2d2d" x="451.4" y="1.5" width="329.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#2d2d2d" x="780.8" y="1.5" width="268.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#353535" x="1049.2" y="1.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#353535" x="1061.4" y="1.5" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#353535" x="1159" y="1.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="25.9" width="1171.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="50.3" width="353.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="353.8" y="50.3" width="451.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="805.2" y="50.3" width="366" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="74.7" width="353.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="353.8" y="74.7" width="451.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="805.2" y="74.7" width="366" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="99.1" width="353.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="353.8" y="99.1" width="451.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="805.2" y="99.1" width="366" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="123.5" width="353.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="353.8" y="123.5" width="451.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="805.2" y="123.5" width="366" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="147.9" width="353.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="353.8" y="147.9" width="451.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="805.2" y="147.9" width="366" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="172.3" width="353.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="353.8" y="172.3" width="451.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="805.2" y="172.3" width="366" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="196.7" width="402.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="402.6" y="196.7" width="366" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="768.6" y="196.7" width="402.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#656565" x="0" y="221.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#656565" x="12.2" y="221.1" width="109.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#656565" x="122" y="221.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="134.2" y="221.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="146.4" y="221.1" width="170.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="317.2" y="221.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="329.4" y="221.1" width="841.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="245.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="12.2" y="245.5" width="109.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="122" y="245.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="134.2" y="245.5" width="1037" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="269.9" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="24.4" y="269.9" width="122" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="146.4" y="269.9" width="73.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="219.6" y="269.9" width="573.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="793" y="269.9" width="353.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="1146.8" y="269.9" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="294.3" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="24.4" y="294.3" width="1122.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="1146.8" y="294.3" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="318.7" width="1171.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#2d2d2d" x="0" y="343.1" width="207.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#2d2d2d" x="207.4" y="343.1" width="146.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#2d2d2d" x="353.8" y="343.1" width="280.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#2d2d2d" x="634.4" y="343.1" width="109.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#2d2d2d" x="744.2" y="343.1" width="207.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#2d2d2d" x="951.6" y="343.1" width="219.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#333333" x="0" y="367.5" width="207.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#333333" x="207.4" y="367.5" width="146.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#333333" x="353.8" y="367.5" width="280.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#333333" x="634.4" y="367.5" width="109.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#333333" x="744.2" y="367.5" width="207.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#333333" x="951.6" y="367.5" width="219.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="391.9" width="207.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="207.4" y="391.9" width="146.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="353.8" y="391.9" width="280.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="634.4" y="391.9" width="109.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="744.2" y="391.9" width="207.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="951.6" y="391.9" width="219.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#171717" x="0" y="416.3" width="207.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#171717" x="207.4" y="416.3" width="146.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#171717" x="353.8" y="416.3" width="280.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#171717" x="634.4" y="416.3" width="109.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#171717" x="744.2" y="416.3" width="207.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#171717" x="951.6" y="416.3" width="219.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="440.7" width="207.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="207.4" y="440.7" width="146.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="353.8" y="440.7" width="280.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="634.4" y="440.7" width="109.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="744.2" y="440.7" width="207.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="951.6" y="440.7" width="219.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#171717" x="0" y="465.1" width="207.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#171717" x="207.4" y="465.1" width="146.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#171717" x="353.8" y="465.1" width="280.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#171717" x="634.4" y="465.1" width="109.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#171717" x="744.2" y="465.1" width="207.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#171717" x="951.6" y="465.1" width="219.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="489.5" width="1171.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="513.9" width="1171.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="538.3" width="1171.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="562.7" width="1171.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="587.1" width="1171.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="611.5" width="1171.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="635.9" width="1171.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="660.3" width="1171.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="684.7" width="1171.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="709.1" width="1171.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="733.5" width="1171.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="757.9" width="1171.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="782.3" width="1171.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="806.7" width="1171.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="831.1" width="1171.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#2d2d2d" x="0" y="855.5" width="36.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#2d2d2d" x="36.6" y="855.5" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#2d2d2d" x="134.2" y="855.5" width="36.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#2d2d2d" x="170.8" y="855.5" width="61" height="24.65" shape-rendering="crispEdges"/><rect fill="#2d2d2d" x="231.8" y="855.5" width="793" height="24.65" shape-rendering="crispEdges"/><rect fill="#2d2d2d" x="1024.8" y="855.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#2d2d2d" x="1037" y="855.5" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#2d2d2d" x="1061.4" y="855.5" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#2d2d2d" x="1159" y="855.5" width="12.2" height="24.65" shape-rendering="crispEdges"/>
177
+ <g class="terminal-1769193694-matrix">
178
+ <text class="terminal-1769193694-r2" x="12.2" y="20" textLength="12.2" clip-path="url(#terminal-1769193694-line-0)">⭘</text><text class="terminal-1769193694-r2" x="353.8" y="20" textLength="61" clip-path="url(#terminal-1769193694-line-0)">avios</text><text class="terminal-1769193694-r3" x="414.8" y="20" textLength="36.6" clip-path="url(#terminal-1769193694-line-0)">&#160;—&#160;</text><text class="terminal-1769193694-r3" x="451.4" y="20" textLength="329.4" clip-path="url(#terminal-1769193694-line-0)">your&#160;Avios,&#160;in&#160;the&#160;terminal</text><text class="terminal-1769193694-r4" x="1061.4" y="20" textLength="97.6" clip-path="url(#terminal-1769193694-line-0)">15:20:42</text><text class="terminal-1769193694-r1" x="1171.2" y="20" textLength="12.2" clip-path="url(#terminal-1769193694-line-0)">
179
+ </text><text class="terminal-1769193694-r1" x="1171.2" y="44.4" textLength="12.2" clip-path="url(#terminal-1769193694-line-1)">
180
+ </text><text class="terminal-1769193694-r5" x="353.8" y="68.8" textLength="451.4" clip-path="url(#terminal-1769193694-line-2)">&#160;█████╗&#160;██╗&#160;&#160;&#160;██╗██╗&#160;██████╗&#160;███████╗</text><text class="terminal-1769193694-r1" x="1171.2" y="68.8" textLength="12.2" clip-path="url(#terminal-1769193694-line-2)">
181
+ </text><text class="terminal-1769193694-r6" x="353.8" y="93.2" textLength="451.4" clip-path="url(#terminal-1769193694-line-3)">██╔══██╗██║&#160;&#160;&#160;██║██║██╔═══██╗██╔════╝</text><text class="terminal-1769193694-r1" x="1171.2" y="93.2" textLength="12.2" clip-path="url(#terminal-1769193694-line-3)">
182
+ </text><text class="terminal-1769193694-r7" x="353.8" y="117.6" textLength="451.4" clip-path="url(#terminal-1769193694-line-4)">███████║██║&#160;&#160;&#160;██║██║██║&#160;&#160;&#160;██║███████╗</text><text class="terminal-1769193694-r1" x="1171.2" y="117.6" textLength="12.2" clip-path="url(#terminal-1769193694-line-4)">
183
+ </text><text class="terminal-1769193694-r8" x="353.8" y="142" textLength="451.4" clip-path="url(#terminal-1769193694-line-5)">██╔══██║╚██╗&#160;██╔╝██║██║&#160;&#160;&#160;██║╚════██║</text><text class="terminal-1769193694-r1" x="1171.2" y="142" textLength="12.2" clip-path="url(#terminal-1769193694-line-5)">
184
+ </text><text class="terminal-1769193694-r9" x="353.8" y="166.4" textLength="451.4" clip-path="url(#terminal-1769193694-line-6)">██║&#160;&#160;██║&#160;╚████╔╝&#160;██║╚██████╔╝███████║</text><text class="terminal-1769193694-r1" x="1171.2" y="166.4" textLength="12.2" clip-path="url(#terminal-1769193694-line-6)">
185
+ </text><text class="terminal-1769193694-r10" x="353.8" y="190.8" textLength="451.4" clip-path="url(#terminal-1769193694-line-7)">╚═╝&#160;&#160;╚═╝&#160;&#160;╚═══╝&#160;&#160;╚═╝&#160;╚═════╝&#160;╚══════╝</text><text class="terminal-1769193694-r1" x="1171.2" y="190.8" textLength="12.2" clip-path="url(#terminal-1769193694-line-7)">
186
+ </text><text class="terminal-1769193694-r11" x="402.6" y="215.2" textLength="366" clip-path="url(#terminal-1769193694-line-8)">✈&#160;&#160;your&#160;Avios,&#160;in&#160;the&#160;terminal</text><text class="terminal-1769193694-r1" x="1171.2" y="215.2" textLength="12.2" clip-path="url(#terminal-1769193694-line-8)">
187
+ </text><text class="terminal-1769193694-r12" x="12.2" y="239.6" textLength="109.8" clip-path="url(#terminal-1769193694-line-9)">Dashboard</text><text class="terminal-1769193694-r13" x="146.4" y="239.6" textLength="170.8" clip-path="url(#terminal-1769193694-line-9)">Reward&#160;Flights</text><text class="terminal-1769193694-r1" x="1171.2" y="239.6" textLength="12.2" clip-path="url(#terminal-1769193694-line-9)">
188
+ </text><text class="terminal-1769193694-r14" x="0" y="264" textLength="12.2" clip-path="url(#terminal-1769193694-line-10)">╸</text><text class="terminal-1769193694-r15" x="12.2" y="264" textLength="109.8" clip-path="url(#terminal-1769193694-line-10)">━━━━━━━━━</text><text class="terminal-1769193694-r14" x="122" y="264" textLength="12.2" clip-path="url(#terminal-1769193694-line-10)">╺</text><text class="terminal-1769193694-r14" x="134.2" y="264" textLength="1037" clip-path="url(#terminal-1769193694-line-10)">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</text><text class="terminal-1769193694-r1" x="1171.2" y="264" textLength="12.2" clip-path="url(#terminal-1769193694-line-10)">
189
+ </text><text class="terminal-1769193694-r16" x="24.4" y="288.4" textLength="122" clip-path="url(#terminal-1769193694-line-11)">Combined&#160;&#160;</text><text class="terminal-1769193694-r17" x="146.4" y="288.4" textLength="73.2" clip-path="url(#terminal-1769193694-line-11)">97,791</text><text class="terminal-1769193694-r18" x="219.6" y="288.4" textLength="573.4" clip-path="url(#terminal-1769193694-line-11)">&#160;&#160;&#160;&#160;&#160;British&#160;Airways&#160;75,751&#160;&#160;&#160;·&#160;&#160;&#160;Iberia&#160;22,040</text><text class="terminal-1769193694-r1" x="1171.2" y="288.4" textLength="12.2" clip-path="url(#terminal-1769193694-line-11)">
190
+ </text><text class="terminal-1769193694-r1" x="1171.2" y="312.8" textLength="12.2" clip-path="url(#terminal-1769193694-line-12)">
191
+ </text><text class="terminal-1769193694-r15" x="0" y="337.2" textLength="1171.2" clip-path="url(#terminal-1769193694-line-13)">────────────────────────────────────────────────────────────────────────────────────────────────</text><text class="terminal-1769193694-r1" x="1171.2" y="337.2" textLength="12.2" clip-path="url(#terminal-1769193694-line-13)">
192
+ </text><text class="terminal-1769193694-r16" x="0" y="361.6" textLength="207.4" clip-path="url(#terminal-1769193694-line-14)">&#160;Programme&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1769193694-r16" x="207.4" y="361.6" textLength="146.4" clip-path="url(#terminal-1769193694-line-14)">&#160;Date&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1769193694-r16" x="353.8" y="361.6" textLength="280.6" clip-path="url(#terminal-1769193694-line-14)">&#160;Description&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1769193694-r16" x="634.4" y="361.6" textLength="109.8" clip-path="url(#terminal-1769193694-line-14)">&#160;Avios&#160;&#160;&#160;</text><text class="terminal-1769193694-r16" x="744.2" y="361.6" textLength="207.4" clip-path="url(#terminal-1769193694-line-14)">&#160;Type&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1769193694-r1" x="1171.2" y="361.6" textLength="12.2" clip-path="url(#terminal-1769193694-line-14)">
193
+ </text><text class="terminal-1769193694-r2" x="0" y="386" textLength="207.4" clip-path="url(#terminal-1769193694-line-15)">&#160;British&#160;Airways&#160;</text><text class="terminal-1769193694-r2" x="207.4" y="386" textLength="146.4" clip-path="url(#terminal-1769193694-line-15)">&#160;2026-07-18&#160;</text><text class="terminal-1769193694-r2" x="353.8" y="386" textLength="280.6" clip-path="url(#terminal-1769193694-line-15)">&#160;Flight&#160;BA286&#160;SFO-LHR&#160;&#160;</text><text class="terminal-1769193694-r2" x="634.4" y="386" textLength="109.8" clip-path="url(#terminal-1769193694-line-15)">&#160;+8,500&#160;&#160;</text><text class="terminal-1769193694-r2" x="744.2" y="386" textLength="207.4" clip-path="url(#terminal-1769193694-line-15)">&#160;Collection&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1769193694-r1" x="1171.2" y="386" textLength="12.2" clip-path="url(#terminal-1769193694-line-15)">
194
+ </text><text class="terminal-1769193694-r2" x="0" y="410.4" textLength="207.4" clip-path="url(#terminal-1769193694-line-16)">&#160;Iberia&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1769193694-r2" x="207.4" y="410.4" textLength="146.4" clip-path="url(#terminal-1769193694-line-16)">&#160;2026-07-12&#160;</text><text class="terminal-1769193694-r2" x="353.8" y="410.4" textLength="280.6" clip-path="url(#terminal-1769193694-line-16)">&#160;Iberia&#160;IB3170&#160;MAD-LHR&#160;</text><text class="terminal-1769193694-r2" x="634.4" y="410.4" textLength="109.8" clip-path="url(#terminal-1769193694-line-16)">&#160;+4,200&#160;&#160;</text><text class="terminal-1769193694-r2" x="744.2" y="410.4" textLength="207.4" clip-path="url(#terminal-1769193694-line-16)">&#160;Reward&#160;Flight&#160;&#160;&#160;</text><text class="terminal-1769193694-r1" x="1171.2" y="410.4" textLength="12.2" clip-path="url(#terminal-1769193694-line-16)">
195
+ </text><text class="terminal-1769193694-r2" x="0" y="434.8" textLength="207.4" clip-path="url(#terminal-1769193694-line-17)">&#160;British&#160;Airways&#160;</text><text class="terminal-1769193694-r2" x="207.4" y="434.8" textLength="146.4" clip-path="url(#terminal-1769193694-line-17)">&#160;2026-07-02&#160;</text><text class="terminal-1769193694-r2" x="353.8" y="434.8" textLength="280.6" clip-path="url(#terminal-1769193694-line-17)">&#160;Tesco&#160;groceries&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1769193694-r2" x="634.4" y="434.8" textLength="109.8" clip-path="url(#terminal-1769193694-line-17)">&#160;+240&#160;&#160;&#160;&#160;</text><text class="terminal-1769193694-r2" x="744.2" y="434.8" textLength="207.4" clip-path="url(#terminal-1769193694-line-17)">&#160;BA&#160;Avios&#160;eStore&#160;</text><text class="terminal-1769193694-r1" x="1171.2" y="434.8" textLength="12.2" clip-path="url(#terminal-1769193694-line-17)">
196
+ </text><text class="terminal-1769193694-r2" x="0" y="459.2" textLength="207.4" clip-path="url(#terminal-1769193694-line-18)">&#160;Iberia&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1769193694-r2" x="207.4" y="459.2" textLength="146.4" clip-path="url(#terminal-1769193694-line-18)">&#160;2026-06-21&#160;</text><text class="terminal-1769193694-r2" x="353.8" y="459.2" textLength="280.6" clip-path="url(#terminal-1769193694-line-18)">&#160;NH&#160;Hotels&#160;Madrid&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1769193694-r2" x="634.4" y="459.2" textLength="109.8" clip-path="url(#terminal-1769193694-line-18)">&#160;+1,600&#160;&#160;</text><text class="terminal-1769193694-r2" x="744.2" y="459.2" textLength="207.4" clip-path="url(#terminal-1769193694-line-18)">&#160;Hotel&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1769193694-r1" x="1171.2" y="459.2" textLength="12.2" clip-path="url(#terminal-1769193694-line-18)">
197
+ </text><text class="terminal-1769193694-r2" x="0" y="483.6" textLength="207.4" clip-path="url(#terminal-1769193694-line-19)">&#160;British&#160;Airways&#160;</text><text class="terminal-1769193694-r2" x="207.4" y="483.6" textLength="146.4" clip-path="url(#terminal-1769193694-line-19)">&#160;2026-06-09&#160;</text><text class="terminal-1769193694-r2" x="353.8" y="483.6" textLength="280.6" clip-path="url(#terminal-1769193694-line-19)">&#160;Redemption&#160;LHR-JFK&#160;&#160;&#160;&#160;</text><text class="terminal-1769193694-r2" x="634.4" y="483.6" textLength="109.8" clip-path="url(#terminal-1769193694-line-19)">&#160;-50,000&#160;</text><text class="terminal-1769193694-r2" x="744.2" y="483.6" textLength="207.4" clip-path="url(#terminal-1769193694-line-19)">&#160;Reward&#160;Flight&#160;&#160;&#160;</text><text class="terminal-1769193694-r1" x="1171.2" y="483.6" textLength="12.2" clip-path="url(#terminal-1769193694-line-19)">
198
+ </text><text class="terminal-1769193694-r1" x="1171.2" y="508" textLength="12.2" clip-path="url(#terminal-1769193694-line-20)">
199
+ </text><text class="terminal-1769193694-r1" x="1171.2" y="532.4" textLength="12.2" clip-path="url(#terminal-1769193694-line-21)">
200
+ </text><text class="terminal-1769193694-r1" x="1171.2" y="556.8" textLength="12.2" clip-path="url(#terminal-1769193694-line-22)">
201
+ </text><text class="terminal-1769193694-r1" x="1171.2" y="581.2" textLength="12.2" clip-path="url(#terminal-1769193694-line-23)">
202
+ </text><text class="terminal-1769193694-r1" x="1171.2" y="605.6" textLength="12.2" clip-path="url(#terminal-1769193694-line-24)">
203
+ </text><text class="terminal-1769193694-r1" x="1171.2" y="630" textLength="12.2" clip-path="url(#terminal-1769193694-line-25)">
204
+ </text><text class="terminal-1769193694-r1" x="1171.2" y="654.4" textLength="12.2" clip-path="url(#terminal-1769193694-line-26)">
205
+ </text><text class="terminal-1769193694-r1" x="1171.2" y="678.8" textLength="12.2" clip-path="url(#terminal-1769193694-line-27)">
206
+ </text><text class="terminal-1769193694-r1" x="1171.2" y="703.2" textLength="12.2" clip-path="url(#terminal-1769193694-line-28)">
207
+ </text><text class="terminal-1769193694-r1" x="1171.2" y="727.6" textLength="12.2" clip-path="url(#terminal-1769193694-line-29)">
208
+ </text><text class="terminal-1769193694-r1" x="1171.2" y="752" textLength="12.2" clip-path="url(#terminal-1769193694-line-30)">
209
+ </text><text class="terminal-1769193694-r1" x="1171.2" y="776.4" textLength="12.2" clip-path="url(#terminal-1769193694-line-31)">
210
+ </text><text class="terminal-1769193694-r1" x="1171.2" y="800.8" textLength="12.2" clip-path="url(#terminal-1769193694-line-32)">
211
+ </text><text class="terminal-1769193694-r1" x="1171.2" y="825.2" textLength="12.2" clip-path="url(#terminal-1769193694-line-33)">
212
+ </text><text class="terminal-1769193694-r1" x="1171.2" y="849.6" textLength="12.2" clip-path="url(#terminal-1769193694-line-34)">
213
+ </text><text class="terminal-1769193694-r19" x="0" y="874" textLength="36.6" clip-path="url(#terminal-1769193694-line-35)">&#160;r&#160;</text><text class="terminal-1769193694-r2" x="36.6" y="874" textLength="97.6" clip-path="url(#terminal-1769193694-line-35)">Refresh&#160;</text><text class="terminal-1769193694-r19" x="134.2" y="874" textLength="36.6" clip-path="url(#terminal-1769193694-line-35)">&#160;q&#160;</text><text class="terminal-1769193694-r2" x="170.8" y="874" textLength="61" clip-path="url(#terminal-1769193694-line-35)">Quit&#160;</text><text class="terminal-1769193694-r20" x="1024.8" y="874" textLength="12.2" clip-path="url(#terminal-1769193694-line-35)">▏</text><text class="terminal-1769193694-r19" x="1037" y="874" textLength="24.4" clip-path="url(#terminal-1769193694-line-35)">^p</text><text class="terminal-1769193694-r2" x="1061.4" y="874" textLength="97.6" clip-path="url(#terminal-1769193694-line-35)">&#160;palette</text>
214
+ </g>
215
+ </g>
216
+ </svg>