From c37d91926fdaef7136aa7dac9b52b478863fefe6 Mon Sep 17 00:00:00 2001 From: Terje Kvernes Date: Wed, 6 Dec 2023 10:11:37 +0100 Subject: [PATCH] feat: Merge Recorder and OutputManager. (#182) * feat: Merge Recorder and OutputManager. This PR seeks to merge Recorder and OutputManager into a unified interface for processing commands and producing output, either to file or console. This ensures that: - Filtering (`|`or `|!`) works from commands called via `source` - Output to files is filtered as expected. - Removes recorder.py and its class. - Incorporates recording into OutputManager. - The OutputManager handles recording (mostly) behind the scenes if we're in recording mode. Outside of log handling we don't have to call recording tools explicitly as its done as part of normal output processing. - Incorporates table formatting into OutputManager where it belongs. - Moves command processing to a shared separate function called from both `source` and the interactive loop. - Adds commands to start and stop recording interactively. - Updates the prompt to show active recording if applicable. NOTE: This PR does not pass the current tests as it fixes #181. These changes should be thourughly reviewed and verified before new test logs are created. Fixes #179, fixes #181. * Add back a comment about shell commands called from scripts. * Clarify comments about recording related attributes. * Avoid reimplementing stop_recording when saving. * Update testsuite results. --- ci/testsuite-result.json | 150 +++++++++++++++++++++ mreg_cli/bacnet.py | 5 +- mreg_cli/cli.py | 101 +++++++++++--- mreg_cli/label.py | 6 +- mreg_cli/log.py | 20 +-- mreg_cli/main.py | 41 +++--- mreg_cli/outputmanager.py | 277 +++++++++++++++++++++++++++++++++++--- mreg_cli/permission.py | 14 +- mreg_cli/policy.py | 13 +- mreg_cli/recorder.py | 137 ------------------- mreg_cli/util.py | 34 +---- 11 files changed, 528 insertions(+), 270 deletions(-) delete mode 100644 mreg_cli/recorder.py diff --git a/ci/testsuite-result.json b/ci/testsuite-result.json index a942dae2..7e111933 100644 --- a/ci/testsuite-result.json +++ b/ci/testsuite-result.json @@ -97,6 +97,9 @@ "name": "example.org" } }, + { + "output": "Zone: example.org\n Nameservers: hostname TTL\n ns1.example.org \nPrimary ns: ns1.example.org\nEmail: hostmaster@example.org\nSerialnumber: 3231206000\nRefresh: 10800\nRetry: 3600\nExpire: 1814400\nSOA TTL: 43200\nDefault TTL: 43200" + }, { "command": "zone list -forward\n" }, @@ -130,6 +133,9 @@ ] } }, + { + "output": "Zones:\n example.org" + }, { "command": "zone set_ns example.org ns2.example.org" }, @@ -392,6 +398,9 @@ "status": 200, "response": {} }, + { + "output": "No used addresses on 10.0.2.0/28" + }, { "command": "network list_unused_addresses 10.0.2.0/28\n" }, @@ -414,6 +423,9 @@ "10.0.2.14" ] }, + { + "output": "10.0.2.4 \n10.0.2.5 \n10.0.2.6 \n10.0.2.7 \n10.0.2.8 \n10.0.2.9 \n10.0.2.10 \n10.0.2.11 \n10.0.2.12 \n10.0.2.13 \n10.0.2.14 " + }, { "command": "network set_reserved 10.0.2.0/28 8\n" }, @@ -577,6 +589,9 @@ "status": 200, "response": {} }, + { + "output": "10.0.2.9 tinyhost.example.org" + }, { "command": "network list_unused_addresses 10.0.2.0/28\n" }, @@ -593,6 +608,9 @@ "10.0.2.14" ] }, + { + "output": "10.0.2.10 \n10.0.2.11 \n10.0.2.12 \n10.0.2.13 \n10.0.2.14 " + }, { "command": "host remove tinyhost\n" }, @@ -728,6 +746,9 @@ "status": 200, "response": {} }, + { + "output": "No used addresses on 2001:db8::/64" + }, { "command": "network list_unused_addresses 2001:db8::/64\n" }, @@ -4835,6 +4856,9 @@ "2001:db8::1003" ] }, + { + "output": "2001:db8::4 \n2001:db8::5 \n2001:db8::6 \n2001:db8::7 \n2001:db8::8 \n2001:db8::9 \n2001:db8::a \n2001:db8::b \n2001:db8::c \n2001:db8::d \n2001:db8::e \n2001:db8::f \n2001:db8::10 \n2001:db8::11 \n2001:db8::12 \n2001:db8::13 \n2001:db8::14 \n2001:db8::15 \n2001:db8::16 \n2001:db8::17 \n2001:db8::18 \n2001:db8::19 \n2001:db8::1a \n2001:db8::1b \n2001:db8::1c \n2001:db8::1d \n2001:db8::1e \n2001:db8::1f \n2001:db8::20 \n2001:db8::21 \n2001:db8::22 \n2001:db8::23 \n2001:db8::24 \n2001:db8::25 \n2001:db8::26 \n2001:db8::27 \n2001:db8::28 \n2001:db8::29 \n2001:db8::2a \n2001:db8::2b \n2001:db8::2c \n2001:db8::2d \n2001:db8::2e \n2001:db8::2f \n2001:db8::30 \n2001:db8::31 \n2001:db8::32 \n2001:db8::33 \n2001:db8::34 \n2001:db8::35 \n2001:db8::36 \n2001:db8::37 \n2001:db8::38 \n2001:db8::39 \n2001:db8::3a \n2001:db8::3b \n2001:db8::3c \n2001:db8::3d \n2001:db8::3e \n2001:db8::3f \n2001:db8::40 \n2001:db8::41 \n2001:db8::42 \n2001:db8::43 \n2001:db8::44 \n2001:db8::45 \n2001:db8::46 \n2001:db8::47 \n2001:db8::48 \n2001:db8::49 \n2001:db8::4a \n2001:db8::4b \n2001:db8::4c \n2001:db8::4d \n2001:db8::4e \n2001:db8::4f \n2001:db8::50 \n2001:db8::51 \n2001:db8::52 \n2001:db8::53 \n2001:db8::54 \n2001:db8::55 \n2001:db8::56 \n2001:db8::57 \n2001:db8::58 \n2001:db8::59 \n2001:db8::5a \n2001:db8::5b \n2001:db8::5c \n2001:db8::5d \n2001:db8::5e \n2001:db8::5f \n2001:db8::60 \n2001:db8::61 \n2001:db8::62 \n2001:db8::63 \n2001:db8::64 \n2001:db8::65 \n2001:db8::66 \n2001:db8::67 \n2001:db8::68 \n2001:db8::69 \n2001:db8::6a \n2001:db8::6b \n2001:db8::6c \n2001:db8::6d \n2001:db8::6e \n2001:db8::6f \n2001:db8::70 \n2001:db8::71 \n2001:db8::72 \n2001:db8::73 \n2001:db8::74 \n2001:db8::75 \n2001:db8::76 \n2001:db8::77 \n2001:db8::78 \n2001:db8::79 \n2001:db8::7a \n2001:db8::7b \n2001:db8::7c \n2001:db8::7d \n2001:db8::7e \n2001:db8::7f \n2001:db8::80 \n2001:db8::81 \n2001:db8::82 \n2001:db8::83 \n2001:db8::84 \n2001:db8::85 \n2001:db8::86 \n2001:db8::87 \n2001:db8::88 \n2001:db8::89 \n2001:db8::8a \n2001:db8::8b \n2001:db8::8c \n2001:db8::8d \n2001:db8::8e \n2001:db8::8f \n2001:db8::90 \n2001:db8::91 \n2001:db8::92 \n2001:db8::93 \n2001:db8::94 \n2001:db8::95 \n2001:db8::96 \n2001:db8::97 \n2001:db8::98 \n2001:db8::99 \n2001:db8::9a \n2001:db8::9b \n2001:db8::9c \n2001:db8::9d \n2001:db8::9e \n2001:db8::9f \n2001:db8::a0 \n2001:db8::a1 \n2001:db8::a2 \n2001:db8::a3 \n2001:db8::a4 \n2001:db8::a5 \n2001:db8::a6 \n2001:db8::a7 \n2001:db8::a8 \n2001:db8::a9 \n2001:db8::aa \n2001:db8::ab \n2001:db8::ac \n2001:db8::ad \n2001:db8::ae \n2001:db8::af \n2001:db8::b0 \n2001:db8::b1 \n2001:db8::b2 \n2001:db8::b3 \n2001:db8::b4 \n2001:db8::b5 \n2001:db8::b6 \n2001:db8::b7 \n2001:db8::b8 \n2001:db8::b9 \n2001:db8::ba \n2001:db8::bb \n2001:db8::bc \n2001:db8::bd \n2001:db8::be \n2001:db8::bf \n2001:db8::c0 \n2001:db8::c1 \n2001:db8::c2 \n2001:db8::c3 \n2001:db8::c4 \n2001:db8::c5 \n2001:db8::c6 \n2001:db8::c7 \n2001:db8::c8 \n2001:db8::c9 \n2001:db8::ca \n2001:db8::cb \n2001:db8::cc \n2001:db8::cd \n2001:db8::ce \n2001:db8::cf \n2001:db8::d0 \n2001:db8::d1 \n2001:db8::d2 \n2001:db8::d3 \n2001:db8::d4 \n2001:db8::d5 \n2001:db8::d6 \n2001:db8::d7 \n2001:db8::d8 \n2001:db8::d9 \n2001:db8::da \n2001:db8::db \n2001:db8::dc \n2001:db8::dd \n2001:db8::de \n2001:db8::df \n2001:db8::e0 \n2001:db8::e1 \n2001:db8::e2 \n2001:db8::e3 \n2001:db8::e4 \n2001:db8::e5 \n2001:db8::e6 \n2001:db8::e7 \n2001:db8::e8 \n2001:db8::e9 \n2001:db8::ea \n2001:db8::eb \n2001:db8::ec \n2001:db8::ed \n2001:db8::ee \n2001:db8::ef \n2001:db8::f0 \n2001:db8::f1 \n2001:db8::f2 \n2001:db8::f3 \n2001:db8::f4 \n2001:db8::f5 \n2001:db8::f6 \n2001:db8::f7 \n2001:db8::f8 \n2001:db8::f9 \n2001:db8::fa \n2001:db8::fb \n2001:db8::fc \n2001:db8::fd \n2001:db8::fe \n2001:db8::ff \n2001:db8::100 \n2001:db8::101 \n2001:db8::102 \n2001:db8::103 \n2001:db8::104 \n2001:db8::105 \n2001:db8::106 \n2001:db8::107 \n2001:db8::108 \n2001:db8::109 \n2001:db8::10a \n2001:db8::10b \n2001:db8::10c \n2001:db8::10d \n2001:db8::10e \n2001:db8::10f \n2001:db8::110 \n2001:db8::111 \n2001:db8::112 \n2001:db8::113 \n2001:db8::114 \n2001:db8::115 \n2001:db8::116 \n2001:db8::117 \n2001:db8::118 \n2001:db8::119 \n2001:db8::11a \n2001:db8::11b \n2001:db8::11c \n2001:db8::11d \n2001:db8::11e \n2001:db8::11f \n2001:db8::120 \n2001:db8::121 \n2001:db8::122 \n2001:db8::123 \n2001:db8::124 \n2001:db8::125 \n2001:db8::126 \n2001:db8::127 \n2001:db8::128 \n2001:db8::129 \n2001:db8::12a \n2001:db8::12b \n2001:db8::12c \n2001:db8::12d \n2001:db8::12e \n2001:db8::12f \n2001:db8::130 \n2001:db8::131 \n2001:db8::132 \n2001:db8::133 \n2001:db8::134 \n2001:db8::135 \n2001:db8::136 \n2001:db8::137 \n2001:db8::138 \n2001:db8::139 \n2001:db8::13a \n2001:db8::13b \n2001:db8::13c \n2001:db8::13d \n2001:db8::13e \n2001:db8::13f \n2001:db8::140 \n2001:db8::141 \n2001:db8::142 \n2001:db8::143 \n2001:db8::144 \n2001:db8::145 \n2001:db8::146 \n2001:db8::147 \n2001:db8::148 \n2001:db8::149 \n2001:db8::14a \n2001:db8::14b \n2001:db8::14c \n2001:db8::14d \n2001:db8::14e \n2001:db8::14f \n2001:db8::150 \n2001:db8::151 \n2001:db8::152 \n2001:db8::153 \n2001:db8::154 \n2001:db8::155 \n2001:db8::156 \n2001:db8::157 \n2001:db8::158 \n2001:db8::159 \n2001:db8::15a \n2001:db8::15b \n2001:db8::15c \n2001:db8::15d \n2001:db8::15e \n2001:db8::15f \n2001:db8::160 \n2001:db8::161 \n2001:db8::162 \n2001:db8::163 \n2001:db8::164 \n2001:db8::165 \n2001:db8::166 \n2001:db8::167 \n2001:db8::168 \n2001:db8::169 \n2001:db8::16a \n2001:db8::16b \n2001:db8::16c \n2001:db8::16d \n2001:db8::16e \n2001:db8::16f \n2001:db8::170 \n2001:db8::171 \n2001:db8::172 \n2001:db8::173 \n2001:db8::174 \n2001:db8::175 \n2001:db8::176 \n2001:db8::177 \n2001:db8::178 \n2001:db8::179 \n2001:db8::17a \n2001:db8::17b \n2001:db8::17c \n2001:db8::17d \n2001:db8::17e \n2001:db8::17f \n2001:db8::180 \n2001:db8::181 \n2001:db8::182 \n2001:db8::183 \n2001:db8::184 \n2001:db8::185 \n2001:db8::186 \n2001:db8::187 \n2001:db8::188 \n2001:db8::189 \n2001:db8::18a \n2001:db8::18b \n2001:db8::18c \n2001:db8::18d \n2001:db8::18e \n2001:db8::18f \n2001:db8::190 \n2001:db8::191 \n2001:db8::192 \n2001:db8::193 \n2001:db8::194 \n2001:db8::195 \n2001:db8::196 \n2001:db8::197 \n2001:db8::198 \n2001:db8::199 \n2001:db8::19a \n2001:db8::19b \n2001:db8::19c \n2001:db8::19d \n2001:db8::19e \n2001:db8::19f \n2001:db8::1a0 \n2001:db8::1a1 \n2001:db8::1a2 \n2001:db8::1a3 \n2001:db8::1a4 \n2001:db8::1a5 \n2001:db8::1a6 \n2001:db8::1a7 \n2001:db8::1a8 \n2001:db8::1a9 \n2001:db8::1aa \n2001:db8::1ab \n2001:db8::1ac \n2001:db8::1ad \n2001:db8::1ae \n2001:db8::1af \n2001:db8::1b0 \n2001:db8::1b1 \n2001:db8::1b2 \n2001:db8::1b3 \n2001:db8::1b4 \n2001:db8::1b5 \n2001:db8::1b6 \n2001:db8::1b7 \n2001:db8::1b8 \n2001:db8::1b9 \n2001:db8::1ba \n2001:db8::1bb \n2001:db8::1bc \n2001:db8::1bd \n2001:db8::1be \n2001:db8::1bf \n2001:db8::1c0 \n2001:db8::1c1 \n2001:db8::1c2 \n2001:db8::1c3 \n2001:db8::1c4 \n2001:db8::1c5 \n2001:db8::1c6 \n2001:db8::1c7 \n2001:db8::1c8 \n2001:db8::1c9 \n2001:db8::1ca \n2001:db8::1cb \n2001:db8::1cc \n2001:db8::1cd \n2001:db8::1ce \n2001:db8::1cf \n2001:db8::1d0 \n2001:db8::1d1 \n2001:db8::1d2 \n2001:db8::1d3 \n2001:db8::1d4 \n2001:db8::1d5 \n2001:db8::1d6 \n2001:db8::1d7 \n2001:db8::1d8 \n2001:db8::1d9 \n2001:db8::1da \n2001:db8::1db \n2001:db8::1dc \n2001:db8::1dd \n2001:db8::1de \n2001:db8::1df \n2001:db8::1e0 \n2001:db8::1e1 \n2001:db8::1e2 \n2001:db8::1e3 \n2001:db8::1e4 \n2001:db8::1e5 \n2001:db8::1e6 \n2001:db8::1e7 \n2001:db8::1e8 \n2001:db8::1e9 \n2001:db8::1ea \n2001:db8::1eb \n2001:db8::1ec \n2001:db8::1ed \n2001:db8::1ee \n2001:db8::1ef \n2001:db8::1f0 \n2001:db8::1f1 \n2001:db8::1f2 \n2001:db8::1f3 \n2001:db8::1f4 \n2001:db8::1f5 \n2001:db8::1f6 \n2001:db8::1f7 \n2001:db8::1f8 \n2001:db8::1f9 \n2001:db8::1fa \n2001:db8::1fb \n2001:db8::1fc \n2001:db8::1fd \n2001:db8::1fe \n2001:db8::1ff \n2001:db8::200 \n2001:db8::201 \n2001:db8::202 \n2001:db8::203 \n2001:db8::204 \n2001:db8::205 \n2001:db8::206 \n2001:db8::207 \n2001:db8::208 \n2001:db8::209 \n2001:db8::20a \n2001:db8::20b \n2001:db8::20c \n2001:db8::20d \n2001:db8::20e \n2001:db8::20f \n2001:db8::210 \n2001:db8::211 \n2001:db8::212 \n2001:db8::213 \n2001:db8::214 \n2001:db8::215 \n2001:db8::216 \n2001:db8::217 \n2001:db8::218 \n2001:db8::219 \n2001:db8::21a \n2001:db8::21b \n2001:db8::21c \n2001:db8::21d \n2001:db8::21e \n2001:db8::21f \n2001:db8::220 \n2001:db8::221 \n2001:db8::222 \n2001:db8::223 \n2001:db8::224 \n2001:db8::225 \n2001:db8::226 \n2001:db8::227 \n2001:db8::228 \n2001:db8::229 \n2001:db8::22a \n2001:db8::22b \n2001:db8::22c \n2001:db8::22d \n2001:db8::22e \n2001:db8::22f \n2001:db8::230 \n2001:db8::231 \n2001:db8::232 \n2001:db8::233 \n2001:db8::234 \n2001:db8::235 \n2001:db8::236 \n2001:db8::237 \n2001:db8::238 \n2001:db8::239 \n2001:db8::23a \n2001:db8::23b \n2001:db8::23c \n2001:db8::23d \n2001:db8::23e \n2001:db8::23f \n2001:db8::240 \n2001:db8::241 \n2001:db8::242 \n2001:db8::243 \n2001:db8::244 \n2001:db8::245 \n2001:db8::246 \n2001:db8::247 \n2001:db8::248 \n2001:db8::249 \n2001:db8::24a \n2001:db8::24b \n2001:db8::24c \n2001:db8::24d \n2001:db8::24e \n2001:db8::24f \n2001:db8::250 \n2001:db8::251 \n2001:db8::252 \n2001:db8::253 \n2001:db8::254 \n2001:db8::255 \n2001:db8::256 \n2001:db8::257 \n2001:db8::258 \n2001:db8::259 \n2001:db8::25a \n2001:db8::25b \n2001:db8::25c \n2001:db8::25d \n2001:db8::25e \n2001:db8::25f \n2001:db8::260 \n2001:db8::261 \n2001:db8::262 \n2001:db8::263 \n2001:db8::264 \n2001:db8::265 \n2001:db8::266 \n2001:db8::267 \n2001:db8::268 \n2001:db8::269 \n2001:db8::26a \n2001:db8::26b \n2001:db8::26c \n2001:db8::26d \n2001:db8::26e \n2001:db8::26f \n2001:db8::270 \n2001:db8::271 \n2001:db8::272 \n2001:db8::273 \n2001:db8::274 \n2001:db8::275 \n2001:db8::276 \n2001:db8::277 \n2001:db8::278 \n2001:db8::279 \n2001:db8::27a \n2001:db8::27b \n2001:db8::27c \n2001:db8::27d \n2001:db8::27e \n2001:db8::27f \n2001:db8::280 \n2001:db8::281 \n2001:db8::282 \n2001:db8::283 \n2001:db8::284 \n2001:db8::285 \n2001:db8::286 \n2001:db8::287 \n2001:db8::288 \n2001:db8::289 \n2001:db8::28a \n2001:db8::28b \n2001:db8::28c \n2001:db8::28d \n2001:db8::28e \n2001:db8::28f \n2001:db8::290 \n2001:db8::291 \n2001:db8::292 \n2001:db8::293 \n2001:db8::294 \n2001:db8::295 \n2001:db8::296 \n2001:db8::297 \n2001:db8::298 \n2001:db8::299 \n2001:db8::29a \n2001:db8::29b \n2001:db8::29c \n2001:db8::29d \n2001:db8::29e \n2001:db8::29f \n2001:db8::2a0 \n2001:db8::2a1 \n2001:db8::2a2 \n2001:db8::2a3 \n2001:db8::2a4 \n2001:db8::2a5 \n2001:db8::2a6 \n2001:db8::2a7 \n2001:db8::2a8 \n2001:db8::2a9 \n2001:db8::2aa \n2001:db8::2ab \n2001:db8::2ac \n2001:db8::2ad \n2001:db8::2ae \n2001:db8::2af \n2001:db8::2b0 \n2001:db8::2b1 \n2001:db8::2b2 \n2001:db8::2b3 \n2001:db8::2b4 \n2001:db8::2b5 \n2001:db8::2b6 \n2001:db8::2b7 \n2001:db8::2b8 \n2001:db8::2b9 \n2001:db8::2ba \n2001:db8::2bb \n2001:db8::2bc \n2001:db8::2bd \n2001:db8::2be \n2001:db8::2bf \n2001:db8::2c0 \n2001:db8::2c1 \n2001:db8::2c2 \n2001:db8::2c3 \n2001:db8::2c4 \n2001:db8::2c5 \n2001:db8::2c6 \n2001:db8::2c7 \n2001:db8::2c8 \n2001:db8::2c9 \n2001:db8::2ca \n2001:db8::2cb \n2001:db8::2cc \n2001:db8::2cd \n2001:db8::2ce \n2001:db8::2cf \n2001:db8::2d0 \n2001:db8::2d1 \n2001:db8::2d2 \n2001:db8::2d3 \n2001:db8::2d4 \n2001:db8::2d5 \n2001:db8::2d6 \n2001:db8::2d7 \n2001:db8::2d8 \n2001:db8::2d9 \n2001:db8::2da \n2001:db8::2db \n2001:db8::2dc \n2001:db8::2dd \n2001:db8::2de \n2001:db8::2df \n2001:db8::2e0 \n2001:db8::2e1 \n2001:db8::2e2 \n2001:db8::2e3 \n2001:db8::2e4 \n2001:db8::2e5 \n2001:db8::2e6 \n2001:db8::2e7 \n2001:db8::2e8 \n2001:db8::2e9 \n2001:db8::2ea \n2001:db8::2eb \n2001:db8::2ec \n2001:db8::2ed \n2001:db8::2ee \n2001:db8::2ef \n2001:db8::2f0 \n2001:db8::2f1 \n2001:db8::2f2 \n2001:db8::2f3 \n2001:db8::2f4 \n2001:db8::2f5 \n2001:db8::2f6 \n2001:db8::2f7 \n2001:db8::2f8 \n2001:db8::2f9 \n2001:db8::2fa \n2001:db8::2fb \n2001:db8::2fc \n2001:db8::2fd \n2001:db8::2fe \n2001:db8::2ff \n2001:db8::300 \n2001:db8::301 \n2001:db8::302 \n2001:db8::303 \n2001:db8::304 \n2001:db8::305 \n2001:db8::306 \n2001:db8::307 \n2001:db8::308 \n2001:db8::309 \n2001:db8::30a \n2001:db8::30b \n2001:db8::30c \n2001:db8::30d \n2001:db8::30e \n2001:db8::30f \n2001:db8::310 \n2001:db8::311 \n2001:db8::312 \n2001:db8::313 \n2001:db8::314 \n2001:db8::315 \n2001:db8::316 \n2001:db8::317 \n2001:db8::318 \n2001:db8::319 \n2001:db8::31a \n2001:db8::31b \n2001:db8::31c \n2001:db8::31d \n2001:db8::31e \n2001:db8::31f \n2001:db8::320 \n2001:db8::321 \n2001:db8::322 \n2001:db8::323 \n2001:db8::324 \n2001:db8::325 \n2001:db8::326 \n2001:db8::327 \n2001:db8::328 \n2001:db8::329 \n2001:db8::32a \n2001:db8::32b \n2001:db8::32c \n2001:db8::32d \n2001:db8::32e \n2001:db8::32f \n2001:db8::330 \n2001:db8::331 \n2001:db8::332 \n2001:db8::333 \n2001:db8::334 \n2001:db8::335 \n2001:db8::336 \n2001:db8::337 \n2001:db8::338 \n2001:db8::339 \n2001:db8::33a \n2001:db8::33b \n2001:db8::33c \n2001:db8::33d \n2001:db8::33e \n2001:db8::33f \n2001:db8::340 \n2001:db8::341 \n2001:db8::342 \n2001:db8::343 \n2001:db8::344 \n2001:db8::345 \n2001:db8::346 \n2001:db8::347 \n2001:db8::348 \n2001:db8::349 \n2001:db8::34a \n2001:db8::34b \n2001:db8::34c \n2001:db8::34d \n2001:db8::34e \n2001:db8::34f \n2001:db8::350 \n2001:db8::351 \n2001:db8::352 \n2001:db8::353 \n2001:db8::354 \n2001:db8::355 \n2001:db8::356 \n2001:db8::357 \n2001:db8::358 \n2001:db8::359 \n2001:db8::35a \n2001:db8::35b \n2001:db8::35c \n2001:db8::35d \n2001:db8::35e \n2001:db8::35f \n2001:db8::360 \n2001:db8::361 \n2001:db8::362 \n2001:db8::363 \n2001:db8::364 \n2001:db8::365 \n2001:db8::366 \n2001:db8::367 \n2001:db8::368 \n2001:db8::369 \n2001:db8::36a \n2001:db8::36b \n2001:db8::36c \n2001:db8::36d \n2001:db8::36e \n2001:db8::36f \n2001:db8::370 \n2001:db8::371 \n2001:db8::372 \n2001:db8::373 \n2001:db8::374 \n2001:db8::375 \n2001:db8::376 \n2001:db8::377 \n2001:db8::378 \n2001:db8::379 \n2001:db8::37a \n2001:db8::37b \n2001:db8::37c \n2001:db8::37d \n2001:db8::37e \n2001:db8::37f \n2001:db8::380 \n2001:db8::381 \n2001:db8::382 \n2001:db8::383 \n2001:db8::384 \n2001:db8::385 \n2001:db8::386 \n2001:db8::387 \n2001:db8::388 \n2001:db8::389 \n2001:db8::38a \n2001:db8::38b \n2001:db8::38c \n2001:db8::38d \n2001:db8::38e \n2001:db8::38f \n2001:db8::390 \n2001:db8::391 \n2001:db8::392 \n2001:db8::393 \n2001:db8::394 \n2001:db8::395 \n2001:db8::396 \n2001:db8::397 \n2001:db8::398 \n2001:db8::399 \n2001:db8::39a \n2001:db8::39b \n2001:db8::39c \n2001:db8::39d \n2001:db8::39e \n2001:db8::39f \n2001:db8::3a0 \n2001:db8::3a1 \n2001:db8::3a2 \n2001:db8::3a3 \n2001:db8::3a4 \n2001:db8::3a5 \n2001:db8::3a6 \n2001:db8::3a7 \n2001:db8::3a8 \n2001:db8::3a9 \n2001:db8::3aa \n2001:db8::3ab \n2001:db8::3ac \n2001:db8::3ad \n2001:db8::3ae \n2001:db8::3af \n2001:db8::3b0 \n2001:db8::3b1 \n2001:db8::3b2 \n2001:db8::3b3 \n2001:db8::3b4 \n2001:db8::3b5 \n2001:db8::3b6 \n2001:db8::3b7 \n2001:db8::3b8 \n2001:db8::3b9 \n2001:db8::3ba \n2001:db8::3bb \n2001:db8::3bc \n2001:db8::3bd \n2001:db8::3be \n2001:db8::3bf \n2001:db8::3c0 \n2001:db8::3c1 \n2001:db8::3c2 \n2001:db8::3c3 \n2001:db8::3c4 \n2001:db8::3c5 \n2001:db8::3c6 \n2001:db8::3c7 \n2001:db8::3c8 \n2001:db8::3c9 \n2001:db8::3ca \n2001:db8::3cb \n2001:db8::3cc \n2001:db8::3cd \n2001:db8::3ce \n2001:db8::3cf \n2001:db8::3d0 \n2001:db8::3d1 \n2001:db8::3d2 \n2001:db8::3d3 \n2001:db8::3d4 \n2001:db8::3d5 \n2001:db8::3d6 \n2001:db8::3d7 \n2001:db8::3d8 \n2001:db8::3d9 \n2001:db8::3da \n2001:db8::3db \n2001:db8::3dc \n2001:db8::3dd \n2001:db8::3de \n2001:db8::3df \n2001:db8::3e0 \n2001:db8::3e1 \n2001:db8::3e2 \n2001:db8::3e3 \n2001:db8::3e4 \n2001:db8::3e5 \n2001:db8::3e6 \n2001:db8::3e7 \n2001:db8::3e8 \n2001:db8::3e9 \n2001:db8::3ea \n2001:db8::3eb \n2001:db8::3ec \n2001:db8::3ed \n2001:db8::3ee \n2001:db8::3ef \n2001:db8::3f0 \n2001:db8::3f1 \n2001:db8::3f2 \n2001:db8::3f3 \n2001:db8::3f4 \n2001:db8::3f5 \n2001:db8::3f6 \n2001:db8::3f7 \n2001:db8::3f8 \n2001:db8::3f9 \n2001:db8::3fa \n2001:db8::3fb \n2001:db8::3fc \n2001:db8::3fd \n2001:db8::3fe \n2001:db8::3ff \n2001:db8::400 \n2001:db8::401 \n2001:db8::402 \n2001:db8::403 \n2001:db8::404 \n2001:db8::405 \n2001:db8::406 \n2001:db8::407 \n2001:db8::408 \n2001:db8::409 \n2001:db8::40a \n2001:db8::40b \n2001:db8::40c \n2001:db8::40d \n2001:db8::40e \n2001:db8::40f \n2001:db8::410 \n2001:db8::411 \n2001:db8::412 \n2001:db8::413 \n2001:db8::414 \n2001:db8::415 \n2001:db8::416 \n2001:db8::417 \n2001:db8::418 \n2001:db8::419 \n2001:db8::41a \n2001:db8::41b \n2001:db8::41c \n2001:db8::41d \n2001:db8::41e \n2001:db8::41f \n2001:db8::420 \n2001:db8::421 \n2001:db8::422 \n2001:db8::423 \n2001:db8::424 \n2001:db8::425 \n2001:db8::426 \n2001:db8::427 \n2001:db8::428 \n2001:db8::429 \n2001:db8::42a \n2001:db8::42b \n2001:db8::42c \n2001:db8::42d \n2001:db8::42e \n2001:db8::42f \n2001:db8::430 \n2001:db8::431 \n2001:db8::432 \n2001:db8::433 \n2001:db8::434 \n2001:db8::435 \n2001:db8::436 \n2001:db8::437 \n2001:db8::438 \n2001:db8::439 \n2001:db8::43a \n2001:db8::43b \n2001:db8::43c \n2001:db8::43d \n2001:db8::43e \n2001:db8::43f \n2001:db8::440 \n2001:db8::441 \n2001:db8::442 \n2001:db8::443 \n2001:db8::444 \n2001:db8::445 \n2001:db8::446 \n2001:db8::447 \n2001:db8::448 \n2001:db8::449 \n2001:db8::44a \n2001:db8::44b \n2001:db8::44c \n2001:db8::44d \n2001:db8::44e \n2001:db8::44f \n2001:db8::450 \n2001:db8::451 \n2001:db8::452 \n2001:db8::453 \n2001:db8::454 \n2001:db8::455 \n2001:db8::456 \n2001:db8::457 \n2001:db8::458 \n2001:db8::459 \n2001:db8::45a \n2001:db8::45b \n2001:db8::45c \n2001:db8::45d \n2001:db8::45e \n2001:db8::45f \n2001:db8::460 \n2001:db8::461 \n2001:db8::462 \n2001:db8::463 \n2001:db8::464 \n2001:db8::465 \n2001:db8::466 \n2001:db8::467 \n2001:db8::468 \n2001:db8::469 \n2001:db8::46a \n2001:db8::46b \n2001:db8::46c \n2001:db8::46d \n2001:db8::46e \n2001:db8::46f \n2001:db8::470 \n2001:db8::471 \n2001:db8::472 \n2001:db8::473 \n2001:db8::474 \n2001:db8::475 \n2001:db8::476 \n2001:db8::477 \n2001:db8::478 \n2001:db8::479 \n2001:db8::47a \n2001:db8::47b \n2001:db8::47c \n2001:db8::47d \n2001:db8::47e \n2001:db8::47f \n2001:db8::480 \n2001:db8::481 \n2001:db8::482 \n2001:db8::483 \n2001:db8::484 \n2001:db8::485 \n2001:db8::486 \n2001:db8::487 \n2001:db8::488 \n2001:db8::489 \n2001:db8::48a \n2001:db8::48b \n2001:db8::48c \n2001:db8::48d \n2001:db8::48e \n2001:db8::48f \n2001:db8::490 \n2001:db8::491 \n2001:db8::492 \n2001:db8::493 \n2001:db8::494 \n2001:db8::495 \n2001:db8::496 \n2001:db8::497 \n2001:db8::498 \n2001:db8::499 \n2001:db8::49a \n2001:db8::49b \n2001:db8::49c \n2001:db8::49d \n2001:db8::49e \n2001:db8::49f \n2001:db8::4a0 \n2001:db8::4a1 \n2001:db8::4a2 \n2001:db8::4a3 \n2001:db8::4a4 \n2001:db8::4a5 \n2001:db8::4a6 \n2001:db8::4a7 \n2001:db8::4a8 \n2001:db8::4a9 \n2001:db8::4aa \n2001:db8::4ab \n2001:db8::4ac \n2001:db8::4ad \n2001:db8::4ae \n2001:db8::4af \n2001:db8::4b0 \n2001:db8::4b1 \n2001:db8::4b2 \n2001:db8::4b3 \n2001:db8::4b4 \n2001:db8::4b5 \n2001:db8::4b6 \n2001:db8::4b7 \n2001:db8::4b8 \n2001:db8::4b9 \n2001:db8::4ba \n2001:db8::4bb \n2001:db8::4bc \n2001:db8::4bd \n2001:db8::4be \n2001:db8::4bf \n2001:db8::4c0 \n2001:db8::4c1 \n2001:db8::4c2 \n2001:db8::4c3 \n2001:db8::4c4 \n2001:db8::4c5 \n2001:db8::4c6 \n2001:db8::4c7 \n2001:db8::4c8 \n2001:db8::4c9 \n2001:db8::4ca \n2001:db8::4cb \n2001:db8::4cc \n2001:db8::4cd \n2001:db8::4ce \n2001:db8::4cf \n2001:db8::4d0 \n2001:db8::4d1 \n2001:db8::4d2 \n2001:db8::4d3 \n2001:db8::4d4 \n2001:db8::4d5 \n2001:db8::4d6 \n2001:db8::4d7 \n2001:db8::4d8 \n2001:db8::4d9 \n2001:db8::4da \n2001:db8::4db \n2001:db8::4dc \n2001:db8::4dd \n2001:db8::4de \n2001:db8::4df \n2001:db8::4e0 \n2001:db8::4e1 \n2001:db8::4e2 \n2001:db8::4e3 \n2001:db8::4e4 \n2001:db8::4e5 \n2001:db8::4e6 \n2001:db8::4e7 \n2001:db8::4e8 \n2001:db8::4e9 \n2001:db8::4ea \n2001:db8::4eb \n2001:db8::4ec \n2001:db8::4ed \n2001:db8::4ee \n2001:db8::4ef \n2001:db8::4f0 \n2001:db8::4f1 \n2001:db8::4f2 \n2001:db8::4f3 \n2001:db8::4f4 \n2001:db8::4f5 \n2001:db8::4f6 \n2001:db8::4f7 \n2001:db8::4f8 \n2001:db8::4f9 \n2001:db8::4fa \n2001:db8::4fb \n2001:db8::4fc \n2001:db8::4fd \n2001:db8::4fe \n2001:db8::4ff \n2001:db8::500 \n2001:db8::501 \n2001:db8::502 \n2001:db8::503 \n2001:db8::504 \n2001:db8::505 \n2001:db8::506 \n2001:db8::507 \n2001:db8::508 \n2001:db8::509 \n2001:db8::50a \n2001:db8::50b \n2001:db8::50c \n2001:db8::50d \n2001:db8::50e \n2001:db8::50f \n2001:db8::510 \n2001:db8::511 \n2001:db8::512 \n2001:db8::513 \n2001:db8::514 \n2001:db8::515 \n2001:db8::516 \n2001:db8::517 \n2001:db8::518 \n2001:db8::519 \n2001:db8::51a \n2001:db8::51b \n2001:db8::51c \n2001:db8::51d \n2001:db8::51e \n2001:db8::51f \n2001:db8::520 \n2001:db8::521 \n2001:db8::522 \n2001:db8::523 \n2001:db8::524 \n2001:db8::525 \n2001:db8::526 \n2001:db8::527 \n2001:db8::528 \n2001:db8::529 \n2001:db8::52a \n2001:db8::52b \n2001:db8::52c \n2001:db8::52d \n2001:db8::52e \n2001:db8::52f \n2001:db8::530 \n2001:db8::531 \n2001:db8::532 \n2001:db8::533 \n2001:db8::534 \n2001:db8::535 \n2001:db8::536 \n2001:db8::537 \n2001:db8::538 \n2001:db8::539 \n2001:db8::53a \n2001:db8::53b \n2001:db8::53c \n2001:db8::53d \n2001:db8::53e \n2001:db8::53f \n2001:db8::540 \n2001:db8::541 \n2001:db8::542 \n2001:db8::543 \n2001:db8::544 \n2001:db8::545 \n2001:db8::546 \n2001:db8::547 \n2001:db8::548 \n2001:db8::549 \n2001:db8::54a \n2001:db8::54b \n2001:db8::54c \n2001:db8::54d \n2001:db8::54e \n2001:db8::54f \n2001:db8::550 \n2001:db8::551 \n2001:db8::552 \n2001:db8::553 \n2001:db8::554 \n2001:db8::555 \n2001:db8::556 \n2001:db8::557 \n2001:db8::558 \n2001:db8::559 \n2001:db8::55a \n2001:db8::55b \n2001:db8::55c \n2001:db8::55d \n2001:db8::55e \n2001:db8::55f \n2001:db8::560 \n2001:db8::561 \n2001:db8::562 \n2001:db8::563 \n2001:db8::564 \n2001:db8::565 \n2001:db8::566 \n2001:db8::567 \n2001:db8::568 \n2001:db8::569 \n2001:db8::56a \n2001:db8::56b \n2001:db8::56c \n2001:db8::56d \n2001:db8::56e \n2001:db8::56f \n2001:db8::570 \n2001:db8::571 \n2001:db8::572 \n2001:db8::573 \n2001:db8::574 \n2001:db8::575 \n2001:db8::576 \n2001:db8::577 \n2001:db8::578 \n2001:db8::579 \n2001:db8::57a \n2001:db8::57b \n2001:db8::57c \n2001:db8::57d \n2001:db8::57e \n2001:db8::57f \n2001:db8::580 \n2001:db8::581 \n2001:db8::582 \n2001:db8::583 \n2001:db8::584 \n2001:db8::585 \n2001:db8::586 \n2001:db8::587 \n2001:db8::588 \n2001:db8::589 \n2001:db8::58a \n2001:db8::58b \n2001:db8::58c \n2001:db8::58d \n2001:db8::58e \n2001:db8::58f \n2001:db8::590 \n2001:db8::591 \n2001:db8::592 \n2001:db8::593 \n2001:db8::594 \n2001:db8::595 \n2001:db8::596 \n2001:db8::597 \n2001:db8::598 \n2001:db8::599 \n2001:db8::59a \n2001:db8::59b \n2001:db8::59c \n2001:db8::59d \n2001:db8::59e \n2001:db8::59f \n2001:db8::5a0 \n2001:db8::5a1 \n2001:db8::5a2 \n2001:db8::5a3 \n2001:db8::5a4 \n2001:db8::5a5 \n2001:db8::5a6 \n2001:db8::5a7 \n2001:db8::5a8 \n2001:db8::5a9 \n2001:db8::5aa \n2001:db8::5ab \n2001:db8::5ac \n2001:db8::5ad \n2001:db8::5ae \n2001:db8::5af \n2001:db8::5b0 \n2001:db8::5b1 \n2001:db8::5b2 \n2001:db8::5b3 \n2001:db8::5b4 \n2001:db8::5b5 \n2001:db8::5b6 \n2001:db8::5b7 \n2001:db8::5b8 \n2001:db8::5b9 \n2001:db8::5ba \n2001:db8::5bb \n2001:db8::5bc \n2001:db8::5bd \n2001:db8::5be \n2001:db8::5bf \n2001:db8::5c0 \n2001:db8::5c1 \n2001:db8::5c2 \n2001:db8::5c3 \n2001:db8::5c4 \n2001:db8::5c5 \n2001:db8::5c6 \n2001:db8::5c7 \n2001:db8::5c8 \n2001:db8::5c9 \n2001:db8::5ca \n2001:db8::5cb \n2001:db8::5cc \n2001:db8::5cd \n2001:db8::5ce \n2001:db8::5cf \n2001:db8::5d0 \n2001:db8::5d1 \n2001:db8::5d2 \n2001:db8::5d3 \n2001:db8::5d4 \n2001:db8::5d5 \n2001:db8::5d6 \n2001:db8::5d7 \n2001:db8::5d8 \n2001:db8::5d9 \n2001:db8::5da \n2001:db8::5db \n2001:db8::5dc \n2001:db8::5dd \n2001:db8::5de \n2001:db8::5df \n2001:db8::5e0 \n2001:db8::5e1 \n2001:db8::5e2 \n2001:db8::5e3 \n2001:db8::5e4 \n2001:db8::5e5 \n2001:db8::5e6 \n2001:db8::5e7 \n2001:db8::5e8 \n2001:db8::5e9 \n2001:db8::5ea \n2001:db8::5eb \n2001:db8::5ec \n2001:db8::5ed \n2001:db8::5ee \n2001:db8::5ef \n2001:db8::5f0 \n2001:db8::5f1 \n2001:db8::5f2 \n2001:db8::5f3 \n2001:db8::5f4 \n2001:db8::5f5 \n2001:db8::5f6 \n2001:db8::5f7 \n2001:db8::5f8 \n2001:db8::5f9 \n2001:db8::5fa \n2001:db8::5fb \n2001:db8::5fc \n2001:db8::5fd \n2001:db8::5fe \n2001:db8::5ff \n2001:db8::600 \n2001:db8::601 \n2001:db8::602 \n2001:db8::603 \n2001:db8::604 \n2001:db8::605 \n2001:db8::606 \n2001:db8::607 \n2001:db8::608 \n2001:db8::609 \n2001:db8::60a \n2001:db8::60b \n2001:db8::60c \n2001:db8::60d \n2001:db8::60e \n2001:db8::60f \n2001:db8::610 \n2001:db8::611 \n2001:db8::612 \n2001:db8::613 \n2001:db8::614 \n2001:db8::615 \n2001:db8::616 \n2001:db8::617 \n2001:db8::618 \n2001:db8::619 \n2001:db8::61a \n2001:db8::61b \n2001:db8::61c \n2001:db8::61d \n2001:db8::61e \n2001:db8::61f \n2001:db8::620 \n2001:db8::621 \n2001:db8::622 \n2001:db8::623 \n2001:db8::624 \n2001:db8::625 \n2001:db8::626 \n2001:db8::627 \n2001:db8::628 \n2001:db8::629 \n2001:db8::62a \n2001:db8::62b \n2001:db8::62c \n2001:db8::62d \n2001:db8::62e \n2001:db8::62f \n2001:db8::630 \n2001:db8::631 \n2001:db8::632 \n2001:db8::633 \n2001:db8::634 \n2001:db8::635 \n2001:db8::636 \n2001:db8::637 \n2001:db8::638 \n2001:db8::639 \n2001:db8::63a \n2001:db8::63b \n2001:db8::63c \n2001:db8::63d \n2001:db8::63e \n2001:db8::63f \n2001:db8::640 \n2001:db8::641 \n2001:db8::642 \n2001:db8::643 \n2001:db8::644 \n2001:db8::645 \n2001:db8::646 \n2001:db8::647 \n2001:db8::648 \n2001:db8::649 \n2001:db8::64a \n2001:db8::64b \n2001:db8::64c \n2001:db8::64d \n2001:db8::64e \n2001:db8::64f \n2001:db8::650 \n2001:db8::651 \n2001:db8::652 \n2001:db8::653 \n2001:db8::654 \n2001:db8::655 \n2001:db8::656 \n2001:db8::657 \n2001:db8::658 \n2001:db8::659 \n2001:db8::65a \n2001:db8::65b \n2001:db8::65c \n2001:db8::65d \n2001:db8::65e \n2001:db8::65f \n2001:db8::660 \n2001:db8::661 \n2001:db8::662 \n2001:db8::663 \n2001:db8::664 \n2001:db8::665 \n2001:db8::666 \n2001:db8::667 \n2001:db8::668 \n2001:db8::669 \n2001:db8::66a \n2001:db8::66b \n2001:db8::66c \n2001:db8::66d \n2001:db8::66e \n2001:db8::66f \n2001:db8::670 \n2001:db8::671 \n2001:db8::672 \n2001:db8::673 \n2001:db8::674 \n2001:db8::675 \n2001:db8::676 \n2001:db8::677 \n2001:db8::678 \n2001:db8::679 \n2001:db8::67a \n2001:db8::67b \n2001:db8::67c \n2001:db8::67d \n2001:db8::67e \n2001:db8::67f \n2001:db8::680 \n2001:db8::681 \n2001:db8::682 \n2001:db8::683 \n2001:db8::684 \n2001:db8::685 \n2001:db8::686 \n2001:db8::687 \n2001:db8::688 \n2001:db8::689 \n2001:db8::68a \n2001:db8::68b \n2001:db8::68c \n2001:db8::68d \n2001:db8::68e \n2001:db8::68f \n2001:db8::690 \n2001:db8::691 \n2001:db8::692 \n2001:db8::693 \n2001:db8::694 \n2001:db8::695 \n2001:db8::696 \n2001:db8::697 \n2001:db8::698 \n2001:db8::699 \n2001:db8::69a \n2001:db8::69b \n2001:db8::69c \n2001:db8::69d \n2001:db8::69e \n2001:db8::69f \n2001:db8::6a0 \n2001:db8::6a1 \n2001:db8::6a2 \n2001:db8::6a3 \n2001:db8::6a4 \n2001:db8::6a5 \n2001:db8::6a6 \n2001:db8::6a7 \n2001:db8::6a8 \n2001:db8::6a9 \n2001:db8::6aa \n2001:db8::6ab \n2001:db8::6ac \n2001:db8::6ad \n2001:db8::6ae \n2001:db8::6af \n2001:db8::6b0 \n2001:db8::6b1 \n2001:db8::6b2 \n2001:db8::6b3 \n2001:db8::6b4 \n2001:db8::6b5 \n2001:db8::6b6 \n2001:db8::6b7 \n2001:db8::6b8 \n2001:db8::6b9 \n2001:db8::6ba \n2001:db8::6bb \n2001:db8::6bc \n2001:db8::6bd \n2001:db8::6be \n2001:db8::6bf \n2001:db8::6c0 \n2001:db8::6c1 \n2001:db8::6c2 \n2001:db8::6c3 \n2001:db8::6c4 \n2001:db8::6c5 \n2001:db8::6c6 \n2001:db8::6c7 \n2001:db8::6c8 \n2001:db8::6c9 \n2001:db8::6ca \n2001:db8::6cb \n2001:db8::6cc \n2001:db8::6cd \n2001:db8::6ce \n2001:db8::6cf \n2001:db8::6d0 \n2001:db8::6d1 \n2001:db8::6d2 \n2001:db8::6d3 \n2001:db8::6d4 \n2001:db8::6d5 \n2001:db8::6d6 \n2001:db8::6d7 \n2001:db8::6d8 \n2001:db8::6d9 \n2001:db8::6da \n2001:db8::6db \n2001:db8::6dc \n2001:db8::6dd \n2001:db8::6de \n2001:db8::6df \n2001:db8::6e0 \n2001:db8::6e1 \n2001:db8::6e2 \n2001:db8::6e3 \n2001:db8::6e4 \n2001:db8::6e5 \n2001:db8::6e6 \n2001:db8::6e7 \n2001:db8::6e8 \n2001:db8::6e9 \n2001:db8::6ea \n2001:db8::6eb \n2001:db8::6ec \n2001:db8::6ed \n2001:db8::6ee \n2001:db8::6ef \n2001:db8::6f0 \n2001:db8::6f1 \n2001:db8::6f2 \n2001:db8::6f3 \n2001:db8::6f4 \n2001:db8::6f5 \n2001:db8::6f6 \n2001:db8::6f7 \n2001:db8::6f8 \n2001:db8::6f9 \n2001:db8::6fa \n2001:db8::6fb \n2001:db8::6fc \n2001:db8::6fd \n2001:db8::6fe \n2001:db8::6ff \n2001:db8::700 \n2001:db8::701 \n2001:db8::702 \n2001:db8::703 \n2001:db8::704 \n2001:db8::705 \n2001:db8::706 \n2001:db8::707 \n2001:db8::708 \n2001:db8::709 \n2001:db8::70a \n2001:db8::70b \n2001:db8::70c \n2001:db8::70d \n2001:db8::70e \n2001:db8::70f \n2001:db8::710 \n2001:db8::711 \n2001:db8::712 \n2001:db8::713 \n2001:db8::714 \n2001:db8::715 \n2001:db8::716 \n2001:db8::717 \n2001:db8::718 \n2001:db8::719 \n2001:db8::71a \n2001:db8::71b \n2001:db8::71c \n2001:db8::71d \n2001:db8::71e \n2001:db8::71f \n2001:db8::720 \n2001:db8::721 \n2001:db8::722 \n2001:db8::723 \n2001:db8::724 \n2001:db8::725 \n2001:db8::726 \n2001:db8::727 \n2001:db8::728 \n2001:db8::729 \n2001:db8::72a \n2001:db8::72b \n2001:db8::72c \n2001:db8::72d \n2001:db8::72e \n2001:db8::72f \n2001:db8::730 \n2001:db8::731 \n2001:db8::732 \n2001:db8::733 \n2001:db8::734 \n2001:db8::735 \n2001:db8::736 \n2001:db8::737 \n2001:db8::738 \n2001:db8::739 \n2001:db8::73a \n2001:db8::73b \n2001:db8::73c \n2001:db8::73d \n2001:db8::73e \n2001:db8::73f \n2001:db8::740 \n2001:db8::741 \n2001:db8::742 \n2001:db8::743 \n2001:db8::744 \n2001:db8::745 \n2001:db8::746 \n2001:db8::747 \n2001:db8::748 \n2001:db8::749 \n2001:db8::74a \n2001:db8::74b \n2001:db8::74c \n2001:db8::74d \n2001:db8::74e \n2001:db8::74f \n2001:db8::750 \n2001:db8::751 \n2001:db8::752 \n2001:db8::753 \n2001:db8::754 \n2001:db8::755 \n2001:db8::756 \n2001:db8::757 \n2001:db8::758 \n2001:db8::759 \n2001:db8::75a \n2001:db8::75b \n2001:db8::75c \n2001:db8::75d \n2001:db8::75e \n2001:db8::75f \n2001:db8::760 \n2001:db8::761 \n2001:db8::762 \n2001:db8::763 \n2001:db8::764 \n2001:db8::765 \n2001:db8::766 \n2001:db8::767 \n2001:db8::768 \n2001:db8::769 \n2001:db8::76a \n2001:db8::76b \n2001:db8::76c \n2001:db8::76d \n2001:db8::76e \n2001:db8::76f \n2001:db8::770 \n2001:db8::771 \n2001:db8::772 \n2001:db8::773 \n2001:db8::774 \n2001:db8::775 \n2001:db8::776 \n2001:db8::777 \n2001:db8::778 \n2001:db8::779 \n2001:db8::77a \n2001:db8::77b \n2001:db8::77c \n2001:db8::77d \n2001:db8::77e \n2001:db8::77f \n2001:db8::780 \n2001:db8::781 \n2001:db8::782 \n2001:db8::783 \n2001:db8::784 \n2001:db8::785 \n2001:db8::786 \n2001:db8::787 \n2001:db8::788 \n2001:db8::789 \n2001:db8::78a \n2001:db8::78b \n2001:db8::78c \n2001:db8::78d \n2001:db8::78e \n2001:db8::78f \n2001:db8::790 \n2001:db8::791 \n2001:db8::792 \n2001:db8::793 \n2001:db8::794 \n2001:db8::795 \n2001:db8::796 \n2001:db8::797 \n2001:db8::798 \n2001:db8::799 \n2001:db8::79a \n2001:db8::79b \n2001:db8::79c \n2001:db8::79d \n2001:db8::79e \n2001:db8::79f \n2001:db8::7a0 \n2001:db8::7a1 \n2001:db8::7a2 \n2001:db8::7a3 \n2001:db8::7a4 \n2001:db8::7a5 \n2001:db8::7a6 \n2001:db8::7a7 \n2001:db8::7a8 \n2001:db8::7a9 \n2001:db8::7aa \n2001:db8::7ab \n2001:db8::7ac \n2001:db8::7ad \n2001:db8::7ae \n2001:db8::7af \n2001:db8::7b0 \n2001:db8::7b1 \n2001:db8::7b2 \n2001:db8::7b3 \n2001:db8::7b4 \n2001:db8::7b5 \n2001:db8::7b6 \n2001:db8::7b7 \n2001:db8::7b8 \n2001:db8::7b9 \n2001:db8::7ba \n2001:db8::7bb \n2001:db8::7bc \n2001:db8::7bd \n2001:db8::7be \n2001:db8::7bf \n2001:db8::7c0 \n2001:db8::7c1 \n2001:db8::7c2 \n2001:db8::7c3 \n2001:db8::7c4 \n2001:db8::7c5 \n2001:db8::7c6 \n2001:db8::7c7 \n2001:db8::7c8 \n2001:db8::7c9 \n2001:db8::7ca \n2001:db8::7cb \n2001:db8::7cc \n2001:db8::7cd \n2001:db8::7ce \n2001:db8::7cf \n2001:db8::7d0 \n2001:db8::7d1 \n2001:db8::7d2 \n2001:db8::7d3 \n2001:db8::7d4 \n2001:db8::7d5 \n2001:db8::7d6 \n2001:db8::7d7 \n2001:db8::7d8 \n2001:db8::7d9 \n2001:db8::7da \n2001:db8::7db \n2001:db8::7dc \n2001:db8::7dd \n2001:db8::7de \n2001:db8::7df \n2001:db8::7e0 \n2001:db8::7e1 \n2001:db8::7e2 \n2001:db8::7e3 \n2001:db8::7e4 \n2001:db8::7e5 \n2001:db8::7e6 \n2001:db8::7e7 \n2001:db8::7e8 \n2001:db8::7e9 \n2001:db8::7ea \n2001:db8::7eb \n2001:db8::7ec \n2001:db8::7ed \n2001:db8::7ee \n2001:db8::7ef \n2001:db8::7f0 \n2001:db8::7f1 \n2001:db8::7f2 \n2001:db8::7f3 \n2001:db8::7f4 \n2001:db8::7f5 \n2001:db8::7f6 \n2001:db8::7f7 \n2001:db8::7f8 \n2001:db8::7f9 \n2001:db8::7fa \n2001:db8::7fb \n2001:db8::7fc \n2001:db8::7fd \n2001:db8::7fe \n2001:db8::7ff \n2001:db8::800 \n2001:db8::801 \n2001:db8::802 \n2001:db8::803 \n2001:db8::804 \n2001:db8::805 \n2001:db8::806 \n2001:db8::807 \n2001:db8::808 \n2001:db8::809 \n2001:db8::80a \n2001:db8::80b \n2001:db8::80c \n2001:db8::80d \n2001:db8::80e \n2001:db8::80f \n2001:db8::810 \n2001:db8::811 \n2001:db8::812 \n2001:db8::813 \n2001:db8::814 \n2001:db8::815 \n2001:db8::816 \n2001:db8::817 \n2001:db8::818 \n2001:db8::819 \n2001:db8::81a \n2001:db8::81b \n2001:db8::81c \n2001:db8::81d \n2001:db8::81e \n2001:db8::81f \n2001:db8::820 \n2001:db8::821 \n2001:db8::822 \n2001:db8::823 \n2001:db8::824 \n2001:db8::825 \n2001:db8::826 \n2001:db8::827 \n2001:db8::828 \n2001:db8::829 \n2001:db8::82a \n2001:db8::82b \n2001:db8::82c \n2001:db8::82d \n2001:db8::82e \n2001:db8::82f \n2001:db8::830 \n2001:db8::831 \n2001:db8::832 \n2001:db8::833 \n2001:db8::834 \n2001:db8::835 \n2001:db8::836 \n2001:db8::837 \n2001:db8::838 \n2001:db8::839 \n2001:db8::83a \n2001:db8::83b \n2001:db8::83c \n2001:db8::83d \n2001:db8::83e \n2001:db8::83f \n2001:db8::840 \n2001:db8::841 \n2001:db8::842 \n2001:db8::843 \n2001:db8::844 \n2001:db8::845 \n2001:db8::846 \n2001:db8::847 \n2001:db8::848 \n2001:db8::849 \n2001:db8::84a \n2001:db8::84b \n2001:db8::84c \n2001:db8::84d \n2001:db8::84e \n2001:db8::84f \n2001:db8::850 \n2001:db8::851 \n2001:db8::852 \n2001:db8::853 \n2001:db8::854 \n2001:db8::855 \n2001:db8::856 \n2001:db8::857 \n2001:db8::858 \n2001:db8::859 \n2001:db8::85a \n2001:db8::85b \n2001:db8::85c \n2001:db8::85d \n2001:db8::85e \n2001:db8::85f \n2001:db8::860 \n2001:db8::861 \n2001:db8::862 \n2001:db8::863 \n2001:db8::864 \n2001:db8::865 \n2001:db8::866 \n2001:db8::867 \n2001:db8::868 \n2001:db8::869 \n2001:db8::86a \n2001:db8::86b \n2001:db8::86c \n2001:db8::86d \n2001:db8::86e \n2001:db8::86f \n2001:db8::870 \n2001:db8::871 \n2001:db8::872 \n2001:db8::873 \n2001:db8::874 \n2001:db8::875 \n2001:db8::876 \n2001:db8::877 \n2001:db8::878 \n2001:db8::879 \n2001:db8::87a \n2001:db8::87b \n2001:db8::87c \n2001:db8::87d \n2001:db8::87e \n2001:db8::87f \n2001:db8::880 \n2001:db8::881 \n2001:db8::882 \n2001:db8::883 \n2001:db8::884 \n2001:db8::885 \n2001:db8::886 \n2001:db8::887 \n2001:db8::888 \n2001:db8::889 \n2001:db8::88a \n2001:db8::88b \n2001:db8::88c \n2001:db8::88d \n2001:db8::88e \n2001:db8::88f \n2001:db8::890 \n2001:db8::891 \n2001:db8::892 \n2001:db8::893 \n2001:db8::894 \n2001:db8::895 \n2001:db8::896 \n2001:db8::897 \n2001:db8::898 \n2001:db8::899 \n2001:db8::89a \n2001:db8::89b \n2001:db8::89c \n2001:db8::89d \n2001:db8::89e \n2001:db8::89f \n2001:db8::8a0 \n2001:db8::8a1 \n2001:db8::8a2 \n2001:db8::8a3 \n2001:db8::8a4 \n2001:db8::8a5 \n2001:db8::8a6 \n2001:db8::8a7 \n2001:db8::8a8 \n2001:db8::8a9 \n2001:db8::8aa \n2001:db8::8ab \n2001:db8::8ac \n2001:db8::8ad \n2001:db8::8ae \n2001:db8::8af \n2001:db8::8b0 \n2001:db8::8b1 \n2001:db8::8b2 \n2001:db8::8b3 \n2001:db8::8b4 \n2001:db8::8b5 \n2001:db8::8b6 \n2001:db8::8b7 \n2001:db8::8b8 \n2001:db8::8b9 \n2001:db8::8ba \n2001:db8::8bb \n2001:db8::8bc \n2001:db8::8bd \n2001:db8::8be \n2001:db8::8bf \n2001:db8::8c0 \n2001:db8::8c1 \n2001:db8::8c2 \n2001:db8::8c3 \n2001:db8::8c4 \n2001:db8::8c5 \n2001:db8::8c6 \n2001:db8::8c7 \n2001:db8::8c8 \n2001:db8::8c9 \n2001:db8::8ca \n2001:db8::8cb \n2001:db8::8cc \n2001:db8::8cd \n2001:db8::8ce \n2001:db8::8cf \n2001:db8::8d0 \n2001:db8::8d1 \n2001:db8::8d2 \n2001:db8::8d3 \n2001:db8::8d4 \n2001:db8::8d5 \n2001:db8::8d6 \n2001:db8::8d7 \n2001:db8::8d8 \n2001:db8::8d9 \n2001:db8::8da \n2001:db8::8db \n2001:db8::8dc \n2001:db8::8dd \n2001:db8::8de \n2001:db8::8df \n2001:db8::8e0 \n2001:db8::8e1 \n2001:db8::8e2 \n2001:db8::8e3 \n2001:db8::8e4 \n2001:db8::8e5 \n2001:db8::8e6 \n2001:db8::8e7 \n2001:db8::8e8 \n2001:db8::8e9 \n2001:db8::8ea \n2001:db8::8eb \n2001:db8::8ec \n2001:db8::8ed \n2001:db8::8ee \n2001:db8::8ef \n2001:db8::8f0 \n2001:db8::8f1 \n2001:db8::8f2 \n2001:db8::8f3 \n2001:db8::8f4 \n2001:db8::8f5 \n2001:db8::8f6 \n2001:db8::8f7 \n2001:db8::8f8 \n2001:db8::8f9 \n2001:db8::8fa \n2001:db8::8fb \n2001:db8::8fc \n2001:db8::8fd \n2001:db8::8fe \n2001:db8::8ff \n2001:db8::900 \n2001:db8::901 \n2001:db8::902 \n2001:db8::903 \n2001:db8::904 \n2001:db8::905 \n2001:db8::906 \n2001:db8::907 \n2001:db8::908 \n2001:db8::909 \n2001:db8::90a \n2001:db8::90b \n2001:db8::90c \n2001:db8::90d \n2001:db8::90e \n2001:db8::90f \n2001:db8::910 \n2001:db8::911 \n2001:db8::912 \n2001:db8::913 \n2001:db8::914 \n2001:db8::915 \n2001:db8::916 \n2001:db8::917 \n2001:db8::918 \n2001:db8::919 \n2001:db8::91a \n2001:db8::91b \n2001:db8::91c \n2001:db8::91d \n2001:db8::91e \n2001:db8::91f \n2001:db8::920 \n2001:db8::921 \n2001:db8::922 \n2001:db8::923 \n2001:db8::924 \n2001:db8::925 \n2001:db8::926 \n2001:db8::927 \n2001:db8::928 \n2001:db8::929 \n2001:db8::92a \n2001:db8::92b \n2001:db8::92c \n2001:db8::92d \n2001:db8::92e \n2001:db8::92f \n2001:db8::930 \n2001:db8::931 \n2001:db8::932 \n2001:db8::933 \n2001:db8::934 \n2001:db8::935 \n2001:db8::936 \n2001:db8::937 \n2001:db8::938 \n2001:db8::939 \n2001:db8::93a \n2001:db8::93b \n2001:db8::93c \n2001:db8::93d \n2001:db8::93e \n2001:db8::93f \n2001:db8::940 \n2001:db8::941 \n2001:db8::942 \n2001:db8::943 \n2001:db8::944 \n2001:db8::945 \n2001:db8::946 \n2001:db8::947 \n2001:db8::948 \n2001:db8::949 \n2001:db8::94a \n2001:db8::94b \n2001:db8::94c \n2001:db8::94d \n2001:db8::94e \n2001:db8::94f \n2001:db8::950 \n2001:db8::951 \n2001:db8::952 \n2001:db8::953 \n2001:db8::954 \n2001:db8::955 \n2001:db8::956 \n2001:db8::957 \n2001:db8::958 \n2001:db8::959 \n2001:db8::95a \n2001:db8::95b \n2001:db8::95c \n2001:db8::95d \n2001:db8::95e \n2001:db8::95f \n2001:db8::960 \n2001:db8::961 \n2001:db8::962 \n2001:db8::963 \n2001:db8::964 \n2001:db8::965 \n2001:db8::966 \n2001:db8::967 \n2001:db8::968 \n2001:db8::969 \n2001:db8::96a \n2001:db8::96b \n2001:db8::96c \n2001:db8::96d \n2001:db8::96e \n2001:db8::96f \n2001:db8::970 \n2001:db8::971 \n2001:db8::972 \n2001:db8::973 \n2001:db8::974 \n2001:db8::975 \n2001:db8::976 \n2001:db8::977 \n2001:db8::978 \n2001:db8::979 \n2001:db8::97a \n2001:db8::97b \n2001:db8::97c \n2001:db8::97d \n2001:db8::97e \n2001:db8::97f \n2001:db8::980 \n2001:db8::981 \n2001:db8::982 \n2001:db8::983 \n2001:db8::984 \n2001:db8::985 \n2001:db8::986 \n2001:db8::987 \n2001:db8::988 \n2001:db8::989 \n2001:db8::98a \n2001:db8::98b \n2001:db8::98c \n2001:db8::98d \n2001:db8::98e \n2001:db8::98f \n2001:db8::990 \n2001:db8::991 \n2001:db8::992 \n2001:db8::993 \n2001:db8::994 \n2001:db8::995 \n2001:db8::996 \n2001:db8::997 \n2001:db8::998 \n2001:db8::999 \n2001:db8::99a \n2001:db8::99b \n2001:db8::99c \n2001:db8::99d \n2001:db8::99e \n2001:db8::99f \n2001:db8::9a0 \n2001:db8::9a1 \n2001:db8::9a2 \n2001:db8::9a3 \n2001:db8::9a4 \n2001:db8::9a5 \n2001:db8::9a6 \n2001:db8::9a7 \n2001:db8::9a8 \n2001:db8::9a9 \n2001:db8::9aa \n2001:db8::9ab \n2001:db8::9ac \n2001:db8::9ad \n2001:db8::9ae \n2001:db8::9af \n2001:db8::9b0 \n2001:db8::9b1 \n2001:db8::9b2 \n2001:db8::9b3 \n2001:db8::9b4 \n2001:db8::9b5 \n2001:db8::9b6 \n2001:db8::9b7 \n2001:db8::9b8 \n2001:db8::9b9 \n2001:db8::9ba \n2001:db8::9bb \n2001:db8::9bc \n2001:db8::9bd \n2001:db8::9be \n2001:db8::9bf \n2001:db8::9c0 \n2001:db8::9c1 \n2001:db8::9c2 \n2001:db8::9c3 \n2001:db8::9c4 \n2001:db8::9c5 \n2001:db8::9c6 \n2001:db8::9c7 \n2001:db8::9c8 \n2001:db8::9c9 \n2001:db8::9ca \n2001:db8::9cb \n2001:db8::9cc \n2001:db8::9cd \n2001:db8::9ce \n2001:db8::9cf \n2001:db8::9d0 \n2001:db8::9d1 \n2001:db8::9d2 \n2001:db8::9d3 \n2001:db8::9d4 \n2001:db8::9d5 \n2001:db8::9d6 \n2001:db8::9d7 \n2001:db8::9d8 \n2001:db8::9d9 \n2001:db8::9da \n2001:db8::9db \n2001:db8::9dc \n2001:db8::9dd \n2001:db8::9de \n2001:db8::9df \n2001:db8::9e0 \n2001:db8::9e1 \n2001:db8::9e2 \n2001:db8::9e3 \n2001:db8::9e4 \n2001:db8::9e5 \n2001:db8::9e6 \n2001:db8::9e7 \n2001:db8::9e8 \n2001:db8::9e9 \n2001:db8::9ea \n2001:db8::9eb \n2001:db8::9ec \n2001:db8::9ed \n2001:db8::9ee \n2001:db8::9ef \n2001:db8::9f0 \n2001:db8::9f1 \n2001:db8::9f2 \n2001:db8::9f3 \n2001:db8::9f4 \n2001:db8::9f5 \n2001:db8::9f6 \n2001:db8::9f7 \n2001:db8::9f8 \n2001:db8::9f9 \n2001:db8::9fa \n2001:db8::9fb \n2001:db8::9fc \n2001:db8::9fd \n2001:db8::9fe \n2001:db8::9ff \n2001:db8::a00 \n2001:db8::a01 \n2001:db8::a02 \n2001:db8::a03 \n2001:db8::a04 \n2001:db8::a05 \n2001:db8::a06 \n2001:db8::a07 \n2001:db8::a08 \n2001:db8::a09 \n2001:db8::a0a \n2001:db8::a0b \n2001:db8::a0c \n2001:db8::a0d \n2001:db8::a0e \n2001:db8::a0f \n2001:db8::a10 \n2001:db8::a11 \n2001:db8::a12 \n2001:db8::a13 \n2001:db8::a14 \n2001:db8::a15 \n2001:db8::a16 \n2001:db8::a17 \n2001:db8::a18 \n2001:db8::a19 \n2001:db8::a1a \n2001:db8::a1b \n2001:db8::a1c \n2001:db8::a1d \n2001:db8::a1e \n2001:db8::a1f \n2001:db8::a20 \n2001:db8::a21 \n2001:db8::a22 \n2001:db8::a23 \n2001:db8::a24 \n2001:db8::a25 \n2001:db8::a26 \n2001:db8::a27 \n2001:db8::a28 \n2001:db8::a29 \n2001:db8::a2a \n2001:db8::a2b \n2001:db8::a2c \n2001:db8::a2d \n2001:db8::a2e \n2001:db8::a2f \n2001:db8::a30 \n2001:db8::a31 \n2001:db8::a32 \n2001:db8::a33 \n2001:db8::a34 \n2001:db8::a35 \n2001:db8::a36 \n2001:db8::a37 \n2001:db8::a38 \n2001:db8::a39 \n2001:db8::a3a \n2001:db8::a3b \n2001:db8::a3c \n2001:db8::a3d \n2001:db8::a3e \n2001:db8::a3f \n2001:db8::a40 \n2001:db8::a41 \n2001:db8::a42 \n2001:db8::a43 \n2001:db8::a44 \n2001:db8::a45 \n2001:db8::a46 \n2001:db8::a47 \n2001:db8::a48 \n2001:db8::a49 \n2001:db8::a4a \n2001:db8::a4b \n2001:db8::a4c \n2001:db8::a4d \n2001:db8::a4e \n2001:db8::a4f \n2001:db8::a50 \n2001:db8::a51 \n2001:db8::a52 \n2001:db8::a53 \n2001:db8::a54 \n2001:db8::a55 \n2001:db8::a56 \n2001:db8::a57 \n2001:db8::a58 \n2001:db8::a59 \n2001:db8::a5a \n2001:db8::a5b \n2001:db8::a5c \n2001:db8::a5d \n2001:db8::a5e \n2001:db8::a5f \n2001:db8::a60 \n2001:db8::a61 \n2001:db8::a62 \n2001:db8::a63 \n2001:db8::a64 \n2001:db8::a65 \n2001:db8::a66 \n2001:db8::a67 \n2001:db8::a68 \n2001:db8::a69 \n2001:db8::a6a \n2001:db8::a6b \n2001:db8::a6c \n2001:db8::a6d \n2001:db8::a6e \n2001:db8::a6f \n2001:db8::a70 \n2001:db8::a71 \n2001:db8::a72 \n2001:db8::a73 \n2001:db8::a74 \n2001:db8::a75 \n2001:db8::a76 \n2001:db8::a77 \n2001:db8::a78 \n2001:db8::a79 \n2001:db8::a7a \n2001:db8::a7b \n2001:db8::a7c \n2001:db8::a7d \n2001:db8::a7e \n2001:db8::a7f \n2001:db8::a80 \n2001:db8::a81 \n2001:db8::a82 \n2001:db8::a83 \n2001:db8::a84 \n2001:db8::a85 \n2001:db8::a86 \n2001:db8::a87 \n2001:db8::a88 \n2001:db8::a89 \n2001:db8::a8a \n2001:db8::a8b \n2001:db8::a8c \n2001:db8::a8d \n2001:db8::a8e \n2001:db8::a8f \n2001:db8::a90 \n2001:db8::a91 \n2001:db8::a92 \n2001:db8::a93 \n2001:db8::a94 \n2001:db8::a95 \n2001:db8::a96 \n2001:db8::a97 \n2001:db8::a98 \n2001:db8::a99 \n2001:db8::a9a \n2001:db8::a9b \n2001:db8::a9c \n2001:db8::a9d \n2001:db8::a9e \n2001:db8::a9f \n2001:db8::aa0 \n2001:db8::aa1 \n2001:db8::aa2 \n2001:db8::aa3 \n2001:db8::aa4 \n2001:db8::aa5 \n2001:db8::aa6 \n2001:db8::aa7 \n2001:db8::aa8 \n2001:db8::aa9 \n2001:db8::aaa \n2001:db8::aab \n2001:db8::aac \n2001:db8::aad \n2001:db8::aae \n2001:db8::aaf \n2001:db8::ab0 \n2001:db8::ab1 \n2001:db8::ab2 \n2001:db8::ab3 \n2001:db8::ab4 \n2001:db8::ab5 \n2001:db8::ab6 \n2001:db8::ab7 \n2001:db8::ab8 \n2001:db8::ab9 \n2001:db8::aba \n2001:db8::abb \n2001:db8::abc \n2001:db8::abd \n2001:db8::abe \n2001:db8::abf \n2001:db8::ac0 \n2001:db8::ac1 \n2001:db8::ac2 \n2001:db8::ac3 \n2001:db8::ac4 \n2001:db8::ac5 \n2001:db8::ac6 \n2001:db8::ac7 \n2001:db8::ac8 \n2001:db8::ac9 \n2001:db8::aca \n2001:db8::acb \n2001:db8::acc \n2001:db8::acd \n2001:db8::ace \n2001:db8::acf \n2001:db8::ad0 \n2001:db8::ad1 \n2001:db8::ad2 \n2001:db8::ad3 \n2001:db8::ad4 \n2001:db8::ad5 \n2001:db8::ad6 \n2001:db8::ad7 \n2001:db8::ad8 \n2001:db8::ad9 \n2001:db8::ada \n2001:db8::adb \n2001:db8::adc \n2001:db8::add \n2001:db8::ade \n2001:db8::adf \n2001:db8::ae0 \n2001:db8::ae1 \n2001:db8::ae2 \n2001:db8::ae3 \n2001:db8::ae4 \n2001:db8::ae5 \n2001:db8::ae6 \n2001:db8::ae7 \n2001:db8::ae8 \n2001:db8::ae9 \n2001:db8::aea \n2001:db8::aeb \n2001:db8::aec \n2001:db8::aed \n2001:db8::aee \n2001:db8::aef \n2001:db8::af0 \n2001:db8::af1 \n2001:db8::af2 \n2001:db8::af3 \n2001:db8::af4 \n2001:db8::af5 \n2001:db8::af6 \n2001:db8::af7 \n2001:db8::af8 \n2001:db8::af9 \n2001:db8::afa \n2001:db8::afb \n2001:db8::afc \n2001:db8::afd \n2001:db8::afe \n2001:db8::aff \n2001:db8::b00 \n2001:db8::b01 \n2001:db8::b02 \n2001:db8::b03 \n2001:db8::b04 \n2001:db8::b05 \n2001:db8::b06 \n2001:db8::b07 \n2001:db8::b08 \n2001:db8::b09 \n2001:db8::b0a \n2001:db8::b0b \n2001:db8::b0c \n2001:db8::b0d \n2001:db8::b0e \n2001:db8::b0f \n2001:db8::b10 \n2001:db8::b11 \n2001:db8::b12 \n2001:db8::b13 \n2001:db8::b14 \n2001:db8::b15 \n2001:db8::b16 \n2001:db8::b17 \n2001:db8::b18 \n2001:db8::b19 \n2001:db8::b1a \n2001:db8::b1b \n2001:db8::b1c \n2001:db8::b1d \n2001:db8::b1e \n2001:db8::b1f \n2001:db8::b20 \n2001:db8::b21 \n2001:db8::b22 \n2001:db8::b23 \n2001:db8::b24 \n2001:db8::b25 \n2001:db8::b26 \n2001:db8::b27 \n2001:db8::b28 \n2001:db8::b29 \n2001:db8::b2a \n2001:db8::b2b \n2001:db8::b2c \n2001:db8::b2d \n2001:db8::b2e \n2001:db8::b2f \n2001:db8::b30 \n2001:db8::b31 \n2001:db8::b32 \n2001:db8::b33 \n2001:db8::b34 \n2001:db8::b35 \n2001:db8::b36 \n2001:db8::b37 \n2001:db8::b38 \n2001:db8::b39 \n2001:db8::b3a \n2001:db8::b3b \n2001:db8::b3c \n2001:db8::b3d \n2001:db8::b3e \n2001:db8::b3f \n2001:db8::b40 \n2001:db8::b41 \n2001:db8::b42 \n2001:db8::b43 \n2001:db8::b44 \n2001:db8::b45 \n2001:db8::b46 \n2001:db8::b47 \n2001:db8::b48 \n2001:db8::b49 \n2001:db8::b4a \n2001:db8::b4b \n2001:db8::b4c \n2001:db8::b4d \n2001:db8::b4e \n2001:db8::b4f \n2001:db8::b50 \n2001:db8::b51 \n2001:db8::b52 \n2001:db8::b53 \n2001:db8::b54 \n2001:db8::b55 \n2001:db8::b56 \n2001:db8::b57 \n2001:db8::b58 \n2001:db8::b59 \n2001:db8::b5a \n2001:db8::b5b \n2001:db8::b5c \n2001:db8::b5d \n2001:db8::b5e \n2001:db8::b5f \n2001:db8::b60 \n2001:db8::b61 \n2001:db8::b62 \n2001:db8::b63 \n2001:db8::b64 \n2001:db8::b65 \n2001:db8::b66 \n2001:db8::b67 \n2001:db8::b68 \n2001:db8::b69 \n2001:db8::b6a \n2001:db8::b6b \n2001:db8::b6c \n2001:db8::b6d \n2001:db8::b6e \n2001:db8::b6f \n2001:db8::b70 \n2001:db8::b71 \n2001:db8::b72 \n2001:db8::b73 \n2001:db8::b74 \n2001:db8::b75 \n2001:db8::b76 \n2001:db8::b77 \n2001:db8::b78 \n2001:db8::b79 \n2001:db8::b7a \n2001:db8::b7b \n2001:db8::b7c \n2001:db8::b7d \n2001:db8::b7e \n2001:db8::b7f \n2001:db8::b80 \n2001:db8::b81 \n2001:db8::b82 \n2001:db8::b83 \n2001:db8::b84 \n2001:db8::b85 \n2001:db8::b86 \n2001:db8::b87 \n2001:db8::b88 \n2001:db8::b89 \n2001:db8::b8a \n2001:db8::b8b \n2001:db8::b8c \n2001:db8::b8d \n2001:db8::b8e \n2001:db8::b8f \n2001:db8::b90 \n2001:db8::b91 \n2001:db8::b92 \n2001:db8::b93 \n2001:db8::b94 \n2001:db8::b95 \n2001:db8::b96 \n2001:db8::b97 \n2001:db8::b98 \n2001:db8::b99 \n2001:db8::b9a \n2001:db8::b9b \n2001:db8::b9c \n2001:db8::b9d \n2001:db8::b9e \n2001:db8::b9f \n2001:db8::ba0 \n2001:db8::ba1 \n2001:db8::ba2 \n2001:db8::ba3 \n2001:db8::ba4 \n2001:db8::ba5 \n2001:db8::ba6 \n2001:db8::ba7 \n2001:db8::ba8 \n2001:db8::ba9 \n2001:db8::baa \n2001:db8::bab \n2001:db8::bac \n2001:db8::bad \n2001:db8::bae \n2001:db8::baf \n2001:db8::bb0 \n2001:db8::bb1 \n2001:db8::bb2 \n2001:db8::bb3 \n2001:db8::bb4 \n2001:db8::bb5 \n2001:db8::bb6 \n2001:db8::bb7 \n2001:db8::bb8 \n2001:db8::bb9 \n2001:db8::bba \n2001:db8::bbb \n2001:db8::bbc \n2001:db8::bbd \n2001:db8::bbe \n2001:db8::bbf \n2001:db8::bc0 \n2001:db8::bc1 \n2001:db8::bc2 \n2001:db8::bc3 \n2001:db8::bc4 \n2001:db8::bc5 \n2001:db8::bc6 \n2001:db8::bc7 \n2001:db8::bc8 \n2001:db8::bc9 \n2001:db8::bca \n2001:db8::bcb \n2001:db8::bcc \n2001:db8::bcd \n2001:db8::bce \n2001:db8::bcf \n2001:db8::bd0 \n2001:db8::bd1 \n2001:db8::bd2 \n2001:db8::bd3 \n2001:db8::bd4 \n2001:db8::bd5 \n2001:db8::bd6 \n2001:db8::bd7 \n2001:db8::bd8 \n2001:db8::bd9 \n2001:db8::bda \n2001:db8::bdb \n2001:db8::bdc \n2001:db8::bdd \n2001:db8::bde \n2001:db8::bdf \n2001:db8::be0 \n2001:db8::be1 \n2001:db8::be2 \n2001:db8::be3 \n2001:db8::be4 \n2001:db8::be5 \n2001:db8::be6 \n2001:db8::be7 \n2001:db8::be8 \n2001:db8::be9 \n2001:db8::bea \n2001:db8::beb \n2001:db8::bec \n2001:db8::bed \n2001:db8::bee \n2001:db8::bef \n2001:db8::bf0 \n2001:db8::bf1 \n2001:db8::bf2 \n2001:db8::bf3 \n2001:db8::bf4 \n2001:db8::bf5 \n2001:db8::bf6 \n2001:db8::bf7 \n2001:db8::bf8 \n2001:db8::bf9 \n2001:db8::bfa \n2001:db8::bfb \n2001:db8::bfc \n2001:db8::bfd \n2001:db8::bfe \n2001:db8::bff \n2001:db8::c00 \n2001:db8::c01 \n2001:db8::c02 \n2001:db8::c03 \n2001:db8::c04 \n2001:db8::c05 \n2001:db8::c06 \n2001:db8::c07 \n2001:db8::c08 \n2001:db8::c09 \n2001:db8::c0a \n2001:db8::c0b \n2001:db8::c0c \n2001:db8::c0d \n2001:db8::c0e \n2001:db8::c0f \n2001:db8::c10 \n2001:db8::c11 \n2001:db8::c12 \n2001:db8::c13 \n2001:db8::c14 \n2001:db8::c15 \n2001:db8::c16 \n2001:db8::c17 \n2001:db8::c18 \n2001:db8::c19 \n2001:db8::c1a \n2001:db8::c1b \n2001:db8::c1c \n2001:db8::c1d \n2001:db8::c1e \n2001:db8::c1f \n2001:db8::c20 \n2001:db8::c21 \n2001:db8::c22 \n2001:db8::c23 \n2001:db8::c24 \n2001:db8::c25 \n2001:db8::c26 \n2001:db8::c27 \n2001:db8::c28 \n2001:db8::c29 \n2001:db8::c2a \n2001:db8::c2b \n2001:db8::c2c \n2001:db8::c2d \n2001:db8::c2e \n2001:db8::c2f \n2001:db8::c30 \n2001:db8::c31 \n2001:db8::c32 \n2001:db8::c33 \n2001:db8::c34 \n2001:db8::c35 \n2001:db8::c36 \n2001:db8::c37 \n2001:db8::c38 \n2001:db8::c39 \n2001:db8::c3a \n2001:db8::c3b \n2001:db8::c3c \n2001:db8::c3d \n2001:db8::c3e \n2001:db8::c3f \n2001:db8::c40 \n2001:db8::c41 \n2001:db8::c42 \n2001:db8::c43 \n2001:db8::c44 \n2001:db8::c45 \n2001:db8::c46 \n2001:db8::c47 \n2001:db8::c48 \n2001:db8::c49 \n2001:db8::c4a \n2001:db8::c4b \n2001:db8::c4c \n2001:db8::c4d \n2001:db8::c4e \n2001:db8::c4f \n2001:db8::c50 \n2001:db8::c51 \n2001:db8::c52 \n2001:db8::c53 \n2001:db8::c54 \n2001:db8::c55 \n2001:db8::c56 \n2001:db8::c57 \n2001:db8::c58 \n2001:db8::c59 \n2001:db8::c5a \n2001:db8::c5b \n2001:db8::c5c \n2001:db8::c5d \n2001:db8::c5e \n2001:db8::c5f \n2001:db8::c60 \n2001:db8::c61 \n2001:db8::c62 \n2001:db8::c63 \n2001:db8::c64 \n2001:db8::c65 \n2001:db8::c66 \n2001:db8::c67 \n2001:db8::c68 \n2001:db8::c69 \n2001:db8::c6a \n2001:db8::c6b \n2001:db8::c6c \n2001:db8::c6d \n2001:db8::c6e \n2001:db8::c6f \n2001:db8::c70 \n2001:db8::c71 \n2001:db8::c72 \n2001:db8::c73 \n2001:db8::c74 \n2001:db8::c75 \n2001:db8::c76 \n2001:db8::c77 \n2001:db8::c78 \n2001:db8::c79 \n2001:db8::c7a \n2001:db8::c7b \n2001:db8::c7c \n2001:db8::c7d \n2001:db8::c7e \n2001:db8::c7f \n2001:db8::c80 \n2001:db8::c81 \n2001:db8::c82 \n2001:db8::c83 \n2001:db8::c84 \n2001:db8::c85 \n2001:db8::c86 \n2001:db8::c87 \n2001:db8::c88 \n2001:db8::c89 \n2001:db8::c8a \n2001:db8::c8b \n2001:db8::c8c \n2001:db8::c8d \n2001:db8::c8e \n2001:db8::c8f \n2001:db8::c90 \n2001:db8::c91 \n2001:db8::c92 \n2001:db8::c93 \n2001:db8::c94 \n2001:db8::c95 \n2001:db8::c96 \n2001:db8::c97 \n2001:db8::c98 \n2001:db8::c99 \n2001:db8::c9a \n2001:db8::c9b \n2001:db8::c9c \n2001:db8::c9d \n2001:db8::c9e \n2001:db8::c9f \n2001:db8::ca0 \n2001:db8::ca1 \n2001:db8::ca2 \n2001:db8::ca3 \n2001:db8::ca4 \n2001:db8::ca5 \n2001:db8::ca6 \n2001:db8::ca7 \n2001:db8::ca8 \n2001:db8::ca9 \n2001:db8::caa \n2001:db8::cab \n2001:db8::cac \n2001:db8::cad \n2001:db8::cae \n2001:db8::caf \n2001:db8::cb0 \n2001:db8::cb1 \n2001:db8::cb2 \n2001:db8::cb3 \n2001:db8::cb4 \n2001:db8::cb5 \n2001:db8::cb6 \n2001:db8::cb7 \n2001:db8::cb8 \n2001:db8::cb9 \n2001:db8::cba \n2001:db8::cbb \n2001:db8::cbc \n2001:db8::cbd \n2001:db8::cbe \n2001:db8::cbf \n2001:db8::cc0 \n2001:db8::cc1 \n2001:db8::cc2 \n2001:db8::cc3 \n2001:db8::cc4 \n2001:db8::cc5 \n2001:db8::cc6 \n2001:db8::cc7 \n2001:db8::cc8 \n2001:db8::cc9 \n2001:db8::cca \n2001:db8::ccb \n2001:db8::ccc \n2001:db8::ccd \n2001:db8::cce \n2001:db8::ccf \n2001:db8::cd0 \n2001:db8::cd1 \n2001:db8::cd2 \n2001:db8::cd3 \n2001:db8::cd4 \n2001:db8::cd5 \n2001:db8::cd6 \n2001:db8::cd7 \n2001:db8::cd8 \n2001:db8::cd9 \n2001:db8::cda \n2001:db8::cdb \n2001:db8::cdc \n2001:db8::cdd \n2001:db8::cde \n2001:db8::cdf \n2001:db8::ce0 \n2001:db8::ce1 \n2001:db8::ce2 \n2001:db8::ce3 \n2001:db8::ce4 \n2001:db8::ce5 \n2001:db8::ce6 \n2001:db8::ce7 \n2001:db8::ce8 \n2001:db8::ce9 \n2001:db8::cea \n2001:db8::ceb \n2001:db8::cec \n2001:db8::ced \n2001:db8::cee \n2001:db8::cef \n2001:db8::cf0 \n2001:db8::cf1 \n2001:db8::cf2 \n2001:db8::cf3 \n2001:db8::cf4 \n2001:db8::cf5 \n2001:db8::cf6 \n2001:db8::cf7 \n2001:db8::cf8 \n2001:db8::cf9 \n2001:db8::cfa \n2001:db8::cfb \n2001:db8::cfc \n2001:db8::cfd \n2001:db8::cfe \n2001:db8::cff \n2001:db8::d00 \n2001:db8::d01 \n2001:db8::d02 \n2001:db8::d03 \n2001:db8::d04 \n2001:db8::d05 \n2001:db8::d06 \n2001:db8::d07 \n2001:db8::d08 \n2001:db8::d09 \n2001:db8::d0a \n2001:db8::d0b \n2001:db8::d0c \n2001:db8::d0d \n2001:db8::d0e \n2001:db8::d0f \n2001:db8::d10 \n2001:db8::d11 \n2001:db8::d12 \n2001:db8::d13 \n2001:db8::d14 \n2001:db8::d15 \n2001:db8::d16 \n2001:db8::d17 \n2001:db8::d18 \n2001:db8::d19 \n2001:db8::d1a \n2001:db8::d1b \n2001:db8::d1c \n2001:db8::d1d \n2001:db8::d1e \n2001:db8::d1f \n2001:db8::d20 \n2001:db8::d21 \n2001:db8::d22 \n2001:db8::d23 \n2001:db8::d24 \n2001:db8::d25 \n2001:db8::d26 \n2001:db8::d27 \n2001:db8::d28 \n2001:db8::d29 \n2001:db8::d2a \n2001:db8::d2b \n2001:db8::d2c \n2001:db8::d2d \n2001:db8::d2e \n2001:db8::d2f \n2001:db8::d30 \n2001:db8::d31 \n2001:db8::d32 \n2001:db8::d33 \n2001:db8::d34 \n2001:db8::d35 \n2001:db8::d36 \n2001:db8::d37 \n2001:db8::d38 \n2001:db8::d39 \n2001:db8::d3a \n2001:db8::d3b \n2001:db8::d3c \n2001:db8::d3d \n2001:db8::d3e \n2001:db8::d3f \n2001:db8::d40 \n2001:db8::d41 \n2001:db8::d42 \n2001:db8::d43 \n2001:db8::d44 \n2001:db8::d45 \n2001:db8::d46 \n2001:db8::d47 \n2001:db8::d48 \n2001:db8::d49 \n2001:db8::d4a \n2001:db8::d4b \n2001:db8::d4c \n2001:db8::d4d \n2001:db8::d4e \n2001:db8::d4f \n2001:db8::d50 \n2001:db8::d51 \n2001:db8::d52 \n2001:db8::d53 \n2001:db8::d54 \n2001:db8::d55 \n2001:db8::d56 \n2001:db8::d57 \n2001:db8::d58 \n2001:db8::d59 \n2001:db8::d5a \n2001:db8::d5b \n2001:db8::d5c \n2001:db8::d5d \n2001:db8::d5e \n2001:db8::d5f \n2001:db8::d60 \n2001:db8::d61 \n2001:db8::d62 \n2001:db8::d63 \n2001:db8::d64 \n2001:db8::d65 \n2001:db8::d66 \n2001:db8::d67 \n2001:db8::d68 \n2001:db8::d69 \n2001:db8::d6a \n2001:db8::d6b \n2001:db8::d6c \n2001:db8::d6d \n2001:db8::d6e \n2001:db8::d6f \n2001:db8::d70 \n2001:db8::d71 \n2001:db8::d72 \n2001:db8::d73 \n2001:db8::d74 \n2001:db8::d75 \n2001:db8::d76 \n2001:db8::d77 \n2001:db8::d78 \n2001:db8::d79 \n2001:db8::d7a \n2001:db8::d7b \n2001:db8::d7c \n2001:db8::d7d \n2001:db8::d7e \n2001:db8::d7f \n2001:db8::d80 \n2001:db8::d81 \n2001:db8::d82 \n2001:db8::d83 \n2001:db8::d84 \n2001:db8::d85 \n2001:db8::d86 \n2001:db8::d87 \n2001:db8::d88 \n2001:db8::d89 \n2001:db8::d8a \n2001:db8::d8b \n2001:db8::d8c \n2001:db8::d8d \n2001:db8::d8e \n2001:db8::d8f \n2001:db8::d90 \n2001:db8::d91 \n2001:db8::d92 \n2001:db8::d93 \n2001:db8::d94 \n2001:db8::d95 \n2001:db8::d96 \n2001:db8::d97 \n2001:db8::d98 \n2001:db8::d99 \n2001:db8::d9a \n2001:db8::d9b \n2001:db8::d9c \n2001:db8::d9d \n2001:db8::d9e \n2001:db8::d9f \n2001:db8::da0 \n2001:db8::da1 \n2001:db8::da2 \n2001:db8::da3 \n2001:db8::da4 \n2001:db8::da5 \n2001:db8::da6 \n2001:db8::da7 \n2001:db8::da8 \n2001:db8::da9 \n2001:db8::daa \n2001:db8::dab \n2001:db8::dac \n2001:db8::dad \n2001:db8::dae \n2001:db8::daf \n2001:db8::db0 \n2001:db8::db1 \n2001:db8::db2 \n2001:db8::db3 \n2001:db8::db4 \n2001:db8::db5 \n2001:db8::db6 \n2001:db8::db7 \n2001:db8::db8 \n2001:db8::db9 \n2001:db8::dba \n2001:db8::dbb \n2001:db8::dbc \n2001:db8::dbd \n2001:db8::dbe \n2001:db8::dbf \n2001:db8::dc0 \n2001:db8::dc1 \n2001:db8::dc2 \n2001:db8::dc3 \n2001:db8::dc4 \n2001:db8::dc5 \n2001:db8::dc6 \n2001:db8::dc7 \n2001:db8::dc8 \n2001:db8::dc9 \n2001:db8::dca \n2001:db8::dcb \n2001:db8::dcc \n2001:db8::dcd \n2001:db8::dce \n2001:db8::dcf \n2001:db8::dd0 \n2001:db8::dd1 \n2001:db8::dd2 \n2001:db8::dd3 \n2001:db8::dd4 \n2001:db8::dd5 \n2001:db8::dd6 \n2001:db8::dd7 \n2001:db8::dd8 \n2001:db8::dd9 \n2001:db8::dda \n2001:db8::ddb \n2001:db8::ddc \n2001:db8::ddd \n2001:db8::dde \n2001:db8::ddf \n2001:db8::de0 \n2001:db8::de1 \n2001:db8::de2 \n2001:db8::de3 \n2001:db8::de4 \n2001:db8::de5 \n2001:db8::de6 \n2001:db8::de7 \n2001:db8::de8 \n2001:db8::de9 \n2001:db8::dea \n2001:db8::deb \n2001:db8::dec \n2001:db8::ded \n2001:db8::dee \n2001:db8::def \n2001:db8::df0 \n2001:db8::df1 \n2001:db8::df2 \n2001:db8::df3 \n2001:db8::df4 \n2001:db8::df5 \n2001:db8::df6 \n2001:db8::df7 \n2001:db8::df8 \n2001:db8::df9 \n2001:db8::dfa \n2001:db8::dfb \n2001:db8::dfc \n2001:db8::dfd \n2001:db8::dfe \n2001:db8::dff \n2001:db8::e00 \n2001:db8::e01 \n2001:db8::e02 \n2001:db8::e03 \n2001:db8::e04 \n2001:db8::e05 \n2001:db8::e06 \n2001:db8::e07 \n2001:db8::e08 \n2001:db8::e09 \n2001:db8::e0a \n2001:db8::e0b \n2001:db8::e0c \n2001:db8::e0d \n2001:db8::e0e \n2001:db8::e0f \n2001:db8::e10 \n2001:db8::e11 \n2001:db8::e12 \n2001:db8::e13 \n2001:db8::e14 \n2001:db8::e15 \n2001:db8::e16 \n2001:db8::e17 \n2001:db8::e18 \n2001:db8::e19 \n2001:db8::e1a \n2001:db8::e1b \n2001:db8::e1c \n2001:db8::e1d \n2001:db8::e1e \n2001:db8::e1f \n2001:db8::e20 \n2001:db8::e21 \n2001:db8::e22 \n2001:db8::e23 \n2001:db8::e24 \n2001:db8::e25 \n2001:db8::e26 \n2001:db8::e27 \n2001:db8::e28 \n2001:db8::e29 \n2001:db8::e2a \n2001:db8::e2b \n2001:db8::e2c \n2001:db8::e2d \n2001:db8::e2e \n2001:db8::e2f \n2001:db8::e30 \n2001:db8::e31 \n2001:db8::e32 \n2001:db8::e33 \n2001:db8::e34 \n2001:db8::e35 \n2001:db8::e36 \n2001:db8::e37 \n2001:db8::e38 \n2001:db8::e39 \n2001:db8::e3a \n2001:db8::e3b \n2001:db8::e3c \n2001:db8::e3d \n2001:db8::e3e \n2001:db8::e3f \n2001:db8::e40 \n2001:db8::e41 \n2001:db8::e42 \n2001:db8::e43 \n2001:db8::e44 \n2001:db8::e45 \n2001:db8::e46 \n2001:db8::e47 \n2001:db8::e48 \n2001:db8::e49 \n2001:db8::e4a \n2001:db8::e4b \n2001:db8::e4c \n2001:db8::e4d \n2001:db8::e4e \n2001:db8::e4f \n2001:db8::e50 \n2001:db8::e51 \n2001:db8::e52 \n2001:db8::e53 \n2001:db8::e54 \n2001:db8::e55 \n2001:db8::e56 \n2001:db8::e57 \n2001:db8::e58 \n2001:db8::e59 \n2001:db8::e5a \n2001:db8::e5b \n2001:db8::e5c \n2001:db8::e5d \n2001:db8::e5e \n2001:db8::e5f \n2001:db8::e60 \n2001:db8::e61 \n2001:db8::e62 \n2001:db8::e63 \n2001:db8::e64 \n2001:db8::e65 \n2001:db8::e66 \n2001:db8::e67 \n2001:db8::e68 \n2001:db8::e69 \n2001:db8::e6a \n2001:db8::e6b \n2001:db8::e6c \n2001:db8::e6d \n2001:db8::e6e \n2001:db8::e6f \n2001:db8::e70 \n2001:db8::e71 \n2001:db8::e72 \n2001:db8::e73 \n2001:db8::e74 \n2001:db8::e75 \n2001:db8::e76 \n2001:db8::e77 \n2001:db8::e78 \n2001:db8::e79 \n2001:db8::e7a \n2001:db8::e7b \n2001:db8::e7c \n2001:db8::e7d \n2001:db8::e7e \n2001:db8::e7f \n2001:db8::e80 \n2001:db8::e81 \n2001:db8::e82 \n2001:db8::e83 \n2001:db8::e84 \n2001:db8::e85 \n2001:db8::e86 \n2001:db8::e87 \n2001:db8::e88 \n2001:db8::e89 \n2001:db8::e8a \n2001:db8::e8b \n2001:db8::e8c \n2001:db8::e8d \n2001:db8::e8e \n2001:db8::e8f \n2001:db8::e90 \n2001:db8::e91 \n2001:db8::e92 \n2001:db8::e93 \n2001:db8::e94 \n2001:db8::e95 \n2001:db8::e96 \n2001:db8::e97 \n2001:db8::e98 \n2001:db8::e99 \n2001:db8::e9a \n2001:db8::e9b \n2001:db8::e9c \n2001:db8::e9d \n2001:db8::e9e \n2001:db8::e9f \n2001:db8::ea0 \n2001:db8::ea1 \n2001:db8::ea2 \n2001:db8::ea3 \n2001:db8::ea4 \n2001:db8::ea5 \n2001:db8::ea6 \n2001:db8::ea7 \n2001:db8::ea8 \n2001:db8::ea9 \n2001:db8::eaa \n2001:db8::eab \n2001:db8::eac \n2001:db8::ead \n2001:db8::eae \n2001:db8::eaf \n2001:db8::eb0 \n2001:db8::eb1 \n2001:db8::eb2 \n2001:db8::eb3 \n2001:db8::eb4 \n2001:db8::eb5 \n2001:db8::eb6 \n2001:db8::eb7 \n2001:db8::eb8 \n2001:db8::eb9 \n2001:db8::eba \n2001:db8::ebb \n2001:db8::ebc \n2001:db8::ebd \n2001:db8::ebe \n2001:db8::ebf \n2001:db8::ec0 \n2001:db8::ec1 \n2001:db8::ec2 \n2001:db8::ec3 \n2001:db8::ec4 \n2001:db8::ec5 \n2001:db8::ec6 \n2001:db8::ec7 \n2001:db8::ec8 \n2001:db8::ec9 \n2001:db8::eca \n2001:db8::ecb \n2001:db8::ecc \n2001:db8::ecd \n2001:db8::ece \n2001:db8::ecf \n2001:db8::ed0 \n2001:db8::ed1 \n2001:db8::ed2 \n2001:db8::ed3 \n2001:db8::ed4 \n2001:db8::ed5 \n2001:db8::ed6 \n2001:db8::ed7 \n2001:db8::ed8 \n2001:db8::ed9 \n2001:db8::eda \n2001:db8::edb \n2001:db8::edc \n2001:db8::edd \n2001:db8::ede \n2001:db8::edf \n2001:db8::ee0 \n2001:db8::ee1 \n2001:db8::ee2 \n2001:db8::ee3 \n2001:db8::ee4 \n2001:db8::ee5 \n2001:db8::ee6 \n2001:db8::ee7 \n2001:db8::ee8 \n2001:db8::ee9 \n2001:db8::eea \n2001:db8::eeb \n2001:db8::eec \n2001:db8::eed \n2001:db8::eee \n2001:db8::eef \n2001:db8::ef0 \n2001:db8::ef1 \n2001:db8::ef2 \n2001:db8::ef3 \n2001:db8::ef4 \n2001:db8::ef5 \n2001:db8::ef6 \n2001:db8::ef7 \n2001:db8::ef8 \n2001:db8::ef9 \n2001:db8::efa \n2001:db8::efb \n2001:db8::efc \n2001:db8::efd \n2001:db8::efe \n2001:db8::eff \n2001:db8::f00 \n2001:db8::f01 \n2001:db8::f02 \n2001:db8::f03 \n2001:db8::f04 \n2001:db8::f05 \n2001:db8::f06 \n2001:db8::f07 \n2001:db8::f08 \n2001:db8::f09 \n2001:db8::f0a \n2001:db8::f0b \n2001:db8::f0c \n2001:db8::f0d \n2001:db8::f0e \n2001:db8::f0f \n2001:db8::f10 \n2001:db8::f11 \n2001:db8::f12 \n2001:db8::f13 \n2001:db8::f14 \n2001:db8::f15 \n2001:db8::f16 \n2001:db8::f17 \n2001:db8::f18 \n2001:db8::f19 \n2001:db8::f1a \n2001:db8::f1b \n2001:db8::f1c \n2001:db8::f1d \n2001:db8::f1e \n2001:db8::f1f \n2001:db8::f20 \n2001:db8::f21 \n2001:db8::f22 \n2001:db8::f23 \n2001:db8::f24 \n2001:db8::f25 \n2001:db8::f26 \n2001:db8::f27 \n2001:db8::f28 \n2001:db8::f29 \n2001:db8::f2a \n2001:db8::f2b \n2001:db8::f2c \n2001:db8::f2d \n2001:db8::f2e \n2001:db8::f2f \n2001:db8::f30 \n2001:db8::f31 \n2001:db8::f32 \n2001:db8::f33 \n2001:db8::f34 \n2001:db8::f35 \n2001:db8::f36 \n2001:db8::f37 \n2001:db8::f38 \n2001:db8::f39 \n2001:db8::f3a \n2001:db8::f3b \n2001:db8::f3c \n2001:db8::f3d \n2001:db8::f3e \n2001:db8::f3f \n2001:db8::f40 \n2001:db8::f41 \n2001:db8::f42 \n2001:db8::f43 \n2001:db8::f44 \n2001:db8::f45 \n2001:db8::f46 \n2001:db8::f47 \n2001:db8::f48 \n2001:db8::f49 \n2001:db8::f4a \n2001:db8::f4b \n2001:db8::f4c \n2001:db8::f4d \n2001:db8::f4e \n2001:db8::f4f \n2001:db8::f50 \n2001:db8::f51 \n2001:db8::f52 \n2001:db8::f53 \n2001:db8::f54 \n2001:db8::f55 \n2001:db8::f56 \n2001:db8::f57 \n2001:db8::f58 \n2001:db8::f59 \n2001:db8::f5a \n2001:db8::f5b \n2001:db8::f5c \n2001:db8::f5d \n2001:db8::f5e \n2001:db8::f5f \n2001:db8::f60 \n2001:db8::f61 \n2001:db8::f62 \n2001:db8::f63 \n2001:db8::f64 \n2001:db8::f65 \n2001:db8::f66 \n2001:db8::f67 \n2001:db8::f68 \n2001:db8::f69 \n2001:db8::f6a \n2001:db8::f6b \n2001:db8::f6c \n2001:db8::f6d \n2001:db8::f6e \n2001:db8::f6f \n2001:db8::f70 \n2001:db8::f71 \n2001:db8::f72 \n2001:db8::f73 \n2001:db8::f74 \n2001:db8::f75 \n2001:db8::f76 \n2001:db8::f77 \n2001:db8::f78 \n2001:db8::f79 \n2001:db8::f7a \n2001:db8::f7b \n2001:db8::f7c \n2001:db8::f7d \n2001:db8::f7e \n2001:db8::f7f \n2001:db8::f80 \n2001:db8::f81 \n2001:db8::f82 \n2001:db8::f83 \n2001:db8::f84 \n2001:db8::f85 \n2001:db8::f86 \n2001:db8::f87 \n2001:db8::f88 \n2001:db8::f89 \n2001:db8::f8a \n2001:db8::f8b \n2001:db8::f8c \n2001:db8::f8d \n2001:db8::f8e \n2001:db8::f8f \n2001:db8::f90 \n2001:db8::f91 \n2001:db8::f92 \n2001:db8::f93 \n2001:db8::f94 \n2001:db8::f95 \n2001:db8::f96 \n2001:db8::f97 \n2001:db8::f98 \n2001:db8::f99 \n2001:db8::f9a \n2001:db8::f9b \n2001:db8::f9c \n2001:db8::f9d \n2001:db8::f9e \n2001:db8::f9f \n2001:db8::fa0 \n2001:db8::fa1 \n2001:db8::fa2 \n2001:db8::fa3 \n2001:db8::fa4 \n2001:db8::fa5 \n2001:db8::fa6 \n2001:db8::fa7 \n2001:db8::fa8 \n2001:db8::fa9 \n2001:db8::faa \n2001:db8::fab \n2001:db8::fac \n2001:db8::fad \n2001:db8::fae \n2001:db8::faf \n2001:db8::fb0 \n2001:db8::fb1 \n2001:db8::fb2 \n2001:db8::fb3 \n2001:db8::fb4 \n2001:db8::fb5 \n2001:db8::fb6 \n2001:db8::fb7 \n2001:db8::fb8 \n2001:db8::fb9 \n2001:db8::fba \n2001:db8::fbb \n2001:db8::fbc \n2001:db8::fbd \n2001:db8::fbe \n2001:db8::fbf \n2001:db8::fc0 \n2001:db8::fc1 \n2001:db8::fc2 \n2001:db8::fc3 \n2001:db8::fc4 \n2001:db8::fc5 \n2001:db8::fc6 \n2001:db8::fc7 \n2001:db8::fc8 \n2001:db8::fc9 \n2001:db8::fca \n2001:db8::fcb \n2001:db8::fcc \n2001:db8::fcd \n2001:db8::fce \n2001:db8::fcf \n2001:db8::fd0 \n2001:db8::fd1 \n2001:db8::fd2 \n2001:db8::fd3 \n2001:db8::fd4 \n2001:db8::fd5 \n2001:db8::fd6 \n2001:db8::fd7 \n2001:db8::fd8 \n2001:db8::fd9 \n2001:db8::fda \n2001:db8::fdb \n2001:db8::fdc \n2001:db8::fdd \n2001:db8::fde \n2001:db8::fdf \n2001:db8::fe0 \n2001:db8::fe1 \n2001:db8::fe2 \n2001:db8::fe3 \n2001:db8::fe4 \n2001:db8::fe5 \n2001:db8::fe6 \n2001:db8::fe7 \n2001:db8::fe8 \n2001:db8::fe9 \n2001:db8::fea \n2001:db8::feb \n2001:db8::fec \n2001:db8::fed \n2001:db8::fee \n2001:db8::fef \n2001:db8::ff0 \n2001:db8::ff1 \n2001:db8::ff2 \n2001:db8::ff3 \n2001:db8::ff4 \n2001:db8::ff5 \n2001:db8::ff6 \n2001:db8::ff7 \n2001:db8::ff8 \n2001:db8::ff9 \n2001:db8::ffa \n2001:db8::ffb \n2001:db8::ffc \n2001:db8::ffd \n2001:db8::ffe \n2001:db8::fff \n2001:db8::1000 \n2001:db8::1001 \n2001:db8::1002 \n2001:db8::1003 " + }, { "command": "network set_reserved 2001:db8::/64 50\n" }, @@ -5537,6 +5561,9 @@ "status": 200, "response": {} }, + { + "output": "10.0.1.4 somehost.example.org" + }, { "command": "network set_description 10.0.1.0/24 \"Frozen but has one host\"\n" }, @@ -5664,6 +5691,9 @@ "10.0.1.255" ] }, + { + "output": "Network: 10.0.1.0/24\nNetmask: 255.255.255.0\nDescription: Frozen but has one host\nCategory: \nLocation: \nVLAN 1234\nDNS delegated: False\nFrozen True\nIP-range: 10.0.1.0 - 10.0.1.255\nReserved host addresses: 3\n 10.0.1.0 (net)\n 10.0.1.1\n 10.0.1.2\n 10.0.1.3\n 10.0.1.255 (broadcast)\nExcluded ranges: 10 ipaddresses\n 10.0.1.20 -> 10.0.1.30\nUsed addresses: 1\nUnused addresses: 239 (excluding reserved adr.)" + }, { "command": "network find -network 10.0.1.0/24 -description '*one host*' -vlan 1234 -frozen 1 -reserved 6 -dns_delegated 0 -category Yellow -location Somewhere\n" }, @@ -6640,6 +6670,9 @@ "2001:db8::3" ] }, + { + "output": "Network: 2001:db8::/64\nNetmask: ffff:ffff:ffff:ffff:0000:0000:0000:0000\nDescription: Frozen but has one host\nCategory: \nLocation: \nVLAN None\nDNS delegated: False\nFrozen True\nIP-range: 2001:db8:: - 2001:db8::ffff:ffff:ffff:ffff\nReserved host addresses: 3\n 2001:db8:: (net)\n 2001:db8::1\n 2001:db8::2\n 2001:db8::3\nExcluded ranges: 16 ipaddresses\n 2001:db8::20 -> 2001:db8::30\nUsed addresses: 1\nUnused addresses: 18446744073709551594 (excluding reserved adr.)" + }, { "command": "host remove somehost\n" }, @@ -7160,6 +7193,9 @@ ] } }, + { + "output": "Name: mygroup\nDescription: This describes the group\nMembers: 1 host\nOwners: myself" + }, { "command": "group create yourgroup \"meh\"\n" }, @@ -7287,6 +7323,9 @@ ] } }, + { + "output": "Name: mygroup\nDescription: This describes the group\nMembers: 1 host, 1 group\nOwners: myself" + }, { "command": "group group_remove mygroup yourgroup\n" }, @@ -7821,6 +7860,9 @@ ] } }, + { + "output": "Delegations:\n wut.example.org\n Comment: This is a comment\n Nameservers: hostname TTL\n ns2.example.org " + }, { "command": "host add testhost.wut.example.org" }, @@ -8150,6 +8192,9 @@ ] } }, + { + "output": "apple \"Here's the description\"\norange 'Round and orange'" + }, { "command": "policy list_atoms ppl\n" }, @@ -8171,6 +8216,9 @@ ] } }, + { + "output": "apple \"Here's the description\"" + }, { "command": "policy role_create fruit \"5 a day\"\n" }, @@ -8233,6 +8281,9 @@ "results": [] } }, + { + "output": "Role Description Labels \nfruit 5 a day " + }, { "command": "policy list_roles fru\n" }, @@ -8268,6 +8319,9 @@ "results": [] } }, + { + "output": "Role Description Labels \nfruit 5 a day " + }, { "command": "policy add_atom fruit apple\n" }, @@ -8401,6 +8455,9 @@ ] } }, + { + "output": "Name: orange\nCreated: 2018-07-07\nDescription: Round and orange\nRoles where this atom is a member:\n fruit" + }, { "command": "policy info fruit\n" }, @@ -8443,6 +8500,9 @@ ] } }, + { + "output": "Name: fruit\nCreated: 2023-12-06\nDescription: 5 a day\nAtom members:\n apple\n orange\nLabels:\n None" + }, { "command": "policy list_members fruit\n" }, @@ -8473,6 +8533,9 @@ ] } }, + { + "output": "Name:\n apple\n orange" + }, { "command": "policy atom_delete apple" }, @@ -8862,6 +8925,9 @@ ] } }, + { + "output": "Name:\n foo.example.org" + }, { "command": "policy host_list foo\n" }, @@ -8919,6 +8985,9 @@ ] } }, + { + "output": "Roles for 'foo.example.org':\n fruit" + }, { "command": "policy host_remove fruit foo\n" }, @@ -9261,6 +9330,9 @@ "results": [] } }, + { + "output": "Range Group Regex Labels \n10.0.0.0/24 somegroup [abc]+.uio.no " + }, { "command": "permission network_remove 10.0.0.0/24 othergroup \"[abc]*.uio.no\"" }, @@ -10232,6 +10304,9 @@ "results": [] } }, + { + "output": "Name: foo.example.org\nContact: hi@ho.com\nComment: meh\nA_Records IP MAC\n 10.0.0.10 11:22:33:aa:bb:cc\nTTL: (Default)\nTXT: v=spf1 -all" + }, { "command": "host find -name *oo*\n" }, @@ -10313,6 +10388,9 @@ ] } }, + { + "output": "Name Contact Comment\nfoo.example.org hi@ho.com meh" + }, { "command": "host find -contact hi*\n" }, @@ -10394,6 +10472,9 @@ ] } }, + { + "output": "Name Contact Comment\nfoo.example.org hi@ho.com meh" + }, { "command": "host find -comment meh\n" }, @@ -10475,6 +10556,9 @@ ] } }, + { + "output": "Name Contact Comment\nfoo.example.org hi@ho.com meh" + }, { "command": "host find -name f* -contact h* -comment m*\n" }, @@ -10556,6 +10640,9 @@ ] } }, + { + "output": "Name Contact Comment\nfoo.example.org hi@ho.com meh" + }, { "command": "host rename foo bar\n" }, @@ -11462,6 +11549,9 @@ "zone": 1 } }, + { + "output": "A_Records IP MAC\n 10.0.0.10 11:22:33:aa:bb:cc" + }, { "command": "host aaaa_add bar 2001:db8::/64" }, @@ -11793,6 +11883,9 @@ "zone": 1 } }, + { + "output": "A_Records IP MAC\n 10.0.0.14 \n 10.0.0.15 11:22:33:44:55:66\nAAAA_Records IP MAC\n 2001:db8::11 \n 2001:db8::12 11:22:33:44:55:67" + }, { "command": "host aaaa_change -old 2001:db8::11 -new 2001:db8::13 bar\n" }, @@ -12184,6 +12277,9 @@ "zone": 1 } }, + { + "output": "A_Records IP MAC\n 10.0.0.10 11:22:33:aa:bb:cc\nAAAA_Records IP MAC\n 2001:db8::14 11:22:33:44:55:67" + }, { "command": "host cname_add bar fubar\n" }, @@ -12350,6 +12446,9 @@ "zone": 1 } }, + { + "output": "Cname: fubar.example.org -> bar.example.org" + }, { "command": "host cname_remove bar fubar\n" }, @@ -12508,6 +12607,9 @@ "zone": 1 } }, + { + "output": "Hinfo: cpu=x86 os=Win" + }, { "command": "host hinfo_remove baz\n" }, @@ -12660,6 +12762,9 @@ "zone": 1 } }, + { + "output": "Loc: 52 22 23.000 N 4 53 32.000 E -2.00m 0.00m 10000m 10m" + }, { "command": "host loc_remove baz\n" }, @@ -12834,6 +12939,9 @@ ] } }, + { + "output": "MX: Priority Server\n 10 mail.example.org" + }, { "command": "host mx_remove baz 10 mail.example.org\n" }, @@ -13017,6 +13125,9 @@ ] } }, + { + "output": "NAPTRs: Preference Order Flag Service Regex Replacement \n 16384 3 u sip [abc]+ wonk " + }, { "command": "host naptr_remove -name baz -preference 16384 -order 3 -flag u -service \"sip\" -regex \"[abc]+\" -replacement \"wonk\"\n" }, @@ -13255,6 +13366,9 @@ ] } }, + { + "output": "PTR override:10.0.0.20 -> baz.example.org" + }, { "command": "host add clover\n" }, @@ -13746,6 +13860,9 @@ ] } }, + { + "output": "SRV: _sip._tcp.example.org 10 5 3456 baz.example.org" + }, { "command": "host srv_remove -name \"_sip._tcp.example.org\" -priority 10 -weight 5 -port 3456 -host baz.example.org\n" }, @@ -13938,6 +14055,9 @@ ] } }, + { + "output": "SSHFPs: Algorithm Type Fingerprint \n 1 1 12345678abcde " + }, { "command": "host sshfp_remove -fingerprint 394875985 bar" }, @@ -14198,6 +14318,9 @@ "zone": 1 } }, + { + "output": "TTL: 3600" + }, { "command": "host ttl_remove bar\n" }, @@ -14370,6 +14493,9 @@ ] } }, + { + "output": "TXT: v=spf1 -all\nTXT: Lorem ipsum dolor sit amet" + }, { "command": "host txt_remove bar \"Whatever\"" }, @@ -14910,6 +15036,9 @@ ] } }, + { + "output": "Name Description \npostit This is a label " + }, { "command": "label info postit\n" }, @@ -14947,6 +15076,9 @@ "results": [] } }, + { + "output": "Name: postit\nDescription: This is a label\nRoles with this label: \n None\nPermissions with this label:\n None" + }, { "command": "label rename postit mylabel -desc 'This is the new description'\n" }, @@ -15107,6 +15239,9 @@ ] } }, + { + "output": "Role Description Labels \nmyrole This is the description postit " + }, { "command": "policy info myrole\n" }, @@ -15154,6 +15289,9 @@ "description": "A label again" } }, + { + "output": "Name: myrole\nCreated: 2023-12-06\nDescription: This is the description\nAtom members:\n None\nLabels:\n postit" + }, { "command": "label info postit\n" }, @@ -15201,6 +15339,9 @@ "results": [] } }, + { + "output": "Name: postit\nDescription: A label again\nRoles with this label: \n myrole\nPermissions with this label:\n None" + }, { "command": "policy label_remove postit myrole\n" }, @@ -15390,6 +15531,9 @@ ] } }, + { + "output": "Range Group Regex Labels \n192.168.0.0/16 mygroup .* postit " + }, { "command": "label info postit\n" }, @@ -15436,6 +15580,9 @@ ] } }, + { + "output": "Name: postit\nDescription: A label again\nRoles with this label: \n None\nPermissions with this label:\n IP range Group Reg.exp. \n 192.168.0.0/16 mygroup .* " + }, { "command": "permission label_remove 192.168.0.0/16 mygroup .* postit\n" }, @@ -15532,6 +15679,9 @@ ] } }, + { + "output": "Range Group Regex Labels \n192.168.0.0/16 mygroup .* " + }, { "command": "permission network_remove 192.168.0.0/16 mygroup .*\n" }, diff --git a/mreg_cli/bacnet.py b/mreg_cli/bacnet.py index 9b6d7638..88160930 100644 --- a/mreg_cli/bacnet.py +++ b/mreg_cli/bacnet.py @@ -2,7 +2,8 @@ from .history import history from .host import host from .log import cli_error, cli_info -from .util import add_formatted_table_for_output, delete, get, get_list, host_info_by_name, post +from .outputmanager import OutputManager +from .util import delete, get, get_list, host_info_by_name, post def bacnetid_add(args) -> None: @@ -74,7 +75,7 @@ def bacnetid_list(args) -> None: if maxval > 4194302: cli_error("The maximum ID value is 4194302.") r = get_list("/api/v1/bacnet/ids/", {"id__range": "{},{}".format(minval, maxval)}) - add_formatted_table_for_output(("ID", "Hostname"), ("id", "hostname"), r) + OutputManager().add_formatted_table(("ID", "Hostname"), ("id", "hostname"), r) host.add_command( diff --git a/mreg_cli/cli.py b/mreg_cli/cli.py index 03814368..daffecbc 100644 --- a/mreg_cli/cli.py +++ b/mreg_cli/cli.py @@ -2,12 +2,15 @@ import html import os import shlex +import sys +from typing import Generator, List from prompt_toolkit import HTML, print_formatted_text from prompt_toolkit.completion import Completer, Completion -from . import recorder, util +from . import util from .exceptions import CliError, CliWarning +from .outputmanager import OutputManager, remove_comments class CliExit(Exception): @@ -143,9 +146,9 @@ def parse(self, command: str) -> None: exc.print_self() except CliExit: - from sys import exit - - exit(0) + # If we have active recordings going on, save them before exiting + OutputManager().save_recording() + sys.exit(0) else: # If no exception occurred make sure errno isn't set to an error @@ -207,6 +210,21 @@ def complete(self, cur, words): start_position=-len(cur), ) + def process_command_line(self, line: str) -> None: + """Process a line containing a command.""" + line = remove_comments(line) + # OutputManager is a singleton class so we + # need to clear it before each command. + output = OutputManager() + output.clear() + # Set the command that generated the output + # Also remove filters and other noise. + cmd = output.from_command(line) + # Run the command + cli.parse(cmd) + # Render the output + output.render() + # Top parser is the root of all the command parsers _top_parser = argparse.ArgumentParser("") @@ -217,6 +235,19 @@ def _quit(args): raise CliExit +def _start_recording(args) -> None: + """Start recording commands and output to the given file.""" + if not args.filename: + raise CliError("No filename given.") + + OutputManager().start_recording(args.filename) + + +def _stop_recording(args): + """Stop recording commands and output to the given file.""" + OutputManager().save_recording() + + # Always need a quit command cli.add_command( prog="quit", @@ -245,16 +276,44 @@ def logout(args): callback=logout, ) +recordings = cli.add_command( + prog="recording", + description="Recording related commands.", + short_desc="Recording related commands", +) -def source(files, ignore_errors, verbose): - """Source reads commands from one or more source files. - Each command must be on one line and the commands must be separated with - newlines. - The files may contain comments. The comment symbol is #. - """ +recordings.add_command( + prog="start", + description="Start recording commands to a file.", + short_desc="Start recording", + callback=_start_recording, + flags=[ + Flag( + "filename", + description="The filename to record to.", + short_desc="Filename", + metavar="filename", + ) + ], +) + +recordings.add_command( + prog="stop", + description="Stop recording commands and output to the given file.", + short_desc="Stop recording", + callback=_stop_recording, +) - rec = recorder.Recorder() +def source(files: List[str], ignore_errors: bool, verbose: bool) -> Generator[str, None, None]: + """Read commands from one or more source files and yield them. + + :param files: List of file paths to read commands from. + :param ignore_errors: If True, continue on errors. + :param verbose: If True, print commands before execution. + + :yields: Command lines from the files. + """ for filename in files: if filename.startswith("~"): filename = os.path.expanduser(filename) @@ -266,15 +325,11 @@ def source(files, ignore_errors, verbose): os.system(line[1:]) continue - # If recording commands, submit the command line. - # Don't record the "source" command itself. - if rec.is_recording() and not line.lstrip().startswith("source"): - rec.record_command(line) - - # In verbose mode all commands are printed before execution. if verbose: print_formatted_text(HTML(f"> {html.escape(line.strip())}")) - cli.parse(line) + + yield line + if cli.last_errno != 0: print_formatted_text( HTML( @@ -284,6 +339,7 @@ def source(files, ignore_errors, verbose): ) ) ) + OutputManager().record_extra_output(f"{filename}: Error on line {i + 1}") if not ignore_errors: return except FileNotFoundError: @@ -293,7 +349,14 @@ def source(files, ignore_errors, verbose): def _source(args): - source(args.files, args.ignore_errors, args.verbose) + """Wrapper for the source function to integrate with the CLI. + + :param args: Arguments from the CLI. + """ + for command in source(args.files, args.ignore_errors, args.verbose): + # Process each command here as needed, similar to the main loop + print(f"Processing command: {command}") + cli.process_command_line(command) # Always need the source command. diff --git a/mreg_cli/label.py b/mreg_cli/label.py index 4669bd17..aac0d468 100644 --- a/mreg_cli/label.py +++ b/mreg_cli/label.py @@ -2,7 +2,7 @@ from .history import history from .log import cli_info, cli_warning from .outputmanager import OutputManager -from .util import add_formatted_table_for_output, delete, get, get_list, patch, post +from .util import delete, get, get_list, patch, post label = cli.add_command( prog="label", @@ -38,7 +38,7 @@ def label_list(args) -> None: if not labels: cli_info("No labels", True) return - add_formatted_table_for_output(("Name", "Description"), ("name", "description"), labels) + OutputManager().add_formatted_table(("Name", "Description"), ("name", "description"), labels) label.add_command(prog="list", description="List labels", callback=label_list, flags=[]) @@ -83,7 +83,7 @@ def label_info(args) -> None: permlist = get_list("/api/v1/permissions/netgroupregex/", params={"labels__name": args.name}) manager.add_line("Permissions with this label:") if permlist: - add_formatted_table_for_output( + OutputManager().add_formatted_table( ("IP range", "Group", "Reg.exp."), ("range", "group", "regex"), permlist, diff --git a/mreg_cli/log.py b/mreg_cli/log.py index 2c73b698..9f150c47 100644 --- a/mreg_cli/log.py +++ b/mreg_cli/log.py @@ -4,8 +4,8 @@ from datetime import datetime from typing import NoReturn, Optional, Type -from . import recorder from .exceptions import CliError, CliWarning +from .outputmanager import OutputManager logfile = None @@ -45,10 +45,10 @@ def cli_error( if raise_exception: # A simplified message for console msg = "ERROR: {}: {}".format(pre, msg) - rec = recorder.Recorder() - if rec.is_recording(): + manager = OutputManager() + if manager.is_recording(): # If recording traffic, also record the console output - rec.record_output(msg) + manager.record_extra_output(msg) # Raise the exception raise exception(msg) return None @@ -69,10 +69,10 @@ def cli_warning( if raise_exception: # A simplified message for console msg = "WARNING: {}: {}".format(pre, msg) - rec = recorder.Recorder() - if rec.is_recording(): + manager = OutputManager() + if manager.is_recording(): # If recording traffic, also record the console output - rec.record_output(msg) + manager.record_extra_output(msg) raise exception(msg) return None @@ -91,7 +91,7 @@ def cli_info(msg: str, print_msg: bool = False) -> None: # A simplified message for console msg = "OK: {}: {}".format(pre, msg) print(msg) - rec = recorder.Recorder() - if rec.is_recording(): + manager = OutputManager() + if manager.is_recording(): # If recording traffic, also record the console output - rec.record_output(msg) + manager.record_extra_output(msg) diff --git a/mreg_cli/main.py b/mreg_cli/main.py index 2436e2de..7044a9b2 100644 --- a/mreg_cli/main.py +++ b/mreg_cli/main.py @@ -6,7 +6,7 @@ from prompt_toolkit import HTML from prompt_toolkit.shortcuts import CompleteStyle, PromptSession -from . import config, log, recorder, util +from . import config, log, util from .cli import cli, source from .exceptions import CliError, CliWarning from .outputmanager import OutputManager @@ -112,9 +112,8 @@ def main(): if "logfile" in conf: log.logfile = conf["logfile"] - rec = recorder.Recorder() if "record_traffic" in conf: - rec.start_recording(conf["record_traffic"]) + OutputManager().start_recording(conf["record_traffic"]) if "user" not in conf: print("Username not set in config or as argument") @@ -144,11 +143,20 @@ def main(): from . import policy # noqa: F401 from . import zone # noqa: F401 + # Define a function that returns the prompt message + def get_prompt_message(): + """Return the prompt message.""" + manager = OutputManager() + if manager.is_recording(): + return HTML(f"[>'{manager.recording_filename()}'] {args.prompt}> ") + else: + return HTML(f"{args.prompt}> ") + # session is a PromptSession object from prompt_toolkit which handles # some configurations of the prompt for us: the text of the prompt; the # completer; and other visual things. session = PromptSession( - message=HTML(f"{args.prompt}> "), + message=get_prompt_message, search_ignore_case=True, completer=cli, complete_while_typing=True, @@ -160,7 +168,8 @@ def main(): # if the --source parameter was given, read commands from the source file and then exit if "source" in conf: - source([conf["source"]], "verbosity" in conf, False) + for command in source([conf["source"]], "verbosity" in conf, False): + cli.process_command_line(command) return # The app runs in an infinite loop and is expected to exit using sys.exit() @@ -173,25 +182,9 @@ def main(): raise SystemExit() from None try: for line in lines.splitlines(): - # If recording commands, submit the command line. - # Don't record the "source" command itself. - if rec.is_recording() and not line.lstrip().startswith("source"): - rec.record_command(line) - # OutputManager is a singleton class so we - # need to clear it before each command. - output = OutputManager() - output.clear() - # Set the command that generated the output - # Also remove filters and other noise. - cmd = output.from_command(line) - # Run the command - cli.parse(cmd) - # Render the output - output.render() - except (CliWarning, CliError) as exc: - exc.print_self() - except ValueError as exc: - print(exc) + cli.process_command_line(line) + except ValueError as e: + print(e) if __name__ == "__main__": diff --git a/mreg_cli/outputmanager.py b/mreg_cli/outputmanager.py index da4be65b..70847a55 100644 --- a/mreg_cli/outputmanager.py +++ b/mreg_cli/outputmanager.py @@ -5,8 +5,89 @@ command. """ +import atexit +import json +import os import re -from typing import Any, List, Tuple +from typing import Any, Dict, List, Optional, Sequence, Tuple, Union, cast +from urllib.parse import urlencode, urlparse + +import requests + +from mreg_cli.exceptions import CliError + + +# These functions are for generic output usage, but can't be in util.py +# because we would get a circular import. +def find_char_outside_quotes( + line: str, target_char: str, return_position: bool = False +) -> Union[str, int]: + """Find a specified character in a line outside of quoted sections. + + :param line: The line of text to process. + :param target_char: The character to find. + :param return_position: If True, return the position of the character; + If False, return the line up to the character. + :return: The position of the character or the line up to the character. + """ + in_quotes = False + current_quote = None + + for i, char in enumerate(line): + if char in ["'", '"']: + if in_quotes and char == current_quote: + in_quotes = False + current_quote = None + elif not in_quotes: + in_quotes = True + current_quote = char + elif char == target_char and not in_quotes: + return i if return_position else line[:i] + + return -1 if return_position else line + + +def remove_comments(line: str) -> str: + """Remove everything after "#" in line of text. + + Note: If the "#" is within a quoted string, it is not deemed to start a comment. + + :param line: The line of text to process. + :return: The line with comments removed. + """ + # Yes, this will always be a string, but linters fail to understand that. + return cast(str, find_char_outside_quotes(line, "#", False)).rstrip(" ") + + +def remove_dict_key_recursive(obj: object, key: str) -> None: + """Remove a key from a dict, recursively. + + This is a destructive operation, and will modify the object in place. + """ + if isinstance(obj, list): + for elem in obj: + remove_dict_key_recursive(elem, key) + return + elif isinstance(obj, dict): + try: + del obj[key] + except KeyError: + pass + for other_value in obj.values(): + remove_dict_key_recursive(other_value, key) + + +def urlpath(url: str, params: str) -> str: + """Return the path and query string of a URL.""" + if params: + url = f"{url}?{urlencode(params)}" + up = urlparse(url) + # Compare to empty string to avoid being tripped up by strings having + # false-like values (0, False, etc) + if up.query != "": + return up.path + "?" + up.query + else: + return up.path from mreg_cli.exceptions import CliError @@ -22,10 +103,30 @@ class OutputManager: _instance = None + COMMANDS_NOT_TO_RECORD = ["recording", "quit", "exit", "source"] + KEYS_NOT_TO_RECORD = [ + "id", + "created_at", + "updated_at", + "serialno", + "serialno_updated_at", + "create_date", + ] + def __new__(cls): if cls._instance is None: cls._instance = super().__new__(cls) + + # Recording related attributes. These must come first as they may + # be encountered when calling clear(). Note that these attributes are + # not reset between commands, which is why they are not themselves + # manipulated in clear(). + cls._recording: bool = False + cls._filename: str = None + cls._recorded_data: List[str] = [] + cls._instance.clear() + return cls._instance def clear(self) -> None: @@ -36,6 +137,130 @@ def clear(self) -> None: self._command = None self.command = None + def start_recording(self, filename: str) -> None: + """Declare intent to start recording to the given filename. + + Note: The file will be overwritten if it exists. + + :param filename: The filename to record to. + """ + # Check that we can write to the file + try: + with open(filename, "w") as _: + pass + except OSError as exc: + raise CliError("Unable open file for writing: {}".format(filename)) from exc + + self._recording = True + self._filename = filename + + atexit.register(self.save_recording) + try: + os.remove(filename) + except OSError: + pass + + def stop_recording(self) -> None: + """Declare intent to stop recording. + + This will delete the recorded data if it has not been saved. + + Note: This does not save the recording, use save_recording() for that. + """ + self._recorded_data = [] + self._recording = False + self._filename = None + + def save_recording(self) -> None: + """Save the recording to the file. + + Returns gracefully if recording is not active. + """ + if not self.is_recording(): + return + + with open(self._filename, "w") as rec_file: + json.dump(self._recorded_data, rec_file, indent=2) + + self.stop_recording() + + def is_recording(self) -> bool: + """Returns True if recording is active.""" + return self._recording + + def recording_filename(self) -> Optional[str]: + """Returns the filename being recorded to. + + Returns gracefully if recording is not active. + """ + if not self.is_recording(): + return None + return self._filename + + def record_command(self, command: str) -> None: + """Record a command, if recording is active. + + :param command: The command to record. + """ + if not self.is_recording() or not command: + return + + # Do not record commands starting with any of the commands in + # COMMANDS_NOT_TO_RECORD + if any(command.startswith(cmd) for cmd in self.COMMANDS_NOT_TO_RECORD): + return + + # Do not record empty commands + if command and command != "\n": + self._recorded_data.append({"command": command}) + + def record_extra_output(self, output: str) -> None: + """Record extra output, if recording is active. + + :param output: The output to record. + """ + if not self.is_recording() or not output: + return + + self._recorded_data.append({"output": output}) + + def record_output(self) -> None: + """Record the output, if recording is active.""" + # Don't record if we're not recording, and don't record + # output as the empty output + if not self.is_recording() or not self._recorded_data: + return + + if not self.lines(): + return + + output = "\n".join(self.lines()) + self._recorded_data.append({"output": output}) + + def record_request( + self, method: str, url: str, params: str, data: Dict[str, Any], result: requests.Response + ) -> None: + if not self.is_recording(): + return + ret_dict: Dict[str, Any] = { + "method": method.upper(), + "url": urlpath(url, params), + "data": data, + "status": result.status_code, + } + try: + obj = result.json() + for key in self.KEYS_NOT_TO_RECORD: + remove_dict_key_recursive(obj, key) + ret_dict["response"] = obj + except requests.JSONDecodeError: + s = result.content.decode("utf-8").strip() + # Compare to empty string to avoid being tripped up by strings having + # false-like values (0, False, etc) + if s != "": + ret_dict["response"] = s + self._recorded_data.append(ret_dict) + def has_output(self) -> bool: """Returns True if there is output to display.""" return len(self._lines) > 0 @@ -43,11 +268,14 @@ def has_output(self) -> bool: def from_command(self, command: str) -> str: """Adds the command that generated the output. + Also records the command if recording is active. + :param command: The command to add. :raises CliError: If the command is invalid. :return: The cleaned command, devoid of filters and other noise. """ self._command, self._filter_re, self._negate = self.get_filter(command) + self.record_command(command) return self._command def add_line(self, line: str) -> None: @@ -81,29 +309,12 @@ def add_formatted_line_with_source( self.add_line(formatted_line) def _find_split_index(self, command: str) -> int: - """Find the index to split the command for filtering. - - It handles both single and double quotes, ensuring that the split - occurs outside of any quoted sections. + """Find the index to split the command for filtering, outside of quoted sections. :param command: The command string to be processed. :return: The index at which to split the command, or -1 if not found. """ - in_quotes = False - current_quote = None - - for i, char in enumerate(command): - if char in ["'", '"']: - if in_quotes and char == current_quote: - in_quotes = False - current_quote = None - elif not in_quotes: - in_quotes = True - current_quote = char - elif char == "|" and not in_quotes: - return i - - return -1 + return find_char_outside_quotes(command, "|", True) # We want to use re.Pattern as the type here, but python 3.6 and older re-modules # don't have that type. So we use Any instead. @@ -146,11 +357,32 @@ def get_filter(self, command: str) -> Tuple[str, Any, bool]: return (command, filter_re, negate) + def add_formatted_table( + self, + headers: Sequence[str], + keys: Sequence[str], + data: List[Dict[str, Any]], + indent: int = 0, + ) -> str: + raw_format = " " * indent + for key, header in zip(keys, headers): + longest = len(header) + for d in data: + longest = max(longest, len(str(d[key]))) + raw_format += "{:<%d} " % longest + + self.add_line(raw_format.format(*headers)) + for d in data: + self.add_line(raw_format.format(*[d[key] for key in keys])) + def lines(self) -> List[str]: """Return the lines of output. - Note that if the command is set, and it has a filter, the lines will + If the command is set, and it has a filter, the lines will be filtered by the command's filter. + + Note: This filtering is not cached, so repeated calls will + re-filter the output (to the same result, presumably). """ lines = self._lines filter_re = self._filter_re @@ -164,7 +396,8 @@ def lines(self) -> List[str]: return [line for line in lines if filter_re.search(line)] def render(self) -> None: - """Prints the output to stdout.""" + """Prints the output to stdout, and records it if recording is active.""" + self.record_output() for line in self.lines(): print(line) diff --git a/mreg_cli/permission.py b/mreg_cli/permission.py index fa5946b5..76208dc8 100644 --- a/mreg_cli/permission.py +++ b/mreg_cli/permission.py @@ -3,16 +3,8 @@ from .cli import Flag, cli from .history import history from .log import cli_info, cli_warning -from .util import ( - add_formatted_table_for_output, - convert_wildcard_to_regex, - delete, - get, - get_list, - is_valid_network, - patch, - post, -) +from .outputmanager import OutputManager +from .util import convert_wildcard_to_regex, delete, get, get_list, is_valid_network, patch, post ################################### # Add the main command 'access' # @@ -77,7 +69,7 @@ def _supernet_of(a, b): headers = ("Range", "Group", "Regex", "Labels") keys = ("range", "group", "regex", "labels") - add_formatted_table_for_output(headers, keys, data) + OutputManager().add_formatted_table(headers, keys, data) permission.add_command( diff --git a/mreg_cli/policy.py b/mreg_cli/policy.py index 9ea31781..a7378809 100644 --- a/mreg_cli/policy.py +++ b/mreg_cli/policy.py @@ -3,16 +3,7 @@ from .history_log import format_history_items, get_history_items from .log import cli_error, cli_info, cli_warning from .outputmanager import OutputManager -from .util import ( - add_formatted_table_for_output, - convert_wildcard_to_regex, - delete, - get, - get_list, - host_info_by_name, - patch, - post, -) +from .util import convert_wildcard_to_regex, delete, get, get_list, host_info_by_name, patch, post ################################## # Add the main command 'policy' # @@ -393,7 +384,7 @@ def list_roles(args) -> None: labels.append(labelnames[j]) i["labels"] = ", ".join(labels) rows.append(i) - add_formatted_table_for_output( + manager.add_formatted_table( ("Role", "Description", "Labels"), ("name", "description", "labels"), rows ) diff --git a/mreg_cli/recorder.py b/mreg_cli/recorder.py deleted file mode 100644 index 5eca8838..00000000 --- a/mreg_cli/recorder.py +++ /dev/null @@ -1,137 +0,0 @@ -import atexit -import json -import os -from typing import Any, Dict -from urllib.parse import urlencode, urlparse - -import requests - - -def remove_dict_key_recursive(obj, key: str) -> None: - if isinstance(obj, list): - for elem in obj: - remove_dict_key_recursive(elem, key) - return - elif isinstance(obj, dict): - try: - del obj[key] - except KeyError: - pass - for other_value in obj.values(): - remove_dict_key_recursive(other_value, key) - - -class Recorder: - # Singleton - __instance = None - - def __new__(cls): - if Recorder.__instance is None: - i = Recorder.__instance = object.__new__(cls) - i.recording = False - i.filename = None - i.recorded_data = [] - return Recorder.__instance - - # the __getattr__( ) method redirects calls to the single instance - def __getattr__(self, name): - if self != Recorder.__instance: - return getattr(Recorder.__instance, name) - else: - raise AttributeError( - "%r object has no attribute %r" % (self.__class__.__name__, name) - ) - - def save_recording(self) -> None: - i = Recorder.__instance - f = open(i.filename, "w") - f.write(json.dumps(i.recorded_data, indent=2)) - f.close() - - """ Start recording http traffic, commands and console output to the given filename. - Warning! If the file exists, it will be deleted/overwritten. """ - - def start_recording(self, filename: str) -> None: - i = Recorder.__instance - i.recording = True - i.filename = filename - atexit.register(Recorder.save_recording, self) - try: - os.remove(filename) - except OSError: - pass - - def is_recording(self) -> bool: - return Recorder.__instance.recording - - def record_command(self, cmd: str) -> None: - if not self.is_recording(): - return - # trim spaces, remove comments - cmd = cmd.lstrip() - if cmd.find("#") > -1: - cmd = cmd[0 : cmd.find("#")].rstrip() - # Don't log empty commands. Compare to empty string to avoid being tripped - # up by strings having false-like values (0, False, etc) - if cmd == "": - return - x = {"command": cmd} - Recorder.__instance.recorded_data.append(x) - - def record_output(self, output: str) -> None: - if not self.is_recording(): - return - x = {"output": output} - Recorder.__instance.recorded_data.append(x) - - """ Returns only the path + query string components of a url """ - - def urlpath(self, url: str, params: str) -> str: - if params: - url = f"{url}?{urlencode(params)}" - up = urlparse(url) - # Compare to empty string to avoid being tripped up by strings having - # false-like values (0, False, etc) - if up.query != "": - return up.path + "?" + up.query - else: - return up.path - - """ Records an http call (method, url and postdata) and the response. """ - - def record( - self, - method: str, - url: str, - params: str, - data: Dict[str, Any], - result: requests.Response, - ) -> None: - if not self.is_recording(): - return - x = { - "method": method.upper(), - "url": self.urlpath(url, params), - "data": data, - "status": result.status_code, - } - try: - obj = result.json() - keys_to_remove = [ - "id", - "created_at", - "updated_at", - "serialno", - "serialno_updated_at", - "create_date", - ] - for key in keys_to_remove: - remove_dict_key_recursive(obj, key) - x["response"] = obj - except requests.JSONDecodeError: - s = result.content.decode("utf-8").strip() - # Compare to empty string to avoid being tripped up by strings having - # false-like values (0, False, etc) - if s != "": - x["response"] = s - Recorder.__instance.recorded_data.append(x) diff --git a/mreg_cli/util.py b/mreg_cli/util.py index ed7b1929..711c524f 100644 --- a/mreg_cli/util.py +++ b/mreg_cli/util.py @@ -12,7 +12,6 @@ List, NoReturn, Optional, - Sequence, Tuple, Union, cast, @@ -31,7 +30,6 @@ import requests from prompt_toolkit import prompt -from . import recorder from .exceptions import CliError, HostNotFoundWarning from .history import history from .log import cli_error, cli_warning @@ -318,7 +316,6 @@ def _request_wrapper( if params is None: params = {} url = requests.compat.urljoin(mregurl, path) - rec = recorder.Recorder() if use_json: result = getattr(session, operation_type)(url, json=params, timeout=HTTP_TIMEOUT) @@ -328,8 +325,9 @@ def _request_wrapper( ) result = cast(requests.Response, result) # convince mypy that result is a Response - if rec.is_recording(): - rec.record(operation_type, url, params, data, result) + manager = OutputManager() + if manager.is_recording(): + manager.record_request(operation_type, url, params, data, result) if first and result.status_code == 401: update_token() @@ -724,29 +722,3 @@ def convert_wildcard_to_regex( regex = "." return (f"{param}__regex", regex) - - -################################################################################ -# # -# Formatting functions # -# # -################################################################################ - - -def add_formatted_table_for_output( - headers: Sequence[str], - keys: Sequence[str], - data: List[Dict[str, Any]], - indent: int = 0, -) -> str: - manager = OutputManager() - raw_format = " " * indent - for key, header in zip(keys, headers): - longest = len(header) - for d in data: - longest = max(longest, len(str(d[key]))) - raw_format += "{:<%d} " % longest - - manager.add_line(raw_format.format(*headers)) - for d in data: - manager.add_line(raw_format.format(*[d[key] for key in keys]))