1+ <!DOCTYPE html>
2+ < html lang ="en ">
3+ < head >
4+ < meta charset ="UTF-8 ">
5+ < meta http-equiv ="X-UA-Compatible " content ="IE=edge ">
6+ < meta name ="viewport " content ="width=device-width, initial-scale=1.0 ">
7+ < meta name ="generator " content ="Asciidoctor 2.0.23 ">
8+ < title > Donate ❤️</ title >
9+ < style >
10+ @import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700" ;
11+ @import "https://cdn.jsdelivr.net/gh/asciidoctor/asciidoctor@2.0/data/stylesheets/asciidoctor-default.css" ;
12+
13+
14+ code {
15+ background : rgba (160 , 210 , 255 , 255 ) !important ;
16+ font-weight : bolder !important ;
17+ }
18+
19+
20+ div .sect2 {
21+ margin-bottom : 7em ;
22+ }
23+ </ style >
24+ < style >
25+ /*! Asciidoctor Tabs | Copyright (c) 2018-present Dan Allen | MIT License */
26+ .tabs {
27+ margin-bottom : 1.25em ;
28+ }
29+
30+ .tablist > ul {
31+ display : flex;
32+ flex-wrap : wrap;
33+ list-style : none;
34+ margin : 0 ;
35+ padding : 0 ;
36+ }
37+
38+ .tablist > ul li {
39+ align-items : center;
40+ background-color : # fff ;
41+ cursor : pointer;
42+ display : flex;
43+ font-weight : bold;
44+ line-height : 1.5 ;
45+ padding : 0.25em 1em ;
46+ position : relative;
47+ }
48+
49+ .tablist > ul li : focus-visible {
50+ outline : none;
51+ }
52+
53+ .tablist .ulist ,
54+ .tablist .ulist > ul li {
55+ margin : 0 ;
56+ }
57+
58+ .tablist .ulist > ul li + li {
59+ margin-left : 0.25em ;
60+ }
61+
62+ .tabs .tablist li ::after {
63+ content : "" ;
64+ display : block;
65+ height : 1px ;
66+ position : absolute;
67+ bottom : -1px ;
68+ left : 0 ;
69+ right : 0 ;
70+ }
71+
72+ .tabs .is-loading .tablist li : not (: first-child ),
73+ .tabs : not (.is-loading ) .tablist li : not (.is-selected ) {
74+ background-color : # f5f5f5 ;
75+ }
76+
77+ .tabs .is-loading .tablist li : first-child ::after ,
78+ .tabs : not (.is-loading ) .tablist li .is-selected ::after {
79+ background-color : # fff ;
80+ }
81+
82+ /*
83+ .tabs:not(.is-loading) .tablist li,
84+ .tabs:not(.is-loading) .tablist li::after {
85+ transition: background-color 200ms ease-in-out;
86+ }
87+ */
88+
89+ .tablist > ul p {
90+ line-height : inherit;
91+ margin : 0 ;
92+ }
93+
94+ .tabpanel {
95+ background-color : # fff ;
96+ padding : 1.25em ;
97+ }
98+
99+ .tablist > ul li ,
100+ .tabpanel {
101+ border : 1px solid # dcdcdc ;
102+ }
103+
104+ .tablist > ul li {
105+ border-bottom : 0 ;
106+ }
107+
108+ .tabs .is-loading .tabpanel + .tabpanel ,
109+ .tabs : not (.is-loading ) .tabpanel .is-hidden {
110+ display : none;
111+ }
112+
113+ .tabpanel > : first-child {
114+ margin-top : 0 ;
115+ }
116+
117+ /* #content is a signature of the Asciidoctor standalone HTML output */
118+ # content .tabpanel > : last-child ,
119+ # content .tabpanel > : last-child > : last-child ,
120+ # content .tabpanel > : last-child > : last-child > li : last-child > : last-child {
121+ margin-bottom : 0 ;
122+ }
123+
124+ .tablecontainer {
125+ overflow-x : auto;
126+ }
127+
128+ # content .tablecontainer {
129+ margin-bottom : 1.25em ;
130+ }
131+
132+ # content .tablecontainer > table .tableblock {
133+ margin-bottom : 0 ;
134+ }
135+ </ style >
136+ </ head >
137+ < body class ="article ">
138+ < div id ="header ">
139+ </ div >
140+ < div id ="content ">
141+ < div class ="sect1 ">
142+ < h2 id ="_donate_️ "> Donate ❤️</ h2 >
143+ < div class ="sectionbody ">
144+ < div class ="paragraph ">
145+ < p > I hope you’re finding KrabzCAM useful in your projects.
146+ I’ve built and maintained this software as a free tool for the community.
147+ If you’ve benefited from using it and would like to show your appreciation,
148+ I kindly invite you to consider making a voluntary donation.</ p >
149+ </ div >
150+ < div class ="paragraph ">
151+ < p > Your support helps me dedicate time and resources to maintain, improve, and expand the software — and it means a lot.
152+ Even small contributions make a big difference.</ p >
153+ </ div >
154+ < div class ="paragraph ">
155+ < p > < code > bitcoin:BC1QVEDQZQCDYCZ5T5ASX3APAN2N9DDSNRYJDEDWE2</ code > </ p >
156+ </ div >
157+ </ div >
158+ </ div >
159+ </ div >
160+ < script >
161+ ; ( function ( ) { /*! Asciidoctor Tabs | Copyright (c) 2018-present Dan Allen | MIT License */
162+ 'use strict'
163+
164+ var config = ( document . currentScript || { } ) . dataset || { }
165+ var forEach = Array . prototype . forEach
166+
167+ init ( document . querySelectorAll ( '.tabs' ) )
168+
169+ function init ( tabsBlocks ) {
170+ if ( ! tabsBlocks . length ) return
171+ forEach . call ( tabsBlocks , function ( tabs ) {
172+ var syncIds = tabs . classList . contains ( 'is-sync' ) ? { } : undefined
173+ var tablist = tabs . querySelector ( '.tablist ul' )
174+ tablist . setAttribute ( 'role' , 'tablist' )
175+ var start
176+ forEach . call ( tablist . querySelectorAll ( 'li' ) , function ( tab , idx ) {
177+ tab . tabIndex = - 1
178+ tab . setAttribute ( 'role' , tab . classList . add ( 'tab' ) || 'tab' )
179+ var id , anchor , syncId
180+ if ( ! ( id = tab . id ) && ( anchor = tab . querySelector ( 'a[id]' ) ) ) {
181+ id = tab . id = anchor . parentNode . removeChild ( anchor ) . id
182+ }
183+ var panel = id && tabs . querySelector ( '.tabpanel[aria-labelledby~="' + id + '"]' )
184+ if ( ! panel ) return idx ? undefined : toggleSelected ( tab , true ) // invalid state
185+ syncIds && ( ( ( syncId = tab . textContent . trim ( ) ) in syncIds ) ? ( syncId = undefined ) : true ) &&
186+ ( syncIds [ ( tab . dataset . syncId = syncId ) ] = tab )
187+ idx || ( syncIds && ( start = { tab : tab , panel : panel } ) ) ? toggleHidden ( panel , true ) : toggleSelected ( tab , true )
188+ tab . setAttribute ( 'aria-controls' , panel . id )
189+ panel . setAttribute ( 'role' , 'tabpanel' )
190+ var onClick = syncId === undefined ? activateTab : activateTabSync
191+ tab . addEventListener ( 'click' , onClick . bind ( { tabs : tabs , tab : tab , panel : panel } ) )
192+ } )
193+ if ( ! tabs . closest ( '.tabpanel' ) ) {
194+ forEach . call ( tabs . querySelectorAll ( '.tabpanel table.tableblock' ) , function ( table ) {
195+ var container = Object . assign ( document . createElement ( 'div' ) , { className : 'tablecontainer' } )
196+ table . parentNode . insertBefore ( container , table ) . appendChild ( table )
197+ } )
198+ }
199+ if ( start ) {
200+ var syncGroupId
201+ for ( var i = 0 , lst = tabs . classList , len = lst . length , className ; i !== len ; i ++ ) {
202+ if ( ! ( className = lst . item ( i ) ) . startsWith ( 'data-sync-group-id=' ) ) continue
203+ tabs . dataset . syncGroupId = syncGroupId = lst . remove ( className ) || className . slice ( 19 ) . replace ( / \u00a0 / g, ' ' )
204+ break
205+ }
206+ if ( syncGroupId === undefined ) tabs . dataset . syncGroupId = syncGroupId = Object . keys ( syncIds ) . sort ( ) . join ( '|' )
207+ var preferredSyncId = 'syncStorageKey' in config &&
208+ window [ ( config . syncStorageScope || 'local' ) + 'Storage' ] . getItem ( config . syncStorageKey + '-' + syncGroupId )
209+ var tab = preferredSyncId && syncIds [ preferredSyncId ]
210+ tab && Object . assign ( start , { tab : tab , panel : document . getElementById ( tab . getAttribute ( 'aria-controls' ) ) } )
211+ toggleSelected ( start . tab , true ) || toggleHidden ( start . panel , false )
212+ }
213+ } )
214+ onHashChange ( )
215+ toggleClassOnEach ( tabsBlocks , 'is-loading' , 'remove' )
216+ window . setTimeout ( toggleClassOnEach . bind ( null , tabsBlocks , 'is-loaded' , 'add' ) , 0 )
217+ window . addEventListener ( 'hashchange' , onHashChange )
218+ }
219+
220+ function activateTab ( e ) {
221+ var tab = this . tab
222+ var tabs = this . tabs || ( this . tabs = tab . closest ( '.tabs' ) )
223+ var panel = this . panel || ( this . panel = document . getElementById ( tab . getAttribute ( 'aria-controls' ) ) )
224+ querySelectorWithSiblings ( tabs , '.tablist .tab' , 'tab' ) . forEach ( function ( el ) {
225+ toggleSelected ( el , el === tab )
226+ } )
227+ querySelectorWithSiblings ( tabs , '.tabpanel' , 'tabpanel' ) . forEach ( function ( el ) {
228+ toggleHidden ( el , el !== panel )
229+ } )
230+ if ( ! this . isSync && 'syncStorageKey' in config && 'syncGroupId' in tabs . dataset ) {
231+ var storageKey = config . syncStorageKey + '-' + tabs . dataset . syncGroupId
232+ window [ ( config . syncStorageScope || 'local' ) + 'Storage' ] . setItem ( storageKey , tab . dataset . syncId )
233+ }
234+ if ( ! e ) return
235+ var loc = window . location
236+ var hashIdx = loc . hash ? loc . href . indexOf ( '#' ) : - 1
237+ if ( ~ hashIdx ) window . history . replaceState ( null , '' , loc . href . slice ( 0 , hashIdx ) )
238+ e . preventDefault ( )
239+ }
240+
241+ function activateTabSync ( e ) {
242+ activateTab . call ( this , e )
243+ var thisTabs = this . tabs
244+ var thisTab = this . tab
245+ var initialY = thisTabs . getBoundingClientRect ( ) . y
246+ forEach . call ( document . querySelectorAll ( '.tabs' ) , function ( tabs ) {
247+ if ( tabs === thisTabs || tabs . dataset . syncGroupId !== thisTabs . dataset . syncGroupId ) return
248+ querySelectorWithSiblings ( tabs , '.tablist .tab' , 'tab' ) . forEach ( function ( tab ) {
249+ if ( tab . dataset . syncId === thisTab . dataset . syncId ) activateTab . call ( { tabs : tabs , tab : tab , isSync : true } )
250+ } )
251+ } )
252+ var shiftedBy = thisTabs . getBoundingClientRect ( ) . y - initialY
253+ if ( shiftedBy && ( shiftedBy = Math . round ( shiftedBy ) ) ) window . scrollBy ( { top : shiftedBy , behavior : 'instant' } )
254+ }
255+
256+ function querySelectorWithSiblings ( scope , selector , siblingClass ) {
257+ var el = scope . querySelector ( selector )
258+ if ( ! el ) return [ ]
259+ var result = [ el ]
260+ while ( ( el = el . nextElementSibling ) && el . classList . contains ( siblingClass ) ) result . push ( el )
261+ return result
262+ }
263+
264+ function toggleClassOnEach ( elements , className , method ) {
265+ forEach . call ( elements , function ( el ) {
266+ el . classList [ method ] ( className )
267+ } )
268+ }
269+
270+ function toggleHidden ( el , state ) {
271+ el . classList [ ( el . hidden = state ) ? 'add' : 'remove' ] ( 'is-hidden' )
272+ }
273+
274+ function toggleSelected ( el , state ) {
275+ el . setAttribute ( 'aria-selected' , '' + state )
276+ el . classList [ state ? 'add' : 'remove' ] ( 'is-selected' )
277+ el . tabIndex = state ? 0 : - 1
278+ }
279+
280+ function onHashChange ( ) {
281+ var id = window . location . hash . slice ( 1 )
282+ if ( ! id ) return
283+ var tab = document . getElementById ( ~ id . indexOf ( '%' ) ? decodeURIComponent ( id ) : id )
284+ if ( ! ( tab && tab . classList . contains ( 'tab' ) ) ) return
285+ 'syncId' in tab . dataset ? activateTabSync . call ( { tab : tab } ) : activateTab . call ( { tab : tab } )
286+ }
287+ } ) ( )
288+ </ script >
289+ </ body >
290+ </ html >
0 commit comments