@kudoai/chatgpt.js 2.6.3 → 2.6.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (178) hide show
  1. package/README.md +341 -0
  2. package/chatgpt.js +6 -4
  3. package/dist/chatgpt.min.js +7 -0
  4. package/docs/README.md +341 -324
  5. package/docs/USERGUIDE.md +1812 -1814
  6. package/docs/de/README.md +341 -324
  7. package/docs/es/README.md +341 -324
  8. package/docs/fr/README.md +341 -324
  9. package/docs/hi/README.md +342 -325
  10. package/docs/it/README.md +341 -324
  11. package/docs/ja/README.md +341 -324
  12. package/docs/ko/README.md +346 -329
  13. package/docs/ne/README.md +342 -325
  14. package/docs/nl/README.md +341 -324
  15. package/docs/pt/README.md +341 -324
  16. package/docs/vi/README.md +341 -324
  17. package/docs/zh-cn/README.md +341 -324
  18. package/docs/zh-tw/README.md +340 -323
  19. package/package.json +50 -31
  20. package/starters/chrome/LICENSE.md +43 -0
  21. package/starters/chrome/docs/README.md +17 -1
  22. package/starters/chrome/docs/SECURITY.md +17 -0
  23. package/starters/chrome/docs/de/LICENSE.md +21 -3
  24. package/starters/chrome/docs/de/README.md +17 -1
  25. package/starters/chrome/docs/es/LICENSE.md +21 -3
  26. package/starters/chrome/docs/es/README.md +17 -1
  27. package/starters/chrome/docs/fr/LICENSE.md +21 -3
  28. package/starters/chrome/docs/fr/README.md +17 -1
  29. package/starters/chrome/docs/hi/LICENSE.md +21 -3
  30. package/starters/chrome/docs/hi/README.md +17 -2
  31. package/starters/chrome/docs/hi/SECURITY.md +17 -0
  32. package/starters/chrome/docs/it/LICENSE.md +21 -3
  33. package/starters/chrome/docs/it/README.md +17 -1
  34. package/starters/chrome/docs/ja/LICENSE.md +21 -3
  35. package/starters/chrome/docs/ja/README.md +17 -2
  36. package/starters/chrome/docs/ko/LICENSE.md +21 -3
  37. package/starters/chrome/docs/ko/README.md +17 -1
  38. package/starters/chrome/docs/nl/LICENSE.md +20 -3
  39. package/starters/chrome/docs/nl/README.md +17 -1
  40. package/starters/chrome/docs/pt/LICENSE.md +21 -3
  41. package/starters/chrome/docs/pt/README.md +17 -1
  42. package/starters/chrome/docs/vi/LICENSE.md +21 -3
  43. package/starters/chrome/docs/vi/README.md +17 -1
  44. package/starters/chrome/docs/zh-cn/LICENSE.md +21 -3
  45. package/starters/chrome/docs/zh-cn/README.md +17 -2
  46. package/starters/chrome/docs/zh-cn/SECURITY.md +17 -0
  47. package/starters/chrome/docs/zh-tw/LICENSE.md +21 -3
  48. package/starters/chrome/docs/zh-tw/README.md +17 -1
  49. package/starters/chrome/extension/content.js +1 -1
  50. package/starters/chrome/extension/lib/chatgpt.js +6 -4
  51. package/starters/chrome/extension/manifest.json +1 -1
  52. package/starters/greasemonkey/LICENSE.md +43 -0
  53. package/starters/greasemonkey/chatgpt.js-greasemonkey-starter.user.js +52 -52
  54. package/starters/greasemonkey/docs/SECURITY.md +17 -0
  55. package/starters/greasemonkey/docs/de/LICENSE.md +31 -0
  56. package/starters/greasemonkey/docs/es/LICENSE.md +31 -0
  57. package/starters/greasemonkey/docs/fr/LICENSE.md +31 -0
  58. package/starters/greasemonkey/docs/hi/LICENSE.md +31 -0
  59. package/starters/greasemonkey/docs/hi/SECURITY.md +17 -0
  60. package/starters/greasemonkey/docs/it/LICENSE.md +29 -0
  61. package/starters/greasemonkey/docs/ja/LICENSE.md +31 -0
  62. package/starters/greasemonkey/docs/ko/LICENSE.md +34 -0
  63. package/starters/greasemonkey/docs/nl/LICENSE.md +30 -0
  64. package/starters/greasemonkey/docs/pt/LICENSE.md +31 -0
  65. package/starters/greasemonkey/docs/vi/LICENSE.md +31 -0
  66. package/starters/greasemonkey/docs/zh-cn/LICENSE.md +31 -0
  67. package/starters/greasemonkey/docs/zh-cn/SECURITY.md +17 -0
  68. package/starters/greasemonkey/docs/zh-tw/LICENSE.md +31 -0
  69. package/dist/chatgpt-2.6.3.min.js +0 -1
  70. package/docs/.nojekyll +0 -0
  71. package/docs/CNAME +0 -1
  72. package/docs/_coverpage.md +0 -16
  73. package/docs/_utils/LICENSE.md +0 -21
  74. package/docs/_utils/minify.js +0 -50
  75. package/docs/assets/docsify/cursors/futuristic/pointer.cur +0 -0
  76. package/docs/assets/docsify/favicons/favicon16.png +0 -0
  77. package/docs/assets/docsify/favicons/favicon320.png +0 -0
  78. package/docs/assets/docsify/favicons/favicon48.png +0 -0
  79. package/docs/assets/docsify/favicons/favicon64.png +0 -0
  80. package/docs/assets/docsify/fonts/eurostile-extended-black/EurostileExtendedBlack.otf +0 -0
  81. package/docs/assets/docsify/fonts/eurostile-extended-black/EurostileExtendedBlack.ttf +0 -0
  82. package/docs/assets/docsify/fonts/eurostile-extended-black/EurostileExtendedBlack.woff +0 -0
  83. package/docs/assets/docsify/fonts/eurostile-extended-black/EurostileExtendedBlack.woff2 +0 -0
  84. package/docs/assets/docsify/fonts/ibm-plex-mono/OFL.txt +0 -93
  85. package/docs/assets/docsify/fonts/ibm-plex-mono/otf/IBMPlexMono-Bold.otf +0 -0
  86. package/docs/assets/docsify/fonts/ibm-plex-mono/otf/IBMPlexMono-BoldItalic.otf +0 -0
  87. package/docs/assets/docsify/fonts/ibm-plex-mono/otf/IBMPlexMono-ExtraLight.otf +0 -0
  88. package/docs/assets/docsify/fonts/ibm-plex-mono/otf/IBMPlexMono-ExtraLightItalic.otf +0 -0
  89. package/docs/assets/docsify/fonts/ibm-plex-mono/otf/IBMPlexMono-Italic.otf +0 -0
  90. package/docs/assets/docsify/fonts/ibm-plex-mono/otf/IBMPlexMono-Light.otf +0 -0
  91. package/docs/assets/docsify/fonts/ibm-plex-mono/otf/IBMPlexMono-LightItalic.otf +0 -0
  92. package/docs/assets/docsify/fonts/ibm-plex-mono/otf/IBMPlexMono-Medium.otf +0 -0
  93. package/docs/assets/docsify/fonts/ibm-plex-mono/otf/IBMPlexMono-MediumItalic.otf +0 -0
  94. package/docs/assets/docsify/fonts/ibm-plex-mono/otf/IBMPlexMono-Regular.otf +0 -0
  95. package/docs/assets/docsify/fonts/ibm-plex-mono/otf/IBMPlexMono-SemiBold.otf +0 -0
  96. package/docs/assets/docsify/fonts/ibm-plex-mono/otf/IBMPlexMono-SemiBoldItalic.otf +0 -0
  97. package/docs/assets/docsify/fonts/ibm-plex-mono/otf/IBMPlexMono-Thin.otf +0 -0
  98. package/docs/assets/docsify/fonts/ibm-plex-mono/otf/IBMPlexMono-ThinItalic.otf +0 -0
  99. package/docs/assets/docsify/fonts/ibm-plex-mono/ttf/IBMPlexMono-Bold.ttf +0 -0
  100. package/docs/assets/docsify/fonts/ibm-plex-mono/ttf/IBMPlexMono-BoldItalic.ttf +0 -0
  101. package/docs/assets/docsify/fonts/ibm-plex-mono/ttf/IBMPlexMono-ExtraLight.ttf +0 -0
  102. package/docs/assets/docsify/fonts/ibm-plex-mono/ttf/IBMPlexMono-ExtraLightItalic.ttf +0 -0
  103. package/docs/assets/docsify/fonts/ibm-plex-mono/ttf/IBMPlexMono-Italic.ttf +0 -0
  104. package/docs/assets/docsify/fonts/ibm-plex-mono/ttf/IBMPlexMono-Light.ttf +0 -0
  105. package/docs/assets/docsify/fonts/ibm-plex-mono/ttf/IBMPlexMono-LightItalic.ttf +0 -0
  106. package/docs/assets/docsify/fonts/ibm-plex-mono/ttf/IBMPlexMono-Medium.ttf +0 -0
  107. package/docs/assets/docsify/fonts/ibm-plex-mono/ttf/IBMPlexMono-MediumItalic.ttf +0 -0
  108. package/docs/assets/docsify/fonts/ibm-plex-mono/ttf/IBMPlexMono-Regular.ttf +0 -0
  109. package/docs/assets/docsify/fonts/ibm-plex-mono/ttf/IBMPlexMono-SemiBold.ttf +0 -0
  110. package/docs/assets/docsify/fonts/ibm-plex-mono/ttf/IBMPlexMono-SemiBoldItalic.ttf +0 -0
  111. package/docs/assets/docsify/fonts/ibm-plex-mono/ttf/IBMPlexMono-Thin.ttf +0 -0
  112. package/docs/assets/docsify/fonts/ibm-plex-mono/ttf/IBMPlexMono-ThinItalic.ttf +0 -0
  113. package/docs/assets/docsify/fonts/ibm-plex-mono/woff/IBMPlexMono-Bold.woff +0 -0
  114. package/docs/assets/docsify/fonts/ibm-plex-mono/woff/IBMPlexMono-BoldItalic.woff +0 -0
  115. package/docs/assets/docsify/fonts/ibm-plex-mono/woff/IBMPlexMono-ExtraLight.woff +0 -0
  116. package/docs/assets/docsify/fonts/ibm-plex-mono/woff/IBMPlexMono-ExtraLightItalic.woff +0 -0
  117. package/docs/assets/docsify/fonts/ibm-plex-mono/woff/IBMPlexMono-Italic.woff +0 -0
  118. package/docs/assets/docsify/fonts/ibm-plex-mono/woff/IBMPlexMono-Light.woff +0 -0
  119. package/docs/assets/docsify/fonts/ibm-plex-mono/woff/IBMPlexMono-LightItalic.woff +0 -0
  120. package/docs/assets/docsify/fonts/ibm-plex-mono/woff/IBMPlexMono-Medium.woff +0 -0
  121. package/docs/assets/docsify/fonts/ibm-plex-mono/woff/IBMPlexMono-MediumItalic.woff +0 -0
  122. package/docs/assets/docsify/fonts/ibm-plex-mono/woff/IBMPlexMono-Regular.woff +0 -0
  123. package/docs/assets/docsify/fonts/ibm-plex-mono/woff/IBMPlexMono-SemiBold.woff +0 -0
  124. package/docs/assets/docsify/fonts/ibm-plex-mono/woff/IBMPlexMono-SemiBoldItalic.woff +0 -0
  125. package/docs/assets/docsify/fonts/ibm-plex-mono/woff/IBMPlexMono-Thin.woff +0 -0
  126. package/docs/assets/docsify/fonts/ibm-plex-mono/woff/IBMPlexMono-ThinItalic.woff +0 -0
  127. package/docs/assets/docsify/fonts/ibm-plex-mono/woff2/IBMPlexMono-Bold.woff2 +0 -0
  128. package/docs/assets/docsify/fonts/ibm-plex-mono/woff2/IBMPlexMono-BoldItalic.woff2 +0 -0
  129. package/docs/assets/docsify/fonts/ibm-plex-mono/woff2/IBMPlexMono-ExtraLight.woff2 +0 -0
  130. package/docs/assets/docsify/fonts/ibm-plex-mono/woff2/IBMPlexMono-ExtraLightItalic.woff2 +0 -0
  131. package/docs/assets/docsify/fonts/ibm-plex-mono/woff2/IBMPlexMono-Italic.woff2 +0 -0
  132. package/docs/assets/docsify/fonts/ibm-plex-mono/woff2/IBMPlexMono-Light.woff2 +0 -0
  133. package/docs/assets/docsify/fonts/ibm-plex-mono/woff2/IBMPlexMono-LightItatlic.woff2 +0 -0
  134. package/docs/assets/docsify/fonts/ibm-plex-mono/woff2/IBMPlexMono-Medium.woff2 +0 -0
  135. package/docs/assets/docsify/fonts/ibm-plex-mono/woff2/IBMPlexMono-MediumItalic.woff2 +0 -0
  136. package/docs/assets/docsify/fonts/ibm-plex-mono/woff2/IBMPlexMono-Regular.woff2 +0 -0
  137. package/docs/assets/docsify/fonts/ibm-plex-mono/woff2/IBMPlexMono-SemiBold.woff2 +0 -0
  138. package/docs/assets/docsify/fonts/ibm-plex-mono/woff2/IBMPlexMono-SemiBoldItalic.woff2 +0 -0
  139. package/docs/assets/docsify/fonts/ibm-plex-mono/woff2/IBMPlexMono-Thin.woff2 +0 -0
  140. package/docs/assets/docsify/fonts/ibm-plex-mono/woff2/IBMPlexMono-ThinItalic.woff2 +0 -0
  141. package/docs/assets/docsify/fonts/major-mono-display/MajorMonoDisplay-Regular.otf +0 -0
  142. package/docs/assets/docsify/fonts/major-mono-display/MajorMonoDisplay-Regular.ttf +0 -0
  143. package/docs/assets/docsify/fonts/major-mono-display/MajorMonoDisplay-Regular.woff +0 -0
  144. package/docs/assets/docsify/fonts/major-mono-display/MajorMonoDisplay-Regular.woff2 +0 -0
  145. package/docs/assets/docsify/fonts/major-mono-display/OFL.txt +0 -93
  146. package/docs/assets/docsify/fonts/polysans-neutral/PolySansNeutral.eot +0 -0
  147. package/docs/assets/docsify/fonts/polysans-neutral/PolySansNeutral.ttf +0 -0
  148. package/docs/assets/docsify/fonts/polysans-neutral/PolySansNeutral.woff +0 -0
  149. package/docs/assets/docsify/fonts/polysans-neutral/PolySansNeutral.woff2 +0 -0
  150. package/docs/assets/docsify/html/footer.html +0 -23
  151. package/docs/assets/docsify/js/min/back-to-top-button.min.js +0 -1
  152. package/docs/assets/docsify/js/min/copy-code-button.min.js +0 -1
  153. package/docs/assets/docsify/js/min/onload-hacks.min.js +0 -3
  154. package/docs/assets/docsify/js/min/starry-background.min.js +0 -1
  155. package/docs/assets/docsify/js/src/back-to-top-button.js +0 -64
  156. package/docs/assets/docsify/js/src/copy-code-button.js +0 -91
  157. package/docs/assets/docsify/js/src/onload-hacks.js +0 -613
  158. package/docs/assets/docsify/js/src/starry-background.js +0 -111
  159. package/docs/assets/docsify/styles/css/style.min.css +0 -1
  160. package/docs/assets/docsify/styles/css/style.min.css.map +0 -1
  161. package/docs/assets/docsify/styles/scss/style.scss +0 -510
  162. package/docs/assets/separators/aqua.png +0 -0
  163. package/docs/de/_coverpage.md +0 -12
  164. package/docs/es/_coverpage.md +0 -12
  165. package/docs/fr/_coverpage.md +0 -12
  166. package/docs/hi/_coverpage.md +0 -12
  167. package/docs/index.html +0 -91
  168. package/docs/it/_coverpage.md +0 -12
  169. package/docs/ja/_coverpage.md +0 -12
  170. package/docs/ko/_coverpage.md +0 -12
  171. package/docs/ne/_coverpage.md +0 -12
  172. package/docs/nl/_coverpage.md +0 -12
  173. package/docs/pt/_coverpage.md +0 -12
  174. package/docs/vi/_coverpage.md +0 -12
  175. package/docs/zh-cn/_coverpage.md +0 -12
  176. package/docs/zh-tw/_coverpage.md +0 -12
  177. package/starters/chrome/LICENSE +0 -21
  178. package/starters/greasemonkey/LICENSE +0 -21
@@ -1,613 +0,0 @@
1
- /* Hack page elements on load */
2
-
3
- const taglineWords = []; // for iObserver's scrambleText() + randomizeCase()
4
- const features = [ // for iObserver's typeText() to #feature-list
5
- '>> Feature-rich', '>> Object-oriented', '>> Easy-to-use',
6
- '>> Lightweight (yet optimally performant)' ];
7
- const visibilityMap = []; // to store flags for section visibility
8
- const sectionColors = [ // for mdLoaded.then's scroll color hacks
9
- '#64ffff', // Importing the Library
10
- '#f9ee16', // Greasemonkey
11
- 'lime', // Chrome
12
- 'orange', // Usage
13
- '#b981f9', // Made w/ chatgpt.js
14
- '#f581f9', // ChatGPT Infinity tile
15
- '#81f9c3' ]; // Contributors
16
- const iniStarZvelocity = window.starVelocity.z,
17
- warpDuration = 1600, hiWarpDuration = 1400, starResetDelay = 15;
18
-
19
- // Define OBSERVERS
20
-
21
- const mdLoaded = new Promise((resolve) => {
22
- const mdObserver = new MutationObserver((mutationsList, observer) => {
23
- if (document.querySelector('#shields')) { observer.disconnect(); resolve(); }});
24
- mdObserver.observe(document.body, { childList: true, subtree: true });
25
- });
26
-
27
- const iObserver = new IntersectionObserver(entries => { entries.forEach(entry => {
28
-
29
- // Set visibility FLAG
30
- const key = entry.target.id || entry.target.className;
31
- visibilityMap[key] = entry.isIntersecting;
32
-
33
- // Handle COVER
34
- if (entry.target.className === 'cover-main') {
35
- if (entry.isIntersecting) {
36
-
37
- // Reset colors
38
- document.querySelector('#kudoai a').style.color = 'white';
39
- window.starColor = 'white';
40
- (document.querySelector('#scrollbar-style') || {}).innerText = (
41
- ':root { scrollbar-color: rgb(210,210,210) #1a1a1a }'
42
- + 'body::-webkit-scrollbar-thumb { background-color: white }');
43
-
44
- // Animate KudoAI logo
45
- const kudo = document.querySelector('.kudo');
46
- kudo.classList.add('hover');
47
- setTimeout(() => { kudo.classList.remove('hover'); }, 955);
48
-
49
- // Scramble entire tagline + add case randomization layer
50
- Array.from( // clear tagline spans to maintain grow effect
51
- document.querySelectorAll('span[id^="tagline"]'))
52
- .forEach(span => { span.textContent = ''; });
53
- scrambleText([taglineWords[0]], document.querySelector('#tagline-pre-adj'));
54
- scrambleText(taglineWords[1], document.querySelector('#tagline-adj'), 750);
55
- scrambleText([taglineWords[2]], document.querySelector('#tagline-post-adj'));
56
- randomizeCase(document.querySelector('#tagline-pre-adj'));
57
- randomizeCase(document.querySelector('#tagline-post-adj'));
58
-
59
- // Star boost
60
- if (window.starVelocity.z <= iniStarZvelocity) { // to avoid reverse boost from scroll-ups
61
- window.starVelocity.z += .024; // boost velocity
62
- setTimeout(() => { // slow velocity
63
- window.starVelocity.z -= .02; }, 1155);
64
- setTimeout(() => { // slow velocity to original
65
- window.starVelocity.z = iniStarZvelocity; }, 1355);
66
- }
67
-
68
- } else // stop scrambling tagline adjective
69
- clearTimeout(scrambleText.timeoutID);
70
-
71
- // Handle FEATURE LIST
72
- } else if (entry.target.id === 'feature-list') { // type features or clear content/timeouts
73
- if (entry.isIntersecting) typeText(features, entry.target, 20);
74
- else { entry.target.innerHTML = ''; clearTimeout(typeText.timeoutID); }
75
- }
76
-
77
- });});
78
-
79
- const onLoadObserver = new MutationObserver(() => {
80
-
81
- // Exit if not loaded
82
- if (!document.querySelector('.cover-main blockquote p')) return;
83
-
84
- // Activate SMOOTH SCROLL
85
- smoothScroll(document, 155, 9);
86
-
87
- // Hack HOMEPAGE
88
- if (/#\/(\w{2}(-\w{2})?\/)?$/.test(location.hash)) {
89
-
90
- // Hide SIDEBAR
91
- if (!isMobileDevice()) document.body.className = 'ready close';
92
-
93
- // Populate [taglineWords] for iObserver's scrambleText() + randomizeCase()
94
- const taglineSpans = Array.from(document.querySelectorAll('span[id^="tagline"]'));
95
- taglineSpans.map(span => { taglineWords.push(
96
- /pre|post/.exec(span.id) ? span.textContent : span.textContent.split('|')); });
97
- taglineSpans.forEach(span => { span.textContent = ''; }); // clear them out
98
-
99
- // Observe COVER for visibility change tagline hacks
100
- iObserver.observe(document.querySelector('.cover-main'));
101
-
102
- // Add TOP GRADIENT
103
- const cover = document.querySelector('.cover'),
104
- topGradient = document.createElement('div');
105
- topGradient.classList.add('top-gradient');
106
- document.body.append(topGradient);
107
- updateTGvisibility(); // since page load can be below fold
108
- function updateTGvisibility() {
109
- topGradient.style.display = ( // hide/show when fold is 85% at top
110
- window.scrollY > 0.85 * cover.offsetHeight ? '' : 'none' ); }
111
-
112
- mdLoaded.then(() => {
113
-
114
- // Scroll slightly to overcome Chromium bug preventing parallax
115
- if (navigator.userAgent.includes('Chrome'))
116
- window.scrollBy(0, 200); setTimeout(() => window.scrollBy(0, -200), 600);
117
-
118
- // Disable SEARCH
119
- document.querySelector('.search').style.display = 'none';
120
- document.querySelector('.sidebar-nav').style.paddingTop = '102px';
121
-
122
- // Create/select FEATURE LIST
123
- const featureListDiv = document.querySelector('#feature-list') || // select div
124
- document.createElement('div'); // ...or create it
125
- if (!featureListDiv.parentElement) { // append created div if not in DOM
126
- featureListDiv.setAttribute('id', 'feature-list');
127
- const introDiv = document.querySelector('#intro');
128
- introDiv.parentElement.insertBefore( // insert after description
129
- featureListDiv, introDiv.nextElementSibling.nextElementSibling);
130
- }
131
-
132
- // ...then observe for visibility change to apply typing hack
133
- iObserver.observe(featureListDiv);
134
-
135
- // Append COPYRIGHT NOTICE footer
136
- const article = document.querySelector('article'), // to insert at end of
137
- copyrightFooter = document.createElement('div');
138
- copyrightFooter.id = 'copyright-footer';
139
- copyrightFooter.innerHTML = '<span style="font-size: 115%">Copyright © 2023–' + new Date().getFullYear()
140
- + ' <a href="https://kudoai.com" target="_blank" rel="noopener">KudoAI</a>.</span><br>'
141
- + 'Designed by <a href="https://adamlui.com" target="_blank" rel="noopener">Adam Lui</a> / '
142
- + 'Powered by <a href="https://docsify.js.org" target="_blank" rel="noopener">Docsify</a> / '
143
- + 'Hosted by <a href="https://github.com" target="_blank" rel="noopener">GitHub</a>';
144
- article.append(copyrightFooter);
145
-
146
- // Replace GitHub demo embed w/ YouTube one
147
- const ghDemo = document.querySelector('a[href*="/assets/10906554/f53c740f-d5e0-49b6-ae02-3b3140b0f8a4"]'),
148
- ytDemo = document.createElement('iframe');
149
- ytDemo.setAttribute('width', '855'); ytDemo.setAttribute('height', '455');
150
- ytDemo.setAttribute('src', 'https://www.youtube.com/embed/yG8DtsEo0PM?rel=0');
151
- ytDemo.setAttribute('allow',
152
- 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share');
153
- ytDemo.setAttribute('allowfullscreen', '');
154
- ytDemo.style.minWidth = 'fit-content'; ytDemo.style.width = '855px'; ytDemo.style.marginBottom = '30px';
155
- ghDemo.parentNode.replaceChild(ytDemo, ghDemo);
156
- ytDemo.parentNode.style.textAlign = 'center';
157
-
158
- // Strip blockquote wrappers from showcase app descriptions
159
- document.querySelectorAll('blockquote').forEach(blockquote => {
160
- const parent = blockquote.parentNode, content = blockquote.innerHTML;
161
- parent.replaceChild(document.createRange().createContextualFragment(content), blockquote);
162
- });
163
-
164
- // Add FADE classes to elements
165
- const fadeUpElements = [], fadeRightElements = [], fadeLeftElements = [];
166
- fadeUpElements.push(...document.querySelectorAll(
167
- '.cover-main img, .cover-main a,' // cover elements
168
- + 'h2, h3, p, pre, main li,' // general elements
169
- + 'div#partners-collage, #copyright-footer')); // footer elements
170
- fadeUpElements.forEach((element) => { element.classList.add('content-fadeup'); });
171
- fadeUpElements.push( // language selector
172
- document.querySelector('#language-menu'));
173
- fadeUpElements[fadeUpElements.length - 1].classList.add('menu-fadeup');
174
- fadeRightElements.push(...document.querySelectorAll( // left-side showcase apps
175
- `#showcase ~ h3:nth-of-type(odd):not(#contributors ~ *),
176
- #showcase ~ h3 + p:nth-of-type(odd):not(#contributors ~ *`));
177
- fadeRightElements.forEach((element) => { element.classList.add('content-faderight'); });
178
- fadeLeftElements.push(...document.querySelectorAll( // right-side showcase apps
179
- `#showcase ~ h3:nth-of-type(even):not(#contributors ~ *),
180
- #showcase ~ h3 + p:nth-of-type(even):not(#contributors ~ *`));
181
- fadeLeftElements.forEach((element) => { element.classList.add('content-fadeleft'); });
182
- const fadeElements = [...fadeUpElements, ...fadeRightElements, ...fadeLeftElements];
183
-
184
- // ...then observe for visibility change to update element/sidebar states
185
- const sideNavItems = [...document.querySelectorAll('.sidebar-nav li')];
186
- const fadeObserver = new IntersectionObserver(
187
- (entries) => { entries.forEach((entry) => {
188
- if (entry.isIntersecting) {
189
- entry.target.classList.add('visible');
190
-
191
- // Update sidebar w/ active class for headings
192
- if (entry.target.tagName.startsWith('H')) {
193
-
194
- // Find the nav item that matches intersecting heading
195
- const headingText = entry.target.querySelector('a').textContent,
196
- activeNavItem = (document.querySelector(
197
- `a[title="${ headingText }"]`) || {}).parentElement;
198
-
199
- // Add `nav-active` class to matched nav item
200
- if (activeNavItem) {
201
- sideNavItems.forEach(item => item.classList.remove('nav-active'));
202
- activeNavItem.classList.add('nav-active');
203
- }
204
- }
205
- } else entry.target.classList.remove('visible');
206
- });}, { root: null, threshold: 0.02 });
207
- fadeElements.forEach((element) => { fadeObserver.observe(element); });
208
-
209
- // Change stars shield link to repo
210
- const starsShieldLink = document.querySelector('a[href$="stargazers"]'),
211
- href = starsShieldLink.getAttribute('href');
212
- starsShieldLink.setAttribute('href', href.replace('/stargazers', ''));
213
-
214
- // Establish TRIGGER POINTS for scroll FX
215
- const triggerElements = [], triggerPoints = [];
216
- triggerElements.push(...document.querySelectorAll('h2'));
217
- triggerElements.push(document.querySelector('h3#-greasemonkey'));
218
- triggerElements.push(document.querySelector('h3#-chrome'));
219
- triggerElements.push( // 1st showcase tile
220
- document.querySelector('img[src*="chatgpt-infinity"]'));
221
- triggerElements.forEach(element => {
222
- const elementPos = element.getBoundingClientRect().top;
223
- const vOffsetDivisor = ( // higher = lower pos
224
- element.id.includes('⚡') ? 1.5 // Importing the Library section
225
- : element.tagName === 'IMG' ? 0.8 // 1st showcase tile
226
- : 8.8 ); // headings
227
- triggerPoints.push(elementPos - window.innerHeight/vOffsetDivisor);
228
- });
229
- triggerPoints.sort((a, b) => a - b); // sort ascending
230
-
231
- // Update COLORS + STAR VELOCITY on scroll
232
- window.addEventListener('scroll', () => {
233
-
234
- // Exit if still in 1st two sections
235
- if (visibilityMap['cover-main'] || visibilityMap['feature-list']) return;
236
-
237
- // Determine current section
238
- let currentSection = 0;
239
- while (window.scrollY > triggerPoints[currentSection] &&
240
- currentSection < triggerPoints.length)
241
- currentSection++;
242
-
243
- // Color/animate logo/stars + color scrollbar if section changed
244
- const sectionColor = sectionColors[currentSection - 2];
245
- if (sectionColor !== window.starColor) {
246
-
247
- // Color/animate stars
248
- window.starColor = sectionColor;
249
- setTimeout(() => { // schedule color reset
250
- if (window.starVelocity.z <= iniStarZvelocity) {
251
- window.starColor = 'white'; }}, warpDuration + starResetDelay);
252
- window.starVelocity.z += .0045; // boost velocity
253
- setTimeout(() => { // slow velocity
254
- window.starVelocity.z = Math.max(iniStarZvelocity, window.starVelocity.z - .0025);
255
- }, hiWarpDuration);
256
- setTimeout(() => { // slow velocity to original
257
- window.starVelocity.z = Math.max(iniStarZvelocity, window.starVelocity.z - .002);
258
- }, warpDuration);
259
-
260
- // Color/animate logo
261
- const kudoAIlogo = document.querySelector('#kudoai a'),
262
- kudo = document.querySelector('.kudo');
263
- kudoAIlogo.style.color = sectionColor;
264
- kudo.classList.add('hover'); // trigger slide animation
265
- setTimeout(() => { // schedule color/animation reset
266
- if (window.starVelocity.z <= iniStarZvelocity) {
267
- kudoAIlogo.style.color = 'white';
268
- kudo.classList.remove('hover');
269
- }}, warpDuration + 5);
270
-
271
- // Color scrollbar
272
- const scrollbarStyle = document.querySelector('#scrollbar-style') || // select div
273
- document.createElement('style'); // ...or create it
274
- if (!scrollbarStyle.parentElement) { // append created div if not in DOM
275
- scrollbarStyle.setAttribute('id', 'scrollbar-style');
276
- document.head.append(scrollbarStyle);
277
- }
278
- scrollbarStyle.innerText = (
279
- `:root { scrollbar-color: ${ sectionColor } #1a1a1a }`
280
- + `body::-webkit-scrollbar-thumb { background-color: ${ sectionColor } }`);
281
- setTimeout(() => { // schedule color reset
282
- if (window.starVelocity.z <= iniStarZvelocity) {
283
- scrollbarStyle.innerText = (
284
- ':root { scrollbar-color: rgb(210,210,210) #1a1a1a }'
285
- + 'body::-webkit-scrollbar-thumb { background-color: white }');
286
- }}, warpDuration + 5);
287
-
288
- }
289
- });
290
-
291
- // Update LANGUAGE SELECTOR word
292
- setTimeout(() => {
293
- const activeLanguage = document.querySelector('.active').innerText;
294
- document.getElementById('dropdown-button').innerText = activeLanguage;
295
- }, 250);
296
-
297
- // Convert OpenAI showcase icons + sidebar logo to dark-mode
298
- document.querySelectorAll('picture').forEach(picture => {
299
- const srcElement = picture.querySelector('source'),
300
- srcSet = srcElement.getAttribute('srcset'),
301
- imgElement = document.createElement('img');
302
- imgElement.setAttribute('src', srcSet);
303
- picture.parentNode.replaceChild(imgElement, picture);
304
- });
305
-
306
- // Append EMAIL SIGNUP footer
307
- const partnersCollage = document.getElementById('partners-collage'), // to insert after
308
- emailFooter = document.createElement('div');
309
- fetch('assets/docsify/html/footer.html')
310
- .then(response => response.text()).then(html => {
311
- emailFooter.innerHTML = html;
312
- partnersCollage.insertAdjacentElement('afterend', emailFooter);
313
- });
314
-
315
- // Remove readme's BACK-TO-TOP link
316
- const readmeBTTlink = document.querySelector('p a[href="#"]');
317
- readmeBTTlink.previousSibling.remove(); readmeBTTlink.remove();
318
-
319
- setTimeout(() => { // Add PARALLAX
320
-
321
- // Target TRIGGERS
322
- const parallaxTriggers = [];
323
- document.querySelectorAll('#main, h2:not([id="about"])').forEach(trigger => {
324
- const y = trigger.getBoundingClientRect().top - window.innerHeight / 1.2;
325
- const triggerElem = trigger.tagName === 'H2' ? trigger.parentElement : trigger;
326
- parallaxTriggers.push({ element: triggerElem, y });
327
- });
328
-
329
- // Add SCROLL listener
330
- window.addEventListener('scroll', () => {
331
- updateTGvisibility();
332
- parallaxTriggers.forEach(trigger => {
333
- if (window.scrollY >= trigger.y && window.scrollY < trigger.y + window.innerHeight) {
334
-
335
- // Target previous elements to hack
336
- const prevElems = [];
337
- if (trigger.element.id === 'main')
338
- prevElems.push(document.querySelector('.cover-main'));
339
- else { // target previous 6 siblings
340
- let currentElem = trigger.element.previousElementSibling;
341
- for (let i = 0; i < 7; i++) {
342
- if (currentElem) {
343
- prevElems.push(currentElem);
344
- currentElem = currentElem.previousElementSibling;
345
- } else break;
346
- }
347
- }
348
-
349
- // Apply transparency + translate to siblings
350
- prevElems.forEach(elem => {
351
- const topGap = trigger.y - window.scrollY,
352
- newOpacity = 1 - Math.abs(topGap) / ( window.innerHeight - 5),
353
- parallaxOffset = topGap * -0.55,
354
- scaleDelay = 285, // px from trigger.y to delay scaling
355
- scaleFactor = topGap > -scaleDelay ? 1
356
- : 1 - Math.abs(topGap + scaleDelay) / 5 / window.innerHeight;
357
- try { elem.classList.remove('content-fadeup'); } catch (err) {}
358
- elem.style.opacity = newOpacity;
359
- elem.style.transform = `translateY(${ parallaxOffset }px) scale(${ scaleFactor })`;
360
- });
361
-
362
- }});});}, 100);
363
- });
364
-
365
- // Hide SITE LANG SELECTOR from NON-HOME pages
366
- } else document.querySelector('.app-nav').style.display = 'none';
367
-
368
- // Hack LICENSE/SECURIY pages
369
- if (/LICENSE|SECURITY/.test(location.hash)) {
370
-
371
- // Hide SIDEBAR
372
- if (!isMobileDevice()) document.body.className = 'ready close';
373
-
374
- // Correct DOC LANG SELECTOR links
375
- mdLoaded.then(() => {
376
- const docLangSelector = document.querySelectorAll('h5 a');
377
- for (const lang of docLangSelector)
378
- lang.href = lang.href.replace(/(.*\/\/.*?\/)((\w{2}(-\w{2})?\/)?.*)\.md/, '$1#/$2');
379
- });
380
- }
381
-
382
- // DISCONNECT observer
383
- onLoadObserver.disconnect();
384
-
385
- });
386
-
387
- // Define FUNCTIONS
388
-
389
- function isMobileDevice() {
390
- return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent); }
391
-
392
- function validateIntArg(arg, name, defaultVal) {
393
- if (arg === undefined) return defaultVal; // no validation required
394
- if (!Number.isInteger(arg) && !/^\d+$/.test(arg))
395
- throw new Error(name + ' must be an integer.');
396
- return parseInt(arg, 10);
397
- }
398
-
399
- function smoothScroll(target, speed, smooth) {
400
-
401
- // Init target
402
- if (target === document)
403
- target = (document.scrollingElement
404
- || document.documentElement
405
- || document.body.parentNode
406
- || document.body); // cross browser support for document scrolling
407
-
408
- // Init variables
409
- let moving = false, pos = target.scrollTop;
410
- const frame = target === document.body && document.documentElement
411
- ? document.documentElement
412
- : target; // safari
413
- // Add listeners
414
- target.addEventListener('mousewheel', scrolled, { passive: false });
415
- target.addEventListener('DOMMouseScroll', scrolled, { passive: false });
416
-
417
- function scrolled(e) {
418
- e.preventDefault(); // disable default scrolling
419
- const delta = normalizeWheelDelta(e);
420
- pos += -delta * speed;
421
- pos = ( // limit scrolling
422
- Math.max(0, Math.min(pos, target.scrollHeight - frame.clientHeight)));
423
- if (!moving) update();
424
- }
425
-
426
- function normalizeWheelDelta(e) {
427
- if (e.detail) {
428
- if (e.wheelDelta)
429
- return e.wheelDelta/e.detail/40 * (e.detail>0 ? 1 : -1); // Opera
430
- else return -e.detail/3; // Firefox
431
- } else return e.wheelDelta/120; // IE/Safari/Chrome
432
- }
433
-
434
- function update() {
435
- moving = true;
436
- const delta = (pos - target.scrollTop) / smooth;
437
- target.scrollTop += delta;
438
- if (Math.abs(delta) > 0.5) requestFrame(update);
439
- else moving = false;
440
- }
441
-
442
- const requestFrame = function() { // requestAnimationFrame cross browser
443
- return (
444
- window.requestAnimationFrame ||
445
- window.webkitRequestAnimationFrame ||
446
- window.mozRequestAnimationFrame ||
447
- window.oRequestAnimationFrame ||
448
- window.msRequestAnimationFrame ||
449
- function(func) { window.setTimeout(func, 1000 / 50); }
450
- );
451
- }();
452
- }
453
-
454
- function scrambleText(text, destination, delayBetweenWords, textIdx = 0) {
455
-
456
- // Validate args
457
- if (typeof text === 'string') text = [text]; // array of strings to scramble
458
- if (!destination?.nodeName) // DOM element to scramble to
459
- throw new Error('Destination (2nd arg) must be a DOM element');
460
- if (delayBetweenWords) { // ms to delay between scrambles
461
- if (!Number.isInteger(delayBetweenWords) && !/^\d+$/.test(delayBetweenWords))
462
- throw new Error('Delay betweeen words (3nd arg) must be an integer (ms)');
463
- delayBetweenWords = parseInt(delayBetweenWords, 10);
464
- }
465
-
466
- // Scramble text
467
- const textToScramble = new Scramble(destination);
468
- textToScramble.setText(text[textIdx])
469
- .then(() => { if (delayBetweenWords && visibilityMap['cover-main']) {
470
- scrambleText.timeoutID = setTimeout(() => {
471
- scrambleText(text, destination, delayBetweenWords, (textIdx + 1) % text.length); },
472
- delayBetweenWords);
473
- }});
474
- }
475
-
476
- function randomizeCase(targetNode, iniDelay, finalDelay, incrementA, incrementB, inflectionPt) {
477
-
478
- // Validate args
479
- if (!targetNode?.nodeName) // DOM element to randomize case of text content
480
- throw new Error('Target node (1st arg) must be a DOM element');
481
- iniDelay = validateIntArg( // ms to initially between case switches
482
- iniDelay, 'Initial delay', 5);
483
- finalDelay = validateIntArg( // ms to finally delay between case switches
484
- finalDelay, 'Final delay', 1000);
485
- incrementA = validateIntArg( // ms to initially increment from iniDelay to finalDelay
486
- incrementA, 'Increment A', 10);
487
- incrementB = validateIntArg( // ms to increment from iniDelay to finalDelay after inflection
488
- incrementB, 'Increment B', 111);
489
- inflectionPt = validateIntArg( // ms of iniDelay state before inflecting to Increment B
490
- inflectionPt, 'Inflection point', 265);
491
-
492
- // Randomize case
493
- targetNode.textContent = targetNode.textContent.split('').map(letter => {
494
- return Math.random() < 0.5 ? letter.toUpperCase() : letter.toLowerCase();
495
- }).join('');
496
- randomizeCase.iniDelay = randomizeCase.iniDelay || iniDelay;
497
- randomizeCase.iniDelay += randomizeCase.iniDelay < inflectionPt ? incrementA : incrementB;
498
- if (randomizeCase.iniDelay > finalDelay) randomizeCase.iniDelay = finalDelay; // cap at `finalDelay`
499
- setTimeout(() => {
500
- randomizeCase(targetNode, iniDelay, finalDelay, incrementA, incrementB, inflectionPt);
501
- }, randomizeCase.iniDelay);
502
- }
503
-
504
- function typeText(txtToType, destination, typeDelay, iniTxtToType, iniTxtPos, linesToScrollAt) {
505
-
506
- // Validate args
507
- if (typeof txtToType === 'string') txtToType = [txtToType]; // array of strings to type
508
- if (!destination?.nodeName) // DOM element to type to
509
- throw new Error('Destination must be a DOM element');
510
- typeDelay = validateIntArg( // ms to delay between chars typed
511
- typeDelay, 'Typing delay', 30);
512
- iniTxtToType = validateIntArg( // index of txt array to start typing
513
- iniTxtToType, 'Initial text array index', 0);
514
- iniTxtPos = validateIntArg( // position in txt string to start typing from
515
- iniTxtPos, 'Initial text string position', 3);
516
- linesToScrollAt = validateIntArg( // lines reached before scrolling up
517
- linesToScrollAt, 'Lines to scroll at', 5);
518
-
519
- // Init variables
520
- let typeContent = ' ',
521
- iniRow = Math.max(0, iniTxtToType - linesToScrollAt);
522
-
523
- // Type text
524
- while (iniRow < iniTxtToType) typeContent += txtToType[iniRow++] + '<br /><br />';
525
- destination.innerHTML = typeContent + txtToType[iniTxtToType].substring(0, iniTxtPos) + '_';
526
- if (iniTxtPos++ == txtToType[iniTxtToType].length) {
527
- iniTxtPos = 0; iniTxtToType++;
528
- if (iniTxtToType != txtToType.length) { // if end of string reached
529
- typeText.timeoutID = setTimeout(() => {
530
- typeText(txtToType, destination, typeDelay, iniTxtToType, iniTxtPos);
531
- }, 88); // pause til next string
532
- }} else typeText.timeoutID = setTimeout(() => {
533
- typeText(txtToType, destination, typeDelay, iniTxtToType, iniTxtPos);
534
- }, typeDelay + (Math.random() * 220) - 110);
535
- }
536
-
537
- // Define SCRAMBLE class
538
-
539
- class Scramble {
540
- constructor(el) {
541
- this.el = el;
542
- this.chars = '!<>-_\\/[]{}—=+*^?#________';
543
- this.update = this.update.bind(this);
544
- }
545
- setText(newText) {
546
- const oldText = this.el.innerText,
547
- length = Math.max(oldText.length, newText.length),
548
- promise = new Promise((resolve) => this.resolve = resolve);
549
- this.queue = [];
550
- for (let i = 0; i < length; i++) {
551
- const from = oldText[i] || '',
552
- to = newText[i] || '',
553
- start = Math.floor(Math.random() * 45), // speed of beginning scramble
554
- end = start + Math.floor(Math.random() * 45); // speed of end scramble
555
- this.queue.push({ from, to, start, end });
556
- }
557
- cancelAnimationFrame(this.frameRequest);
558
- this.frame = 0; this.update(); return promise;
559
- }
560
- update() {
561
- let output = '', complete = 0;
562
- for (let i = 0, n = this.queue.length; i < n; i++) {
563
- let { from, to, start, end, char } = this.queue[i];
564
- if (this.frame >= end) { complete++; output += to; }
565
- else if (this.frame >= start) {
566
- if (!char || Math.random() < 0.28) {
567
- char = this.randomChar();
568
- this.queue[i].char = char;
569
- }
570
- output += `<span class="dud">${ char }</span>`;
571
- } else output += from;
572
- }
573
- this.el.innerHTML = output;
574
- if (complete === this.queue.length) this.resolve();
575
- else {
576
- this.frameRequest = requestAnimationFrame(this.update);
577
- this.frame++;
578
- }
579
- }
580
- randomChar() {
581
- return this.chars[Math.floor(Math.random() * this.chars.length)]; }
582
- }
583
-
584
- // Run MAIN routine
585
-
586
- // Add listeners to language selector
587
- const languageMenu = document.getElementById('language-menu'),
588
- languageSelector = document.getElementById('language-selector');
589
- languageMenu.style.display = 'none'; // hide on page load
590
- let hideTimeout; // to account for gap between button & menu
591
- languageSelector.addEventListener('mouseenter', () => {
592
- clearTimeout(hideTimeout); languageMenu.style.display = 'block'; });
593
- languageSelector.addEventListener('mouseleave', () => {
594
- hideTimeout = setTimeout(() => { languageMenu.style.display = 'none'; }, 55); });
595
- languageMenu.addEventListener('mouseenter', () => {
596
- clearTimeout(hideTimeout); languageMenu.style.display = 'block'; });
597
- languageMenu.addEventListener('mouseleave', () => {
598
- clearTimeout(hideTimeout); hideTimeout = setTimeout(() => {
599
- languageMenu.style.display = 'none'; }, 55);
600
- });
601
- document.querySelectorAll('#language-selector a').forEach((link) => { // add listener to hide tooltips
602
- link.addEventListener('mouseenter', () => { link.removeAttribute('title'); });});
603
- document.querySelectorAll('.dropdown-link').forEach((link) => { // add listener to dismisss menu
604
- link.addEventListener('click', () => { languageMenu.style.display = 'none'; });});
605
-
606
- // Observe for load + re-connect on nav to new hash
607
- onLoadObserver.observe(document.body, { childList: true, subtree: true });
608
- let fromUnhashedURL = window.location.href.includes('#');
609
- window.addEventListener('hashchange', () => {
610
- if (!fromUnhashedURL) fromUnhashedURL = true;
611
- else if (fromUnhashedURL)
612
- onLoadObserver.observe(document.body, { childList: true, subtree: true });
613
- });