Upload index.html with huggingface_hub
Browse files- index.html +82 -18
index.html
CHANGED
|
@@ -1,19 +1,83 @@
|
|
| 1 |
-
<!doctype html>
|
| 2 |
-
<
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
</html>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!doctype html><html lang="en"><meta charset="utf-8">
|
| 2 |
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
| 3 |
+
<title>Hardcoded Connection String Audit for Azure IoT Hub (azure-iot-toolkit) + 7 More VS Code Stacks — 26 rules, 32 snippets</title>
|
| 4 |
+
<meta name="description" content="26 rules and 32 safe-replacement snippets across 8 VS Code stacks. Hosted secret scanning is published at $19 per active committer per month (GitHub Secret Protection pricing page); this is a one-time $29, runs on your machine, and sends nothing anywhere.">
|
| 5 |
+
<script defer data-auto-init src="https://cdn.jsdelivr.net/npm/@polar-sh/checkout@latest/dist/embed.global.js"></script>
|
| 6 |
+
<style>
|
| 7 |
+
:root{color-scheme:light dark}
|
| 8 |
+
body{margin:0;font:16px/1.6 system-ui,-apple-system,"Segoe UI",sans-serif;
|
| 9 |
+
background:#fbfbfa;color:#16161d}
|
| 10 |
+
@media(prefers-color-scheme:dark){body{background:#14141a;color:#e8e8ea}}
|
| 11 |
+
.wrap{max-width:880px;margin:0 auto;padding:28px 20px 64px}
|
| 12 |
+
h1{font-size:1.7rem;line-height:1.25;margin:.2em 0 .3em}
|
| 13 |
+
p.sub{margin:0 0 1.4em;opacity:.8}
|
| 14 |
+
textarea{width:100%;min-height:230px;font:13px/1.5 ui-monospace,Menlo,Consolas,monospace;
|
| 15 |
+
padding:12px;border:1px solid #c9c9d1;border-radius:10px;background:transparent;color:inherit;
|
| 16 |
+
box-sizing:border-box}
|
| 17 |
+
button{font:600 15px/1 inherit;padding:12px 22px;border:0;border-radius:10px;
|
| 18 |
+
background:#1d4ed8;color:#fff;cursor:pointer;margin:12px 0}
|
| 19 |
+
button:hover{background:#1a43bd}
|
| 20 |
+
table{border-collapse:collapse;width:100%;margin-top:14px;font-size:14px}
|
| 21 |
+
th,td{border-bottom:1px solid #d8d8e0;padding:8px 6px;text-align:left;vertical-align:top}
|
| 22 |
+
th{font-weight:600;opacity:.75}
|
| 23 |
+
td.n{width:64px;font:13px ui-monospace,monospace;opacity:.7}
|
| 24 |
+
.ok{padding:14px;border-radius:10px;background:#e8f5ec;color:#14532d;margin-top:14px}
|
| 25 |
+
@media(prefers-color-scheme:dark){.ok{background:#15321f;color:#bbf7d0}}
|
| 26 |
+
.next{margin-top:30px;padding:18px;border:1px solid #d8d8e0;border-radius:12px}
|
| 27 |
+
.next h2{font-size:1.05rem;margin:0 0 .5em}
|
| 28 |
+
.next ul{margin:.3em 0 1em 1.1em;padding:0}
|
| 29 |
+
a.buy{display:inline-block;font:600 15px/1 inherit;padding:13px 22px;border-radius:10px;
|
| 30 |
+
background:#1d4ed8;color:#fff;text-decoration:none}
|
| 31 |
+
a.buy:hover{background:#1a43bd}
|
| 32 |
+
.anchor{font-size:14px;opacity:.85;margin:.2em 0 1em}
|
| 33 |
+
.afterhit{margin-top:16px;padding:14px;border:1px solid #d8d8e0;border-radius:10px;font-size:14px}
|
| 34 |
+
.afterhit p{margin:0 0 10px}
|
| 35 |
+
</style>
|
| 36 |
+
<div class="wrap">
|
| 37 |
+
<h1>Hardcoded Connection String Audit for Azure IoT Hub (azure-iot-toolkit) + 7 More VS Code Stacks — 26 rules, 32 snippets</h1>
|
| 38 |
+
<p class="sub">26 rules and 32 safe-replacement snippets across 8 VS Code stacks. Hosted secret scanning is published at $19 per active committer per month (GitHub Secret Protection pricing page); this is a one-time $29, runs on your machine, and sends nothing anywhere.</p>
|
| 39 |
+
<textarea id="src" placeholder="Paste the file here"></textarea>
|
| 40 |
+
<button id="go">Check</button>
|
| 41 |
+
<div id="out"></div>
|
| 42 |
+
<div class="next">
|
| 43 |
+
<h2>What a licence adds</h2>
|
| 44 |
+
<ul>
|
| 45 |
+
<li><b>Scale</b> — the same 26 rules across every file in the workspace, not the one file you have open.</li>
|
| 46 |
+
<li><b>Handover</b> — the findings written out as a CSV, JSON or HTML file you keep in the repo and hand to a reviewer.</li>
|
| 47 |
+
</ul>
|
| 48 |
+
<p class="anchor">GitHub Secret Protection is published at <b>$19 per active committer per month</b>, billed for as long as the team keeps committing. This is <b>$29 once</b>, runs on your machine, and sends nothing anywhere. Full refund within 7 days.</p>
|
| 49 |
+
<a class="buy" href="https://buy.polar.sh/polar_cl_1tgGYRxH9pxpXj2qrSYA5SmeCbtVqYcXEKLoD4CR3y7" data-polar-checkout data-polar-checkout-theme="light">Get the full version — $29 once</a>
|
| 50 |
+
</div>
|
| 51 |
+
</div>
|
| 52 |
+
<script>
|
| 53 |
+
var RULES=[{"pattern": "HostName=[^;\\s\"']+\\.azure-devices\\.net;[^\\n]*SharedAccessKey=[A-Za-z0-9+/=]{16,}", "flags": "i", "message": "An IoT Hub connection string with a live SharedAccessKey is written into this file. Anyone who clones the repository can send and receive on that device identity.", "fix": "HostName=${IOTHUB_HOSTNAME};DeviceId=${IOTHUB_DEVICE_ID};SharedAccessKey=${IOTHUB_DEVICE_KEY}"}, {"pattern": "SharedAccessSignature\\s+sr=[^&\\s]+&sig=[A-Za-z0-9%+/=]{16,}", "flags": "i", "message": "A SAS token is pasted here. It works until it expires and it cannot be revoked on its own without regenerating the policy key.", "fix": "SharedAccessSignature=${IOTHUB_SAS_TOKEN}"}, {"pattern": "symmetricKey\\s*[:=]\\s*[\"'][A-Za-z0-9+/=]{20,}[\"']", "flags": "i", "message": "A Device Provisioning Service symmetric key is hardcoded. Read it from the environment, or provision with an X.509 certificate instead."}, {"pattern": "DefaultEndpointsProtocol=https?;AccountName=[^;]+;AccountKey=[A-Za-z0-9+/=]{40,}", "flags": "i", "message": "A storage account key is in this file. That key grants full read and write on every container in the account, including IoT file uploads.", "fix": "DefaultEndpointsProtocol=https;AccountName=${AZURE_STORAGE_ACCOUNT};AccountKey=${AZURE_STORAGE_KEY}"}, {"pattern": "Endpoint=sb://[^;]+;SharedAccessKeyName=[^;]+;SharedAccessKey=[A-Za-z0-9+/=]{16,}", "flags": "i", "message": "An Event Hubs or Service Bus connection string with its key is hardcoded. This is usually the telemetry endpoint the whole device fleet writes to.", "fix": "Endpoint=${EVENTHUB_ENDPOINT};SharedAccessKeyName=${EVENTHUB_KEY_NAME};SharedAccessKey=${EVENTHUB_KEY}"}, {"pattern": "(?:Server|Data Source)=[^;\\n]+;[^\\n]*(?:Password|Pwd)=[^;\"'\\s]{4,}", "flags": "i", "message": "A SQL Server connection string carries the password inline. Use Microsoft Entra authentication, or read the whole string from the environment.", "fix": "Server=${SQL_SERVER};Database=${SQL_DATABASE};Authentication=Active Directory Default;Encrypt=true"}, {"pattern": "TrustServerCertificate\\s*=\\s*(?:true|yes)", "flags": "i", "message": "TrustServerCertificate is on, so the driver accepts any certificate and the encrypted connection can be intercepted.", "fix": "TrustServerCertificate=false"}, {"pattern": "jdbc:sqlserver://[^\\s\"']*(?:password|Password)=[^;\\s\"']{4,}", "flags": "", "message": "A JDBC URL for SQL Server contains the password. JDBC URLs end up in logs and stack traces.", "fix": "jdbc:sqlserver://${SQL_SERVER};database=${SQL_DATABASE};authentication=ActiveDirectoryDefault;encrypt=true"}, {"pattern": "\"password\"\\s*:\\s*\"[^\"]{4,}\"", "flags": "", "message": "A saved connection stores the password in plain JSON. Let the client ask for it at connect time instead.", "fix": "\"askForPassword\": true"}, {"pattern": "(?:client-key-data|client-certificate-data|token):\\s*[A-Za-z0-9+/=._-]{40,}", "flags": "", "message": "A kubeconfig credential is committed here. It authenticates to the cluster from any machine that has this file."}, {"pattern": "az\\s+aks\\s+get-credentials[^\\n]*--admin", "flags": "i", "message": "This fetches the cluster-admin certificate, which is not tied to a user and cannot be revoked for one person. Fetch user credentials instead.", "fix": "az aks get-credentials --resource-group ${AKS_RESOURCE_GROUP} --name ${AKS_CLUSTER_NAME}"}, {"pattern": "--docker-password[=\\s]+[^\\s\"']{4,}", "flags": "", "message": "A registry password is passed on the command line. It lands in shell history and in CI logs.", "fix": "--docker-password=${REGISTRY_PASSWORD}"}, {"pattern": "Preferences(?:\\.Default)?\\.Set\\s*\\(\\s*\"[^\"]*(?:token|password|secret|key)[^\"]*\"", "flags": "i", "message": "A secret is being written to Preferences, which is unencrypted on the device. Use SecureStorage, which uses the platform keystore."}, {"pattern": "\"(?:ApiKey|ClientSecret|ConnectionString|AccountKey)\"\\s*:\\s*\"[^\"]{8,}\"", "flags": "", "message": "A secret sits in an appsettings file that ships inside the app package. Anyone can unzip the package and read it."}, {"pattern": "const\\s+string\\s+\\w*(?:ApiKey|Secret|Token|Password)\\w*\\s*=\\s*\"[^\"]{8,}\"", "flags": "i", "message": "A credential is compiled in as a constant. It stays readable in the assembly with any decompiler."}, {"pattern": "^[\\t ]*[\\w.-]*(?:password|secret|api[-_.]?key|token)[\\w.-]*\\s*=\\s*\\S{4,}$", "flags": "im", "message": "A configuration property holds a real value. MicroProfile Config reads environment variables first, so leave the value out of the file."}, {"pattern": "@ConfigProperty\\s*\\([^)]*defaultValue\\s*=\\s*\"[^\"]{12,}\"", "flags": "", "message": "A long defaultValue on @ConfigProperty is a secret baked into the class file. Drop the default and let startup fail loudly when it is missing."}, {"pattern": "add\\(\\s*\"Authorization\"\\s*,\\s*\"(?:Bearer|Basic)\\s+[^\"]{16,}\"", "flags": "", "message": "An Authorization header is hardcoded in the Rest Client. Inject it through config so it can be rotated without a rebuild."}, {"pattern": "Sys\\.setenv\\s*\\(\\s*[\\w.]*(?:KEY|TOKEN|SECRET|PASSWORD|PAT)[\\w.]*\\s*=\\s*[\"'][^\"']{8,}", "flags": "", "message": "Sys.setenv is being called with a literal secret. Put the value in .Renviron, which stays out of git, and read it with Sys.getenv."}, {"pattern": "dbConnect\\s*\\([^)]*password\\s*=\\s*[\"'][^\"']{3,}[\"']", "flags": "i", "message": "A database password is written into the dbConnect call. It will also sit in .Rhistory and in the rendered notebook."}, {"pattern": "options\\s*\\(\\s*[\\w.]*(?:key|token|secret)[\\w.]*\\s*=\\s*[\"'][^\"']{8,}[\"']", "flags": "i", "message": "A key is set through options(), so it is saved with the workspace image and printed by any call that dumps options."}, {"pattern": "add_headers\\s*\\(\\s*Authorization\\s*=\\s*[\"'](?:Bearer|Basic)\\s+[^\"']{16,}", "flags": "", "message": "A bearer token is written into a request chunk. Rendering this document with echo on prints the token into the output file."}, {"pattern": "-----BEGIN (?:RSA |EC |DSA |OPENSSH |PGP )?PRIVATE KEY-----", "flags": "", "message": "A private key block is inside this file. Keep the key on disk outside the repository and pass its path in an environment variable.", "fix": "# private key removed - load it from the path in ${PRIVATE_KEY_PATH}"}, {"pattern": "\\b(?:https?|mongodb|postgres(?:ql)?|amqps?|mqtts?)://[^\\s/:@\"']+:[^\\s/:@\"']+@", "flags": "i", "message": "A user name and password are embedded in a URL. Proxies and error pages copy whole URLs, so this credential travels further than the file."}, {"pattern": "\\bey[A-Za-z0-9_-]{10,}\\.[A-Za-z0-9_-]{10,}\\.[A-Za-z0-9_-]{10,}", "flags": "", "message": "A JSON Web Token is pasted here. It is valid until it expires, and its payload is readable by anyone."}, {"pattern": "^[\\t ]*(?:AWS_SECRET_ACCESS_KEY|AZURE_CLIENT_SECRET|IOTHUB_CONNECTION_STRING|DATABASE_PASSWORD)\\s*=\\s*\\S{6,}$", "flags": "im", "message": "A filled-in secret variable is in a tracked file. Keep values in .env, git-ignore it, and commit .env.example with the names only."}];
|
| 54 |
+
function scan(t){var L=String(t).split(/\r?\n/),h=[],i,r,re;
|
| 55 |
+
for(i=0;i<L.length;i++){for(var k=0;k<RULES.length;k++){r=RULES[k];
|
| 56 |
+
try{re=new RegExp(r.pattern,r.flags||'')}catch(e){continue}
|
| 57 |
+
if(re.test(L[i]))h.push({line:i+1,msg:r.message})}}
|
| 58 |
+
return h}
|
| 59 |
+
document.getElementById('go').onclick=function(){
|
| 60 |
+
var t=document.getElementById('src').value,o=document.getElementById('out');
|
| 61 |
+
if(!t.trim()){o.innerHTML='';return}
|
| 62 |
+
var h=scan(t);
|
| 63 |
+
if(!h.length){o.innerHTML='<div class="ok">No hardcoded credential matched any of the 26 rules here.</div>';return}
|
| 64 |
+
var s='<table><tr><th>Line</th><th>Finding</th></tr>';
|
| 65 |
+
for(var i=0;i<h.length;i++){s+='<tr><td class="n">'+h[i].line+'</td><td>'+
|
| 66 |
+
String(h[i].msg).replace(/&/g,'&').replace(/</g,'<')+'</td></tr>'}
|
| 67 |
+
o.innerHTML=s+'</table>'+'<div class="afterhit"><p><b>'+h.length+'</b> in this one file. A repository is not one file.</p>'+'<a class="buy" href="https://buy.polar.sh/polar_cl_1tgGYRxH9pxpXj2qrSYA5SmeCbtVqYcXEKLoD4CR3y7" data-polar-checkout data-polar-checkout-theme="light">Audit every file and export the findings \u2014 $29 once</a></div>'};
|
| 68 |
+
</script>
|
| 69 |
</html>
|
| 70 |
+
|
| 71 |
+
<section data-yj-alert="rule" style="margin:1rem auto 1.5rem;max-width:46rem;padding:1.1rem 1.25rem;border:1px solid #d9dee6;border-radius:12px;background:#fbfcfd;font:15px/1.55 system-ui,-apple-system,Segoe UI,sans-serif"><b style="font-size:1.05rem">Get one email when this rule changes</b><div style="opacity:.78;margin:.35rem 0 .8rem">We watch the regulation and vendor sources behind Connection String & Secret Audit — 8 Stacks every day. When a rule changes, you get a single email with what changed and the updated check. No newsletter.</div><div style="display:flex;gap:8px;flex-wrap:wrap"><input id="yjae" type="email" placeholder="you@example.com" style="flex:1;min-width:210px;padding:11px 13px;border:1px solid rgba(140,150,165,.34);border-radius:8px;background:#fff;color:inherit"><button id="yjab" style="padding:11px 18px;border-radius:8px;border:0;cursor:pointer;background:#0f7b3f;color:#fff;font:600 15px system-ui,sans-serif">Notify me</button></div><div id="yjao" hidden style="margin-top:.6rem;color:#0f7b3f">You're on the list. One email when it changes.</div><script>(function(){var b=document.getElementById("yjab"),e=document.getElementById("yjae");if(!b||!e)return;b.addEventListener("click",function(){var v=e.value.trim();if(!/.+@.+\..+/.test(v))return;try{localStorage.setItem("yj_em","1");}catch(_){}fetch(location.origin+"/api/subscribe",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({email:v,slug:"connection-string-secret-audit",lang:"en",source:"rule_alert"})}).then(function(r){var o=document.getElementById("yjao");o.hidden=false;if(!r.ok){o.textContent="Could not save - please try again.";}}).catch(function(){var o=document.getElementById("yjao");o.hidden=false;o.textContent="Could not save - please try again.";});});})();</script></section>
|
| 72 |
+
|
| 73 |
+
|
| 74 |
+
<section data-yj-install="free" style="margin:2rem auto 1rem;max-width:46rem;padding:1.25rem 1.25rem;border:1px solid #cfe3d6;border-radius:12px;background:#f6fbf8;font:16px/1.6 system-ui,-apple-system,Segoe UI,sans-serif"><h2 style="margin:0 0 .4rem;font-size:1.2rem">Install free</h2><p style="margin:0 0 .8rem;color:#41505f">Free for the file open in your editor - no key, no limit. The workspace sweep and the report ask for a key.</p><a href="https://www.npmjs.com/package/@readystack/connection-string-secret-audit" rel="noopener" data-yj-install-door="npm" onclick="try{navigator.sendBeacon('/api/ev',new Blob([JSON.stringify({t:'install',slug:'connection-string-secret-audit',src:'npm',path:location.pathname})],{type:'application/json'}))}catch(e){}" style="display:inline-block;margin:0 .5rem .5rem 0;padding:.6rem 1rem;border-radius:8px;background:#0f7b3f;color:#fff;text-decoration:none;font-weight:600">npm</a><a href="https://www.npmjs.com/package/@readystack/connection-string-secret-audit" rel="noopener" data-yj-install-door="mcp" onclick="try{navigator.sendBeacon('/api/ev',new Blob([JSON.stringify({t:'install',slug:'connection-string-secret-audit',src:'mcp',path:location.pathname})],{type:'application/json'}))}catch(e){}" style="display:inline-block;margin:0 .5rem .5rem 0;padding:.6rem 1rem;border-radius:8px;background:#0f7b3f;color:#fff;text-decoration:none;font-weight:600">MCP server (npx)</a><a href="https://hub.docker.com/r/getreadystack/connection-string-secret-audit" rel="noopener" data-yj-install-door="docker" onclick="try{navigator.sendBeacon('/api/ev',new Blob([JSON.stringify({t:'install',slug:'connection-string-secret-audit',src:'docker',path:location.pathname})],{type:'application/json'}))}catch(e){}" style="display:inline-block;margin:0 .5rem .5rem 0;padding:.6rem 1rem;border-radius:8px;background:#0f7b3f;color:#fff;text-decoration:none;font-weight:600">Docker Hub</a><pre style="margin:.5rem 0 0;padding:.6rem .8rem;background:#f3f5f8;border-radius:8px;font-size:.9rem;overflow:auto">npx @readystack/connection-string-secret-audit <file>
|
| 75 |
+
npx @readystack/connection-string-secret-audit --mcp
|
| 76 |
+
docker run --rm -v "$PWD:/w" getreadystack/connection-string-secret-audit /w</pre><p style="margin:.6rem 0 0;font-size:.92rem;color:#41505f"><a href="https://buy.polar.sh/polar_cl_l6iN1uWt0FwWu7tBsczD0jWpP2vxFM54Wdwqb3KPi1G" rel="nofollow" style="color:#0f7b3f;text-decoration:underline">Team? One key for every ReadyStack linter, 5 seats, $149 once</a></p></section>
|
| 77 |
+
<section data-yj-cta="paid" style="margin:3rem auto;max-width:46rem;padding:1.5rem 1.25rem;border:1px solid #d8dee9;border-radius:12px;background:#fbfcfe;font:16px/1.6 system-ui,-apple-system,Segoe UI,sans-serif"><h2 style="margin:0 0 .5rem;font-size:1.25rem">Get the complete version <span class="yj-price">$29</span></h2><p style="margin:.25rem 0 1rem;color:#41505f">This page is the working piece. The full pack has everything below.</p><p style="margin:0 0 1rem;color:#41505f">26 rules and 32 safe-replacement snippets for hardcoded connection strings, keys and kubeconfigs across 8 VS Code stacks. Runs on your machine and sends nothing anywhere.</p><p style="margin:0 0 1rem;color:#5b6b7c;font-size:.94rem">GitHub Secret Protection is published at $19 per active committer per month, billed every month and re-counted as committers come and go (GitHub Docs, checked 2026-09-08)</p><a href="https://buy.polar.sh/polar_cl_1tgGYRxH9pxpXj2qrSYA5SmeCbtVqYcXEKLoD4CR3y7" rel="nofollow" style="display:inline-block;padding:.7rem 1.3rem;border-radius:8px;background:#1b64f2;color:#fff;text-decoration:none;font-weight:600">Buy the full version — $29</a></section>
|
| 78 |
+
<section class="yj-related" style="max-width:920px;margin:56px auto 40px;padding:0 20px"><h2 style="font:600 21px/1.3 system-ui,sans-serif;margin:0 0 6px;color:#1b1f24">More from ReadyStack</h2><p style="font:400 14.5px/1.5 system-ui,sans-serif;margin:0 0 20px;color:#5b6570">Ready-to-use files. One-time download, no subscription.</p><div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:14px"><a class="yj-rel-c" href="https://getreadystack.com/tools/terraform-module-kubernetes"><span class="yj-rel-t">Terraform Module: Kubernetes Hardened Namespace (PSA + default-deny NetworkPol</span><span class="yj-rel-p">$3</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/n8n-social-media-workflow-agency-content-approval"><span class="yj-rel-t">n8n Social Media Workflow for Agency Content Approval — 6 Client Sign-Off Auto</span><span class="yj-rel-p">$59</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/revit-window-family"><span class="yj-rel-t">Revit Window Family Starter Blocks — 12 Dimensioned DXF Window Blocks for Impo</span><span class="yj-rel-p">$100</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/wedding-photographer-presets"><span class="yj-rel-t">Wedding Photographer Presets for Full-Day Bridal, Ceremony and Reception Galle</span><span class="yj-rel-p">$44</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/wordpress-ada-compliance-plugin"><span class="yj-rel-t">ADA Compliance Plugin for WordPress: Title II Grievance Form</span><span class="yj-rel-p">$60</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/photographer-website-template"><span class="yj-rel-t">Photographer Website Template — 27-Page Wedding & Portrait Studio Site in Plai</span><span class="yj-rel-p">$49</span></a></div><style>.yj-rel-c{display:flex;flex-direction:column;gap:8px;padding:15px 16px;border:1px solid #e2e6ea;border-radius:6px;text-decoration:none;background:#fff}.yj-rel-c:hover{border-color:#b9c2cb;background:#fafbfc}.yj-rel-t{font:500 14.5px/1.42 system-ui,sans-serif;color:#1b1f24}.yj-rel-p{font:600 13px system-ui,sans-serif;color:#0a6238}</style></section><!--yj-share-s101--><div style="margin:28px 0 8px;text-align:center"><button id="yjcp" type="button" style="font:inherit;padding:10px 18px;border:1px solid #8884;border-radius:10px;background:transparent;cursor:pointer">Copy link</button><button id="yjimg" type="button" style="font:inherit;padding:10px 18px;margin-left:8px;border:1px solid #8884;border-radius:10px;background:transparent;cursor:pointer">Save result as image</button></div><script>(function(){var b=document.getElementById("yjimg");if(!b)return;b.addEventListener("click",function(){var o=document.getElementById("out");var txt=(o&&(o.innerText||o.textContent)||"").trim();if(!txt){b.textContent="(no result yet)";setTimeout(function(){b.textContent="Save result as image";},1500);return;}var lines=txt.split(String.fromCharCode(10)).filter(function(x){return x.trim();}).slice(0,10);var W=1200,P=56,c=document.createElement("canvas");c.width=W;var lh=38,H=P*2+70+lines.length*lh+60;c.height=H;var x=c.getContext("2d");x.fillStyle="#1a1512";x.fillRect(0,0,W,H);x.fillStyle="#f3e9d2";x.font="600 34px system-ui,Segoe UI,Arial";var t=(document.title||"").split("|")[0].trim();x.fillText(t.slice(0,54),P,P+34);x.font="22px ui-monospace,Menlo,Consolas,monospace";x.fillStyle="#e8dcc4";for(var i=0;i<lines.length;i++){x.fillText(lines[i].slice(0,88),P,P+70+i*lh+22);}x.font="600 22px system-ui,Segoe UI,Arial";x.fillStyle="#c9a227";var d=location.hostname.replace("www.","");x.fillText(d,W-P-x.measureText(d).width,H-P+6);c.toBlob(function(bl){var u=URL.createObjectURL(bl),a=document.createElement("a");a.href=u;a.download=(t||"result").replace(/[^a-z0-9]+/gi,"-").toLowerCase()+"-"+d+".png";document.body.appendChild(a);a.click();setTimeout(function(){URL.revokeObjectURL(u);a.remove();},2000);},"image/png");});})();</script><script>(function(){var b=document.getElementById("yjcp");if(!b)return;var t=b.textContent;b.addEventListener("click",function(){var u=location.href.split("#")[0];function d(){b.textContent="Link copied";setTimeout(function(){b.textContent=t;},1800);}if(navigator.clipboard&&navigator.clipboard.writeText){navigator.clipboard.writeText(u).then(d,function(){prompt("",u);});}else{prompt("",u);}});})();</script><div class="yj-home-find"><div class="yj-lgbar"><a href="/" class="yj-lg on">EN</a><a href="/de/" class="yj-lg">DE</a><a href="/ja/" class="yj-lg">JA</a><a href="/es/" class="yj-lg">ES</a><a href="/pt/" class="yj-lg">PT</a></div><section class="yj-find"><h2>Find a tool</h2><input id="yjq" type="search" autocomplete="off" placeholder="Type a product name, format or task"><div id="yjr"></div></section><style>.yj-lgbar{position:absolute;top:14px;right:18px;display:flex;gap:6px;z-index:60}.yj-lg{font:600 12px/1 system-ui,sans-serif;padding:6px 9px;border-radius:4px;text-decoration:none;color:#8b96a3;border:1px solid rgba(140,150,165,.28)}.yj-lg:hover{color:#e8eaed;border-color:rgba(160,175,195,.6)}.yj-lg.on{color:#0e1116;background:#cfd6de;border-color:#cfd6de}.yj-find{max-width:760px;margin:34px auto 8px;padding:0 20px}.yj-find h2{font:600 20px/1.3 system-ui,sans-serif;margin:0 0 10px}#yjq{width:100%;box-sizing:border-box;padding:13px 15px;font:400 15.5px system-ui,sans-serif;border:1px solid rgba(140,150,165,.34);border-radius:8px;background:rgba(255,255,255,.04);color:inherit}#yjq:focus{outline:none;border-color:#7FD1C4}#yjr{margin-top:10px;display:flex;flex-direction:column;gap:6px}#yjr a{display:flex;justify-content:space-between;gap:12px;padding:11px 14px;border:1px solid rgba(140,150,165,.22);border-radius:6px;text-decoration:none;font:400 14.5px/1.4 system-ui,sans-serif;color:inherit}#yjr a:hover{border-color:#7FD1C4}#yjr .pr{font:600 13px system-ui,sans-serif;color:#5fbf9a;white-space:nowrap}</style><script>(function(){var q=document.getElementById("yjq"),r=document.getElementById("yjr"),D=null;function load(){if(D)return Promise.resolve(D);return fetch("/search-index.json").then(function(x){return x.json();}).then(function(j){D=j;return j;}).catch(function(){D=[];return D;});}function esc(t){return String(t).replace(/[&<>"]/g,function(c){return {"&":"&","<":"<",">":">",'"':"""}[c];});}function run(){var v=q.value.trim().toLowerCase();if(v.length<2){r.innerHTML="";return;}load().then(function(j){var w=v.split(/\s+/),o=[];for(var i=0;i<j.length&&o.length<12;i++){var t=j[i].t.toLowerCase();var ok=true;for(var k=0;k<w.length;k++){if(t.indexOf(w[k])<0){ok=false;break;}}if(ok)o.push(j[i]);}r.innerHTML=o.length?o.map(function(x){return "<a href=\""+esc(x.u)+"\">"+"<span>"+esc(x.t)+"</span>"+(x.p?"<span class=\"pr\">$"+x.p+"</span>":"")+"</a>";}).join(""):"";});}q.addEventListener("input",run);q.addEventListener("focus",load);})();</script></div>
|
| 79 |
+
|
| 80 |
+
|
| 81 |
+
<script data-yj="yj-view-beacon">(function(){try{var p=location.pathname;var k='yjv:'+p;if(sessionStorage.getItem(k))return;sessionStorage.setItem(k,'1');fetch('/api/ev',{method:'POST',keepalive:true,headers:{'Content-Type':'application/json'},body:JSON.stringify({path:p,lang:"en",ref:(document.referrer||''),src:(function(){try{return (new URLSearchParams(location.search).get('ref')||'').replace(/[^a-z_]/g,'').slice(0,12)}catch(e){return ''}})()})}).catch(function(){});}catch(e){}})();</script>
|
| 82 |
+
|
| 83 |
+
<script data-yj="yj-use-beacon">(function(){try{var o=document.getElementById('out');if(!o)return;var p=location.pathname,k='yju:'+p,sent=false;function fire(){if(sent||sessionStorage.getItem(k))return;if(!(o.textContent||'').replace(/\s+/g,'').length)return;sent=true;sessionStorage.setItem(k,'1');fetch('/api/ev',{method:'POST',keepalive:true,headers:{'Content-Type':'application/json'},body:JSON.stringify({path:p,lang:"en",t:'use',src:(function(){try{return (new URLSearchParams(location.search).get('ref')||'').replace(/[^a-z_]/g,'').slice(0,12)}catch(e){return ''}})()})}).catch(function(){});}var mo=new MutationObserver(function(){fire();if(sent)mo.disconnect();});mo.observe(o,{childList:true,characterData:true,subtree:true});}catch(e){}})();</script>
|