]> gitweb.stoutner.com Git - PrivacyBrowserAndroid.git/blob - app/src/main/java/com/stoutner/privacybrowser/helpers/ParseFilterListHelper.kt
First wrong button text in View Headers in night theme. https://redmine.stoutner...
[PrivacyBrowserAndroid.git] / app / src / main / java / com / stoutner / privacybrowser / helpers / ParseFilterListHelper.kt
1 /*
2  * Copyright 2018-2019, 2021-2024 Soren Stoutner <soren@stoutner.com>.
3  *
4  * This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android>.
5  *
6  * Privacy Browser Android is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Privacy Browser Android is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Privacy Browser Android.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 package com.stoutner.privacybrowser.helpers
21
22 import android.content.res.AssetManager
23
24 import java.io.BufferedReader
25 import java.io.IOException
26 import java.io.InputStreamReader
27
28 import java.util.ArrayList
29
30 // Define the schema of the string array in each entry of the resource requests array list.
31 const val REQUEST_DISPOSITION = 0
32 const val REQUEST_URL = 1
33 const val REQUEST_BLOCKLIST = 2
34 const val REQUEST_SUBLIST = 3
35 const val REQUEST_BLOCKLIST_ENTRIES = 4
36 const val REQUEST_BLOCKLIST_ORIGINAL_ENTRY = 5
37
38 // Define the allow lists.
39 const val MAIN_ALLOWLIST = "1"
40 const val FINAL_ALLOWLIST = "2"
41 const val DOMAIN_ALLOWLIST = "3"
42 const val DOMAIN_INITIAL_ALLOWLIST = "4"
43 const val DOMAIN_FINAL_ALLOWLIST = "5"
44 const val THIRD_PARTY_ALLOWLIST = "6"
45 const val THIRD_PARTY_DOMAIN_ALLOWLIST = "7"
46 const val THIRD_PARTY_DOMAIN_INITIAL_ALLOWLIST = "8"
47
48 // Define the block lists.
49 const val MAIN_BLOCKLIST = "9"
50 const val INITIAL_BLOCKLIST = "10"
51 const val FINAL_BLOCKLIST = "11"
52 const val DOMAIN_BLOCKLIST = "12"
53 const val DOMAIN_INITIAL_BLOCKLIST = "13"
54 const val DOMAIN_FINAL_BLOCKLIST = "14"
55 const val DOMAIN_REGULAR_EXPRESSION_BLOCKLIST = "15"
56 const val THIRD_PARTY_BLOCKLIST = "16"
57 const val THIRD_PARTY_INITIAL_BLOCKLIST = "17"
58 const val THIRD_PARTY_DOMAIN_BLOCKLIST = "18"
59 const val THIRD_PARTY_DOMAIN_INITIAL_BLOCKLIST = "19"
60 const val THIRD_PARTY_REGULAR_EXPRESSION_BLOCKLIST = "20"
61 const val THIRD_PARTY_DOMAIN_REGULAR_EXPRESSION_BLOCKLIST = "21"
62 const val REGULAR_EXPRESSION_BLOCKLIST = "22"
63
64 class ParseFilterListHelper {
65     fun parseFilterList(assetManager: AssetManager, filterListName: String): ArrayList<List<Array<String>>> {
66         // Initialize the header list.
67         val headers: MutableList<Array<String>> = ArrayList()  // 0.
68
69         // Initialize the allow lists.
70         val mainAllowList: MutableList<Array<String>> = ArrayList()  // 1.
71         val finalAllowList: MutableList<Array<String>> = ArrayList()  // 2.
72         val domainAllowList: MutableList<Array<String>> = ArrayList()  // 3.
73         val domainInitialAllowList: MutableList<Array<String>> = ArrayList()  // 4.
74         val domainFinalAllowList: MutableList<Array<String>> = ArrayList()  // 5.
75         val thirdPartyAllowList: MutableList<Array<String>> = ArrayList()  // 6.
76         val thirdPartyDomainAllowList: MutableList<Array<String>> = ArrayList()  // 7.
77         val thirdPartyDomainInitialAllowList: MutableList<Array<String>> = ArrayList()  // 8.
78
79         // Initialize the block lists.
80         val mainBlockList: MutableList<Array<String>> = ArrayList()  // 9.
81         val initialBlockList: MutableList<Array<String>> = ArrayList()  // 10.
82         val finalBlockList: MutableList<Array<String>> = ArrayList()  // 11.
83         val domainBlockList: MutableList<Array<String>> = ArrayList()  // 12.
84         val domainInitialBlockList: MutableList<Array<String>> = ArrayList()  // 13.
85         val domainFinalBlockList: MutableList<Array<String>> = ArrayList()  // 14.
86         val domainRegularExpressionBlockList: MutableList<Array<String>> = ArrayList()  // 15.
87         val thirdPartyBlockList: MutableList<Array<String>> = ArrayList()  // 16.
88         val thirdPartyInitialBlockList: MutableList<Array<String>> = ArrayList()  // 17.
89         val thirdPartyDomainBlockList: MutableList<Array<String>> = ArrayList()  // 18.
90         val thirdPartyDomainInitialBlockList: MutableList<Array<String>> = ArrayList()  // 19.
91         val regularExpressionBlockList: MutableList<Array<String>> = ArrayList()  // 20.
92         val thirdPartyRegularExpressionBlockList: MutableList<Array<String>> = ArrayList()  // 21.
93         val thirdPartyDomainRegularExpressionBlockList: MutableList<Array<String>> = ArrayList()  // 22.
94
95         // Parse the filter list.  The `try` is required by input stream reader.
96         try {
97             // Load the filter list into a buffered reader.
98             val bufferedReader = BufferedReader(InputStreamReader(assetManager.open(filterListName)))
99
100             // Create strings for storing the filter list entries.
101             var filterListEntry: String
102             var originalFilterListEntry: String
103
104             // Parse the filter list.
105             bufferedReader.forEachLine {
106                 // Store the original filter list entry.
107                 originalFilterListEntry = it
108
109                 // Remove any `^` from the filter list entry.  Privacy Browser does not process them in the interest of efficiency.
110                 filterListEntry = it.replace("^", "")
111
112                 // Parse the entry.
113                 if (filterListEntry.contains("##") || filterListEntry.contains("#?#") || filterListEntry.contains("#@#") || filterListEntry.startsWith("[")) {
114                     // Entries that contain `##`, `#?#`, and `#@#` are for hiding elements in the main page's HTML.  Entries that start with `[` describe the AdBlock compatibility level.
115                     // Do nothing.  Privacy Browser does not currently use these entries.
116
117                     //Log.i("FilterLists", "Not added:  " + filterListEntry)
118                 } else if (filterListEntry.contains("\$csp=script-src")) {  // Ignore entries that contain `$csp=script-src`.
119                     // Do nothing.  It is uncertain what this directive is even supposed to mean, and it is blocking entire websites like androidcentral.com.  https://redmine.stoutner.com/issues/306.
120
121                     //Log.i("FilterLists", "Not added:  " + originalFilterListEntry)
122                 } else if (filterListEntry.contains("\$websocket") || filterListEntry.contains("\$third-party,websocket") || filterListEntry.contains("\$script,websocket")) {
123                     // Ignore entries with `websocket`.
124                     // Do nothing.  Privacy Browser does not differentiate between websocket requests and other requests and these entries cause a lot of false positives.
125
126                     //Log.i("FilterLists", "Not added:  " + originalFilterlistEntry)
127                 } else if (filterListEntry.startsWith("!")) {   // Comment entries.
128                     if (filterListEntry.startsWith("! Version:")) {
129                         // Get the list version number.
130                         val listVersion = arrayOf(filterListEntry.substring(11))
131
132                         // Store the list version in the headers list.
133                         headers.add(listVersion)
134                     }
135
136                     if (filterListEntry.startsWith("! Title:")) {
137                         // Get the list title.
138                         val listTitle = arrayOf(filterListEntry.substring(9))
139
140                         // Store the list title in the headers list.
141                         headers.add(listTitle)
142                     }
143
144                     //Log.i("FilterLists", "Not added:  " + filterListEntry);
145                 } else if (filterListEntry.startsWith("@@")) {  // Entries that begin with `@@` are allowed entries.
146                     // Remove the `@@`
147                     filterListEntry = filterListEntry.substring(2)
148
149                     // Strip out any initial `||`.  Privacy Browser doesn't differentiate items that only match against the end of the domain name.
150                     if (filterListEntry.startsWith("||"))
151                         filterListEntry = filterListEntry.substring(2)
152
153                     // Check if the entry contains an Adblock filter option (indicated by `$`).
154                     if (filterListEntry.contains("$")) {  // The entry contains a filter option.
155                         if (filterListEntry.contains("~third-party")) {  // Ignore entries that contain `~third-party`.
156                             // Do nothing.
157
158                             //Log.i("FilterLists", headers.get(1)[0] + " not added:  " + originalFilterListEntry)
159                         } else if (filterListEntry.contains("third-party")) {  // Third-party allowed entries.
160                             // Check if the entry only applies to certain domains.
161                             if (filterListEntry.contains("domain=")) {  // Third-party domain allowed entries.
162                                 // Parse the entry.
163                                 var entry = filterListEntry.substring(0, filterListEntry.indexOf("$"))
164                                 val filters = filterListEntry.substring(filterListEntry.indexOf("$") + 1)
165                                 var domains = filters.substring(filters.indexOf("domain=") + 7)
166
167                                 if (domains.contains("~")) {  // It is uncertain what a `~` domain means inside an `@@` entry.
168                                     // Do Nothing
169
170                                     //Log.i("FilterLists", headers.get(1)[0] + " not added:  " + originalFilterListEntry)
171                                 } else if (filterListEntry.startsWith("|")) {  // Third-party domain initial allowed entries.
172                                     // Strip out the initial `|`.
173                                     entry = entry.substring(1)
174
175                                     if (entry == "http://" || entry == "https://") {  // Ignore generic entries.
176                                         // Do nothing.  These entries are designed for filter options that Privacy Browser does not use.
177
178                                         //Log.i("FilterLists", headers.get(1)[0] + " not added:  " + originalFilterListEntry);
179                                     } else {  // Process third-party domain initial allowed entries.
180                                         // Process each domain.
181                                         do {
182                                             // Create a string to keep track of the current domain.
183                                             var domain: String
184
185                                             // Populate the current domain.
186                                             if (domains.contains("|")) {  // There is more than one domain in the list.
187                                                 // Get the first domain from the list.
188                                                 domain = domains.substring(0, domains.indexOf("|"))
189
190                                                 // Remove the first domain from the list.
191                                                 domains = domains.substring(domains.indexOf("|") + 1)
192                                             } else {  // There is only one domain in the list.
193                                                 domain = domains
194                                             }
195
196                                             // Process the domain entry.
197                                             if (entry.contains("*")) {  // Process a third-party domain initial allowed double entry.
198                                                 // Get the index of the wildcard.
199                                                 val wildcardIndex = entry.indexOf("*")
200
201                                                 // Split the entry into components.
202                                                 val firstEntry = entry.substring(0, wildcardIndex)
203                                                 val secondEntry = entry.substring(wildcardIndex + 1)
204
205                                                 // Create an entry string array.
206                                                 val domainDoubleEntry = arrayOf(domain, firstEntry, secondEntry, originalFilterListEntry)
207
208                                                 // Add the entry to the allow list.
209                                                 thirdPartyDomainInitialAllowList.add(domainDoubleEntry)
210
211                                                 //Log.i("FilterLists", headers.get(1)[0] + " third-party domain initial allow list added:  " + domain + " , " + firstEntry + " , " + secondEntry +
212                                                 //        "  -  " + originalFilterListEntry)
213                                             } else {  // Process a third-party domain initial allowed single entry.
214                                                 // Create a domain entry string array.
215                                                 val domainEntry = arrayOf(domain, entry, originalFilterListEntry)
216
217                                                 // Add the entry to the third party domain initial allow list.
218                                                 thirdPartyDomainInitialAllowList.add(domainEntry)
219
220                                                 //Log.i("FilterLists", headers.get(1)[0] + " third-party domain initial allow list added: " + domain + " , " + entry + "  -  " + originalFilterListEntry)
221                                             }
222                                         // Repeat until all the domains have been processed.
223                                         } while (domains.contains("|"))
224                                     }
225                                 } else {  // Third-party domain entries.
226                                     // Process each domain.
227                                     do {
228                                         // Create a string to keep track of the current domain.
229                                         var domain: String
230
231                                         // Populate the current domain.
232                                         if (domains.contains("|")) {  // There is more than one domain in the list.
233                                             // Get the first domain from the list.
234                                             domain = domains.substring(0, domains.indexOf("|"))
235
236                                             // Remove the first domain from the list.
237                                             domains = domains.substring(domains.indexOf("|") + 1)
238                                         } else {  // There is only one domain in the list.
239                                             domain = domains
240                                         }
241
242                                         // Remove any trailing `*` from the entry.
243                                         if (entry.endsWith("*")) {
244                                             entry = entry.substring(0, entry.length - 1)
245                                         }
246
247                                         // Process the domain entry.
248                                         if (entry.contains("*")) {  // Process a third-party domain double entry.
249                                             // Get the index of the wildcard.
250                                             val wildcardIndex = entry.indexOf("*")
251
252                                             // Split the entry into components.
253                                             val firstEntry = entry.substring(0, wildcardIndex)
254                                             val secondEntry = entry.substring(wildcardIndex + 1)
255
256                                             // Create an entry string array.
257                                             val domainDoubleEntry = arrayOf(domain, firstEntry, secondEntry, originalFilterListEntry)
258
259                                             // Add the entry to the allow list.
260                                             thirdPartyDomainAllowList.add(domainDoubleEntry)
261
262                                             //Log.i("FilterLists", headers.get(1)[0] + " third-party domain allow list added:  " + domain + " , " + firstEntry + " , " + secondEntry + "  -  " +
263                                             //        originalFilterListEntry)
264                                         } else {  // Process a third-party domain single entry.
265                                             // Create an entry string array.
266                                             val domainEntry = arrayOf(domain, entry, originalFilterListEntry)
267
268                                             // Add the entry to the allow list.
269                                             thirdPartyDomainAllowList.add(domainEntry)
270
271                                             //Log.i("FilterLists", headers.get(1)[0] + " third-party domain allow list added:  " + domain + " , " + entry + "  -  " + originalFilterListEntry)
272                                         }
273                                     // Repeat until all the domains have been processed.
274                                     } while (domains.contains("|"))
275                                 }
276                             } else {  // Process third-party allow list entries.
277                                 // Parse the entry
278                                 val entry = filterListEntry.substring(0, filterListEntry.indexOf("$"))
279
280                                 // Process the entry.
281                                 if (entry.contains("*")) {  // There are two or more entries.
282                                     // Get the index of the wildcard.
283                                     val wildcardIndex = entry.indexOf("*")
284
285                                     // Split the entry into components.
286                                     val firstEntry = entry.substring(0, wildcardIndex)
287                                     val secondEntry = entry.substring(wildcardIndex + 1)
288
289                                     // Process the second entry.
290                                     if (secondEntry.contains("*")) {  // There are three or more entries.
291                                         // Get the index of the wildcard.
292                                         val secondWildcardIndex = secondEntry.indexOf("*")
293
294                                         // Split the entry into components.
295                                         val realSecondEntry = secondEntry.substring(0, secondWildcardIndex)
296                                         val thirdEntry = secondEntry.substring(secondWildcardIndex + 1)
297
298                                         // Process the third entry.
299                                         if (thirdEntry.contains("*")) {  // There are four or more entries.
300                                             // Get the index of the wildcard.
301                                             val thirdWildcardIndex = thirdEntry.indexOf("*")
302
303                                             // Split the entry into components.
304                                             val realThirdEntry = thirdEntry.substring(0, thirdWildcardIndex)
305                                             val fourthEntry = thirdEntry.substring(thirdWildcardIndex + 1)
306
307                                             // Process the fourth entry.
308                                             if (fourthEntry.contains("*")) {  // Process a third-party allow list quintuple entry.
309                                                 // Get the index of the wildcard.
310                                                 val fourthWildcardIndex = fourthEntry.indexOf("*")
311
312                                                 // Split the entry into components.
313                                                 val realFourthEntry = fourthEntry.substring(0, fourthWildcardIndex)
314                                                 val fifthEntry = fourthEntry.substring(fourthWildcardIndex + 1)
315
316                                                 // Create an entry string array.
317                                                 val quintupleEntry = arrayOf(firstEntry, realSecondEntry, realThirdEntry, realFourthEntry, fifthEntry, originalFilterListEntry)
318
319                                                 // Add the entry to the allow list.
320                                                 thirdPartyAllowList.add(quintupleEntry)
321
322                                                 //Log.i("FilerLists", headers.get(1)[0] + " third-party allow list added:  " + firstEntry + " , " + realSecondEntry + " , " + realThirdEntry + " , " +
323                                                 //        realFourthEntry + " , " + fifthEntry + "  -  " + originalFilterListEntry)
324                                             } else {  // Third-party allow list quadruple entry.
325                                                 // Create an entry string array.
326                                                 val quadrupleEntry = arrayOf(firstEntry, realSecondEntry, realThirdEntry, fourthEntry, originalFilterListEntry)
327
328                                                 // Add the entry to the allow list.
329                                                 thirdPartyAllowList.add(quadrupleEntry)
330
331                                                 //Log.i("FilterLists", headers.get(1)[0] + " third-party allow list added:  " + firstEntry + " , " + realSecondEntry + " , " + realThirdEntry + " , " +
332                                                 //        fourthEntry + "  -  " + originalAllowListEntry)
333                                             }
334                                         } else {  // Process a third-party allow list triple entry.
335                                             // Create an entry string array.
336                                             val tripleEntry = arrayOf(firstEntry, realSecondEntry, thirdEntry, originalFilterListEntry)
337
338                                             // Add the entry to the allow list.
339                                             thirdPartyAllowList.add(tripleEntry)
340
341                                             //Log.i("AllowLists", headers.get(1)[0] + " third-party allow list added:  " + firstEntry + " , " + realSecondEntry + " , " + thirdEntry + "  -  " +
342                                             //        originalFilterListEntry)
343                                         }
344                                     } else {  // Process a third-party allow list double entry.
345                                         // Create an entry string array.
346                                         val doubleEntry = arrayOf(firstEntry, secondEntry, originalFilterListEntry)
347
348                                         // Add the entry to the allow list.
349                                         thirdPartyAllowList.add(doubleEntry)
350
351                                         //Log.i("FilterLists", headers.get(1)[0] + " third-party allow list added:  " + firstEntry + " , " + secondEntry + "  -  " + originalFilterListEntry)
352                                     }
353                                 } else {  // Process a third-party allow list single entry.
354                                     // Create an entry string array.
355                                     val singleEntry = arrayOf(entry, originalFilterListEntry)
356
357                                     // Add the entry to the allow list.
358                                     thirdPartyAllowList.add(singleEntry)
359
360                                     //Log.i("FilterLists", headers.get(1)[0] + " third-party domain allow list added:  " + entry + "  -  " + originalFilterListEntry)
361                                 }
362                             }
363                         } else if (filterListEntry.contains("domain=")) {  // Process domain allow list entries.
364                             // Parse the entry
365                             var entry = filterListEntry.substring(0, filterListEntry.indexOf("$"))
366                             val filters = filterListEntry.substring(filterListEntry.indexOf("$") + 1)
367                             var domains = filters.substring(filters.indexOf("domain=") + 7)
368
369                             // Process the entry.
370                             if (entry.startsWith("|")) {  // Initial domain allow list entries.
371                                 // Strip the initial `|`.
372                                 entry = entry.substring(1)
373
374                                 // Process the entry.
375                                 if (entry == "http://" || entry == "https://") {  // Ignore generic entries.
376                                     // Do nothing.  These entries are designed for filter options that Privacy Browser does not use.
377
378                                     //Log.i("FilterLists", headers.get(1)[0] + " not added:  " + originalFilterListEntry)
379                                 } else {  // Initial domain allow list entry.
380                                     // Process each domain.
381                                     do {
382                                         // Create a string to keep track of the current domain.
383                                         var domain: String
384
385                                         // Get the first domain.
386                                         if (domains.contains("|")) {  // There is more than one domain in the list.
387                                             // Get the first domain from the list.
388                                             domain = domains.substring(0, domains.indexOf("|"))
389
390                                             // Remove the first domain from the list.
391                                             domains = domains.substring(domains.indexOf("|") + 1)
392                                         } else {  // There is only one domain in the list.
393                                             domain = domains
394                                         }
395
396                                         // Process the entry.
397                                         if (entry.contains("*")) {  // There are two or more entries.
398                                             // Get the index of the wildcard.
399                                             val wildcardIndex = entry.indexOf("*")
400
401                                             // Split the entry into components.
402                                             val firstEntry = entry.substring(0, wildcardIndex)
403                                             val secondEntry = entry.substring(wildcardIndex + 1)
404
405                                             // Process the second entry.
406                                             if (secondEntry.contains("*")) {  // Process a domain initial triple entry.
407                                                 // Get the index of the wildcard.
408                                                 val secondWildcardIndex = secondEntry.indexOf("*")
409
410                                                 // Split the entry into components.
411                                                 val realSecondEntry = secondEntry.substring(0, secondWildcardIndex)
412                                                 val thirdEntry = secondEntry.substring(secondWildcardIndex + 1)
413
414                                                 // Create an entry string array.
415                                                 val domainTripleEntry = arrayOf(domain, firstEntry, realSecondEntry, thirdEntry, originalFilterListEntry)
416
417                                                 // Add the entry to the allow list.
418                                                 domainInitialAllowList.add(domainTripleEntry)
419
420                                                 //Log.i("FilterLists", headers.get(1)[0] + " domain initial allow list entry added:  " + domain + " , " + firstEntry + " , " + realSecondEntry + " , " +
421                                                 //        thirdEntry + "  -  " + originalFilterListEntry)
422                                             } else {  // Process a domain initial double entry.
423                                                 // Create an entry string array.
424                                                 val domainDoubleEntry = arrayOf(domain, firstEntry, secondEntry, originalFilterListEntry)
425
426                                                 // Add the entry to the allow list.
427                                                 domainInitialAllowList.add(domainDoubleEntry)
428
429                                                 //Log.i("FilterLists", headers.get(1)[0] + " domain initial allow list entry added:  " + domain + " , " + firstEntry + " , " + secondEntry + "  -  " +
430                                                 //        originalFilterListEntry)
431                                             }
432                                         } else {  // Process a domain initial single entry.
433                                             // Create an entry string array.
434                                             val domainEntry = arrayOf(domain, entry, originalFilterListEntry)
435
436                                             // Add the entry to the allow list.
437                                             domainInitialAllowList.add(domainEntry)
438
439                                             //Log.i("FilterLists", headers.get(1)[0] + " domain initial allow list entry added:  " + domain + " , " + entry + "  -  " + originalFilterListEntry)
440                                         }
441                                     // Repeat until all the domains have been processed.
442                                     } while (domains.contains("|"))
443                                 }
444                             } else if (entry.endsWith("|")) {  // Final domain allow list entries.
445                                 // Strip the `|` from the end of the entry.
446                                 entry = entry.substring(0, entry.length - 1)
447
448                                 // Process each domain.
449                                 do {
450                                     // Create a string to keep track of the current domain.
451                                     var domain: String
452
453                                     // Get the first domain.
454                                     if (domains.contains("|")) {  // There is more than one domain in the list.
455                                         // Get the first domain from the list.
456                                         domain = domains.substring(0, domains.indexOf("|"))
457
458                                         // Remove the first domain from the list.
459                                         domains = domains.substring(domains.indexOf("|") + 1)
460                                     } else {  // There is only one domain in the list.
461                                         domain = domains
462                                     }
463
464                                     if (entry.contains("*")) {  // Domain final allow list double entry.
465                                         // Get the index of the wildcard.
466                                         val wildcardIndex = entry.indexOf("*")
467
468                                         // Split the entry into components.
469                                         val firstEntry = entry.substring(0, wildcardIndex)
470                                         val secondEntry = entry.substring(wildcardIndex + 1)
471
472                                         // Create an entry string array.
473                                         val domainDoubleEntry = arrayOf(domain, firstEntry, secondEntry, originalFilterListEntry)
474
475                                         // Add the entry to the allow list.
476                                         domainFinalAllowList.add(domainDoubleEntry)
477
478                                         //Log.i("FilterLists", headers.get(1)[0] + " domain final allow list added:  " + domain + " , " + firstEntry + " , " + secondEntry + "  -  " +
479                                         //        originalFilterListEntry);
480                                     } else {  // Process a domain final allow list single entry.
481                                         // create an entry string array.
482                                         val domainEntry = arrayOf(domain, entry, originalFilterListEntry)
483
484                                         // Add the entry to the allow list.
485                                         domainFinalAllowList.add(domainEntry)
486
487                                         //Log.i("FilterLists", headers.get(1)[0] + " domain final allow list added: " + domain + " , " + entry + "  -  " + originalFilterListEntry);
488                                     }
489                                 // Repeat until all the domains have been processed.
490                                 } while (domains.contains("|"))
491                             } else {  // Standard domain allow list entries with filters.
492                                 if (domains.contains("~")) {  // It is uncertain what a `~` domain means inside an `@@` entry.
493                                     // Do Nothing
494
495                                     //Log.i("FilterLists", headers.get(1)[0] + " not added:  " + originalFilterListEntry)
496                                 } else {
497                                     // Process each domain.
498                                     do {
499                                         // Create a string to keep track of the current domain.
500                                         var domain: String
501
502                                         // Get the first domain.
503                                         if (domains.contains("|")) {  // There is more than one domain in the list.
504                                             // Get the first domain from the list.
505                                             domain = domains.substring(0, domains.indexOf("|"))
506
507                                             // Remove the first domain from the list.
508                                             domains = domains.substring(domains.indexOf("|") + 1)
509                                         } else {  // There is only one domain in the list.
510                                             domain = domains
511                                         }
512
513                                         // Process the entry.
514                                         if (entry.contains("*")) {  // There are two or more entries.
515                                             // Get the index of the wildcard.
516                                             val wildcardIndex = entry.indexOf("*")
517
518                                             // Split the entry into components.
519                                             val firstEntry = entry.substring(0, wildcardIndex)
520                                             val secondEntry = entry.substring(wildcardIndex + 1)
521
522                                             // Process the second entry.
523                                             if (secondEntry.contains("*")) {  // There are three or more entries.
524                                                 // Get the index of the wildcard.
525                                                 val secondWildcardIndex = secondEntry.indexOf("*")
526
527                                                 // Split the entry into components.
528                                                 val realSecondEntry = secondEntry.substring(0, secondWildcardIndex)
529                                                 val thirdEntry = secondEntry.substring(secondWildcardIndex + 1)
530
531                                                 // Process the third entry.
532                                                 if (thirdEntry.contains("*")) {  // Process a domain allow list quadruple entry.
533                                                     // Get the index of the wildcard.
534                                                     val thirdWildcardIndex = thirdEntry.indexOf("*")
535
536                                                     // Split the entry into components.
537                                                     val realThirdEntry = thirdEntry.substring(0, thirdWildcardIndex)
538                                                     val fourthEntry = thirdEntry.substring(thirdWildcardIndex + 1)
539
540                                                     // Create an entry string array.
541                                                     val domainQuadrupleEntry = arrayOf(domain, firstEntry, realSecondEntry, realThirdEntry, fourthEntry, originalFilterListEntry)
542
543                                                     // Add the entry to the allow list.
544                                                     domainAllowList.add(domainQuadrupleEntry)
545
546                                                     //Log.i("FilterLists", headers.get(1)[0] + " domain allow list added:  " + domain + " , " + firstEntry + " , " + realSecondEntry + " , " +
547                                                     //        realThirdEntry + " , " + fourthEntry + "  -  " + originalFilterListEntry)
548                                                 } else {  // Process a domain allow list triple entry.
549                                                     // Create an entry string array.
550                                                     val domainTripleEntry = arrayOf(domain, firstEntry, realSecondEntry, thirdEntry, originalFilterListEntry)
551
552                                                     // Add the entry to the allow list.
553                                                     domainAllowList.add(domainTripleEntry)
554
555                                                     //Log.i("FilterLists", headers.get(1)[0] + " domain allow list added:  " + domain + " , " + firstEntry + " , " + realSecondEntry + " , " +
556                                                     //        thirdEntry + "  -  " + originalFilterListEntry)
557                                                 }
558                                             } else {  // Process a domain allow list double entry.
559                                                 // Create an entry string array.
560                                                 val domainDoubleEntry = arrayOf(domain, firstEntry, secondEntry, originalFilterListEntry)
561
562                                                 // Add the entry to the allow list.
563                                                 domainAllowList.add(domainDoubleEntry)
564
565                                                 //Log.i("FilterLists", headers.get(1)[0] + " domain allow list added:  " + domain + " , " + firstEntry + " , " + secondEntry + "  -  " originalFilterListEntry)
566                                             }
567                                         } else {  // Process a domain allow list single entry.
568                                             // Create an entry string array.
569                                             val domainEntry = arrayOf(domain, entry, originalFilterListEntry)
570
571                                             // Add the entry to the allow list.
572                                             domainAllowList.add(domainEntry)
573
574                                             //Log.i("FilterLists", headers.get(1)[0] + " domain allow list added:  " + domain + " , " + entry + "  -  " + originalFilterListEntry)
575                                         }
576                                     // Repeat until all the domains have been processed.
577                                     } while (domains.contains("|"))
578                                 }
579                             }
580                         }  // Ignore all other filter entries.
581                     } else if (filterListEntry.endsWith("|")) {  // Final allow list entries.
582                         // Remove the final `|` from the entry.
583                         val entry = filterListEntry.substring(0, filterListEntry.length - 1)
584
585                         // Process the entry.
586                         if (entry.contains("*")) {  // Process a final allow list double entry
587                             // Get the index of the wildcard.
588                             val wildcardIndex = entry.indexOf("*")
589
590                             // split the entry into components.
591                             val firstEntry = entry.substring(0, wildcardIndex)
592                             val secondEntry = entry.substring(wildcardIndex + 1)
593
594                             // Create an entry string array.
595                             val doubleEntry = arrayOf(firstEntry, secondEntry, originalFilterListEntry)
596
597                             // Add the entry to the allow list.
598                             finalAllowList.add(doubleEntry)
599
600                             //Log.i("FilterLists", headers.get(1)[0] + " final allow list added:  " + firstEntry + " , " + secondEntry + "  -  " + originalFilterListEntry)
601                         } else {  // Process a final allow list single entry.
602                             // Create an entry string array.
603                             val singleEntry = arrayOf(entry, originalFilterListEntry)
604
605                             // Add the entry to the allow list.
606                             finalAllowList.add(singleEntry)
607
608                             //Log.i("FilterLists", headers.get(1)[0] + " final allow list added:  " + entry + "  -  " + originalFilterListEntry)
609                         }
610                     } else {  // Main allow list entries.
611                         // Process the entry.
612                         if (filterListEntry.contains("*")) {  // There are two or more entries.
613                             // Get the index of the wildcard.
614                             val wildcardIndex = filterListEntry.indexOf("*")
615
616                             // Split the entry into components.
617                             val firstEntry = filterListEntry.substring(0, wildcardIndex)
618                             val secondEntry = filterListEntry.substring(wildcardIndex + 1)
619
620                             // Process the second entry.
621                             if (secondEntry.contains("*")) {  // Main allow list triple entry.
622                                 // Get the index of the wildcard.
623                                 val secondWildcardIndex = secondEntry.indexOf("*")
624
625                                 // Split the entry into components.
626                                 val realSecondEntry = secondEntry.substring(0, secondWildcardIndex)
627                                 val thirdEntry = secondEntry.substring(secondWildcardIndex + 1)
628
629                                 // Create an entry string array.
630                                 val tripleEntry = arrayOf(firstEntry, realSecondEntry, thirdEntry, originalFilterListEntry)
631
632                                 // Add the entry to the allow list.
633                                 mainAllowList.add(tripleEntry)
634
635                                 //Log.i("FilterLists", headers.get(1)[0] + " main allow list added:  " + firstEntry + " , " + realSecondEntry + " , " + thirdEntry + "  -  " + originalFilterListEntry)
636                             } else {  // Process a main allow list double entry.
637                                 // Create an entry string array.
638                                 val doubleEntry = arrayOf(firstEntry, secondEntry, originalFilterListEntry)
639
640                                 // Add the entry to the allow list.
641                                 mainAllowList.add(doubleEntry)
642
643                                 //Log.i("FilterLists", headers.get(1)[0] + " main allow list added:  " + firstEntry + " , " + secondEntry + "  -  " + originalFilterListEntry)
644                             }
645                         } else {  // Process a main allow list single entry.
646                             // Create an entry string array.
647                             val singleEntry = arrayOf(filterListEntry, originalFilterListEntry)
648
649                             // Add the entry to the allow list.
650                             mainAllowList.add(singleEntry)
651
652                             //Log.i("FilterLists", headers.get(1)[0] + " main allow list added:  " + filterListEntry + "  -  " + originalFilterListEntry)
653                         }
654                     }
655                 } else if (filterListEntry.endsWith("|")) {  // Final block list entries.
656                     // Strip out the final "|"
657                     var entry = filterListEntry.substring(0, filterListEntry.length - 1)
658
659                     // Strip out any initial `||`.  They are redundant in this case because the block list entry is being matched against the end of the URL.
660                     if (entry.startsWith("||"))
661                         entry = entry.substring(2)
662
663                     // Process the entry.
664                     if (entry.contains("*")) {  // Process a final block list double entry.
665                         // Get the index of the wildcard.
666                         val wildcardIndex = entry.indexOf("*")
667
668                         // Split the entry into components.
669                         val firstEntry = entry.substring(0, wildcardIndex)
670                         val secondEntry = entry.substring(wildcardIndex + 1)
671
672                         // Create an entry string array.
673                         val doubleEntry = arrayOf(firstEntry, secondEntry, originalFilterListEntry)
674
675                         // Add the entry to the block list.
676                         finalBlockList.add(doubleEntry)
677
678                         //Log.i("FilterLists", headers.get(1)[0] + " final block list added:  " + firstEntry + " , " + secondEntry + "  -  " + originalFilterListEntry)
679                     } else {  // Process a final block list single entry.
680                         // Create an entry string array.
681                         val singleEntry = arrayOf(entry, originalFilterListEntry)
682
683                         // Add the entry to the block list.
684                         finalBlockList.add(singleEntry)
685
686                         //Log.i("FilterLists", headers.get(1)[0] + " final block list added:  " + entry + "  -  " + originalFilterListEntry)
687                     }
688                 } else if (filterListEntry.contains("$")) {  // Entries with filter options.
689                     // Strip out any initial `||`.  These will be treated like any other entry.
690                     if (filterListEntry.startsWith("||"))
691                         filterListEntry = filterListEntry.substring(2)
692
693                     // Process the entry.
694                     if (filterListEntry.contains("third-party")) {  // Third-party entries.
695                         // Process the entry.
696                         if (filterListEntry.contains("~third-party")) {  // Third-party filter allow list entries.
697                             // Do not process these allow list entries.  They are designed to combine with block filters that Privacy Browser doesn't use, like `subdocument` and `xmlhttprequest`.
698
699                             //Log.i("FilterLists", headers.get(1)[0] + " not added:  " + originalFilterListEntry)
700                         } else if (filterListEntry.contains("domain=")) {  // Third-party domain entries.
701                             // Process the domain entry.
702                             if (filterListEntry.startsWith("|")) {  // Third-party domain initial entries.
703                                 // Strip the initial `|`.
704                                 filterListEntry = filterListEntry.substring(1)
705
706                                 // Parse the entry
707                                 val entry = filterListEntry.substring(0, filterListEntry.indexOf("$"))
708                                 val filters = filterListEntry.substring(filterListEntry.indexOf("$") + 1)
709                                 var domains = filters.substring(filters.indexOf("domain=") + 7)
710
711                                 // Process the entry.
712                                 if (entry == "http:" || entry == "https:" || entry == "http://" || entry == "https://") {  // Ignore generic entries.
713                                     // Do nothing.  These entries will almost entirely disable the website.
714                                     // Often the original entry blocks filter options like `$script`, which Privacy Browser does not differentiate.
715
716                                     //Log.i("FilterLists", headers.get(1)[0] + " not added:  " + originalFilterListEntry)
717                                 } else {  // Third-party domain initial entries.
718                                     // Process each domain.
719                                     do {
720                                         // Create a string to keep track of the current domain.
721                                         var domain: String
722
723                                         // Get the first domain.
724                                         if (domains.contains("|")) {  // There is more than one domain in the list.
725                                             // Get the first domain from the list.
726                                             domain = domains.substring(0, domains.indexOf("|"))
727
728                                             // Remove the first domain from the list.
729                                             domains = domains.substring(domains.indexOf("|") + 1)
730                                         } else {  // There is only one domain in the list.
731                                             domain = domains
732                                         }
733
734                                         // Process the entry.
735                                         if (entry.contains("*")) {  // Three are two or more entries.
736                                             // Get the index of the wildcard.
737                                             val wildcardIndex = entry.indexOf("*")
738
739                                             // Split the entry into components.
740                                             val firstEntry = entry.substring(0, wildcardIndex)
741                                             val secondEntry = entry.substring(wildcardIndex + 1)
742
743                                             // Process the second entry.
744                                             if (secondEntry.contains("*")) {  // Third-party domain initial block list triple entry.
745                                                 // Get the index of the wildcard.
746                                                 val secondWildcardIndex = secondEntry.indexOf("*")
747
748                                                 // Split the entry into components.
749                                                 val realSecondEntry = secondEntry.substring(0, secondWildcardIndex)
750                                                 val thirdEntry = secondEntry.substring(secondWildcardIndex + 1)
751
752                                                 // Create an entry string array.
753                                                 val tripleDomainEntry = arrayOf(domain, firstEntry, realSecondEntry, thirdEntry, originalFilterListEntry)
754
755                                                 // Add the entry to the block list.
756                                                 thirdPartyDomainInitialBlockList.add(tripleDomainEntry)
757
758                                                 //Log.i("FilterLists", headers.get(1)[0] + " third-party domain initial block list added:  " + domain + " , " + firstEntry + " , " + realSecondEntry +
759                                                 //        " , " + thirdEntry + "  -  " + originalFilterListEntry)
760                                             } else {  // Process a third-party domain initial block list double entry.
761                                                 // Create an entry string array.
762                                                 val doubleDomainEntry = arrayOf(domain, firstEntry, secondEntry, originalFilterListEntry)
763
764                                                 // Add the entry to the block list.
765                                                 thirdPartyDomainInitialBlockList.add(doubleDomainEntry)
766
767                                                 //Log.i("FilterLists", headers.get(1)[0] + " third-party domain initial block list added: " + domain + " , " + firstEntry + " , " + secondEntry +
768                                                 //        "  -  " + originalFilterListEntry)
769                                             }
770                                         } else {  // Process a third-party domain initial block list single entry.
771                                             // Create an entry string array.
772                                             val singleEntry = arrayOf(domain, entry, originalFilterListEntry)
773
774                                             // Add the entry to the block list.
775                                             thirdPartyDomainInitialBlockList.add(singleEntry)
776
777                                             //Log.i("FilterLists", headers.get(1)[0] + " third-party domain initial block list added:  " + domain + " , " + entry + "  -  " + originalFilterListEntry)
778                                         }
779                                     // Repeat until all the domains have been processed.
780                                     } while (domains.contains("|"))
781                                 }
782                             } else if (filterListEntry.contains("\\")) {  // Process a third-party domain block list regular expression.
783                                 // Parse the entry.  At least one regular expression in this entry contains `$`, so the parser uses `/$`.
784                                 val entry = filterListEntry.substring(0, filterListEntry.indexOf("/$") + 1)
785                                 val filters = filterListEntry.substring(filterListEntry.indexOf("/$") + 2)
786                                 var domains = filters.substring(filters.indexOf("domain=") + 7)
787
788                                 // Process each domain.
789                                 do {
790                                     // Create a string to keep track of the current domain.
791                                     var domain: String
792
793                                     // Get the first domain.
794                                     if (domains.contains("|")) {  // There is more than one domain in the list.
795                                         // Get the first domain from the list.
796                                         domain = domains.substring(0, domains.indexOf("|"))
797
798                                         // Remove the first domain from the list.
799                                         domains = domains.substring(domains.indexOf("|") + 1)
800                                     } else {  // There is only one domain in the list.
801                                         domain = domains
802                                     }
803
804                                     // Create an entry string array.
805                                     val domainEntry = arrayOf(domain, entry, originalFilterListEntry)
806
807                                     // Add the entry to the block list.
808                                     thirdPartyDomainRegularExpressionBlockList.add(domainEntry)
809
810                                     //Log.i("FilterLists", headers.get(1)[0] + " third-party domain regular expression block list added:  " + domain + " , " + entry + "  -  " + originalFilterListEntry)
811                                 // Repeat until all the domains have been processed.
812                                 } while (domains.contains("|"))
813                             } else {  // Third-party domain entries.
814                                 // Parse the entry
815                                 var entry = filterListEntry.substring(0, filterListEntry.indexOf("$"))
816                                 val filters = filterListEntry.substring(filterListEntry.indexOf("$") + 1)
817                                 var domains = filters.substring(filters.indexOf("domain=") + 7)
818
819                                 // Strip any trailing "*" from the entry.
820                                 if (entry.endsWith("*"))
821                                     entry = entry.substring(0, entry.length - 1)
822
823                                 // Create an allow domain tracker.
824                                 var allowDomain = false
825
826                                 // Process each domain.
827                                 do {
828                                     // Create a string to keep track of the current domain.
829                                     var domain: String
830
831                                     // Get the first domain.
832                                     if (domains.contains("|")) {  // There is more than one domain in the list.
833                                         // Get the first domain from the list.
834                                         domain = domains.substring(0, domains.indexOf("|"))
835
836                                         // Remove the first domain from the list.
837                                         domains = domains.substring(domains.indexOf("|") + 1)
838                                     } else {  // The is only one domain in the list.
839                                         domain = domains
840                                     }
841
842                                     // Differentiate between block list domains and allow list domains.
843                                     if (domain.startsWith("~")) {  // Allow list third-party domain entry.
844                                         // Strip the initial `~`.
845                                         domain = domain.substring(1)
846
847                                         // Set the allow list domain flag.
848                                         allowDomain = true
849
850                                         // Process the entry.
851                                         if (entry.contains("*")) {  // Third-party domain allow list double entry.
852                                             // Get the index of the wildcard.
853                                             val wildcardIndex = entry.indexOf("*")
854
855                                             // Split the entry into components.
856                                             val firstEntry = entry.substring(0, wildcardIndex)
857                                             val secondEntry = entry.substring(wildcardIndex + 1)
858
859                                             // Create an entry string array.
860                                             val domainDoubleEntry = arrayOf(domain, firstEntry, secondEntry, originalFilterListEntry)
861
862                                             // Add the entry to the allow list.
863                                             thirdPartyDomainAllowList.add(domainDoubleEntry)
864
865                                             //Log.i("FilterLists", headers.get(1)[0] + " third-party domain allow list added:  " + domain + " , " + firstEntry + " , " + secondEntry + "  -  " +
866                                             //        originalFilterListEntry)
867                                         } else {  // Process a third-party domain allow list single entry.
868                                             // Create an entry string array.
869                                             val domainEntry = arrayOf(domain, entry, originalFilterListEntry)
870
871                                             // Add the entry to the allow list.
872                                             thirdPartyDomainAllowList.add(domainEntry)
873
874                                             //Log.i("FilterLists", headers.get(1)[0] + " third-party domain allow list added:  " + domain + " , " + entry + "  -  " + originalFilterListEntry)
875                                         }
876                                     } else {  // Third-party domain block list entries.
877                                         if (entry.contains("*")) {  // Process a third-party domain block list double entry.
878                                             // Get the index of the wildcard.
879                                             val wildcardIndex = entry.indexOf("*")
880
881                                             // Split the entry into components.
882                                             val firstEntry = entry.substring(0, wildcardIndex)
883                                             val secondEntry = entry.substring(wildcardIndex + 1)
884
885                                             // Create an entry string array.
886                                             val domainDoubleEntry = arrayOf(domain, firstEntry, secondEntry, originalFilterListEntry)
887
888                                             // Add the entry to the block list
889                                             thirdPartyDomainBlockList.add(domainDoubleEntry)
890
891                                             //Log.i("FilterLists", headers.get(1)[0] + " third-party domain block list added:  " + domain + " , " + firstEntry + " , " + secondEntry + "  -  " +
892                                             //        originalFilterListEntry)
893                                         } else {  // Process a third-party domain block list single entry.
894                                             // Create an entry string array.
895                                             val domainEntry = arrayOf(domain, entry, originalFilterListEntry)
896
897                                             // Add the entry to the block list.
898                                             thirdPartyDomainBlockList.add(domainEntry)
899
900                                             //Log.i("FilterLists", headers.get(1)[0] + " third-party domain block list added:  " + domain + " , " + entry + "  -  " + originalFilterListEntry)
901                                         }
902                                     }
903                                 // Repeat until all the domains have been processed.
904                                 } while (domains.contains("|"))
905
906                                 // Add a third-party block list entry if an allow list domain was processed.
907                                 if (allowDomain) {
908                                     if (entry.contains("*")) {  // Third-party block list double entry.
909                                         // Get the index of the wildcard.
910                                         val wildcardIndex = entry.indexOf("*")
911
912                                         // Split the entry into components.
913                                         val firstEntry = entry.substring(0, wildcardIndex)
914                                         val secondEntry = entry.substring(wildcardIndex + 1)
915
916                                         // Create an entry string array.
917                                         val doubleEntry = arrayOf(firstEntry, secondEntry, originalFilterListEntry)
918
919                                         // Add the entry to the block list.
920                                         thirdPartyBlockList.add(doubleEntry)
921
922                                         //Log.i("FilterLists", headers.get(1)[0] + " third-party block list added:  " + firstEntry + " , " + secondEntry + "  -  " + originalFilterListEntry)
923                                     } else {  // Process a third-party block list single entry.
924                                         // Create an entry string array.
925                                         val singleEntry = arrayOf(entry, originalFilterListEntry)
926
927                                         // Add an entry to the block list.
928                                         thirdPartyBlockList.add(singleEntry)
929
930                                         //Log.i("FilterLists", headers.get(1)[0] + " third-party block list added:  " + entry + "  -  " + originalFilterListEntry)
931                                     }
932                                 }
933                             }
934                         } else if (filterListEntry.startsWith("|")) {  // Third-party initial block list entries.
935                             // Strip the initial `|`.
936                             filterListEntry = filterListEntry.substring(1)
937
938                             // Get the entry.
939                             val entry = filterListEntry.substring(0, filterListEntry.indexOf("$"))
940
941                             // Process the entry.
942                             if (entry.contains("*")) {  // Process a third-party initial block list double entry.
943                                 // Get the index of the wildcard.
944                                 val wildcardIndex = entry.indexOf("*")
945
946                                 // Split the entry into components.
947                                 val firstEntry = entry.substring(0, wildcardIndex)
948                                 val secondEntry = entry.substring(wildcardIndex + 1)
949
950                                 // Create an entry string array.
951                                 val thirdPartyDoubleEntry = arrayOf(firstEntry, secondEntry, originalFilterListEntry)
952
953                                 // Add the entry to the block list.
954                                 thirdPartyInitialBlockList.add(thirdPartyDoubleEntry)
955
956                                 //Log.i("FilterLists", headers.get(1)[0] + " third-party initial block list added:  " + firstEntry + " , " + secondEntry + "  -  " + originalFilterListEntry)
957                             } else {  // Process a third-party initial block list single entry.
958                                 // Create an entry string array.
959                                 val singleEntry = arrayOf(entry, originalFilterListEntry)
960
961                                 // Add the entry to the block list.
962                                 thirdPartyInitialBlockList.add(singleEntry)
963
964                                 //Log.i("FilterLists", headers.get(1)[0] + " third-party initial block list added:  " + entry + "  -  " + originalFilterListEntry)
965                             }
966                         } else if (filterListEntry.contains("\\")) {  // Third-party regular expression block list entry.
967                             // Get the entry.
968                             val entry = if (filterListEntry.contains("$/$"))  // The first `$` is part of the regular expression.
969                                 filterListEntry.substring(0, filterListEntry.indexOf("$/$") + 2)
970                             else  // The only `$` indicates the filter options.
971                                 filterListEntry.substring(0, filterListEntry.indexOf("$"))
972
973                             // Create an entry string array.
974                             val singleEntry = arrayOf(entry, originalFilterListEntry)
975
976                             // Add the entry to the block list.
977                             thirdPartyRegularExpressionBlockList.add(singleEntry)
978
979                             //Log.i("FilterLists", headers.get(1)[0] + " third-party regular expression block list added:  " + entry + "  -  " + originalFilterListEntry)
980                         } else if (filterListEntry.contains("*")) {  // Third-party and regular expression block list entries.
981                             // Get the entry.
982                             var entry = filterListEntry.substring(0, filterListEntry.indexOf("$"))
983
984                             // Process the entry.
985                             if (entry.endsWith("*")) {  // Third-party block list single entry.
986                                 // Strip the final `*`.
987                                 entry = entry.substring(0, entry.length - 1)
988
989                                 // Create an entry string array.
990                                 val singleEntry = arrayOf(entry, originalFilterListEntry)
991
992                                 // Add the entry to the block list.
993                                 thirdPartyBlockList.add(singleEntry)
994
995                                 //Log.i("FilterLists", headers.get(1)[0] + " third party block list added:  " + entry + "  -  " + originalFilterListEntry)
996                             } else {  // There are two or more entries.
997                                 // Get the index of the wildcard.
998                                 val wildcardIndex = entry.indexOf("*")
999
1000                                 // Split the entry into components.
1001                                 val firstEntry = entry.substring(0, wildcardIndex)
1002                                 val secondEntry = entry.substring(wildcardIndex + 1)
1003
1004                                 // Process the second entry.
1005                                 if (secondEntry.contains("*")) {  // There are three or more entries.
1006                                     // Get the index of the wildcard.
1007                                     val secondWildcardIndex = secondEntry.indexOf("*")
1008
1009                                     // Split the entry into components.
1010                                     val realSecondEntry = secondEntry.substring(0, secondWildcardIndex)
1011                                     val thirdEntry = secondEntry.substring(secondWildcardIndex + 1)
1012
1013                                     // Process a third entry.
1014                                     if (thirdEntry.contains("*")) {  // Third-party block list quadruple entry.
1015                                         // Get the index of the wildcard.
1016                                         val thirdWildcardIndex = thirdEntry.indexOf("*")
1017
1018                                         // Split the entry into components.
1019                                         val realThirdEntry = thirdEntry.substring(0, thirdWildcardIndex)
1020                                         val fourthEntry = thirdEntry.substring(thirdWildcardIndex + 1)
1021
1022                                         // Create an entry string array.
1023                                         val quadrupleEntry = arrayOf(firstEntry, realSecondEntry, realThirdEntry, fourthEntry, originalFilterListEntry)
1024
1025                                         // Add the entry to the block list.
1026                                         thirdPartyBlockList.add(quadrupleEntry)
1027
1028                                         //Log.i("FilterLists", headers.get(1)[0] + " third-party block list added:  " + firstEntry + " , " + realSecondEntry + " , " + realThirdEntry + " , " +
1029                                         //        fourthEntry + "  -  " + originalFilterListEntry);
1030                                     } else {  // Third-party block list triple entry.
1031                                         // Create an entry string array.
1032                                         val tripleEntry = arrayOf(firstEntry, realSecondEntry, thirdEntry, originalFilterListEntry)
1033
1034                                         // Add the entry to the block list.
1035                                         thirdPartyBlockList.add(tripleEntry)
1036
1037                                         //Log.i("FilterLists", headers.get(1)[0] + " third-party block list added:  " + firstEntry + " , " + realSecondEntry + " , " + thirdEntry + "  -  " +
1038                                         //        originalFilterListEntry)
1039                                     }
1040                                 } else {  // Third-party block list double entry.
1041                                     // Create an entry string array.
1042                                     val doubleEntry = arrayOf(firstEntry, secondEntry, originalFilterListEntry)
1043
1044                                     // Add the entry to the block list.
1045                                     thirdPartyBlockList.add(doubleEntry)
1046
1047                                     //Log.i("FilterLists", headers.get(1)[0] + " third-party block list added:  " + firstEntry + " , " + secondEntry + "  -  " + originalFilterListEntry)
1048                                 }
1049                             }
1050                         } else {  // Third party block list single entry.
1051                             // Get the entry.
1052                             val entry = filterListEntry.substring(0, filterListEntry.indexOf("$"))
1053
1054                             // Create an entry string array.
1055                             val singleEntry = arrayOf(entry, originalFilterListEntry)
1056
1057                             // Add the entry to the block list.
1058                             thirdPartyBlockList.add(singleEntry)
1059
1060                             //Log.i("FilterLists", headers.get(1)[0] + " third party block list added:  " + entry + "  -  " + originalFilterListEntry)
1061                         }
1062                     } else if (filterListEntry.substring(filterListEntry.indexOf("$")).contains("domain=")) {  // Domain entries.
1063                         // Process the entry.
1064                         if (filterListEntry.contains("~")) {  // Domain allow list entries.
1065                             // Separate the filters.
1066                             var entry = filterListEntry.substring(0, filterListEntry.indexOf("$"))
1067                             val filters = filterListEntry.substring(filterListEntry.indexOf("$") + 1)
1068                             var domains = filters.substring(filters.indexOf("domain=") + 7)
1069
1070                             // Strip any final `*` from the entry.  They are redundant.
1071                             if (entry.endsWith("*"))
1072                                 entry = entry.substring(0, entry.length - 1)
1073
1074                             // Process each domain.
1075                             do {
1076                                 // Create a string to keep track of the current domain.
1077                                 var domain: String
1078
1079                                 // Get the first domain.
1080                                 if (domains.contains("|")) {  // There is more than one domain in the list.
1081                                     // Get the first domain from the list.
1082                                     domain = domains.substring(0, domains.indexOf("|"))
1083
1084                                     // Remove the first domain from the list.
1085                                     domains = domains.substring(domains.indexOf("|") + 1)
1086                                 } else {  // There is only one domain in the list.
1087                                     domain = domains
1088                                 }
1089
1090                                 // Strip the initial `~`.
1091                                 domain = domain.substring(1)
1092
1093                                 // Process the entry.
1094                                 if (entry.contains("*")) {  // There are two or more entries.
1095                                     // Get the index of the wildcard.
1096                                     val wildcardIndex = entry.indexOf("*")
1097
1098                                     // Split the entry into components.
1099                                     val firstEntry = entry.substring(0, wildcardIndex)
1100                                     val secondEntry = entry.substring(wildcardIndex + 1)
1101
1102                                     // Process the second entry.
1103                                     if (secondEntry.contains("*")) {  // Domain allow list triple entry.
1104                                         // Get the index of the wildcard.
1105                                         val secondWildcardIndex = secondEntry.indexOf("*")
1106
1107                                         // Split the entry into components.
1108                                         val realSecondEntry = secondEntry.substring(0, secondWildcardIndex)
1109                                         val thirdEntry = secondEntry.substring(secondWildcardIndex + 1)
1110
1111                                         // Create an entry string array.
1112                                         val domainTripleEntry = arrayOf(domain, firstEntry, realSecondEntry, thirdEntry, originalFilterListEntry)
1113
1114                                         // Add the entry to the allow list.
1115                                         domainAllowList.add(domainTripleEntry)
1116
1117                                         //Log.i("FilterLists", headers.get(1)[0] + " domain allow list added:  " + domain + " , " + firstEntry + " , " + realSecondEntry + " , " + thirdEntry +
1118                                         //        "  -  " + originalFilterListEntry)
1119                                     } else {  // Process a domain allow list double entry.
1120                                         // Create an entry string array.
1121                                         val domainDoubleEntry = arrayOf(domain, firstEntry, secondEntry, originalFilterListEntry)
1122
1123                                         // Add the entry to the allow list.
1124                                         domainAllowList.add(domainDoubleEntry)
1125
1126                                         //Log.i("FilterLists", headers.get(1)[0] + " domain allow list added:  " + domain + " , " + firstEntry + " , " + secondEntry + "  -  " + originalFilterListEntry)
1127                                     }
1128                                 } else {  // Process a domain allow list single entry.
1129                                     // Create an entry string array.
1130                                     val domainEntry = arrayOf(domain, entry, originalFilterListEntry)
1131
1132                                     // Add the entry to the allow list.
1133                                     domainAllowList.add(domainEntry)
1134
1135                                     //Log.i("FilterLists", headers.get(1)[0] + " domain allow list added:  " + domain + " , " + entry + "  -  " + originalFilterListEntry)
1136                                 }
1137                             // Repeat until all the domains have been processed.
1138                             } while (domains.contains("|"))
1139                         } else {  // Domain block list entries.
1140                             // Separate the filters.
1141                             var entry = filterListEntry.substring(0, filterListEntry.indexOf("$"))
1142                             val filters = filterListEntry.substring(filterListEntry.indexOf("$") + 1)
1143                             var domains = filters.substring(filters.indexOf("domain=") + 7)
1144
1145                             // Only process the item if the entry is not empty.  For example, some lines begin with `$websocket`, which create an empty entry.
1146                             if (entry.isNotEmpty()) {
1147                                 // Process each domain.
1148                                 do {
1149                                     // Create a string to keep track of the current domain.
1150                                     var domain: String
1151
1152                                     // Get the first domain.
1153                                     if (domains.contains("|")) {  // There is more than one domain in the list.
1154                                         // Get the first domain from the list.
1155                                         domain = domains.substring(0, domains.indexOf("|"))
1156
1157                                         // Remove the first domain from the list.
1158                                         domains = domains.substring(domains.indexOf("|") + 1)
1159                                     } else {  // There is only one domain in the list.
1160                                         domain = domains
1161                                     }
1162
1163                                     // Process the entry.
1164                                     if (entry.startsWith("|")) {  // Domain initial block list entries.
1165                                         // Remove the initial `|`;
1166                                         entry = entry.substring(1)
1167
1168                                         // Process the entry.
1169                                         if (entry == "http://" || entry == "https://") {
1170                                             // Do nothing.  These entries will entirely block the website.
1171                                             // Often the original entry blocks `$script` but Privacy Browser does not currently differentiate between scripts and other entries.
1172
1173                                             //Log.i("FilterLists", headers.get(1)[0] + " not added:  " + originalFilterListEntry)
1174                                         } else {  // Domain initial block list entry.
1175                                             // Create an entry string array.
1176                                             val domainEntry = arrayOf(domain, entry, originalFilterListEntry)
1177
1178                                             // Add the entry to the block list.
1179                                             domainInitialBlockList.add(domainEntry)
1180
1181                                             //Log.i("FilterLists", headers.get(1)[0] + " domain initial block list added:  " + domain + " , " + entryBase + "  -  " + originalFilterListEntry)
1182                                         }
1183                                     } else if (entry.endsWith("|")) {  // Domain final block list entries.
1184                                         // Remove the final `|`.
1185                                         entry = entry.substring(0, entry.length - 1)
1186
1187                                         // Process the entry.
1188                                         if (entry.contains("*")) {  // Process a domain final block list double entry.
1189                                             // Get the index of the wildcard.
1190                                             val wildcardIndex = entry.indexOf("*")
1191
1192                                             // Split the entry into components.
1193                                             val firstEntry = entry.substring(0, wildcardIndex)
1194                                             val secondEntry = entry.substring(wildcardIndex + 1)
1195
1196                                             // Create an entry string array.
1197                                             val domainDoubleEntry = arrayOf(domain, firstEntry, secondEntry, originalFilterListEntry)
1198
1199                                             // Add the entry to the block list.
1200                                             domainFinalBlockList.add(domainDoubleEntry)
1201
1202                                             //Log.i("FilterLists", headers.get(1)[0] + " domain final block list added:  " + domain + " , " + firstEntry + " , " + secondEntry + "  -  " +
1203                                             //        originalFilterListEntry)
1204                                         } else {  // Domain final block list single entry.
1205                                             // Create an entry string array.
1206                                             val domainEntry = arrayOf(domain, entry, originalFilterListEntry)
1207
1208                                             // Add the entry to the block list.
1209                                             domainFinalBlockList.add(domainEntry)
1210
1211                                             //Log.i("FilterLists", headers.get(1)[0] + " domain final block list added:  " + domain + " , " + entryBase + "  -  " + originalFilterListEntry)
1212                                         }
1213                                     } else if (entry.contains("\\")) {  // Domain regular expression block list entry.
1214                                         // Create an entry string array.
1215                                         val domainEntry = arrayOf(domain, entry, originalFilterListEntry)
1216
1217                                         // Add the entry to the block list.
1218                                         domainRegularExpressionBlockList.add(domainEntry)
1219
1220                                         //Log.i("FilterLists", headers.get(1)[0] + " domain regular expression block list added:  " + domain + " , " + entry + "  -  " + originalFilterListEntry)
1221                                     } else if (entry.contains("*")) {  // There are two or more entries.
1222                                         // Get the index of the wildcard.
1223                                         val wildcardIndex = entry.indexOf("*")
1224
1225                                         // Split the entry into components.
1226                                         val firstEntry = entry.substring(0, wildcardIndex)
1227                                         val secondEntry = entry.substring(wildcardIndex + 1)
1228
1229                                         // Process the second entry.
1230                                         if (secondEntry.contains("*")) {  // Process a domain block list triple entry.
1231                                             // Get the index of the wildcard.
1232                                             val secondWildcardIndex = secondEntry.indexOf("*")
1233
1234                                             // Split the entry into components.
1235                                             val realSecondEntry = secondEntry.substring(0, secondWildcardIndex)
1236                                             val thirdEntry = secondEntry.substring(secondWildcardIndex + 1)
1237
1238                                             // Create an entry string array.
1239                                             val domainTripleEntry = arrayOf(domain, firstEntry, realSecondEntry, thirdEntry, originalFilterListEntry)
1240
1241                                             // Add the entry to the block list.
1242                                             domainBlockList.add(domainTripleEntry)
1243
1244                                             //Log.i("FilterLists", headers.get(1)[0] + " domain block list added:  " + domain + " , " + firstEntry + " , " + realSecondEntry + " , " + thirdEntry +
1245                                             //        "  -  " + originalFilterListEntry)
1246                                         } else {  // Process a domain block list double entry.
1247                                             // Create an entry string array.
1248                                             val domainDoubleEntry = arrayOf(domain, firstEntry, secondEntry, originalFilterListEntry)
1249
1250                                             // Add the entry to the block list.
1251                                             domainBlockList.add(domainDoubleEntry)
1252
1253                                             //Log.i("FilterLists", headers.get(1)[0] + " domain block list added:  " + domain + " , " + firstEntry + " , " + secondEntry + "  -  " +
1254                                             //        originalFilterListEntry)
1255                                         }
1256                                     } else {  // Process a domain block list single entry.
1257                                         // Create an entry string array.
1258                                         val domainEntry = arrayOf(domain, entry, originalFilterListEntry)
1259
1260                                         // Add the entry to the block list.
1261                                         domainBlockList.add(domainEntry)
1262
1263                                         //Log.i("FilterLists", headers.get(1)[0] + " domain block list added:  " + domain + " , " + entry + "  -  " + originalFilterListEntry)
1264                                     }
1265                                 // Repeat until all the domains have been processed.
1266                                 } while (domains.contains("|"))
1267                             }
1268                         }
1269                     } else if (filterListEntry.contains("~")) {  // Allow list entries.  Privacy Browser does not differentiate against these filter options, so they are just generally allowed.
1270                         // Remove the filter options.
1271                         filterListEntry = filterListEntry.substring(0, filterListEntry.indexOf("$"))
1272
1273                         // Strip any trailing `*`.
1274                         if (filterListEntry.endsWith("*"))
1275                             filterListEntry = filterListEntry.substring(0, filterListEntry.length - 1)
1276
1277                         // Process the entry.
1278                         if (filterListEntry.contains("*")) {  // Allow list double entry.
1279                             // Get the index of the wildcard.
1280                             val wildcardIndex = filterListEntry.indexOf("*")
1281
1282                             // Split the entry into components.
1283                             val firstEntry = filterListEntry.substring(0, wildcardIndex)
1284                             val secondEntry = filterListEntry.substring(wildcardIndex + 1)
1285
1286                             // Create an entry string array.
1287                             val doubleEntry = arrayOf(firstEntry, secondEntry, originalFilterListEntry)
1288
1289                             // Add the entry to the allow list.
1290                             mainAllowList.add(doubleEntry)
1291
1292                             //Log.i("FilterLists", headers.get(1)[0] + " main allow list added:  " + firstEntry + " , " + secondEntry + "  -  " + originalFilterListEntry)
1293                         } else {  // Allow list single entry.
1294                             // Create an entry string array.
1295                             val singleEntry = arrayOf(filterListEntry, originalFilterListEntry)
1296
1297                             // Add the entry to the allow list.
1298                             mainAllowList.add(singleEntry)
1299
1300                             //Log.i("FilterLists", headers.get(1)[0] + " main allow list added:  " + filterListEntry + "  -  + " + originalFilterListEntry)
1301                         }
1302                     } else if (filterListEntry.contains("\\")) {  // Regular expression block list entry.
1303                         // Remove the filter options.
1304                         filterListEntry = filterListEntry.substring(0, filterListEntry.indexOf("$"))
1305
1306                         // Create an entry string array.
1307                         val singleEntry = arrayOf(filterListEntry, originalFilterListEntry)
1308
1309                         // Add the entry to the block list.
1310                         regularExpressionBlockList.add(singleEntry)
1311
1312                         //Log.i("FilterLists", headers.get(1)[0] + " regular expression block list added: " + filterListEntry + "  -  " + originalFilterListEntry);
1313                     } else {  // Block list entries.
1314                         // Remove the filter options.
1315                         if (!filterListEntry.contains("\$file"))  // EasyPrivacy contains an entry with `$file` that does not have filter options.
1316                             filterListEntry = filterListEntry.substring(0, filterListEntry.indexOf("$"))
1317
1318                         // Strip any trailing `*`.  These are redundant.
1319                         if (filterListEntry.endsWith("*"))
1320                             filterListEntry = filterListEntry.substring(0, filterListEntry.length - 1)
1321
1322                         // Process the entry.
1323                         if (filterListEntry.startsWith("|")) {  // Initial block list entries.
1324                             // Strip the initial `|`.
1325                             val entry = filterListEntry.substring(1)
1326
1327                             if (entry.contains("*")) {  // Process an initial block list double entry.
1328                                 // Get the index of the wildcard.
1329                                 val wildcardIndex = entry.indexOf("*")
1330
1331                                 // Split the entry into components.
1332                                 val firstEntry = entry.substring(0, wildcardIndex)
1333                                 val secondEntry = entry.substring(wildcardIndex + 1)
1334
1335                                 // Create an entry string array.
1336                                 val doubleEntry = arrayOf(firstEntry, secondEntry, originalFilterListEntry)
1337
1338                                 // Add the entry to the block list.
1339                                 initialBlockList.add(doubleEntry)
1340
1341                                 //Log.i("FilterLists", headers.get(1)[0] + " initial block list added:  " + firstEntry + " , " + secondEntry + "  -  " + originalFilterListEntry)
1342                             } else {  // Initial blocklist single entry.
1343                                 // Create an entry string array.
1344                                 val singleEntry = arrayOf(entry, originalFilterListEntry)
1345
1346                                 // Add the entry to the block list.
1347                                 initialBlockList.add(singleEntry)
1348
1349                                 //Log.i("FilterLists", headers.get(1)[0] + " initial block list added:  " + entry + "  -  " + originalFilterListEntry)
1350                             }
1351                         } else if (filterListEntry.endsWith("|")) {  // Final block list entries.
1352                             // Ignore entries with `object` filters.  They can block entire websites and don't have any meaning in the context of Privacy Browser.
1353                             if (!originalFilterListEntry.contains("\$object")) {
1354                                 // Strip the final `|`.
1355                                 val entry = filterListEntry.substring(0, filterListEntry.length - 1)
1356
1357                                 // Process the entry.
1358                                 if (entry.contains("*")) {  // There are two or more entries.
1359                                     // Get the index of the wildcard.
1360                                     val wildcardIndex = entry.indexOf("*")
1361
1362                                     // Split the entry into components.
1363                                     val firstEntry = entry.substring(0, wildcardIndex)
1364                                     val secondEntry = entry.substring(wildcardIndex + 1)
1365
1366                                     // Process the second entry.
1367                                     if (secondEntry.contains("*")) {  // Final block list triple entry.
1368                                         // Get the index of the wildcard.
1369                                         val secondWildcardIndex = secondEntry.indexOf("*")
1370
1371                                         // Split the entry into components.
1372                                         val realSecondEntry = secondEntry.substring(0, secondWildcardIndex)
1373                                         val thirdEntry = secondEntry.substring(secondWildcardIndex + 1)
1374
1375                                         // Create an entry string array.
1376                                         val tripleEntry = arrayOf(firstEntry, realSecondEntry, thirdEntry, originalFilterListEntry)
1377
1378                                         // Add the entry to the block list.
1379                                         finalBlockList.add(tripleEntry)
1380
1381                                         //Log.i("FilterLists", headers.get(1)[0] + " final block list added:  " + firstEntry + " , " + realSecondEntry + " , " + thirdEntry + "  -  " + originalFilterListEntry)
1382                                     } else {  // Final block list double entry.
1383                                         // Create an entry string array.
1384                                         val doubleEntry = arrayOf(firstEntry, secondEntry, originalFilterListEntry)
1385
1386                                         // Add the entry to the block list.
1387                                         finalBlockList.add(doubleEntry)
1388
1389                                         //Log.i("FilterLists", headers.get(1)[0] + " final block list added:  " + firstEntry + " , " + secondEntry + "  -  " + originalFilterListEntry)
1390                                     }
1391                                 } else {  // Final block list single entry.
1392                                     // Create an entry sting array.
1393                                     val singleEntry = arrayOf(entry, originalFilterListEntry)
1394
1395                                     // Add the entry to the block list.
1396                                     finalBlockList.add(singleEntry)
1397
1398                                     //Log.i("FilterLists", headers.get(1)[0] + " final block list added:  " + entry + "  -  " + originalFilterListEntry)
1399                                 }
1400                             }
1401                         } else if (filterListEntry.contains("*")) {  // There are two or more entries.
1402                             // Get the index of the wildcard.
1403                             val wildcardIndex = filterListEntry.indexOf("*")
1404
1405                             // Split the entry into components.
1406                             val firstEntry = filterListEntry.substring(0, wildcardIndex)
1407                             val secondEntry = filterListEntry.substring(wildcardIndex + 1)
1408
1409                             // Process the second entry.
1410                             if (secondEntry.contains("*")) {  // Main block list triple entry.
1411                                 // Get the index of the wildcard.
1412                                 val secondWildcardIndex = secondEntry.indexOf("*")
1413
1414                                 // Split the entry into components.
1415                                 val realSecondEntry = secondEntry.substring(0, secondWildcardIndex)
1416                                 val thirdEntry = secondEntry.substring(secondWildcardIndex + 1)
1417
1418                                 // Create an entry string array.
1419                                 val tripleEntry = arrayOf(firstEntry, realSecondEntry, thirdEntry, originalFilterListEntry)
1420
1421                                 // Add the entry to the block list.
1422                                 mainBlockList.add(tripleEntry)
1423
1424                                 //Log.i("FilterLists", headers.get(1)[0] + " main block list added:  " + firstEntry + " , " + realSecondEntry + " , " + thirdEntry + "  -  " + originalFilterListEntry)
1425                             } else {  // Main block list double entry.
1426                                 // Create an entry string array.
1427                                 val doubleEntry = arrayOf(firstEntry, secondEntry, originalFilterListEntry)
1428
1429                                 // Add the entry to the block list.
1430                                 mainBlockList.add(doubleEntry)
1431
1432                                 //Log.i("FilterLists", headers.get(1)[0] + " main block list added:  " + firstEntry + " , " + secondEntry + "  -  " + originalFilterListEntry)
1433                             }
1434                         } else if (filterListEntry.isNotBlank()){  // Main block list single entry.
1435                             // Create an entry string array.
1436                             val singleEntry = arrayOf(filterListEntry, originalFilterListEntry)
1437
1438                             // Add the entry to the block list.
1439                             mainBlockList.add(singleEntry)
1440
1441                             //Log.i("FilterLists", headers.get(1)[0] + " main block list added:  " + filterListEntry + "  -  " + originalFilterListEntry)
1442                         } else {  // The entry is blank (empty or all white spaces).
1443                             // Do nothing.
1444
1445                             //Log.i("FilterLists", "${headers[1][0]} not added:  $filterListEntry,  $originalFilterListEntry")
1446                         }
1447                     }
1448                 } else {  // Main block list entries.
1449                     // Strip out any initial `||`.  These will be treated like any other entry.
1450                     if (filterListEntry.startsWith("||"))
1451                         filterListEntry = filterListEntry.substring(2)
1452
1453                     // Strip out any initial `*`.
1454                     if (filterListEntry.startsWith("*"))
1455                         filterListEntry = filterListEntry.substring(1)
1456
1457                     // Strip out any trailing `*`.
1458                     if (filterListEntry.endsWith("*"))
1459                         filterListEntry = filterListEntry.substring(0, filterListEntry.length - 1)
1460
1461                     // Process the entry.
1462                     if (filterListEntry.startsWith("|")) {  // Initial block list entries.
1463                         // Strip the initial `|`.
1464                         val entry = filterListEntry.substring(1)
1465
1466                         // Process the entry.
1467                         if (entry.contains("*")) {  // Initial block list double entry.
1468                             // Get the index of the wildcard.
1469                             val wildcardIndex = entry.indexOf("*")
1470
1471                             // Split the entry into components.
1472                             val firstEntry = entry.substring(0, wildcardIndex)
1473                             val secondEntry = entry.substring(wildcardIndex + 1)
1474
1475                             // Create an entry string array.
1476                             val doubleEntry = arrayOf(firstEntry, secondEntry, originalFilterListEntry)
1477
1478                             // Add the entry to the block list.
1479                             initialBlockList.add(doubleEntry)
1480
1481                             //Log.i("FilterLists", headers.get(1)[0] + " initial block list added:  " + firstEntry + " , " + secondEntry + "  -  " + originalFilterListEntry)
1482                         } else {  // Initial block list single entry.
1483                             // Create an entry string array.
1484                             val singleEntry = arrayOf(entry, originalFilterListEntry)
1485
1486                             // Add the entry to the block list.
1487                             initialBlockList.add(singleEntry)
1488
1489                             //Log.i("FilterLists", headers.get(1)[0] + " initial block list added:  " + entry + "  -  " + originalFilterListEntry)
1490                         }
1491                     } else if (filterListEntry.endsWith("|")) {  // Final block list entries.
1492                         // Strip the final `|`.
1493                         val entry = filterListEntry.substring(0, filterListEntry.length - 1)
1494
1495                         // Process the entry.
1496                         if (entry.contains("*")) {  // There are two or more entries.
1497                             // Get the index of the wildcard.
1498                             val wildcardIndex = entry.indexOf("*")
1499
1500                             // Split the entry into components.
1501                             val firstEntry = entry.substring(0, wildcardIndex)
1502                             val secondEntry = entry.substring(wildcardIndex + 1)
1503
1504                             // Process the second entry.
1505                             if (secondEntry.contains("*")) {  // Final block list triple entry.
1506                                 // Get the index of the wildcard.
1507                                 val secondWildcardIndex = secondEntry.indexOf("*")
1508
1509                                 // Split the entry into components.
1510                                 val realSecondEntry = secondEntry.substring(0, secondWildcardIndex)
1511                                 val thirdEntry = secondEntry.substring(secondWildcardIndex + 1)
1512
1513                                 // Create an entry string array.
1514                                 val tripleEntry = arrayOf(firstEntry, realSecondEntry, thirdEntry, originalFilterListEntry)
1515
1516                                 // Add the entry to the block list.
1517                                 finalBlockList.add(tripleEntry)
1518
1519                                 //Log.i("FilterLists", headers.get(1)[0] + " final block list added:  " + firstEntry + " , " + realSecondEntry + " , " + thirdEntry + "  -  " + originalFilterListEntry)
1520                             } else {  // Final block list double entry.
1521                                 // Create an entry string array.
1522                                 val doubleEntry = arrayOf(firstEntry, secondEntry, originalFilterListEntry)
1523
1524                                 // Add the entry to the block list.
1525                                 finalBlockList.add(doubleEntry)
1526
1527                                 //Log.i("FilterLists", headers.get(1)[0] + " final block list added:  " + firstEntry + " , " + secondEntry + "  -  " + originalFilterListEntry)
1528                             }
1529                         } else {  // Final block list single entry.
1530                             // Create an entry string array.
1531                             val singleEntry = arrayOf(entry, originalFilterListEntry)
1532
1533                             // Add the entry to the block list.
1534                             finalBlockList.add(singleEntry)
1535
1536                             //Log.i("FilterLists", headers.get(1)[0] + " final block list added:  " + entry + "  -  " + originalFilterListEntry)
1537                         }
1538                     } else {  // Main block list entries.
1539                         if (filterListEntry.contains("*")) {  // There are two or more entries.
1540                             // Get the index of the wildcard.
1541                             val wildcardIndex = filterListEntry.indexOf("*")
1542
1543                             // Split the entry into components.
1544                             val firstEntry = filterListEntry.substring(0, wildcardIndex)
1545                             val secondEntry = filterListEntry.substring(wildcardIndex + 1)
1546
1547                             // Process the second entry.
1548                             if (secondEntry.contains("*")) {  // There are three or more entries.
1549                                 // Get the index of the wildcard.
1550                                 val secondWildcardIndex = secondEntry.indexOf("*")
1551
1552                                 // Split the entry into components.
1553                                 val realSecondEntry = secondEntry.substring(0, secondWildcardIndex)
1554                                 val thirdEntry = secondEntry.substring(secondWildcardIndex + 1)
1555
1556                                 // Process the third entry.
1557                                 if (thirdEntry.contains("*")) {  // There are four or more entries.
1558                                     // Get the index of the wildcard.
1559                                     val thirdWildcardIndex = thirdEntry.indexOf("*")
1560
1561                                     // Split the entry into components.
1562                                     val realThirdEntry = thirdEntry.substring(0, thirdWildcardIndex)
1563                                     val fourthEntry = thirdEntry.substring(thirdWildcardIndex + 1)
1564
1565                                     // Process the fourth entry.
1566                                     if (fourthEntry.contains("*")) {  // Main block list quintuple entry.
1567                                         // Get the index of the wildcard.
1568                                         val fourthWildcardIndex = fourthEntry.indexOf("*")
1569
1570                                         // Split the entry into components.
1571                                         val realFourthEntry = fourthEntry.substring(0, fourthWildcardIndex)
1572                                         val fifthEntry = fourthEntry.substring(fourthWildcardIndex + 1)
1573
1574                                         // Create an entry string array.
1575                                         val quintupleEntry = arrayOf(firstEntry, realSecondEntry, realThirdEntry, realFourthEntry, fifthEntry, originalFilterListEntry)
1576
1577                                         // Add the entry to the block list.
1578                                         mainBlockList.add(quintupleEntry)
1579
1580                                         //Log.i("FilterLists", headers.get(1)[0] + " main block list added:  " + firstEntry + " , " + realSecondEntry + " , " + realThirdEntry + " , " + realFourthEntry + " , " +
1581                                         //      fifthEntry + "  -  " + originalFilterListEntry)
1582                                     } else {  // Main block list quadruple entry.
1583                                         // Create an entry string array.
1584                                         val quadrupleEntry = arrayOf(firstEntry, realSecondEntry, realThirdEntry, fourthEntry, originalFilterListEntry)
1585
1586                                         // Add the entry to the block list.
1587                                         mainBlockList.add(quadrupleEntry)
1588
1589                                         //Log.i("FilterLists", headers.get(1)[0] + " main block list added:  " + firstEntry + " , " + realSecondEntry + " , " + realThirdEntry + " , " + fourthEntry + "  -  " +
1590                                         //      originalFilterListEntry)
1591                                     }
1592                                 } else {  // Main block list triple entry.
1593                                     // Create an entry string array.
1594                                     val tripleEntry = arrayOf(firstEntry, realSecondEntry, thirdEntry, originalFilterListEntry)
1595
1596                                     // Add the entry to the block list.
1597                                     mainBlockList.add(tripleEntry)
1598
1599                                     //Log.i("FilterLists", headers.get(1)[0] + " main block list added:  " + firstEntry + " , " + realSecondEntry + " , " + thirdEntry + "  -  " + originalFilterListEntry)
1600                                 }
1601                             } else {  // Main block list double entry.
1602                                 // Create an entry string array.
1603                                 val doubleEntry = arrayOf(firstEntry, secondEntry, originalFilterListEntry)
1604
1605                                 // Add the entry to the block list.
1606                                 mainBlockList.add(doubleEntry)
1607
1608                                 //Log.i("FilterLists", headers.get(1)[0] + " main block list added:  " + firstEntry + " , " + secondEntry + "  -  " + originalFilterListEntry)
1609                             }
1610                         } else if (filterListEntry.isNotBlank()){  // Main block list single entry.
1611                             // Create an entry string array.
1612                             val singleEntry = arrayOf(filterListEntry, originalFilterListEntry)
1613
1614                             // Add the entry to the block list.
1615                             mainBlockList.add(singleEntry)
1616
1617                             //Log.i("FilterLists", headers.get(1)[0] + " main block list added:  " + filterListEntry + "  -  " + originalFilterListEntry)
1618                         } else {  // The entry is blank (empty or all white spaces).
1619                             // Do nothing.
1620
1621                             //Log.i("FilterLists", "${headers[1][0]} not added:  $filterListEntry,  $originalFilterListEntry")
1622                         }
1623                     }
1624                 }
1625             }
1626             // Close the buffered reader.
1627             bufferedReader.close()
1628         } catch (e: IOException) {
1629             // Do nothing.
1630         }
1631
1632         // Initialize the combined list.
1633         val combinedLists = ArrayList<List<Array<String>>>()
1634
1635         // Add the headers (0).
1636         combinedLists.add(headers) // 0.
1637
1638         // Add the allow lists (1-8).
1639         combinedLists.add(mainAllowList) // 1.
1640         combinedLists.add(finalAllowList) // 2.
1641         combinedLists.add(domainAllowList) // 3.
1642         combinedLists.add(domainInitialAllowList) // 4.
1643         combinedLists.add(domainFinalAllowList) // 5.
1644         combinedLists.add(thirdPartyAllowList) // 6.
1645         combinedLists.add(thirdPartyDomainAllowList) // 7.
1646         combinedLists.add(thirdPartyDomainInitialAllowList) // 8.
1647
1648         // Add the block lists (9-22).
1649         combinedLists.add(mainBlockList) // 9.
1650         combinedLists.add(initialBlockList) // 10.
1651         combinedLists.add(finalBlockList) // 11.
1652         combinedLists.add(domainBlockList) //  12.
1653         combinedLists.add(domainInitialBlockList) // 13.
1654         combinedLists.add(domainFinalBlockList) // 14.
1655         combinedLists.add(domainRegularExpressionBlockList) // 15.
1656         combinedLists.add(thirdPartyBlockList) // 16.
1657         combinedLists.add(thirdPartyInitialBlockList) // 17.
1658         combinedLists.add(thirdPartyDomainBlockList) // 18.
1659         combinedLists.add(thirdPartyDomainInitialBlockList) // 19.
1660         combinedLists.add(thirdPartyRegularExpressionBlockList) // 20.
1661         combinedLists.add(thirdPartyDomainRegularExpressionBlockList) // 21.
1662         combinedLists.add(regularExpressionBlockList) // 22.
1663
1664         // Return the combined lists.
1665         return combinedLists
1666     }
1667 }