.github/images/modal.webp
.github/images/modal.webp
This is a binary file and will not be displayed.
.github/images/preview.webp
.github/images/preview.webp
This is a binary file and will not be displayed.
.github/images/settings.webp
.github/images/settings.webp
This is a binary file and will not be displayed.
+25
LICENSE.md
+25
LICENSE.md
···
+44
README.md
+44
README.md
···+<img src="https://cachet.dunkirk.sh/emojis/bluesky/r" height="175" align="right" alt="Bluesky logo">+> A userscript that lets you appoint your own trusted verifiers and display verifications from their `app.bsky.graph.verification` collection.+> ⚠️ **extremely rapidly iterating so nothing is stable** - so far everything is still backwards compatible though!+By default we have `bsky.app`, `nytimes.com`, `wired.com`, and `theathletic.bsky.social` as trusted verifiers. You can add more by going to bluesky settings and clicking on "Community Verifications"+That will open a modal where you can add more trusted verifiers and modify how the verification badge looks.++- Chrome: [Tampermonkey](https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo)+- Edge: [Tampermonkey](https://microsoftedge.microsoft.com/addons/detail/tampermonkey/iikmkjmpaadaobahmlepeloendndfphd)+2. Click [here](https://github.com/taciturnaxolotl/serif/raw/refs/heads/main/bluesky-community-verifications.user.js) to install the script.+The code is licensed under `AGPL 3.0`! That means AGPL 3.0 requires publishing source code changes when the software is used over a network, guaranteeing that users can access the code. All artwork and images are copyright reserved but may be used with proper attribution to the authors.+<img src="https://raw.githubusercontent.com/taciturnaxolotl/carriage/master/.github/images/line-break.svg" />+<i><code>© 2025-present <a href="https://github.com/taciturnaxolotl">Kieran Klukas</a></code></i>+<a href="https://github.com/taciturnaxolotl/serif/blob/master/LICENSE.md"><img src="https://img.shields.io/static/v1.svg?style=for-the-badge&label=License&message=MIT&logoColor=d9e0ee&colorA=363a4f&colorB=b7bdf8"/></a>
+12
bluesky-community-verifications.meta.js
+12
bluesky-community-verifications.meta.js
···+// @updateURL https://tangled.sh/@dunkirk.sh/serif/raw/main/bluesky-community-verifications.user.meta.js+// @downloadURL https://tangled.sh/@dunkirk.sh/serif/raw/main/bluesky-community-verifications.user.js
+890
-220
bluesky-community-verifications.user.js
+890
-220
bluesky-community-verifications.user.js
···+// @updateURL https://tangled.sh/@dunkirk.sh/serif/raw/main/bluesky-community-verifications.user.meta.js+// @downloadURL https://tangled.sh/@dunkirk.sh/serif/raw/main/bluesky-community-verifications.user.js···············+`https://public.api.bsky.app/xrpc/app.bsky.actor.searchActors?term=${encodeURIComponent(searchQuery)}&limit=5`,+? `https://bsky.social/xrpc/com.atproto.repo.listRecords?repo=${userHandle}&collection=app.bsky.graph.verification&cursor=${cursor}`+: `https://bsky.social/xrpc/com.atproto.repo.listRecords?repo=${userHandle}&collection=app.bsky.graph.verification`;+<svg fill="none" width="28" viewBox="0 0 24 24" height="28" style="color: rgb(241, 243, 245);">+<path fill="hsl(211, 20%, 95.3%)" d="M21.2,9.3c-0.5-0.5-1.1-0.7-1.8-0.7h-2.3V6.3c0-2.1-1.7-3.7-3.7-3.7h-3c-2.1,0-3.7,1.7-3.7,3.7v2.3H4.6+c-0.7,0-1.3,0.3-1.8,0.7c-0.5,0.5-0.7,1.1-0.7,1.8v9.3c0,0.7,0.3,1.3,0.7,1.8c0.5,0.5,1.1,0.7,1.8,0.7h14.9c0.7,0,1.3-0.3,1.8-0.7+c0.5-0.5,0.7-1.1,0.7-1.8v-9.3C22,10.4,21.7,9.8,21.2,9.3z M14.1,15.6l-1.3,1.3c-0.1,0.1-0.3,0.2-0.5,0.2c-0.2,0-0.3-0.1-0.5-0.2l-3.3-3.3+c-0.1-0.1-0.2-0.3-0.2-0.5c0-0.2,0.1-0.3,0.2-0.5l1.3-1.3c0.1-0.1,0.3-0.2,0.5-0.2c0.2,0,0.3,0.1,0.5,0.2l1.5,1.5l4.2-4.2+c0.1-0.1,0.3-0.2,0.5-0.2c0.2,0,0.3,0.1,0.5,0.2l1.3,1.3c0.1,0.1,0.2,0.3,0.2,0.5c0,0.2-0.1,0.3-0.2,0.5L14.1,15.6z M9.7,6.3···+<input type="radio" name="badgeType" value="checkmark" ${getBadgeType() === "checkmark" ? "checked" : ""}>+<input type="radio" name="badgeType" value="star" ${getBadgeType() === "star" ? "checked" : ""}>+<input type="radio" name="badgeType" value="heart" ${getBadgeType() === "heart" ? "checked" : ""}>+<input type="radio" name="badgeType" value="shield" ${getBadgeType() === "shield" ? "checked" : ""}>+<input type="radio" name="badgeType" value="lock" ${getBadgeType() === "lock" ? "checked" : ""}>+<input type="radio" name="badgeType" value="verified" ${getBadgeType() === "verified" ? "checked" : ""}>+<input type="color" id="badgeColorPicker" value="${getBadgeColor()}" style="margin-right: 10px;">+<span id="badgeColorPreview" style="display: inline-block; width: 24px; height: 24px; background-color: ${getBadgeColor()}; border-radius: 50%; margin-right: 10px;"></span>+<button id="resetBadgeColor" style="padding: 5px 10px; background: #473A3A; color: white; border: none; border-radius: 4px; cursor: pointer;">Reset to Default</button>-<input id="trustedUserInput" type="text" placeholder="username.bsky.social" style="flex: 1; padding: 8px; margin-right: 10px; border: 1px solid #ccc; border-radius: 4px;">-<button id="addTrustedUserBtn" style="background-color: #2D578D; color: white; border: none; border-radius: 4px; padding: 8px 15px; cursor: pointer;">Add</button>+<input id="trustedUserInput" type="text" placeholder="Search for a user..." style="flex: 1; padding: 8px; margin-right: 10px; border: 1px solid #ccc; border-radius: 4px;">+<button id="addTrustedUserBtn" style="background-color: #2D578D; color: white; border: none; border-radius: 4px; padding: 8px 15px; cursor: pointer;">Add</button>·········-`https://bsky.social/xrpc/com.atproto.repo.getRecord?repo=${handle}&collection=app.bsky.actor.profile&rkey=self`,+`https://public.api.bsky.app/xrpc/com.atproto.repo.getRecord?repo=${handle}&collection=app.bsky.actor.profile&rkey=self`,···-`https://bsky.social/xrpc/com.atproto.repo.listRecords?repo=${handle}&collection=app.bsky.graph.verification`,+`https://public.api.bsky.app/xrpc/com.atproto.repo.getRecord?repo=${handle}&collection=app.bsky.actor.profile&rkey=self`,+// Also check periodically for posts that might have been loaded but not caught by the observer······
site/favicon/apple-touch-icon.png
site/favicon/apple-touch-icon.png
This is a binary file and will not be displayed.
site/favicon/favicon-96x96.png
site/favicon/favicon-96x96.png
This is a binary file and will not be displayed.
site/favicon/favicon.ico
site/favicon/favicon.ico
This is a binary file and will not be displayed.
+26
site/favicon/favicon.svg
+26
site/favicon/favicon.svg
···+<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><svg viewBox="0 0 128 128" xmlns="http://www.w3.org/2000/svg">+<path d="M120.27,7.69 C117.89,5.31 114.72,4 111.36,4 C108,4 104.83,5.31 102.45,7.69 C97.54,12.61 97.54,20.61 102.45,25.53 C104.83,27.91 108,29.22 111.36,29.22 C114.73,29.22 117.89,27.91 120.28,25.53 C125.19,20.61 125.19,12.61 120.27,7.69 Z M106.38,11.63 C107.71,10.3 109.48,9.57 111.35,9.57 C113.22,9.57 115,10.3 116.33,11.63 C119.08,14.38 119.08,18.85 116.33,21.59 C115,22.92 113.23,23.65 111.35,23.65 C109.47,23.65 107.7,22.92 106.38,21.59 C103.64,18.85 103.64,14.38 106.38,11.63 Z" fill="#E2A610"></path>+<path d="M105.51,30.95 L97.04,22.47 L103.08,16.42 C104.42,15.08 106.59,15.08 107.94,16.42 L111.56,20.04 C112.9,21.38 112.9,23.55 111.56,24.89 L105.51,30.95 Z" fill="#FFCA28"></path>+<path d="M107.69,28.76 C107.69,28.76 109.02,26.09 105.45,22.52 C101.88,18.95 99.18,20.32 99.18,20.32 L97.04,22.47 L105.51,30.95 L107.69,28.76 Z" fill="#E2A610"></path>+<path d="M120.7,65.63 A58.33 58.37 0 1 1 4.04,65.63 A58.33 58.37 0 1 1 120.7,65.63 Z" fill="#FFCA28"></path>+<path d="M109.66,65.63 A47.29 47.32 0 1 1 15.08,65.63 A47.29 47.32 0 1 1 109.66,65.63 Z" fill="#FFFFFF"></path>+<path d="M68.78,72.05 L62.37,99.76 L55.96,72.05 L28.26,65.63 L55.96,59.22 L62.37,31.5 L68.78,59.22 L96.48,65.63 Z" fill="#E0C3AB"></path>+<path d="M71.43,65.63 L86.49,89.77 L62.37,74.7 L38.25,89.77 L53.31,65.63 L38.25,41.5 L62.37,56.56 L86.49,41.5 Z" fill="#B2947C"></path>+<path d="M50.45,86.94 C50.45,86.94 63.27,77.85 68.13,72.99 C73,68.14 83.26,53.87 83.26,53.87 C86.01,50.82 89.1,43.11 89.96,40.87 C90.05,40.63 89.82,40.39 89.58,40.48 C87.62,41.23 81.41,43.68 77.08,46.44 C71.67,49.9 61.99,57.81 57.48,62.32 C52.97,66.83 47.11,75.52 43.78,80.25 C41,84.21 37.52,91.57 36.47,93.86 C36.35,94.11 36.61,94.37 36.86,94.26 C39.22,93.27 46.87,89.9 50.45,86.94 Z" fill="#212121" opacity="0.32"></path>+<path d="M82.66,52.46 C85.52,48.81 88.23,41.62 89.03,39.39 C89.13,39.12 88.87,38.86 88.59,38.95 C86.36,39.75 79.18,42.47 75.53,45.33 C71.18,48.74 56.71,60.63 56.71,60.63 L67.36,71.29 C67.37,71.29 79.25,56.81 82.66,52.46 Z" fill="#F44336"></path>+<path d="M41.41,79.48 C38.55,83.13 35.84,90.32 35.04,92.55 C34.94,92.82 35.2,93.08 35.48,92.99 C37.71,92.19 44.89,89.47 48.54,86.61 C52.89,83.2 67.36,71.31 67.36,71.31 L56.7,60.65 C56.7,60.65 44.82,75.12 41.41,79.48 Z" fill="#2F7889"></path>+<path d="M69.59,65.98 A7.56 7.57 0 1 1 54.47,65.98 A7.56 7.57 0 1 1 69.59,65.98 Z" fill="#94D1E0"></path>+<path d="M90.46,37.52 L90.46,37.52 C89.12,36.18 89.12,34 90.46,32.66 L94.02,29.1 L98.88,33.96 L95.33,37.52 C93.98,38.87 91.8,38.87 90.46,37.52 Z" fill="#F44336"></path>+<path d="M34.28,93.74 L34.28,93.74 C35.62,95.08 35.62,97.26 34.28,98.6 L30.72,102.16 L25.86,97.3 L29.41,93.74 C30.76,92.4 32.94,92.4 34.28,93.74 Z" fill="#B2947C"></path>+<path d="M102.1,65.63 L102.1,65.63 C102.1,63.73 103.64,62.19 105.54,62.19 L110.56,62.19 L110.56,69.07 L105.54,69.07 C103.64,69.07 102.1,67.53 102.1,65.63 Z" fill="#E0C3AB"></path>+<path d="M22.65,65.63 L22.65,65.63 C22.65,67.53 21.11,69.07 19.21,69.07 L14.19,69.07 L14.19,62.19 L19.21,62.19 C21.11,62.19 22.65,63.73 22.65,65.63 Z" fill="#E0C3AB"></path>+<path d="M90.46,93.74 L90.46,93.74 C91.8,92.4 93.98,92.4 95.32,93.74 L98.87,97.3 L94.01,102.16 L90.45,98.6 C89.12,97.26 89.12,95.09 90.46,93.74 Z" fill="#B2947C"></path>+<path d="M34.28,37.52 L34.28,37.52 C32.94,38.86 30.76,38.86 29.42,37.52 L25.87,33.96 L30.73,29.1 L34.29,32.66 C35.62,34 35.62,36.18 34.28,37.52 Z" fill="#B2947C"></path>+<path d="M62.37,105.38 L62.37,105.38 C64.27,105.38 65.81,106.92 65.81,108.82 L65.81,113.85 L58.94,113.85 L58.94,108.82 C58.93,106.92 60.47,105.38 62.37,105.38 Z" fill="#E0C3AB"></path>+<path d="M62.37,25.88 L62.37,25.88 C60.47,25.88 58.93,24.34 58.93,22.44 L58.93,17.41 L65.8,17.41 L65.8,22.44 C65.81,24.34 64.27,25.88 62.37,25.88 Z" fill="#E0C3AB"></path>+<path d="M111.16,65.63 Q111.16,85.852 96.87,100.151 Q82.58,114.45 62.37,114.45 Q42.16,114.45 27.87,100.151 Q13.58,85.852 13.58,65.63 Q13.58,45.408 27.87,31.109 Q42.16,16.81 62.37,16.81 Q82.58,16.81 96.87,31.109 Q111.16,45.408 111.16,65.63 Z M108.16,65.63 Q108.16,46.65 94.748,33.23 Q81.337,19.81 62.37,19.81 Q43.403,19.81 29.992,33.23 Q16.58,46.65 16.58,65.63 Q16.58,84.609 29.992,98.03 Q43.403,111.45 62.37,111.45 Q81.337,111.45 94.748,98.03 Q108.16,84.609 108.16,65.63 Z" fill="#E2A610"></path>+<path d="M8.72,64.92 C8.72,64.92 6.6,54.18 12.25,40.88 C20.59,21.26 38.6,10.46 57.97,9.62 C72.5,8.99 80.88,13.78 80.88,13.78 C80.88,13.78 69.06,12.81 60.91,13.17 C41.25,14.04 27.59,23.01 18.23,38.35 C10.53,50.99 8.72,64.92 8.72,64.92 Z" fill="#FFF59D"></path>
+21
site/favicon/site.webmanifest
+21
site/favicon/site.webmanifest
···
site/favicon/web-app-manifest-192x192.png
site/favicon/web-app-manifest-192x192.png
This is a binary file and will not be displayed.
site/favicon/web-app-manifest-512x512.png
site/favicon/web-app-manifest-512x512.png
This is a binary file and will not be displayed.
+262
site/index.html
+262
site/index.html
···
site/og.png
site/og.png
This is a binary file and will not be displayed.
+204
site/og.svg
+204
site/og.svg
···+d="m -23.077937,6.6686188 c -0.595,-0.5950003 -1.3875,-0.9225003 -2.2275,-0.9225003 -0.84,0 -1.6325,0.3275 -2.2275,0.9225003 -1.2275,1.2300002 -1.2275,3.2300002 0,4.4600002 0.595,0.595 1.3875,0.9225 2.2275,0.9225 0.8425,0 1.6325,-0.3275 2.23,-0.9225 1.2275,-1.23 1.2275,-3.23 -0.002,-4.4600002 z m -3.4725,0.9850002 c 0.3325,-0.3325002 0.775,-0.5150002 1.2425,-0.5150002 0.4675,0 0.9125,0.1825 1.245,0.5150002 0.6875,0.6875 0.6875,1.805 0,2.49 -0.3325,0.3325 -0.775,0.515 -1.245,0.515 -0.47,0 -0.9125,-0.1825 -1.2425,-0.515 -0.685,-0.685 -0.685,-1.8025 0,-2.49 z"+d="m -26.767937,12.483619 -2.1175,-2.12 1.51,-1.5125 c 0.335,-0.335 0.8775,-0.335 1.215,0 l 0.905,0.905 c 0.335,0.335 0.335,0.8775 0,1.2125 z"+d="m -26.222937,11.936119 c 0,0 0.3325,-0.6675 -0.56,-1.56 -0.8925,-0.8925 -1.5675,-0.55 -1.5675,-0.55 l -0.535,0.5375 2.1175,2.12 z"+d="m -35.950437,22.758619 -1.6025,6.9275 -1.6025,-6.9275 -6.925,-1.605 6.925,-1.6025 1.6025,-6.93 1.6025,6.93 6.925,1.6025 z"+d="m -35.287937,21.153619 3.765,6.035 -6.03,-3.7675 -6.03,3.7675 3.765,-6.035 -3.765,-6.0325 6.03,3.765 6.03,-3.765 z"+d="m -40.532937,26.481119 c 0,0 3.205,-2.2725 4.42,-3.4875 1.2175,-1.2125 3.7825,-4.78 3.7825,-4.78 0.6875,-0.7625 1.46,-2.69 1.675,-3.25 0.0225,-0.06 -0.035,-0.12 -0.095,-0.0975 -0.49,0.1875 -2.0425,0.8 -3.125,1.49 -1.3525,0.865 -3.7725,2.8425 -4.9,3.97 -1.1275,1.1275 -2.5925,3.3 -3.425,4.4825 -0.695,0.99 -1.565,2.83 -1.8275,3.4025 -0.03,0.0625 0.035,0.1275 0.0975,0.1 0.59,-0.2475 2.5025,-1.09 3.3975,-1.83 z"+d="m -32.480437,17.861119 c 0.715,-0.9125 1.3925,-2.71 1.5925,-3.2675 0.025,-0.0675 -0.04,-0.1325 -0.11,-0.11 -0.5575,0.2 -2.3525,0.88 -3.265,1.595 -1.0875,0.8525 -4.705,3.825 -4.705,3.825 l 2.6625,2.665 c 0.002,0 2.9725,-3.62 3.825,-4.7075 z"+d="m -42.792937,24.616119 c -0.715,0.9125 -1.3925,2.71 -1.5925,3.2675 -0.025,0.0675 0.04,0.1325 0.11,0.11 0.5575,-0.2 2.3525,-0.88 3.265,-1.595 1.0875,-0.8525 4.705,-3.825 4.705,-3.825 l -2.665,-2.665 c 0,0 -2.97,3.6175 -3.8225,4.7075 z"+d="m -30.530437,14.126119 v 0 c -0.335,-0.335 -0.335,-0.88 0,-1.215 l 0.89,-0.89 1.215,1.215 -0.8875,0.89 c -0.3375,0.3375 -0.8825,0.3375 -1.2175,0 z"+d="m -44.575437,28.181119 v 0 c 0.335,0.335 0.335,0.88 0,1.215 l -0.89,0.89 -1.215,-1.215 0.8875,-0.89 c 0.3375,-0.335 0.8825,-0.335 1.2175,0 z"+d="m -27.620437,21.153619 v 0 c 0,-0.475 0.385,-0.86 0.86,-0.86 h 1.255 v 1.72 h -1.255 c -0.475,0 -0.86,-0.385 -0.86,-0.86 z"+d="m -47.482937,21.153619 v 0 c 0,0.475 -0.385,0.86 -0.86,0.86 h -1.255 v -1.72 h 1.255 c 0.475,0 0.86,0.385 0.86,0.86 z"+d="m -30.530437,28.181119 v 0 c 0.335,-0.335 0.88,-0.335 1.215,0 l 0.8875,0.89 -1.215,1.215 -0.89,-0.89 c -0.3325,-0.335 -0.3325,-0.8775 0.002,-1.215 z"+d="m -44.575437,14.126119 v 0 c -0.335,0.335 -0.88,0.335 -1.215,0 l -0.8875,-0.89 1.215,-1.215 0.89,0.89 c 0.3325,0.335 0.3325,0.88 -0.002,1.215 z"+d="m -37.552937,31.091119 v 0 c 0.475,0 0.86,0.385 0.86,0.86 v 1.2575 h -1.7175 v -1.2575 c -0.002,-0.475 0.3825,-0.86 0.8575,-0.86 z"+d="m -37.552937,11.216119 v 0 c -0.475,0 -0.86,-0.385 -0.86,-0.86 v -1.2575 h 1.7175 v 1.2575 c 0.002,0.475 -0.3825,0.86 -0.8575,0.86 z"+d="m -25.355437,21.153619 q 0,5.0555 -3.5725,8.63025 -3.5725,3.57475 -8.625,3.57475 -5.0525,0 -8.625,-3.57475 -3.5725,-3.57475 -3.5725,-8.63025 0,-5.0555 3.5725,-8.63025 3.5725,-3.57475 8.625,-3.57475 5.0525,0 8.625,3.57475 3.5725,3.57475 3.5725,8.63025 z m -0.75,0 q 0,-4.745 -3.353,-8.1 -3.35275,-3.355 -8.0945,-3.355 -4.74175,0 -8.0945,3.355 -3.353,3.355 -3.353,8.1 0,4.74475 3.353,8.1 3.35275,3.355 8.0945,3.355 4.74175,0 8.0945,-3.355 3.353,-3.35525 3.353,-8.1 z"+d="m -50.965437,20.976119 c 0,0 -0.53,-2.685 0.8825,-6.01 2.085,-4.905 6.5875,-7.6050002 11.43,-7.8150002 3.6325,-0.1575 5.7275,1.0400002 5.7275,1.0400002 0,0 -2.955,-0.2425 -4.9925,-0.1525 -4.915,0.2175 -8.33,2.46 -10.67,6.295 -1.925,3.16 -2.3775,6.6425 -2.3775,6.6425 z"+style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:146.667px;font-family:Serif;-inkscape-font-specification:'Serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:center;writing-mode:lr-tb;direction:ltr;white-space:pre;shape-inside:url(#rect1);display:inline;fill:#6f73d2;fill-opacity:1;stroke:none;stroke-width:0.895748"+style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:48px;font-family:Serif;-inkscape-font-specification:'Serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;white-space:pre;shape-inside:url(#rect1-9);display:inline;fill:#6f73d2;fill-opacity:1;stroke:none;stroke-width:0.895748"
+1225
site/pfp-updates/bsky-pfp-updates.sh
+1225
site/pfp-updates/bsky-pfp-updates.sh
···+if [ "$BLUESKY_HANDLE" = "your-handle.bsky.social" ] || [ "$BLUESKY_HANDLE" = "null" ] || [ -z "$BLUESKY_HANDLE" ]; then+elif [ "$BLUESKY_PASSWORD" = "your-app-password" ] || [ "$BLUESKY_PASSWORD" = "null" ] || [ -z "$BLUESKY_PASSWORD" ]; then+log_error "Bluesky authentication failed: $(echo "$auth_response" | jq -r '.message // "Unknown error"')"+"https://bsky.social/xrpc/com.atproto.repo.getRecord?repo=$did&collection=pfp.updates.${weather_type}&rkey=$rkey" \+if [ "$stored_hash" = "$image_hash" ] && [ -n "$stored_blob" ] && [ "$stored_blob" != "empty" ]; then+log_error "Failed to store blob reference: $(echo "$store_response" | jq -r '.message // "Unknown error"')"+"https://bsky.social/xrpc/com.atproto.repo.listRecords?repo=$did&collection=pfp.updates.${timeline}" \+echo "$list_response" | jq -r '.records[] | " hour \(.value.hour) - Hash: \(.value.imageHash[0:12])... (Created: \(.value.createdAt))"'+"https://bsky.social/xrpc/com.atproto.repo.listRecords?repo=$did&collection=pfp.updates.${timeline}" \+old_records=$(echo "$list_response" | jq --arg cutoff "$cutoff_date" '.records[] | select(.value.createdAt < $cutoff)')+-d "{\"repo\":\"$did\",\"collection\":\"pfp.updates.${timeline}\",\"rkey\":\"$rkey\"}" > /dev/null+"https://bsky.social/xrpc/com.atproto.repo.getRecord?repo=$did&collection=app.bsky.actor.profile&rkey=self" \+profile_data=$(echo "$current_profile" | jq --argjson avatar "$blob_ref" '.value | .avatar = $avatar')+log_error "Failed to update profile picture: $(echo "$update_response" | jq -r '.message // "Unknown error"')"+if [ "$SLACK_ENABLED" != "true" ] || [ -z "$SLACK_USER_TOKEN" ] || [ "$SLACK_USER_TOKEN" = "null" ]; then+if [ "$WEATHER_ENABLED" != "true" ] || [ -z "$WEATHER_API_KEY" ] || [ "$WEATHER_API_KEY" = "null" ]; then+geocode_response=$(curl -s "http://api.openweathermap.org/geo/1.0/direct?q=$WEATHER_LOCATION&limit=1&appid=$WEATHER_API_KEY")+weather_response=$(curl -s "http://api.openweathermap.org/data/2.5/weather?lat=$lat&lon=$lon&appid=$WEATHER_API_KEY" --connect-timeout 10)+local weather_main=$(echo "$weather_response" | jq -r '.weather[0].main' | tr '[:upper:]' '[:lower:]')+timeline=$(jq -r ".weather.timeline_mapping.\"$weather_main\" // \"$DEFAULT_TIMELINE\"" "$CONFIG_FILE")+if [ "$WEATHER_ENABLED" = "true" ] && [ -n "$WEATHER_API_KEY" ] && [ "$WEATHER_API_KEY" != "null" ]; then+Automatically updates your profile pictures across multiple platforms based on time and weather.
+2241
site/pfp-updates/index.html
+2241
site/pfp-updates/index.html
···+`Configuring hour ${hour} (${hour === 0 ? "12" : hour > 12 ? hour - 12 : hour}${hour < 12 ? "AM" : "PM"})`;+info.textContent = `${current}/${total} images rendered across ${timelineCount} timeline(s)`;