From 8e6a6aae09959f9a215e08fea2d293c6b840f53c Mon Sep 17 00:00:00 2001 From: Kevin Pham Date: Thu, 7 Dec 2023 21:39:48 -0600 Subject: [PATCH 01/10] fix tailwind css builder for github action --- .github/workflows/build-css.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-css.yaml b/.github/workflows/build-css.yaml index ced8ee6..8d8fa70 100644 --- a/.github/workflows/build-css.yaml +++ b/.github/workflows/build-css.yaml @@ -37,7 +37,7 @@ jobs: echo "Changes detected, committing..." git config --global user.name "Github action" git config --global user.email "username@users.noreply.github.com" - git add cmd + git add handlers git commit -m "Generated stylesheet" git push fi From 7661c66250dc94e4dc274973e998eeed8d109853 Mon Sep 17 00:00:00 2001 From: ladddder <151469127+ladddder@users.noreply.github.com> Date: Fri, 8 Dec 2023 09:26:26 +0100 Subject: [PATCH 02/10] #65 use full URL in package line --- cmd/main.go | 9 +++++---- go.mod | 2 +- handlers/api_content.go | 7 ++++--- handlers/api_modifiers.go | 3 ++- handlers/api_modifiers_codegen/api_modifiers_codegen.go | 2 +- handlers/api_modifiers_structdef.gen.go | 2 +- handlers/api_raw.go | 7 ++++--- handlers/outline.go | 7 ++++--- handlers/proxy.go | 9 +++++---- internal/cli/ruleset_merge.go | 2 +- proxychain/codegen/codegen.go | 8 ++++---- proxychain/requestmodifiers/add_cache_buster_query.go | 3 ++- proxychain/requestmodifiers/forward_request_headers.go | 2 +- proxychain/requestmodifiers/masquerade_as_trusted_bot.go | 5 +++-- proxychain/requestmodifiers/modify_domain_with_regex.go | 2 +- proxychain/requestmodifiers/modify_outgoing_cookies.go | 2 +- proxychain/requestmodifiers/modify_path_with_regex.go | 2 +- proxychain/requestmodifiers/modify_query_params.go | 2 +- proxychain/requestmodifiers/modify_request_headers.go | 2 +- proxychain/requestmodifiers/request_archive_is.go | 5 +++-- proxychain/requestmodifiers/request_google_cache.go | 2 +- proxychain/requestmodifiers/request_wayback_machine.go | 5 +++-- proxychain/requestmodifiers/resolve_with_google_doh.go | 2 +- proxychain/requestmodifiers/spoof_origin.go | 2 +- proxychain/requestmodifiers/spoof_referrer.go | 5 +++-- .../requestmodifiers/spoof_referrer_from_baidu_post.go | 2 +- .../requestmodifiers/spoof_referrer_from_bing_search.go | 2 +- .../spoof_referrer_from_google_search.go | 2 +- .../spoof_referrer_from_linkedin_post.go | 2 +- .../requestmodifiers/spoof_referrer_from_naver_post.go | 2 +- .../spoof_referrer_from_pinterest_post.go | 2 +- .../requestmodifiers/spoof_referrer_from_qq_post.go | 2 +- .../requestmodifiers/spoof_referrer_from_reddit_post.go | 2 +- .../requestmodifiers/spoof_referrer_from_tumblr_post.go | 2 +- .../requestmodifiers/spoof_referrer_from_twitter_post.go | 2 +- .../spoof_referrer_from_vkontake_post.go | 2 +- .../requestmodifiers/spoof_referrer_from_weibo_post.go | 2 +- proxychain/requestmodifiers/spoof_user_agent.go | 5 +++-- proxychain/requestmodifiers/spoof_x_forwarded_for.go | 2 +- proxychain/responsemodifiers/api_content.go | 5 +++-- proxychain/responsemodifiers/api_content_test.go | 2 +- proxychain/responsemodifiers/block_element_removal.go | 5 +++-- .../responsemodifiers/block_third_party_scripts.go | 5 +++-- proxychain/responsemodifiers/bypass_cors.go | 2 +- proxychain/responsemodifiers/bypass_csp.go | 2 +- proxychain/responsemodifiers/delete_localstorage_data.go | 2 +- .../responsemodifiers/delete_sessionstorage_data.go | 2 +- proxychain/responsemodifiers/forward_response_headers.go | 2 +- .../responsemodifiers/generate_readable_outline.go | 2 +- proxychain/responsemodifiers/inject_script.go | 5 +++-- proxychain/responsemodifiers/modify_incoming_cookies.go | 2 +- proxychain/responsemodifiers/modify_response_header.go | 2 +- .../responsemodifiers/patch_dynamic_resource_urls.go | 5 +++-- proxychain/responsemodifiers/patch_tracker_scripts.go | 2 +- .../responsemodifiers/rewrite_http_resource_urls.go | 5 +++-- proxychain/ruleset/rule.go | 2 +- proxychain/ruleset/rule_reqmod_types.gen.go | 4 ++-- proxychain/ruleset/rule_resmod_types.gen.go | 4 ++-- 58 files changed, 104 insertions(+), 86 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index 997b655..5820a46 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -7,10 +7,11 @@ import ( "log" "os" - "ladder/handlers" - "ladder/internal/cli" - "ladder/proxychain/requestmodifiers/bot" - "ladder/proxychain/ruleset" + "github.com/everywall/ladder/handlers" + "github.com/everywall/ladder/internal/cli" + + "github.com/everywall/ladder/proxychain/requestmodifiers/bot" + ruleset_v2 "github.com/everywall/ladder/proxychain/ruleset" "github.com/akamensky/argparse" "github.com/gofiber/fiber/v2" diff --git a/go.mod b/go.mod index 52de4ce..15fb7f3 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module ladder +module github.com/everywall/ladder go 1.21.1 diff --git a/handlers/api_content.go b/handlers/api_content.go index bf495b4..306cbad 100644 --- a/handlers/api_content.go +++ b/handlers/api_content.go @@ -1,9 +1,10 @@ package handlers import ( - "ladder/proxychain" - rx "ladder/proxychain/requestmodifiers" - tx "ladder/proxychain/responsemodifiers" + rx "github.com/everywall/ladder/proxychain/requestmodifiers" + tx "github.com/everywall/ladder/proxychain/responsemodifiers" + + "github.com/everywall/ladder/proxychain" "github.com/gofiber/fiber/v2" ) diff --git a/handlers/api_modifiers.go b/handlers/api_modifiers.go index 6242536..cb30df5 100644 --- a/handlers/api_modifiers.go +++ b/handlers/api_modifiers.go @@ -2,8 +2,9 @@ package handlers import ( "encoding/json" + + "github.com/everywall/ladder/proxychain/responsemodifiers/api" "github.com/gofiber/fiber/v2" - "ladder/proxychain/responsemodifiers/api" ) func NewAPIModifersListHandler(opts *ProxyOptions) fiber.Handler { diff --git a/handlers/api_modifiers_codegen/api_modifiers_codegen.go b/handlers/api_modifiers_codegen/api_modifiers_codegen.go index 22edc01..c3c3a44 100644 --- a/handlers/api_modifiers_codegen/api_modifiers_codegen.go +++ b/handlers/api_modifiers_codegen/api_modifiers_codegen.go @@ -146,7 +146,7 @@ package handlers // for use in proxychains. import ( - "ladder/proxychain/responsemodifiers/api" + "github.com/everywall/ladder/proxychain/responsemodifiers/api" ) type ModifiersAPIResponse struct { diff --git a/handlers/api_modifiers_structdef.gen.go b/handlers/api_modifiers_structdef.gen.go index ae24f52..64e5ac1 100644 --- a/handlers/api_modifiers_structdef.gen.go +++ b/handlers/api_modifiers_structdef.gen.go @@ -5,7 +5,7 @@ package handlers // for use in proxychains. import ( - "ladder/proxychain/responsemodifiers/api" + "github.com/everywall/ladder/proxychain/responsemodifiers/api" ) type ModifiersAPIResponse struct { diff --git a/handlers/api_raw.go b/handlers/api_raw.go index 3895a1e..c6327af 100644 --- a/handlers/api_raw.go +++ b/handlers/api_raw.go @@ -1,9 +1,10 @@ package handlers import ( - "ladder/proxychain" - rx "ladder/proxychain/requestmodifiers" - tx "ladder/proxychain/responsemodifiers" + rx "github.com/everywall/ladder/proxychain/requestmodifiers" + tx "github.com/everywall/ladder/proxychain/responsemodifiers" + + "github.com/everywall/ladder/proxychain" "github.com/gofiber/fiber/v2" ) diff --git a/handlers/outline.go b/handlers/outline.go index 2960bd0..6fec17b 100644 --- a/handlers/outline.go +++ b/handlers/outline.go @@ -1,9 +1,10 @@ package handlers import ( - "ladder/proxychain" - rx "ladder/proxychain/requestmodifiers" - tx "ladder/proxychain/responsemodifiers" + rx "github.com/everywall/ladder/proxychain/requestmodifiers" + tx "github.com/everywall/ladder/proxychain/responsemodifiers" + + "github.com/everywall/ladder/proxychain" "github.com/gofiber/fiber/v2" ) diff --git a/handlers/proxy.go b/handlers/proxy.go index 5984267..d08fe30 100644 --- a/handlers/proxy.go +++ b/handlers/proxy.go @@ -1,10 +1,11 @@ package handlers import ( - "ladder/proxychain" - rx "ladder/proxychain/requestmodifiers" - tx "ladder/proxychain/responsemodifiers" - "ladder/proxychain/ruleset" + rx "github.com/everywall/ladder/proxychain/requestmodifiers" + tx "github.com/everywall/ladder/proxychain/responsemodifiers" + + "github.com/everywall/ladder/proxychain" + ruleset_v2 "github.com/everywall/ladder/proxychain/ruleset" "github.com/gofiber/fiber/v2" ) diff --git a/internal/cli/ruleset_merge.go b/internal/cli/ruleset_merge.go index 2a7a75d..40999c6 100644 --- a/internal/cli/ruleset_merge.go +++ b/internal/cli/ruleset_merge.go @@ -5,7 +5,7 @@ import ( "io" "os" - "ladder/proxychain/ruleset" + ruleset_v2 "github.com/everywall/ladder/proxychain/ruleset" ) // HandleRulesetMerge merges a set of ruleset files, specified by the rulesetPath or RULESET env variable, into either YAML or Gzip format. diff --git a/proxychain/codegen/codegen.go b/proxychain/codegen/codegen.go index dacca5a..6d1292f 100644 --- a/proxychain/codegen/codegen.go +++ b/proxychain/codegen/codegen.go @@ -70,8 +70,8 @@ package ruleset_v2 // for use in proxychains. import ( - "ladder/proxychain" - tx "ladder/proxychain/responsemodifiers" + "github.com/everywall/ladder/proxychain" + tx "github.com/everywall/ladder/proxychain/responsemodifiers" ) type ResponseModifierFactory func(params ...string) proxychain.ResponseModification @@ -142,8 +142,8 @@ package ruleset_v2 // for use in proxychains. import ( - "ladder/proxychain" - rx "ladder/proxychain/requestmodifiers" + "github.com/everywall/ladder/proxychain" + rx "github.com/everywall/ladder/proxychain/requestmodifiers" ) type RequestModifierFactory func(params ...string) proxychain.RequestModification diff --git a/proxychain/requestmodifiers/add_cache_buster_query.go b/proxychain/requestmodifiers/add_cache_buster_query.go index e60f2e0..d36fdd3 100644 --- a/proxychain/requestmodifiers/add_cache_buster_query.go +++ b/proxychain/requestmodifiers/add_cache_buster_query.go @@ -1,8 +1,9 @@ package requestmodifiers import ( - "ladder/proxychain" "math/rand" + + "github.com/everywall/ladder/proxychain" ) // AddCacheBusterQuery modifies query params to add a random parameter key diff --git a/proxychain/requestmodifiers/forward_request_headers.go b/proxychain/requestmodifiers/forward_request_headers.go index 41a2cfd..1e8a439 100644 --- a/proxychain/requestmodifiers/forward_request_headers.go +++ b/proxychain/requestmodifiers/forward_request_headers.go @@ -3,7 +3,7 @@ package requestmodifiers import ( "strings" //"fmt" - "ladder/proxychain" + "github.com/everywall/ladder/proxychain" ) var forwardBlacklist map[string]bool diff --git a/proxychain/requestmodifiers/masquerade_as_trusted_bot.go b/proxychain/requestmodifiers/masquerade_as_trusted_bot.go index b29159d..eb8db8d 100644 --- a/proxychain/requestmodifiers/masquerade_as_trusted_bot.go +++ b/proxychain/requestmodifiers/masquerade_as_trusted_bot.go @@ -1,8 +1,9 @@ package requestmodifiers import ( - "ladder/proxychain" - "ladder/proxychain/requestmodifiers/bot" + "github.com/everywall/ladder/proxychain/requestmodifiers/bot" + + "github.com/everywall/ladder/proxychain" ) // MasqueradeAsGoogleBot modifies user agent and x-forwarded for diff --git a/proxychain/requestmodifiers/modify_domain_with_regex.go b/proxychain/requestmodifiers/modify_domain_with_regex.go index 47db02e..21ea69e 100644 --- a/proxychain/requestmodifiers/modify_domain_with_regex.go +++ b/proxychain/requestmodifiers/modify_domain_with_regex.go @@ -4,7 +4,7 @@ import ( "fmt" "regexp" - "ladder/proxychain" + "github.com/everywall/ladder/proxychain" ) func ModifyDomainWithRegex(matchRegex string, replacement string) proxychain.RequestModification { diff --git a/proxychain/requestmodifiers/modify_outgoing_cookies.go b/proxychain/requestmodifiers/modify_outgoing_cookies.go index e1415a8..71869ec 100644 --- a/proxychain/requestmodifiers/modify_outgoing_cookies.go +++ b/proxychain/requestmodifiers/modify_outgoing_cookies.go @@ -5,7 +5,7 @@ import ( //http "github.com/Danny-Dasilva/fhttp" http "github.com/bogdanfinn/fhttp" - "ladder/proxychain" + "github.com/everywall/ladder/proxychain" ) // SetOutgoingCookie modifes a specific cookie name diff --git a/proxychain/requestmodifiers/modify_path_with_regex.go b/proxychain/requestmodifiers/modify_path_with_regex.go index c2514a3..2c0f20b 100644 --- a/proxychain/requestmodifiers/modify_path_with_regex.go +++ b/proxychain/requestmodifiers/modify_path_with_regex.go @@ -4,7 +4,7 @@ import ( "fmt" "regexp" - "ladder/proxychain" + "github.com/everywall/ladder/proxychain" ) func ModifyPathWithRegex(matchRegex string, replacement string) proxychain.RequestModification { diff --git a/proxychain/requestmodifiers/modify_query_params.go b/proxychain/requestmodifiers/modify_query_params.go index afdad39..681ce8b 100644 --- a/proxychain/requestmodifiers/modify_query_params.go +++ b/proxychain/requestmodifiers/modify_query_params.go @@ -4,7 +4,7 @@ import ( //"fmt" "net/url" - "ladder/proxychain" + "github.com/everywall/ladder/proxychain" ) // ModifyQueryParams replaces query parameter values in URL's query params in a ProxyChain's URL. diff --git a/proxychain/requestmodifiers/modify_request_headers.go b/proxychain/requestmodifiers/modify_request_headers.go index 8c60e24..8938fa9 100644 --- a/proxychain/requestmodifiers/modify_request_headers.go +++ b/proxychain/requestmodifiers/modify_request_headers.go @@ -1,7 +1,7 @@ package requestmodifiers import ( - "ladder/proxychain" + "github.com/everywall/ladder/proxychain" ) // SetRequestHeader modifies a specific outgoing header diff --git a/proxychain/requestmodifiers/request_archive_is.go b/proxychain/requestmodifiers/request_archive_is.go index 90956e9..625925a 100644 --- a/proxychain/requestmodifiers/request_archive_is.go +++ b/proxychain/requestmodifiers/request_archive_is.go @@ -5,8 +5,9 @@ import ( "net/url" "regexp" - "ladder/proxychain" - tx "ladder/proxychain/responsemodifiers" + tx "github.com/everywall/ladder/proxychain/responsemodifiers" + + "github.com/everywall/ladder/proxychain" ) const archivistUrl string = "https://archive.is/latest" diff --git a/proxychain/requestmodifiers/request_google_cache.go b/proxychain/requestmodifiers/request_google_cache.go index 457ed66..6baa1de 100644 --- a/proxychain/requestmodifiers/request_google_cache.go +++ b/proxychain/requestmodifiers/request_google_cache.go @@ -3,7 +3,7 @@ package requestmodifiers import ( "net/url" - "ladder/proxychain" + "github.com/everywall/ladder/proxychain" ) const googleCacheUrl string = "https://webcache.googleusercontent.com/search?q=cache:" diff --git a/proxychain/requestmodifiers/request_wayback_machine.go b/proxychain/requestmodifiers/request_wayback_machine.go index 92b9e97..81ead32 100644 --- a/proxychain/requestmodifiers/request_wayback_machine.go +++ b/proxychain/requestmodifiers/request_wayback_machine.go @@ -4,8 +4,9 @@ import ( "net/url" "regexp" - "ladder/proxychain" - tx "ladder/proxychain/responsemodifiers" + tx "github.com/everywall/ladder/proxychain/responsemodifiers" + + "github.com/everywall/ladder/proxychain" ) const waybackUrl string = "https://web.archive.org/web/" diff --git a/proxychain/requestmodifiers/resolve_with_google_doh.go b/proxychain/requestmodifiers/resolve_with_google_doh.go index c94ac5b..0a69870 100644 --- a/proxychain/requestmodifiers/resolve_with_google_doh.go +++ b/proxychain/requestmodifiers/resolve_with_google_doh.go @@ -14,7 +14,7 @@ import ( //"net/http" */ - "ladder/proxychain" + "github.com/everywall/ladder/proxychain" ) // resolveWithGoogleDoH resolves DNS using Google's DNS-over-HTTPS diff --git a/proxychain/requestmodifiers/spoof_origin.go b/proxychain/requestmodifiers/spoof_origin.go index bf54844..b871048 100644 --- a/proxychain/requestmodifiers/spoof_origin.go +++ b/proxychain/requestmodifiers/spoof_origin.go @@ -1,7 +1,7 @@ package requestmodifiers import ( - "ladder/proxychain" + "github.com/everywall/ladder/proxychain" ) // SpoofOrigin modifies the origin header diff --git a/proxychain/requestmodifiers/spoof_referrer.go b/proxychain/requestmodifiers/spoof_referrer.go index 775fc56..4735bf3 100644 --- a/proxychain/requestmodifiers/spoof_referrer.go +++ b/proxychain/requestmodifiers/spoof_referrer.go @@ -3,8 +3,9 @@ package requestmodifiers import ( "fmt" - "ladder/proxychain" - tx "ladder/proxychain/responsemodifiers" + tx "github.com/everywall/ladder/proxychain/responsemodifiers" + + "github.com/everywall/ladder/proxychain" ) // SpoofReferrer modifies the referrer header. diff --git a/proxychain/requestmodifiers/spoof_referrer_from_baidu_post.go b/proxychain/requestmodifiers/spoof_referrer_from_baidu_post.go index 2c849b9..aa9aaed 100644 --- a/proxychain/requestmodifiers/spoof_referrer_from_baidu_post.go +++ b/proxychain/requestmodifiers/spoof_referrer_from_baidu_post.go @@ -6,7 +6,7 @@ import ( "strings" "time" - "ladder/proxychain" + "github.com/everywall/ladder/proxychain" ) // SpoofReferrerFromBaiduSearch modifies the referrer header diff --git a/proxychain/requestmodifiers/spoof_referrer_from_bing_search.go b/proxychain/requestmodifiers/spoof_referrer_from_bing_search.go index c1e3ffe..25c01a5 100644 --- a/proxychain/requestmodifiers/spoof_referrer_from_bing_search.go +++ b/proxychain/requestmodifiers/spoof_referrer_from_bing_search.go @@ -1,7 +1,7 @@ package requestmodifiers import ( - "ladder/proxychain" + "github.com/everywall/ladder/proxychain" ) // SpoofReferrerFromBingSearch modifies the referrer header diff --git a/proxychain/requestmodifiers/spoof_referrer_from_google_search.go b/proxychain/requestmodifiers/spoof_referrer_from_google_search.go index f183292..0d8b5fd 100644 --- a/proxychain/requestmodifiers/spoof_referrer_from_google_search.go +++ b/proxychain/requestmodifiers/spoof_referrer_from_google_search.go @@ -1,7 +1,7 @@ package requestmodifiers import ( - "ladder/proxychain" + "github.com/everywall/ladder/proxychain" ) // SpoofReferrerFromGoogleSearch modifies the referrer header diff --git a/proxychain/requestmodifiers/spoof_referrer_from_linkedin_post.go b/proxychain/requestmodifiers/spoof_referrer_from_linkedin_post.go index 633b878..7def19c 100644 --- a/proxychain/requestmodifiers/spoof_referrer_from_linkedin_post.go +++ b/proxychain/requestmodifiers/spoof_referrer_from_linkedin_post.go @@ -1,7 +1,7 @@ package requestmodifiers import ( - "ladder/proxychain" + "github.com/everywall/ladder/proxychain" ) // SpoofReferrerFromLinkedInPost modifies the referrer header diff --git a/proxychain/requestmodifiers/spoof_referrer_from_naver_post.go b/proxychain/requestmodifiers/spoof_referrer_from_naver_post.go index 6268f83..17d765f 100644 --- a/proxychain/requestmodifiers/spoof_referrer_from_naver_post.go +++ b/proxychain/requestmodifiers/spoof_referrer_from_naver_post.go @@ -3,7 +3,7 @@ package requestmodifiers import ( "fmt" - "ladder/proxychain" + "github.com/everywall/ladder/proxychain" ) // SpoofReferrerFromNaverSearch modifies the referrer header diff --git a/proxychain/requestmodifiers/spoof_referrer_from_pinterest_post.go b/proxychain/requestmodifiers/spoof_referrer_from_pinterest_post.go index 321ca5d..929a26d 100644 --- a/proxychain/requestmodifiers/spoof_referrer_from_pinterest_post.go +++ b/proxychain/requestmodifiers/spoof_referrer_from_pinterest_post.go @@ -1,7 +1,7 @@ package requestmodifiers import ( - "ladder/proxychain" + "github.com/everywall/ladder/proxychain" ) // SpoofReferrerFromPinterestPost modifies the referrer header diff --git a/proxychain/requestmodifiers/spoof_referrer_from_qq_post.go b/proxychain/requestmodifiers/spoof_referrer_from_qq_post.go index 2961cc7..6892838 100644 --- a/proxychain/requestmodifiers/spoof_referrer_from_qq_post.go +++ b/proxychain/requestmodifiers/spoof_referrer_from_qq_post.go @@ -1,7 +1,7 @@ package requestmodifiers import ( - "ladder/proxychain" + "github.com/everywall/ladder/proxychain" ) // SpoofReferrerFromQQPost modifies the referrer header diff --git a/proxychain/requestmodifiers/spoof_referrer_from_reddit_post.go b/proxychain/requestmodifiers/spoof_referrer_from_reddit_post.go index 4103024..31c8800 100644 --- a/proxychain/requestmodifiers/spoof_referrer_from_reddit_post.go +++ b/proxychain/requestmodifiers/spoof_referrer_from_reddit_post.go @@ -1,7 +1,7 @@ package requestmodifiers import ( - "ladder/proxychain" + "github.com/everywall/ladder/proxychain" ) // SpoofReferrerFromRedditPost modifies the referrer header diff --git a/proxychain/requestmodifiers/spoof_referrer_from_tumblr_post.go b/proxychain/requestmodifiers/spoof_referrer_from_tumblr_post.go index f44f094..4860097 100644 --- a/proxychain/requestmodifiers/spoof_referrer_from_tumblr_post.go +++ b/proxychain/requestmodifiers/spoof_referrer_from_tumblr_post.go @@ -1,7 +1,7 @@ package requestmodifiers import ( - "ladder/proxychain" + "github.com/everywall/ladder/proxychain" ) // SpoofReferrerFromTumblrPost modifies the referrer header diff --git a/proxychain/requestmodifiers/spoof_referrer_from_twitter_post.go b/proxychain/requestmodifiers/spoof_referrer_from_twitter_post.go index 5cd54ab..eeff10c 100644 --- a/proxychain/requestmodifiers/spoof_referrer_from_twitter_post.go +++ b/proxychain/requestmodifiers/spoof_referrer_from_twitter_post.go @@ -1,7 +1,7 @@ package requestmodifiers import ( - "ladder/proxychain" + "github.com/everywall/ladder/proxychain" ) // SpoofReferrerFromTwitterPost modifies the referrer header diff --git a/proxychain/requestmodifiers/spoof_referrer_from_vkontake_post.go b/proxychain/requestmodifiers/spoof_referrer_from_vkontake_post.go index e555117..ddc9627 100644 --- a/proxychain/requestmodifiers/spoof_referrer_from_vkontake_post.go +++ b/proxychain/requestmodifiers/spoof_referrer_from_vkontake_post.go @@ -1,7 +1,7 @@ package requestmodifiers import ( - "ladder/proxychain" + "github.com/everywall/ladder/proxychain" ) // SpoofReferrerFromVkontaktePost modifies the referrer header diff --git a/proxychain/requestmodifiers/spoof_referrer_from_weibo_post.go b/proxychain/requestmodifiers/spoof_referrer_from_weibo_post.go index 068d482..d845390 100644 --- a/proxychain/requestmodifiers/spoof_referrer_from_weibo_post.go +++ b/proxychain/requestmodifiers/spoof_referrer_from_weibo_post.go @@ -4,7 +4,7 @@ import ( "fmt" "math/rand" - "ladder/proxychain" + "github.com/everywall/ladder/proxychain" ) // SpoofReferrerFromWeiboPost modifies the referrer header diff --git a/proxychain/requestmodifiers/spoof_user_agent.go b/proxychain/requestmodifiers/spoof_user_agent.go index 921d7ae..e902f9a 100644 --- a/proxychain/requestmodifiers/spoof_user_agent.go +++ b/proxychain/requestmodifiers/spoof_user_agent.go @@ -4,8 +4,9 @@ import ( _ "embed" "strings" - "ladder/proxychain" - tx "ladder/proxychain/responsemodifiers" + tx "github.com/everywall/ladder/proxychain/responsemodifiers" + + "github.com/everywall/ladder/proxychain" ) // https://github.com/faisalman/ua-parser-js/tree/master diff --git a/proxychain/requestmodifiers/spoof_x_forwarded_for.go b/proxychain/requestmodifiers/spoof_x_forwarded_for.go index c12dd28..c7762bf 100644 --- a/proxychain/requestmodifiers/spoof_x_forwarded_for.go +++ b/proxychain/requestmodifiers/spoof_x_forwarded_for.go @@ -1,7 +1,7 @@ package requestmodifiers import ( - "ladder/proxychain" + "github.com/everywall/ladder/proxychain" ) // SpoofXForwardedFor modifies the X-Forwarded-For header diff --git a/proxychain/responsemodifiers/api_content.go b/proxychain/responsemodifiers/api_content.go index 2814091..c715bf3 100644 --- a/proxychain/responsemodifiers/api_content.go +++ b/proxychain/responsemodifiers/api_content.go @@ -7,8 +7,9 @@ import ( "github.com/markusmobius/go-trafilatura" - "ladder/proxychain" - "ladder/proxychain/responsemodifiers/api" + "github.com/everywall/ladder/proxychain/responsemodifiers/api" + + "github.com/everywall/ladder/proxychain" ) // APIContent creates an JSON representation of the article and returns it as an API response. diff --git a/proxychain/responsemodifiers/api_content_test.go b/proxychain/responsemodifiers/api_content_test.go index dbfa82f..9c60c57 100644 --- a/proxychain/responsemodifiers/api_content_test.go +++ b/proxychain/responsemodifiers/api_content_test.go @@ -7,7 +7,7 @@ import ( "net/url" "testing" - "ladder/proxychain/responsemodifiers/api" + "github.com/everywall/ladder/proxychain/responsemodifiers/api" ) func TestCreateAPIErrReader(t *testing.T) { diff --git a/proxychain/responsemodifiers/block_element_removal.go b/proxychain/responsemodifiers/block_element_removal.go index d3521d0..7dd8b76 100644 --- a/proxychain/responsemodifiers/block_element_removal.go +++ b/proxychain/responsemodifiers/block_element_removal.go @@ -4,8 +4,9 @@ import ( _ "embed" "strings" - "ladder/proxychain" - "ladder/proxychain/responsemodifiers/rewriters" + "github.com/everywall/ladder/proxychain/responsemodifiers/rewriters" + + "github.com/everywall/ladder/proxychain" ) //go:embed vendor/block_element_removal.js diff --git a/proxychain/responsemodifiers/block_third_party_scripts.go b/proxychain/responsemodifiers/block_third_party_scripts.go index 398a6cc..9af1d0c 100644 --- a/proxychain/responsemodifiers/block_third_party_scripts.go +++ b/proxychain/responsemodifiers/block_third_party_scripts.go @@ -5,8 +5,9 @@ import ( "fmt" "strings" - "ladder/proxychain" - "ladder/proxychain/responsemodifiers/rewriters" + "github.com/everywall/ladder/proxychain/responsemodifiers/rewriters" + + "github.com/everywall/ladder/proxychain" ) // BlockThirdPartyScripts rewrites HTML and injects JS to block all third party JS from loading. diff --git a/proxychain/responsemodifiers/bypass_cors.go b/proxychain/responsemodifiers/bypass_cors.go index 291b6f8..4a02c4e 100644 --- a/proxychain/responsemodifiers/bypass_cors.go +++ b/proxychain/responsemodifiers/bypass_cors.go @@ -1,7 +1,7 @@ package responsemodifiers import ( - "ladder/proxychain" + "github.com/everywall/ladder/proxychain" ) // BypassCORS modifies response headers to prevent the browser diff --git a/proxychain/responsemodifiers/bypass_csp.go b/proxychain/responsemodifiers/bypass_csp.go index 9d08ef0..90e1da8 100644 --- a/proxychain/responsemodifiers/bypass_csp.go +++ b/proxychain/responsemodifiers/bypass_csp.go @@ -1,7 +1,7 @@ package responsemodifiers import ( - "ladder/proxychain" + "github.com/everywall/ladder/proxychain" ) // TODO: handle edge case where CSP is specified in meta tag: diff --git a/proxychain/responsemodifiers/delete_localstorage_data.go b/proxychain/responsemodifiers/delete_localstorage_data.go index e214b80..6268ef2 100644 --- a/proxychain/responsemodifiers/delete_localstorage_data.go +++ b/proxychain/responsemodifiers/delete_localstorage_data.go @@ -4,7 +4,7 @@ import ( _ "embed" "strings" - "ladder/proxychain" + "github.com/everywall/ladder/proxychain" ) // DeleteLocalStorageData deletes localstorage cookies. diff --git a/proxychain/responsemodifiers/delete_sessionstorage_data.go b/proxychain/responsemodifiers/delete_sessionstorage_data.go index d44be33..b55e20c 100644 --- a/proxychain/responsemodifiers/delete_sessionstorage_data.go +++ b/proxychain/responsemodifiers/delete_sessionstorage_data.go @@ -4,7 +4,7 @@ import ( _ "embed" "strings" - "ladder/proxychain" + "github.com/everywall/ladder/proxychain" ) // DeleteSessionStorageData deletes localstorage cookies. diff --git a/proxychain/responsemodifiers/forward_response_headers.go b/proxychain/responsemodifiers/forward_response_headers.go index 1cdf008..8f36ca9 100644 --- a/proxychain/responsemodifiers/forward_response_headers.go +++ b/proxychain/responsemodifiers/forward_response_headers.go @@ -5,7 +5,7 @@ import ( "net/url" "strings" - "ladder/proxychain" + "github.com/everywall/ladder/proxychain" ) var forwardBlacklist map[string]bool diff --git a/proxychain/responsemodifiers/generate_readable_outline.go b/proxychain/responsemodifiers/generate_readable_outline.go index f84c61d..430f190 100644 --- a/proxychain/responsemodifiers/generate_readable_outline.go +++ b/proxychain/responsemodifiers/generate_readable_outline.go @@ -10,7 +10,7 @@ import ( "net/url" "strings" - "ladder/proxychain" + "github.com/everywall/ladder/proxychain" "golang.org/x/net/html" "golang.org/x/net/html/atom" diff --git a/proxychain/responsemodifiers/inject_script.go b/proxychain/responsemodifiers/inject_script.go index e9ec024..6383b49 100644 --- a/proxychain/responsemodifiers/inject_script.go +++ b/proxychain/responsemodifiers/inject_script.go @@ -4,8 +4,9 @@ import ( _ "embed" "strings" - "ladder/proxychain" - "ladder/proxychain/responsemodifiers/rewriters" + "github.com/everywall/ladder/proxychain/responsemodifiers/rewriters" + + "github.com/everywall/ladder/proxychain" ) // injectScript modifies HTTP responses diff --git a/proxychain/responsemodifiers/modify_incoming_cookies.go b/proxychain/responsemodifiers/modify_incoming_cookies.go index 5ad63cc..4c77468 100644 --- a/proxychain/responsemodifiers/modify_incoming_cookies.go +++ b/proxychain/responsemodifiers/modify_incoming_cookies.go @@ -7,7 +7,7 @@ import ( //"net/http" //http "github.com/Danny-Dasilva/fhttp" - "ladder/proxychain" + "github.com/everywall/ladder/proxychain" ) // DeleteIncomingCookies prevents ALL cookies from being sent from the proxy server diff --git a/proxychain/responsemodifiers/modify_response_header.go b/proxychain/responsemodifiers/modify_response_header.go index 2eca24d..e76c757 100644 --- a/proxychain/responsemodifiers/modify_response_header.go +++ b/proxychain/responsemodifiers/modify_response_header.go @@ -1,7 +1,7 @@ package responsemodifiers import ( - "ladder/proxychain" + "github.com/everywall/ladder/proxychain" ) // SetResponseHeader modifies response headers from the upstream server diff --git a/proxychain/responsemodifiers/patch_dynamic_resource_urls.go b/proxychain/responsemodifiers/patch_dynamic_resource_urls.go index 53d30d8..b418b54 100644 --- a/proxychain/responsemodifiers/patch_dynamic_resource_urls.go +++ b/proxychain/responsemodifiers/patch_dynamic_resource_urls.go @@ -5,8 +5,9 @@ import ( "fmt" "strings" - "ladder/proxychain" - "ladder/proxychain/responsemodifiers/rewriters" + "github.com/everywall/ladder/proxychain/responsemodifiers/rewriters" + + "github.com/everywall/ladder/proxychain" ) //go:embed vendor/patch_dynamic_resource_urls.js diff --git a/proxychain/responsemodifiers/patch_tracker_scripts.go b/proxychain/responsemodifiers/patch_tracker_scripts.go index 1d1aaa7..21ca84c 100644 --- a/proxychain/responsemodifiers/patch_tracker_scripts.go +++ b/proxychain/responsemodifiers/patch_tracker_scripts.go @@ -7,7 +7,7 @@ import ( "log" "regexp" - "ladder/proxychain" + "github.com/everywall/ladder/proxychain" ) //go:embed vendor/ddg-tracker-surrogates/mapping.json diff --git a/proxychain/responsemodifiers/rewrite_http_resource_urls.go b/proxychain/responsemodifiers/rewrite_http_resource_urls.go index cde7a92..91c9949 100644 --- a/proxychain/responsemodifiers/rewrite_http_resource_urls.go +++ b/proxychain/responsemodifiers/rewrite_http_resource_urls.go @@ -5,8 +5,9 @@ import ( "fmt" "strings" - "ladder/proxychain" - "ladder/proxychain/responsemodifiers/rewriters" + "github.com/everywall/ladder/proxychain/responsemodifiers/rewriters" + + "github.com/everywall/ladder/proxychain" ) // RewriteHTMLResourceURLs modifies HTTP responses diff --git a/proxychain/ruleset/rule.go b/proxychain/ruleset/rule.go index 56f778d..221a411 100644 --- a/proxychain/ruleset/rule.go +++ b/proxychain/ruleset/rule.go @@ -6,7 +6,7 @@ import ( "fmt" //"gopkg.in/yaml.v3" - "ladder/proxychain" + "github.com/everywall/ladder/proxychain" ) type Rule struct { diff --git a/proxychain/ruleset/rule_reqmod_types.gen.go b/proxychain/ruleset/rule_reqmod_types.gen.go index f885537..a444551 100644 --- a/proxychain/ruleset/rule_reqmod_types.gen.go +++ b/proxychain/ruleset/rule_reqmod_types.gen.go @@ -5,8 +5,8 @@ package ruleset_v2 // for use in proxychains. import ( - "ladder/proxychain" - rx "ladder/proxychain/requestmodifiers" + "github.com/everywall/ladder/proxychain" + rx "github.com/everywall/ladder/proxychain/requestmodifiers" ) type RequestModifierFactory func(params ...string) proxychain.RequestModification diff --git a/proxychain/ruleset/rule_resmod_types.gen.go b/proxychain/ruleset/rule_resmod_types.gen.go index eb42a02..bce41d3 100644 --- a/proxychain/ruleset/rule_resmod_types.gen.go +++ b/proxychain/ruleset/rule_resmod_types.gen.go @@ -5,8 +5,8 @@ package ruleset_v2 // for use in proxychains. import ( - "ladder/proxychain" - tx "ladder/proxychain/responsemodifiers" + "github.com/everywall/ladder/proxychain" + tx "github.com/everywall/ladder/proxychain/responsemodifiers" ) type ResponseModifierFactory func(params ...string) proxychain.ResponseModification From 81c99821f083821f32a97d9ba63f0679732fea1d Mon Sep 17 00:00:00 2001 From: Kevin Pham Date: Fri, 8 Dec 2023 10:20:27 -0600 Subject: [PATCH 03/10] fix title on outline generatation if it contains a ; --- .github/workflows/build-css.yaml | 2 +- handlers/api_modifiers_structdef.gen.go | 4 ++-- proxychain/responsemodifiers/generate_readable_outline.go | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-css.yaml b/.github/workflows/build-css.yaml index 8d8fa70..ce6f75e 100644 --- a/.github/workflows/build-css.yaml +++ b/.github/workflows/build-css.yaml @@ -28,7 +28,7 @@ jobs: name: Build Tailwind CSS run: pnpm build - - name: Commit generated stylesheet + name: Commit generated stylesheet for handlers/styles.css run: | if git diff --quiet handlers/styles.css; then echo "No changes to commit." diff --git a/handlers/api_modifiers_structdef.gen.go b/handlers/api_modifiers_structdef.gen.go index 64e5ac1..c0e2699 100644 --- a/handlers/api_modifiers_structdef.gen.go +++ b/handlers/api_modifiers_structdef.gen.go @@ -485,7 +485,7 @@ var AllMods Modifiers = Modifiers{ Description: "DeleteIncomingCookies prevents ALL cookies from being sent from the proxy server back down to the client.", CodeEditLink: "https://github.com/everywall/ladder/edit/origin/proxy_v2/proxychain/responsemodifiers/modify_incoming_cookies.go", Params: []Param{ - {Name: "_", Type: "&{Ellipsis:16319 Elt:string}"}, + {Name: "_", Type: "&{Ellipsis:16342 Elt:string}"}, }, }, { @@ -493,7 +493,7 @@ var AllMods Modifiers = Modifiers{ Description: "DeleteIncomingCookiesExcept prevents non-whitelisted cookies from being sent from the proxy server to the client. Cookies whose names are in the whitelist are not removed.", CodeEditLink: "https://github.com/everywall/ladder/edit/origin/proxy_v2/proxychain/responsemodifiers/modify_incoming_cookies.go", Params: []Param{ - {Name: "whitelist", Type: "&{Ellipsis:16864 Elt:string}"}, + {Name: "whitelist", Type: "&{Ellipsis:16887 Elt:string}"}, }, }, { diff --git a/proxychain/responsemodifiers/generate_readable_outline.go b/proxychain/responsemodifiers/generate_readable_outline.go index 430f190..1d9e4d9 100644 --- a/proxychain/responsemodifiers/generate_readable_outline.go +++ b/proxychain/responsemodifiers/generate_readable_outline.go @@ -68,7 +68,7 @@ func GenerateReadableOutline() proxychain.ResponseModification { "Success": true, "Image": extract.Metadata.Image, "Description": extract.Metadata.Description, - "Sitename": extract.Metadata.Sitename, + "Sitename": strings.Split(extract.Metadata.Sitename, ";")[0], "Hostname": extract.Metadata.Hostname, "Url": "/" + chain.Request.URL.String(), "Title": extract.Metadata.Title, // todo: modify CreateReadableDocument so we don't have

titles duplicated? From 22f00074782f61a1d92430ac53bb7b99114a04dd Mon Sep 17 00:00:00 2001 From: Kevin Pham Date: Fri, 8 Dec 2023 14:06:34 -0600 Subject: [PATCH 04/10] improve outline UX; add print mode and reading time estimation --- handlers/api_modifiers_structdef.gen.go | 6 +- .../generate_readable_outline.go | 112 +++++++++++++++--- .../vendor/generate_readable_outline.html | 72 ++++++----- 3 files changed, 142 insertions(+), 48 deletions(-) diff --git a/handlers/api_modifiers_structdef.gen.go b/handlers/api_modifiers_structdef.gen.go index c0e2699..6a8abc0 100644 --- a/handlers/api_modifiers_structdef.gen.go +++ b/handlers/api_modifiers_structdef.gen.go @@ -160,7 +160,7 @@ var AllMods Modifiers = Modifiers{ Description: "DeleteOutGoingCookiesExcept prevents non-whitelisted cookies from being sent from the client to the upstream proxy server. Cookies whose names are in the whitelist are not removed.", CodeEditLink: "https://github.com/everywall/ladder/edit/origin/proxy_v2/proxychain/requestmodifiers/modify_outgoing_cookies.go", Params: []Param{ - {Name: "whitelist", Type: "&{Ellipsis:12348 Elt:string}"}, + {Name: "whitelist", Type: "&{Ellipsis:12476 Elt:string}"}, }, }, { @@ -485,7 +485,7 @@ var AllMods Modifiers = Modifiers{ Description: "DeleteIncomingCookies prevents ALL cookies from being sent from the proxy server back down to the client.", CodeEditLink: "https://github.com/everywall/ladder/edit/origin/proxy_v2/proxychain/responsemodifiers/modify_incoming_cookies.go", Params: []Param{ - {Name: "_", Type: "&{Ellipsis:16342 Elt:string}"}, + {Name: "_", Type: "&{Ellipsis:18778 Elt:string}"}, }, }, { @@ -493,7 +493,7 @@ var AllMods Modifiers = Modifiers{ Description: "DeleteIncomingCookiesExcept prevents non-whitelisted cookies from being sent from the proxy server to the client. Cookies whose names are in the whitelist are not removed.", CodeEditLink: "https://github.com/everywall/ladder/edit/origin/proxy_v2/proxychain/responsemodifiers/modify_incoming_cookies.go", Params: []Param{ - {Name: "whitelist", Type: "&{Ellipsis:16887 Elt:string}"}, + {Name: "whitelist", Type: "&{Ellipsis:19323 Elt:string}"}, }, }, { diff --git a/proxychain/responsemodifiers/generate_readable_outline.go b/proxychain/responsemodifiers/generate_readable_outline.go index 1d9e4d9..b5ccc47 100644 --- a/proxychain/responsemodifiers/generate_readable_outline.go +++ b/proxychain/responsemodifiers/generate_readable_outline.go @@ -7,16 +7,15 @@ import ( "html/template" "io" "log" + "math" "net/url" "strings" + "time" "github.com/everywall/ladder/proxychain" - + "github.com/markusmobius/go-trafilatura" "golang.org/x/net/html" "golang.org/x/net/html/atom" - - //"github.com/go-shiori/dom" - "github.com/markusmobius/go-trafilatura" ) //go:embed vendor/generate_readable_outline.html @@ -63,19 +62,24 @@ func GenerateReadableOutline() proxychain.ResponseModification { html.Render(&b, extract.ContentNode) distilledHTML := b.String() + siteName := strings.Split(extract.Metadata.Sitename, ";")[0] + title := strings.Split(extract.Metadata.Title, "|")[0] + fmtDate := createWikipediaDateLink(extract.Metadata.Date) + readingTime := formatDuration(estimateReadingTime(extract.ContentText)) + // populate template parameters data := map[string]interface{}{ "Success": true, "Image": extract.Metadata.Image, "Description": extract.Metadata.Description, - "Sitename": strings.Split(extract.Metadata.Sitename, ";")[0], + "Sitename": siteName, "Hostname": extract.Metadata.Hostname, "Url": "/" + chain.Request.URL.String(), - "Title": extract.Metadata.Title, // todo: modify CreateReadableDocument so we don't have

titles duplicated? - "Date": extract.Metadata.Date.String(), - "Author": createWikipediaSearchLinks(extract.Metadata.Author), - //"Author": extract.Metadata.Author, - "Body": distilledHTML, + "Title": title, + "Date": fmtDate, + "Author": createDDGFeelingLuckyLinks(extract.Metadata.Author, extract.Metadata.Hostname), + "Body": distilledHTML, + "ReadingTime": readingTime, } // ============================================================================ @@ -157,9 +161,20 @@ func rewriteHrefLinks(n *html.Node, baseURL string, apiPath string) { recurse(n) } -// createWikipediaSearchLinks takes in comma or semicolon separated terms, -// then turns them into links searching for the term. -func createWikipediaSearchLinks(searchTerms string) string { +// createWikipediaDateLink takes in a date +// and returns an link pointing to the current events page for that day +func createWikipediaDateLink(t time.Time) string { + url := fmt.Sprintf("https://en.wikipedia.org/wiki/Portal:Current_events#%s", t.Format("2006_January_2")) + date := t.Format("January 2, 2006") + return fmt.Sprintf("%s", url, date) +} + +// createDDGFeelingLuckyLinks takes in comma or semicolon separated terms, +// then turns them into links searching for the term using DuckDuckGo's I'm +// feeling lucky feature. It will redirect the user immediately to the first search result. +func createDDGFeelingLuckyLinks(searchTerms string, siteHostname string) string { + + siteHostname = strings.TrimSpace(siteHostname) semiColonSplit := strings.Split(searchTerms, ";") var links []string @@ -171,11 +186,13 @@ func createWikipediaSearchLinks(searchTerms string) string { continue } - encodedTerm := url.QueryEscape(trimmedTerm) + ddgQuery := fmt.Sprintf(` site:%s intitle:"%s"`, strings.TrimPrefix(siteHostname, "www."), trimmedTerm) - wikiURL := fmt.Sprintf("https://en.wikipedia.org/w/index.php?search=%s", encodedTerm) + encodedTerm := `\%s:` + url.QueryEscape(ddgQuery) + //ddgURL := `https://html.duckduckgo.com/html/?q=` + encodedTerm + ddgURL := `https://www.duckduckgo.com/?q=` + encodedTerm - link := fmt.Sprintf("%s", wikiURL, trimmedTerm) + link := fmt.Sprintf("%s", ddgURL, trimmedTerm) links = append(links, link) } @@ -187,3 +204,66 @@ func createWikipediaSearchLinks(searchTerms string) string { return strings.Join(links, " ") } + +// estimateReadingTime estimates how long the given text will take to read using the given configuration. +func estimateReadingTime(text string) time.Duration { + if len(text) == 0 { + return 0 + } + + // Init options with default values. + WordsPerMinute := 200 + WordBound := func(b byte) bool { + return b == ' ' || b == '\n' || b == '\r' || b == '\t' + } + + words := 0 + start := 0 + end := len(text) - 1 + + // Fetch bounds. + for WordBound(text[start]) { + start++ + } + for WordBound(text[end]) { + end-- + } + + // Calculate the number of words. + for i := start; i <= end; { + for i <= end && !WordBound(text[i]) { + i++ + } + + words++ + + for i <= end && WordBound(text[i]) { + i++ + } + } + + // Reading time stats. + minutes := math.Ceil(float64(words) / float64(WordsPerMinute)) + duration := time.Duration(math.Ceil(minutes) * float64(time.Minute)) + + return duration + +} + +func formatDuration(d time.Duration) string { + // Check if the duration is less than one minute + if d < time.Minute { + seconds := int(d.Seconds()) + return fmt.Sprintf("%d seconds", seconds) + } + + // Convert the duration to minutes + minutes := int(d.Minutes()) + + // Format the string for one or more minutes + if minutes == 1 { + return "1 minute" + } else { + return fmt.Sprintf("%d minutes", minutes) + } +} diff --git a/proxychain/responsemodifiers/vendor/generate_readable_outline.html b/proxychain/responsemodifiers/vendor/generate_readable_outline.html index 0f0d251..79a9fd6 100644 --- a/proxychain/responsemodifiers/vendor/generate_readable_outline.html +++ b/proxychain/responsemodifiers/vendor/generate_readable_outline.html @@ -45,7 +45,7 @@ xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 512 512" - class="h-8 focus:outline-none focus:ring focus:border-[#7AA7D1] ring-offset-2" + class="noprint h-8 focus:outline-none focus:ring focus:border-[#7AA7D1] ring-offset-2" > -
+