j1-template 2024.1.5 → 2024.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (193) hide show
  1. checksums.yaml +4 -4
  2. data/_includes/themes/j1/layouts/content_generator_page.html +0 -34
  3. data/_includes/themes/j1/modules/searcher/generator.html +4 -1
  4. data/_includes/themes/j1/modules/searcher/procedures/topsearch.proc +59 -56
  5. data/assets/data/authclient.html +1 -8
  6. data/assets/data/banner.html +1 -7
  7. data/assets/data/fab.html +2 -13
  8. data/assets/data/footer.html +0 -3
  9. data/assets/data/galeries.html +2 -13
  10. data/assets/data/gemini-ui.html +74 -21
  11. data/assets/data/iframes.html +1 -4
  12. data/assets/data/masonry.html +1 -13
  13. data/assets/data/masterslider.html +10 -21
  14. data/assets/data/menu.html +6 -14
  15. data/assets/data/mmenu.html +6 -5
  16. data/assets/data/mmenu_toc.html +2 -1
  17. data/assets/data/panel.html +4 -11
  18. data/assets/data/particles.yml +8 -8
  19. data/assets/data/quicklinks.html +4 -23
  20. data/assets/data/rtext_resizer.html +3 -1
  21. data/assets/data/slick.html +9 -11
  22. data/assets/data/translator.html +0 -1
  23. data/assets/themes/j1/adapter/js/advertising.js +141 -172
  24. data/assets/themes/j1/adapter/js/algolia.js +61 -54
  25. data/assets/themes/j1/adapter/js/analytics.js +67 -47
  26. data/assets/themes/j1/adapter/js/asciidoctor.js +32 -20
  27. data/assets/themes/j1/adapter/js/attic.js +75 -69
  28. data/assets/themes/j1/adapter/js/bmd.js +195 -177
  29. data/assets/themes/j1/adapter/js/carousel.js +786 -761
  30. data/assets/themes/j1/adapter/js/chatbot.js +77 -35
  31. data/assets/themes/j1/adapter/js/clipboard.js +66 -49
  32. data/assets/themes/j1/adapter/js/comments.js +92 -70
  33. data/assets/themes/j1/adapter/js/cookieConsent.js +466 -462
  34. data/assets/themes/j1/adapter/js/customFunctions.js +52 -35
  35. data/assets/themes/j1/adapter/js/customModule.js +56 -46
  36. data/assets/themes/j1/adapter/js/docsearch.js +54 -34
  37. data/assets/themes/j1/adapter/js/dropdowns.js +65 -52
  38. data/assets/themes/j1/adapter/js/fab.js +123 -109
  39. data/assets/themes/j1/adapter/js/gallery.js +494 -476
  40. data/assets/themes/j1/adapter/js/gemini.js +933 -299
  41. data/assets/themes/j1/adapter/js/iconPicker.js +255 -235
  42. data/assets/themes/j1/adapter/js/iconPickerPage.js +279 -0
  43. data/assets/themes/j1/adapter/js/iframer.js +81 -61
  44. data/assets/themes/j1/adapter/js/j1.js +3285 -3222
  45. data/assets/themes/j1/adapter/js/lazyLoader.js +241 -222
  46. data/assets/themes/j1/adapter/js/lightbox.js +241 -241
  47. data/assets/themes/j1/adapter/js/logger.js +77 -66
  48. data/assets/themes/j1/adapter/js/lunr.js +688 -86
  49. data/assets/themes/j1/adapter/js/masonry.js +426 -411
  50. data/assets/themes/j1/adapter/js/masterslider.js +526 -527
  51. data/assets/themes/j1/adapter/js/mmenu.js +101 -66
  52. data/assets/themes/j1/adapter/js/navigator.js +291 -356
  53. data/assets/themes/j1/adapter/js/particles.js +61 -40
  54. data/assets/themes/j1/adapter/js/rangeSlider.js +65 -48
  55. data/assets/themes/j1/adapter/js/rouge.js +287 -269
  56. data/assets/themes/j1/adapter/js/rtable.js +309 -293
  57. data/assets/themes/j1/adapter/js/rtextResizer.js +57 -44
  58. data/assets/themes/j1/adapter/js/scroller.js +170 -133
  59. data/assets/themes/j1/adapter/js/slick.js +487 -485
  60. data/assets/themes/j1/adapter/js/slimSelect.js +290 -0
  61. data/assets/themes/j1/adapter/js/speak2me.js +124 -128
  62. data/assets/themes/j1/adapter/js/themeToggler.js +280 -260
  63. data/assets/themes/j1/adapter/js/{themer.js → themes.js} +145 -113
  64. data/assets/themes/j1/adapter/js/toccer.js +87 -54
  65. data/assets/themes/j1/adapter/js/translator.js +73 -70
  66. data/assets/themes/j1/adapter/js/waves.js +74 -58
  67. data/assets/themes/j1/core/css/themes/unolight/bootstrap.css +29 -11
  68. data/assets/themes/j1/core/css/themes/unolight/bootstrap.min.css +2 -2
  69. data/assets/themes/j1/core/js/template.js +474 -420
  70. data/assets/themes/j1/core/js/template.min.js +7 -7
  71. data/assets/themes/j1/core/js/template.min.js.map +1 -1
  72. data/assets/themes/j1/modules/carousel/css/theme/uno.css +4 -4
  73. data/assets/themes/j1/modules/carousel/css/theme/uno.min.css +1 -1
  74. data/assets/themes/j1/modules/clipboard/js/clipboard.js +0 -1
  75. data/assets/themes/j1/modules/cookieConsent/js/cookieConsent.js +4 -4
  76. data/assets/themes/j1/modules/iconPicker/css/theme/uno.css +58 -0
  77. data/assets/themes/j1/modules/iconPicker/css/theme/uno.min.css +16 -0
  78. data/assets/themes/j1/modules/iconPicker/js/universal-icon-picker.0.js +493 -0
  79. data/assets/themes/j1/modules/iconPicker/js/universal-icon-picker.js +7 -7
  80. data/assets/themes/j1/modules/lightGallery/js/plugins/lg-video.js +4 -4
  81. data/assets/themes/j1/modules/lightGallery/js/plugins/lg-video.min.js +2 -10
  82. data/assets/themes/j1/modules/lunr/css/j1.css +12 -6
  83. data/assets/themes/j1/modules/lunr/css/j1.min.css +1 -1
  84. data/assets/themes/j1/modules/lunr/js/j1.js +46 -43
  85. data/assets/themes/j1/modules/lunr/js/j1.min.js +1 -1
  86. data/assets/themes/j1/modules/masterslider/js/masterslider.js +1 -1
  87. data/assets/themes/j1/modules/scroller/js/scroller.js +64 -74
  88. data/assets/themes/j1/modules/scroller/js/scroller.min.js +1 -1
  89. data/assets/themes/j1/modules/slick/slider/css/theme/uno.css +4 -4
  90. data/assets/themes/j1/modules/slick/slider/css/theme/uno.min.css +1 -1
  91. data/assets/themes/j1/modules/slimSelect/js/select.js +1865 -1821
  92. data/assets/themes/j1/modules/slimSelect/js/select.min.js +2 -1
  93. data/assets/themes/j1/modules/themeSwitcher/js/switcher.js +87 -89
  94. data/assets/themes/j1/modules/themeSwitcher/js/switcher.min.js +1 -1
  95. data/assets/themes/j1/modules/videojs/js/plugins/vm/api/player.min.js +5 -7
  96. data/assets/themes/j1/modules/videojs/js/plugins/vm/api/v2.20.1/player.min.js +23 -0
  97. data/lib/j1/version.rb +1 -1
  98. data/lib/starter_web/Gemfile +2 -2
  99. data/lib/starter_web/README.md +5 -5
  100. data/lib/starter_web/_config.yml +1 -1
  101. data/lib/starter_web/_data/blocks/_panel.yml +775 -0
  102. data/lib/starter_web/_data/blocks/panel.yml +53 -53
  103. data/lib/starter_web/_data/j1_config.yml +3 -2
  104. data/lib/starter_web/_data/layouts/default.yml +0 -2
  105. data/lib/starter_web/_data/modules/_scroller.yml +102 -0
  106. data/lib/starter_web/_data/modules/carousel.yml +3 -3
  107. data/lib/starter_web/_data/modules/defaults/attics.yml +5 -5
  108. data/lib/starter_web/_data/modules/defaults/docsearch.yml +1 -1
  109. data/lib/starter_web/_data/modules/defaults/gemini.yml +204 -46
  110. data/lib/starter_web/_data/modules/defaults/{iconPicker.yml → icon_picker.yml} +6 -12
  111. data/lib/starter_web/_data/modules/defaults/lunr.yml +20 -5
  112. data/lib/starter_web/_data/modules/defaults/masterslider.yml +4 -4
  113. data/lib/starter_web/_data/modules/defaults/navigator.yml +20 -24
  114. data/lib/starter_web/_data/modules/defaults/particles.yml +3 -3
  115. data/lib/starter_web/_data/modules/defaults/slim_select.yml +54 -0
  116. data/lib/starter_web/_data/modules/defaults/{themer.yml → themes.yml} +171 -171
  117. data/lib/starter_web/_data/modules/defaults/toccer.yml +1 -1
  118. data/lib/starter_web/_data/modules/gallery.yml +33 -38
  119. data/lib/starter_web/_data/modules/gemini.yml +42 -3
  120. data/lib/starter_web/_data/modules/{iconPicker.yml → icon_picker.yml} +31 -3
  121. data/lib/starter_web/_data/modules/lunr.yml +12 -1
  122. data/lib/starter_web/_data/modules/masonry.yml +37 -38
  123. data/lib/starter_web/_data/modules/masterslider.yml +78 -95
  124. data/lib/starter_web/_data/modules/navigator_menu.yml +12 -20
  125. data/lib/starter_web/_data/modules/particles.yml +3 -3
  126. data/lib/starter_web/_data/modules/scroller.yml +3 -3
  127. data/lib/starter_web/_data/modules/slim_select.yml +110 -0
  128. data/lib/starter_web/_data/modules/{themer.yml → themes.yml} +4 -4
  129. data/lib/starter_web/_data/resources.yml +57 -47
  130. data/lib/starter_web/_data/templates/feed.xml +1 -1
  131. data/lib/starter_web/_includes/attributes.asciidoc +354 -355
  132. data/lib/starter_web/_plugins/asciidoctor/gemini-ui-block.rb +1 -1
  133. data/lib/starter_web/_plugins/asciidoctor/slim-select-block.rb +45 -0
  134. data/lib/starter_web/_plugins/index/lunr.rb +1 -1
  135. data/lib/starter_web/collections/asciidoc_skeletons/simple-post/_posts/yyyy-mm-dd-your-post-name.asciidoc +5 -2
  136. data/lib/starter_web/collections/posts/public/featured/_posts/0000-00-00-welcome-to-j1.adoc.erb +3 -3
  137. data/lib/starter_web/collections/posts/public/featured/_posts/2021-01-01-about-cookies.adoc +9 -9
  138. data/lib/starter_web/collections/posts/public/featured/_posts/2021-02-01-static-site-generators.adoc +4 -4
  139. data/lib/starter_web/collections/posts/public/featured/_posts/2022-02-01-about-j1.adoc +3 -2
  140. data/lib/starter_web/collections/posts/public/featured/_posts/2023-10-18-url-types.adoc +12 -12
  141. data/lib/starter_web/package.json +1 -1
  142. data/lib/starter_web/pages/public/about/features.adoc +1 -1
  143. data/lib/starter_web/pages/public/about/reporting_issues.adoc +1 -0
  144. data/lib/starter_web/pages/public/asciidoc_skeletons/documentation/_includes/attributes.asciidoc +44 -44
  145. data/lib/starter_web/pages/public/asciidoc_skeletons/documentation/documentation.adoc +1 -0
  146. data/lib/starter_web/pages/public/asciidoc_skeletons/multi-document/_includes/attributes.asciidoc +12 -12
  147. data/lib/starter_web/pages/public/blog/navigator/archive/allview.html +1 -1
  148. data/lib/starter_web/pages/public/{legal/learn → learn}/roundtrip/_includes/attributes.asciidoc +42 -28
  149. data/lib/starter_web/pages/public/{legal/learn → learn}/roundtrip/highlghter_rouge.adoc +1 -0
  150. data/lib/starter_web/pages/public/{legal/learn → learn}/roundtrip/lunr_search.adoc +1 -0
  151. data/lib/starter_web/pages/public/{legal/learn → learn}/roundtrip/present_audio_video.adoc +18 -2
  152. data/lib/starter_web/pages/public/{legal/learn → learn}/roundtrip/present_images.adoc +500 -507
  153. data/lib/starter_web/pages/public/legal/en/100_copyright.adoc +6 -11
  154. data/lib/starter_web/pages/public/legal/en/200_impress.adoc +4 -11
  155. data/lib/starter_web/pages/public/legal/en/300_privacy.adoc +5 -12
  156. data/lib/starter_web/pages/public/legal/en/400_comment_policy.adoc +5 -10
  157. data/lib/starter_web/pages/public/tools/previewer/_includes/attributes.asciidoc +10 -9
  158. data/lib/starter_web/pages/public/tools/previewer/preview_bootstrap_theme.adoc +77 -75
  159. metadata +50 -46
  160. data/lib/starter_web/pages/public/manuals/integrations/gemini/_includes/attributes.asciidoc +0 -47
  161. data/lib/starter_web/pages/public/manuals/integrations/gemini/_includes/documents/preview_google_adsense.asciidoc +0 -448
  162. data/lib/starter_web/pages/public/manuals/integrations/gemini/_includes/documents/readme +0 -0
  163. data/lib/starter_web/pages/public/manuals/integrations/gemini/_includes/tables/readme +0 -0
  164. data/lib/starter_web/pages/public/manuals/integrations/gemini/gemini.adoc +0 -525
  165. data/lib/starter_web/pages/public/manuals/integrations/gemini/security.asccidoc +0 -274
  166. data/lib/starter_web/pages/public/manuals/integrations/gemini/security.hrml +0 -560
  167. /data/lib/starter_web/pages/public/{legal/learn → learn}/bookshelf/article_previewer/viewer_biography.adoc +0 -0
  168. /data/lib/starter_web/pages/public/{legal/learn → learn}/bookshelf/article_previewer/viewer_fantasy.adoc +0 -0
  169. /data/lib/starter_web/pages/public/{legal/learn → learn}/bookshelf/article_previewer/viewer_romance.adoc +0 -0
  170. /data/lib/starter_web/pages/public/{legal/learn → learn}/bookshelf/jekyll_collections.adoc +0 -0
  171. /data/lib/starter_web/pages/public/{legal/learn → learn}/bookshelf/viewer_all_books.adoc +0 -0
  172. /data/lib/starter_web/pages/public/{legal/learn → learn}/roundtrip/_includes/documents/100_gistblock.asciidoc +0 -0
  173. /data/lib/starter_web/pages/public/{legal/learn → learn}/roundtrip/_includes/documents/410_bottom_info.asciidoc +0 -0
  174. /data/lib/starter_web/pages/public/{legal/learn → learn}/roundtrip/_includes/documents/410_bottom_left_warning.asciidoc +0 -0
  175. /data/lib/starter_web/pages/public/{legal/learn → learn}/roundtrip/_includes/documents/410_bottom_right_danger.asciidoc +0 -0
  176. /data/lib/starter_web/pages/public/{legal/learn → learn}/roundtrip/_includes/documents/410_central_success.asciidoc +0 -0
  177. /data/lib/starter_web/pages/public/{legal/learn → learn}/roundtrip/_includes/documents/410_full_height_left_info.asciidoc +0 -0
  178. /data/lib/starter_web/pages/public/{legal/learn → learn}/roundtrip/_includes/documents/410_full_height_right_success.asciidoc +0 -0
  179. /data/lib/starter_web/pages/public/{legal/learn → learn}/roundtrip/_includes/documents/410_table_bs_modal_examples.asciidoc +0 -0
  180. /data/lib/starter_web/pages/public/{legal/learn → learn}/roundtrip/_includes/documents/410_top_info.asciidoc +0 -0
  181. /data/lib/starter_web/pages/public/{legal/learn → learn}/roundtrip/_includes/documents/410_top_left_info.asciidoc +0 -0
  182. /data/lib/starter_web/pages/public/{legal/learn → learn}/roundtrip/_includes/documents/410_top_right_success.asciidoc +0 -0
  183. /data/lib/starter_web/pages/public/{legal/learn → learn}/roundtrip/_includes/documents/419_advanced_modals_demo.asciidoc +0 -0
  184. /data/lib/starter_web/pages/public/{legal/learn → learn}/roundtrip/_includes/documents/tables/bs_modal_examples.asciidoc +0 -0
  185. /data/lib/starter_web/pages/public/{legal/learn → learn}/roundtrip/_includes/documents/themes_bootstrap.asciidoc +0 -0
  186. /data/lib/starter_web/pages/public/{legal/learn → learn}/roundtrip/_includes/documents/themes_rouge.asciidoc +0 -0
  187. /data/lib/starter_web/pages/public/{legal/learn → learn}/roundtrip/asciidoc_extensions.adoc +0 -0
  188. /data/lib/starter_web/pages/public/{legal/learn → learn}/roundtrip/bootstrap_themes.adoc +0 -0
  189. /data/lib/starter_web/pages/public/{legal/learn → learn}/roundtrip/icon_fonts.adoc +0 -0
  190. /data/lib/starter_web/pages/public/{legal/learn → learn}/roundtrip/modal_extentions.adoc +0 -0
  191. /data/lib/starter_web/pages/public/{legal/learn → learn}/roundtrip/responsive_tables.adoc +0 -0
  192. /data/lib/starter_web/pages/public/{legal/learn → learn}/roundtrip/typography.adoc +0 -0
  193. /data/lib/starter_web/pages/public/{legal/learn → learn}/where_to_go.adoc +0 -0
@@ -27,30 +27,33 @@ regenerate: true
27
27
 
28
28
  {% comment %} Set global settings
29
29
  -------------------------------------------------------------------------------- {% endcomment %}
30
- {% assign environment = site.environment %}
31
- {% assign asset_path = "/assets/themes/j1" %}
30
+ {% assign environment = site.environment %}
31
+ {% assign asset_path = "/assets/themes/j1" %}
32
32
 
33
33
  {% comment %} Process YML config data
34
34
  ================================================================================ {% endcomment %}
35
35
 
36
36
  {% comment %} Set config files
37
37
  -------------------------------------------------------------------------------- {% endcomment %}
38
- {% assign template_config = site.data.j1_config %}
39
- {% assign blocks = site.data.blocks %}
40
- {% assign modules = site.data.modules %}
38
+ {% assign template_config = site.data.j1_config %}
39
+ {% assign blocks = site.data.blocks %}
40
+ {% assign modules = site.data.modules %}
41
41
 
42
42
  {% comment %} Set config data (settings only)
43
43
  -------------------------------------------------------------------------------- {% endcomment %}
44
- {% assign gemini_defaults = modules.defaults.gemini.defaults %}
45
- {% assign gemini_settings = modules.gemini.settings %}
44
+ {% assign slim_select_defaults = modules.defaults.slim_select.defaults %}
45
+ {% assign slim_select_settings = modules.slim_select.settings %}
46
+ {% assign gemini_defaults = modules.defaults.gemini.defaults %}
47
+ {% assign gemini_settings = modules.gemini.settings %}
46
48
 
47
49
  {% comment %} Set config options (settings only)
48
50
  -------------------------------------------------------------------------------- {% endcomment %}
49
- {% assign gemini_options = gemini_defaults | merge: gemini_settings %}
51
+ {% assign slim_select_options = slim_select_defaults | merge: slim_select_settings %}
52
+ {% assign gemini_options = gemini_defaults | merge: gemini_settings %}
50
53
 
51
54
  {% comment %} Variables
52
55
  -------------------------------------------------------------------------------- {% endcomment %}
53
- {% assign comments = gemini_options.enabled %}
56
+ {% assign comments = gemini_options.enabled %}
54
57
 
55
58
  {% comment %} Detect prod mode
56
59
  -------------------------------------------------------------------------------- {% endcomment %}
@@ -84,245 +87,456 @@ regenerate: true
84
87
  /* eslint indent: "off" */
85
88
  // -----------------------------------------------------------------------------
86
89
  'use strict';
87
- j1.adapter.gemini = (function (j1, window) {
90
+ j1.adapter.gemini = ((j1, window) => {
91
+
92
+ {% comment %} Set global variables
93
+ ------------------------------------------------------------------------------ {% endcomment %}
94
+ var environment = '{{environment}}';
95
+ var state = 'not_started';
96
+ var leafletScript = document.createElement('script');
97
+ var geocoderScript = document.createElement('script');
98
+ var safetySettings = [];
99
+ var generationConfig = {} ;
100
+ var genAIError = false;
101
+ var genAIErrorType = '';
102
+ var response = '';
103
+ var modal_error_text = '';
104
+ var modulesLoaded = false;
105
+ var textHistory = []; // Array to store the history of entered text
106
+ var historyIndex = -1; // Index to keep track of the current position in the history
107
+ var chat_prompt = {};
108
+ var maxRetries = 3;
109
+ var logStartOnce = false;
110
+
111
+ var url;
112
+ var baseUrl;
113
+ var cookie_names;
114
+ var cookie_written;
115
+ var hostname;
116
+ var auto_domain;
117
+ var check_cookie_option_domain;
118
+ var cookie_domain;
119
+ var secure;
120
+
121
+ var gemini_model;
122
+ var apiKey;
123
+ var validApiKey;
124
+ var genAI;
125
+ var result;
126
+ var retryCount;
127
+
128
+ var latitude;
129
+ var longitude;
130
+ var country;
131
+ var city;
132
+
133
+ var newItem;
134
+ var itemExists;
135
+
136
+ var selectList;
137
+ var $slimSelect;
138
+ var textarea;
139
+ var promptHistoryMax;
140
+ var promptHistoryEnabled;
141
+ var promptHistoryFromCookie;
142
+ var allowPromptHistoryUpdatesOnMax;
143
+
144
+ var _this;
145
+ var logger;
146
+ var logText;
147
+
148
+ // values taken from API
149
+ var HarmCategory, HarmBlockThreshold;
150
+
151
+ // date|time
152
+ var startTime;
153
+ var endTime;
154
+ var startTimeModule;
155
+ var endTimeModule;
156
+ var timeSeconds;
157
+
158
+ var eventListenersReady;
88
159
 
89
- {% comment %} Set global variables
90
- -------------------------------------------------------------------------------- {% endcomment %}
91
- var environment = '{{environment}}';
92
- var state = 'not_started';
93
- var leafletScript = document.createElement('script');
94
- var geocoderScript = document.createElement('script');
95
- var safetySettings = [];
96
- var genAIError = false;
97
- var genAIErrorType = '';
98
- var response = '';
99
- var modal_error_text = '';
100
- var moduleLoaded = false;
101
- var moduleLoaded = false;
102
- var apiKey;
103
- var validApiKey;
104
- var genAI;
105
- var frontmatterOptions;
106
- var result;
107
- var _this;
108
- var logger;
109
- var logText;
110
- var HarmCategory, HarmBlockThreshold;
111
-
112
- // -----------------------------------------------------------------------
113
- // Module variable settings
114
- // -----------------------------------------------------------------------
115
- var geminiDefaults = $.extend({}, {{gemini_defaults | replace: 'nil', 'null' | replace: '=>', ':' }});
116
- var geminiSettings = $.extend({}, {{gemini_settings | replace: 'nil', 'null' | replace: '=>', ':' }});
117
- var geminiOptions = $.extend(true, {}, geminiDefaults, geminiSettings, frontmatterOptions);
118
-
119
- const defaultPrompt = geminiOptions.prompt.default;
120
- const httpError400 = geminiOptions.errors.http400;
121
- const httpError500 = geminiOptions.errors.http500;
160
+ // ---------------------------------------------------------------------------
161
+ // module variable settings
162
+ // ---------------------------------------------------------------------------
122
163
 
123
- // -----------------------------------------------------------------------------
124
- // Helper functions
125
- // -----------------------------------------------------------------------------
164
+ // create settings object from module options
165
+ //
166
+ var slimSelectDefaults = $.extend({}, {{slim_select_defaults | replace: 'nil', 'null' | replace: '=>', ':' }});
167
+ var slimSelectSettings = $.extend({}, {{slim_select_settings | replace: 'nil', 'null' | replace: '=>', ':' }});
168
+ var slimSelectOptions = $.extend(true, {}, slimSelectDefaults, slimSelectSettings);
169
+
170
+ var geminiDefaults = $.extend({}, {{gemini_defaults | replace: 'nil', 'null' | replace: '=>', ':' }});
171
+ var geminiSettings = $.extend({}, {{gemini_settings | replace: 'nil', 'null' | replace: '=>', ':' }});
172
+ var geminiOptions = $.extend(true, {}, geminiDefaults, geminiSettings);
173
+
174
+ const defaultPrompt = geminiOptions.prompt.default;
175
+ const httpError400 = geminiOptions.errors.http400;
176
+ const httpError500 = geminiOptions.errors.http500;
177
+
178
+ // ---------------------------------------------------------------------------
179
+ // helper functions
180
+ // ---------------------------------------------------------------------------
181
+
182
+ function addPromptHistoryEventListeners(slimSelectData) {
183
+ var index = 1;
184
+ slimSelectData.forEach (() => {
185
+ var span = 'opt_prompt_history_' + index;
186
+ var spanElement = document.getElementById(span);
187
+
188
+ var dependencies_met_span_ready = setInterval (() => {
189
+ var spanElementReady = (($(spanElement).length) !== 0) ? true : false;
190
+ if (spanElementReady) {
191
+ logger.debug('\n' + 'add eventListener to: ' + span);
192
+ spanElement.addEventListener('click', spanElementEventListener);
193
+
194
+ clearInterval(dependencies_met_span_ready);
195
+ }
196
+ }, 10);
197
+ index++;
198
+ }); // END forEach data
199
+ } // END addPromptHistoryEventListeners
200
+
201
+ function spanElementEventListener(event) {
202
+ var optionText = event.currentTarget.nextSibling.data;
203
+ var slimData = $slimSelect.getData();
204
+ var textHistory = [];
205
+ var chatHistory = j1.existsCookie(cookie_names.chat_prompt)
206
+ ? j1.readCookie(cookie_names.chat_prompt)
207
+ : {};
208
+ var foundItem;
209
+ var newHistory;
210
+ var newData;
211
+
212
+ // suppress default actions|bubble up
213
+ event.preventDefault();
214
+ event.stopPropagation();
215
+
216
+ // update slimSelect data
217
+ foundItem = -1;
218
+ for (var i = 0; i < slimData.length; i++) {
219
+ if (slimData[i].text === optionText) {
220
+ foundItem = i;
221
+ break;
222
+ }
223
+ }
224
+
225
+ if (foundItem !== -1) {
226
+ delete slimData[foundItem];
227
+
228
+ // create new reindexed data object
229
+ newData = Object.values(slimData);
230
+ // update the select
231
+ $slimSelect.setData(newData);
232
+ }
233
+
234
+ // update prompt history data
235
+ foundItem = -1;
236
+ // convert chat prompt object to array
237
+ textHistory = Object.values(chatHistory);
238
+ for (var i = 0; i < textHistory.length; i++) {
239
+ if (textHistory[i] === optionText) {
240
+ foundItem = i;
241
+ break;
242
+ }
243
+ }
244
+
245
+ if (foundItem !== -1) {
246
+ delete textHistory[foundItem];
247
+
248
+ // create new reindexed data object
249
+ newHistory = Object.values(textHistory);
250
+
251
+ // remove duplicates from history
252
+ if (newHistory.length > 1) {
253
+ // create a 'Set' from the history array to automatically remove duplicates
254
+ var uniqueArray = [...new Set(newHistory)];
255
+ newHistory = Object.values(uniqueArray);
256
+ } // END if allowHistoryDupicates
257
+
258
+ // update the prompt history
259
+ if (promptHistoryFromCookie) {
260
+ logger.debug('\n' + 'save prompt history to cookie');
261
+ j1.removeCookie({
262
+ name: cookie_names.chat_prompt,
263
+ domain: auto_domain,
264
+ secure: secure
265
+ });
266
+
267
+ if (newHistory.length > 0) {
268
+ cookie_written = j1.writeCookie({
269
+ name: cookie_names.chat_prompt,
270
+ data: newHistory,
271
+ secure: secure
272
+ });
273
+ } else {
274
+ cookie_written = j1.writeCookie({
275
+ name: cookie_names.chat_prompt,
276
+ data: {},
277
+ secure: secure
278
+ });
279
+ logger.info('\n' + 'spanElementEventListener, hide prompt history on last element');
280
+ $("#prompt_history_container").hide();
281
+ } // END if length
282
+ } // END if promptHistoryFromCookie
283
+ }
284
+
285
+ logger.info('\n' + 'spanElementEventListener, option deleted:\n' + optionText);
286
+
287
+ // close currently required to re-add history prompt events on next beforeOpen
288
+ $slimSelect.close();
289
+ } // END spanElementEventListener
126
290
 
127
291
  // Log the geolocation position
128
292
  function showPosition(position) {
129
- var latitude = position.coords.latitude;
130
- var longitude = position.coords.longitude;
131
- console.debug("Detected geocode (lat:long): " + latitude + ':' + longitude);
132
- } //END function showPosition
293
+ latitude = position.coords.latitude;
294
+ longitude = position.coords.longitude;
295
+
296
+ logger.debug('\n' + 'detected geocode (lat:long): ' + latitude + ':' + longitude);
297
+ } // END function showPosition
133
298
 
134
299
  function locateCountry(position) {
135
- const latitude = position.coords.latitude;
136
- const longitude = position.coords.longitude;
300
+ latitude = position.coords.latitude;
301
+ longitude = position.coords.longitude;
137
302
 
138
303
  // Reverse geocode to find the country
139
304
  fetch(`//nominatim.openstreetmap.org/reverse?format=jsonv2&lat=${latitude}&lon=${longitude}`)
140
305
  .then(response => response.json())
141
- .then(data => {
142
- const country = '<b>' + data.address.country;
143
- const city = data.address.city;
144
- $("#modal_error").html(modal_error_text + '<br>' + country);
306
+ .then((data) => {
307
+ country = data.address.country;
308
+ city = data.address.city;
309
+ $("#modal_error").html(modal_error_text + '<br>' + '<b>' + country + '</b>');
310
+ logger.warn('\n' + 'location is not supported: ' + country + ':' + city);
145
311
  })
146
- .catch(error => {
147
- console.warn('Error:', error);
312
+ .catch((error) => {
313
+ logger.error('\n' + 'error detect location: ' + error);
148
314
  });
149
- } //END function locateCountry
315
+ } // END function locateCountry
150
316
 
151
317
  function geoFindMe() {
152
318
 
153
319
  function success(position) {
154
- const latitude = position.coords.latitude;
155
- const longitude = position.coords.longitude;
320
+ latitude = position.coords.latitude;
321
+ longitude = position.coords.longitude;
156
322
 
157
323
  locateCountry(position);
158
- } //END function success
324
+ } // END function success
159
325
 
160
326
  function error() {
161
327
  logger.warn('\n' + 'Unable to retrieve the location');
162
- } //END function error
328
+ } // END function error
163
329
 
164
330
  if (!navigator.geolocation) {
165
331
  logger.warn('\n' + 'Geolocation API is not supported by the browser');
166
332
  } else {
167
333
  navigator.geolocation.getCurrentPosition(success, error);
168
334
  }
169
- } //END function geoFindMe
335
+ } // END function geoFindMe
170
336
 
171
337
  async function runner() {
172
- let input = document.getElementById("name");
338
+ var input = document.getElementById("name");
173
339
 
174
- // For text-only input, use the gemini-pro model
340
+ // For text-only input, use the selected model
175
341
  const model = genAI.getGenerativeModel({
176
- model: "gemini-pro",
177
- safetySettings
342
+ model: gemini_model,
343
+ safetySettings,
344
+ generationConfig
178
345
  });
179
346
 
180
347
  var prompt = $('textarea#prompt').val();
181
- if (prompt.length == 0) {
182
- prompt = defaultPrompt;
348
+ if (prompt.length === 0) {
349
+ // use default prompt
350
+ prompt = defaultPrompt.replace(/\s+$/g, '');
351
+ logger.debug('\n' + 'use default prompt: ' + prompt);
183
352
  document.getElementById('prompt').value = prompt;
184
353
  }
185
354
 
186
- try {
187
- result = await model.generateContent(prompt);
188
- } catch (e) {
189
- var error = e.toString();
190
- if (error.includes("400")) {
191
- genAIErrorType = 400;
355
+ // run a request
356
+ startTime = Date.now();
357
+ retryCount = 1;
358
+ logger.info('\n' + 'processing request: started');
359
+ while (retryCount <= maxRetries) {
360
+ try {
361
+ logger.debug('\n' + 'processing request: #' + retryCount + '|' + maxRetries);
362
+ result = await model.generateContent(prompt);
363
+
364
+ // exit the loop on success
365
+ break;
366
+ } catch (e) {
367
+ var error = e.toString();
368
+ if (error.includes('400')) {
369
+ genAIErrorType = 400;
192
370
  modal_error_text = httpError400;
193
- $("#modal_error").html(modal_error_text);
194
- logger.warn('\n' + 'Location is not supported');
195
- } else if (error.includes("50")) {
196
- genAIErrorType = 500;
371
+ if (geminiOptions.detect_geo_location) {
372
+ geoFindMe();
373
+ $("#modal_error").html(modal_error_text);
374
+ } else {
375
+ $("#modal_error").html(modal_error_text);
376
+ logger.warn('\n' + 'location not supported');
377
+ }
378
+ } else if (error.includes('50')) {
379
+ genAIErrorType = 500;
197
380
  modal_error_text = httpError500;
198
381
  $("#modal_error").html(modal_error_text);
199
- logger.warn('\n' + 'Service currently not available');
382
+ logger.warn('\n' + 'service not available');
200
383
  }
201
384
  genAIError = true;
202
- } finally {
203
- if (!genAIError) {
204
- try {
205
- response = await result.response;
206
- } catch (e) {
207
- logger.warn('\n' + e);
208
- } finally {
209
- $("#spinner").hide();
210
-
211
- // Evaluate|Process feedback returned from API
212
- var candidateRatings = geminiOptions.candidateRatings;
213
- var responseText = '';
214
- var safetyRatings;
215
- var safetyRating;
216
- var safetyCategory;
217
- var ratingCategory;
218
- var ratingProbability;
219
- var responseFinishReason;
220
-
221
- if (response.promptFeedback !== undefined) {
222
- safetyRatings = response.promptFeedback.safetyRatings;
223
- responseFinishReason = response.promptFeedback.blockReason;
224
- if (responseFinishReason == 'SAFETY') {
225
- safetyRatings.forEach(rating => {
226
- if (rating.probability !== undefined && rating.probability !== 'NEGLIGIBLE' && rating.probability !== 'LOW') {
227
- if (rating.category !== undefined) {
228
- ratingCategory = rating.category;
229
- ratingProbability = rating.probability;
385
+ } finally {
386
+ if (!genAIError) {
387
+ try {
388
+ logger.debug('\n' + 'collecting results ...');
389
+ response = await result.response;
390
+ } catch (e) {
391
+ logger.warn('\n' + e);
392
+ } finally {
393
+ $("#spinner").hide();
394
+
395
+ // Evaluate|Process feedback returned from API
396
+ var candidateRatings = geminiOptions.api_options.candidateRatings;
397
+ var responseText = '';
398
+ var safetyRatings;
399
+ var safetyRating;
400
+ var safetyCategory;
401
+ var ratingCategory;
402
+ var ratingProbability;
403
+ var responseFinishReason;
404
+
405
+ if (response.promptFeedback !== undefined) {
406
+ safetyRatings = response.promptFeedback.safetyRatings;
407
+ responseFinishReason = response.promptFeedback.blockReason;
408
+ if (responseFinishReason === 'SAFETY') {
409
+ safetyRatings.forEach(rating => {
410
+ if (rating.probability !== undefined && rating.probability !== 'NEGLIGIBLE' && rating.probability !== 'LOW') {
411
+ if (rating.category !== undefined) {
412
+ ratingCategory = rating.category;
413
+ ratingProbability = rating.probability;
414
+ }
230
415
  }
416
+ });
417
+ if (ratingCategory !== undefined && ratingCategory !== '' && ratingProbability !== undefined && ratingProbability !== '') {
418
+ logger.warn('\n' + 'Security issue detected, reason: ' + ratingCategory + ' = ' + ratingProbability);
231
419
  }
232
- });
233
- if (ratingCategory !== undefined && ratingCategory !== '' && ratingProbability !== undefined && ratingProbability !== '') {
234
- logger.warn('\n' + 'Security issue detected, reason: ' + ratingCategory + ' = ' + ratingProbability);
420
+ var ratingCategoryText = ratingCategory.replace("HARM_CATEGORY_", '').toLowerCase();
421
+ var ratingProbabilityText = ratingProbability.toLowerCase();
422
+ responseText = 'Response disabled due to security reasons (<b>' + ratingCategoryText + ': ' + ratingProbabilityText + '</b>). Please modify your prompt.';
423
+ }
424
+ if (response.text !== undefined && response.text.length > 0) {
425
+ responseText = response.text;
235
426
  }
236
- responseText = 'Response disabled due to security reasons. You need to <b>change your prompt</b> to get proper results.';
237
- }
238
- if (response.text !== undefined && response.text.length > 0) {
239
- responseText = response.text;
240
427
  }
241
- }
242
-
243
- if (response.candidates !== undefined) {
244
- safetyRatings = response.candidates[0].safetyRatings;
245
- responseFinishReason = response.candidates[0].finishReason;
246
428
 
247
- if (responseFinishReason == 'STOP') {
248
- for (const [key, value] of Object.entries(candidateRatings)) {
249
- safetyRatings.forEach(rating => {
250
- if (rating == 'HARM_CATEGORY_DANGEROUS_CONTENT' || rating.category == 'HARM_CATEGORY_HARASSMENT' || rating.category == 'HARM_CATEGORY_HATE_SPEECH' || rating.category == 'HARM_CATEGORY_SEXUALLY_EXPLICIT') {
251
- if (rating.probability !== "NEGLIGIBLE") {
252
- if (candidateRatings.HARM_CATEGORY_DANGEROUS_CONTENT == "BLOCK_NONE") {
253
- safetyCategory = rating.category;
254
- safetyRating = candidateRatings.HARM_CATEGORY_DANGEROUS_CONTENT;
255
- responseText = response.candidates[0].content.parts[0].text;
256
- }
257
- if (candidateRatings.HARM_CATEGORY_HARASSMENT == "BLOCK_NONE") {
258
- safetyCategory = rating.category;
259
- safetyRating = candidateRatings.HARM_CATEGORY_HARASSMENT;
260
- responseText = response.candidates[0].content.parts[0].text;
261
- }
262
- if (candidateRatings.HARM_CATEGORY_HATE_SPEECH == "BLOCK_NONE") {
263
- safetyCategory = rating.category;
264
- safetyRating = candidateRatings.HARM_CATEGORY_HATE_SPEECH;
265
- responseText = response.candidates[0].content.parts[0].text;
266
- }
267
- if (candidateRatings.HARM_CATEGORY_SEXUALLY_EXPLICIT == "BLOCK_NONE") {
268
- safetyCategory = rating.category;
269
- safetyRating = candidateRatings.HARM_CATEGORY_SEXUALLY_EXPLICIT;
429
+ if (response.candidates !== undefined) {
430
+ safetyRatings = response.candidates[0].safetyRatings;
431
+ responseFinishReason = response.candidates[0].finishReason;
432
+
433
+ if (responseFinishReason === 'STOP') {
434
+ for (const [key, value] of Object.entries(candidateRatings)) {
435
+ safetyRatings.forEach(rating => {
436
+ if (rating === 'HARM_CATEGORY_DANGEROUS_CONTENT' || rating.category === 'HARM_CATEGORY_HARASSMENT' || rating.category === 'HARM_CATEGORY_HATE_SPEECH' || rating.category === 'HARM_CATEGORY_SEXUALLY_EXPLICIT') {
437
+ if (rating.probability !== "NEGLIGIBLE") {
438
+ if (candidateRatings.HARM_CATEGORY_DANGEROUS_CONTENT === "BLOCK_NONE") {
439
+ safetyCategory = rating.category;
440
+ safetyRating = candidateRatings.HARM_CATEGORY_DANGEROUS_CONTENT;
441
+ responseText = response.candidates[0].content.parts[0].text;
442
+ }
443
+ if (candidateRatings.HARM_CATEGORY_HARASSMENT === "BLOCK_NONE") {
444
+ safetyCategory = rating.category;
445
+ safetyRating = candidateRatings.HARM_CATEGORY_HARASSMENT;
446
+ responseText = response.candidates[0].content.parts[0].text;
447
+ }
448
+ if (candidateRatings.HARM_CATEGORY_HATE_SPEECH === "BLOCK_NONE") {
449
+ safetyCategory = rating.category;
450
+ safetyRating = candidateRatings.HARM_CATEGORY_HATE_SPEECH;
451
+ responseText = response.candidates[0].content.parts[0].text;
452
+ }
453
+ if (candidateRatings.HARM_CATEGORY_SEXUALLY_EXPLICIT === "BLOCK_NONE") {
454
+ safetyCategory = rating.category;
455
+ safetyRating = candidateRatings.HARM_CATEGORY_SEXUALLY_EXPLICIT;
456
+ responseText = response.candidates[0].content.parts[0].text;
457
+ }
458
+ } else {
270
459
  responseText = response.candidates[0].content.parts[0].text;
271
- }
272
- } else {
273
- responseText = response.candidates[0].content.parts[0].text;
274
- } //END if rating.probability
275
- } //END if rating.category
276
- }); //END forEach
277
- } //END for
278
-
279
- if (safetyCategory !== undefined) {
280
- logger.debug('\n' + safetyCategory + ': ' + safetyRating);
281
- }
282
- if (response.candidates[0].finishReason == 'SAFETY') {
460
+ } // END if rating.probability
461
+ } // END if rating.category
462
+ }); // END forEach
463
+ } // END for
464
+
465
+ if (safetyCategory !== undefined) {
466
+ logger.debug('\n' + safetyCategory + ': ' + safetyRating);
467
+ }
468
+ } // END responseFinishReason STOP
469
+
470
+ if (response.candidates[0].finishReason === 'MAX_TOKENS') {
471
+ responseText = 'Response disabled due to model settings (<b>maxOutputTokens: ' + geminiOptions.api_options.generationConfig.maxOutputTokens + '</b>). You need to increase your settings to get full response.';
472
+ } // END responseFinishReason MAX_TOKENS
473
+
474
+ if (response.candidates[0].finishReason === 'SAFETY') {
283
475
  responseText = 'Response disabled due to security reasons. You need to <b>change your prompt</b> to get proper results.';
476
+ console.warn('Response disabled due to security reasons');
477
+ } // END responseFinishReason SAFETY
478
+
479
+ if (response.candidates[0].finishReason === 'RECITATION') {
480
+ responseText = 'Response flagged "RECITATION". Resposne currently not supported';
481
+ console.warn('finishReason "RECITATION" currently not supported');
482
+ } // END responseFinishReason RECITATION
483
+
484
+ if (response.candidates[0].finishReason === 'OTHER') {
485
+ responseText = 'Response disabled due to unknown reasons.';
486
+ console.warn('Response disabled due to unknown reasons');
487
+ } // END responseFinishReason OTHER
488
+
489
+ } // END if response.candidates
490
+
491
+ if (responseText.length > 0) {
492
+ // Set|Show UI elements
493
+ if (responseText.length < geminiOptions.api_options.responseLengthMin) {
494
+ logger.warn('\n' + 'Response generated too short: <' + geminiOptions.api_options.responseLengthMin + ' characters');
495
+ document.getElementById('md_result').innerHTML = 'Response generated too short (less than ' + geminiOptions.api_options.responseLengthMin + ' characters). Please re-run the generation for better results';
496
+ } else {
497
+ document.getElementById('md_result').innerHTML = marked.parse(responseText);
284
498
  }
285
- } //END if finishReason
286
- }
287
-
288
- if (responseText.length > 0) {
289
- // Set|Show UI elements
290
- if (responseText.length < geminiOptions.responseLengthMin) {
291
- logger.warn('\n' + 'Response generated too short: <' + geminiOptions.responseLengthMin + ' characters');
292
- document.getElementById('md_result').innerHTML = 'Response generated too short (less than ' + geminiOptions.responseLengthMin + ' characters). Please re-run the generation for better results';
293
- } else {
294
- document.getElementById('md_result').innerHTML = marked.parse(responseText);
499
+ $("#result").show();
500
+ $("#response").show();
501
+ } // END responseText length
502
+ } // END finally
503
+ } else {
504
+ if (retryCount === 3) {
505
+ logger.debug('\n' + 'requests failed after max retries: ' + maxRetries);
506
+
507
+ $("#spinner").hide();
508
+ if (geminiOptions.detectGeoLocation) {
509
+ geoFindMe();
295
510
  }
296
- $("#result").show();
297
- $("#response").show();
511
+ setTimeout (() => {
512
+ $('#confirmError').modal('show');
513
+ }, 1000);
298
514
  }
299
- } //END finally
300
- } else {
301
- if (geminiOptions.detectGeoLocation) {
302
- geoFindMe();
303
- }
304
- $("#spinner").hide();
305
- setTimeout (function() {
306
- $('#errorModal').modal('show');
307
- }, 1000);
308
- } //END else
309
- } //END finally
310
- } //END async function runner()
515
+ // increment retry counter
516
+ retryCount++;
517
+ } // END else
518
+ } // END finally
519
+ } // END while (retry)
520
+
521
+ endTime = Date.now();
522
+ logger.debug('\n' + 'request execution time: ' + (endTime-startTime) + 'ms');
523
+ logger.info('\n' + 'processing request: finished');
524
+
525
+ } // END async function runner()
311
526
 
312
527
  // ---------------------------------------------------------------------------
313
- // Main object
528
+ // main
314
529
  // ---------------------------------------------------------------------------
530
+ //
315
531
  return {
316
532
 
317
533
  // -------------------------------------------------------------------------
318
- // init()
319
- // adapter initializer
534
+ // module initializer
320
535
  // -------------------------------------------------------------------------
321
- init: function (options) {
322
- var logStartOnce = false;
536
+ init: (options) => {
323
537
 
324
538
  // -----------------------------------------------------------------------
325
- // Default module settings
539
+ // default module settings
326
540
  // -----------------------------------------------------------------------
327
541
  var settings = $.extend({
328
542
  module_name: 'j1.adapter.gemini',
@@ -330,135 +544,169 @@ const httpError500 = geminiOptions.errors.http500;
330
544
  }, options);
331
545
 
332
546
  // -----------------------------------------------------------------------
333
- // Module variable settings
547
+ // module variable settings
334
548
  // -----------------------------------------------------------------------
335
-
336
- // create settings object from frontmatter
337
- frontmatterOptions = options != null ? $.extend({}, options) : {};
338
-
339
- _this = j1.adapter.gemini;
340
- logger = log4javascript.getLogger('j1.adapter.gemini');
341
-
342
- // Module loader
549
+ _this = j1.adapter.gemini;
550
+ logger = log4javascript.getLogger('j1.adapter.gemini');
551
+ cookie_names = j1.getCookieNames();
552
+ url = new liteURL(window.location.href);
553
+ baseUrl = url.origin;
554
+ hostname = url.hostname;
555
+ auto_domain = hostname.substring(hostname.lastIndexOf('.', hostname.lastIndexOf('.') - 1) + 1);
556
+ secure = (url.protocol.includes('https')) ? true : false;
557
+ promptHistoryEnabled = geminiOptions.prompt_history_enabled;
558
+ promptHistoryFromCookie = geminiOptions.prompt_history_from_cookie;
559
+
560
+ var data;
561
+ var option;
562
+
563
+ // module loader
343
564
  _this.loadModules();
344
565
 
345
- // UI loader
566
+ // ui loader
346
567
  _this.loadUI();
347
568
 
348
- // Module initializer
349
- var dependencies_met_page_ready = setInterval (function (options) {
350
- var pageState = $('#no_flicker').css("display");
351
- var pageVisible = (pageState == 'block') ? true : false;
352
- var uiLoaded = (j1.xhrDOMState['#gemini_ui'] == 'success') ? true : false;
569
+ // -----------------------------------------------------------------------
570
+ // module initializer
571
+ // -----------------------------------------------------------------------
572
+ var dependencies_met_page_ready = setInterval (() => {
573
+ var pageState = $('#content').css("display");
574
+ var pageVisible = (pageState === 'block') ? true : false;
575
+ var j1CoreFinished = (j1.getState() === 'finished') ? true : false;
576
+ // var slimSelectFinished = (j1.adapter.slimSelect.getState() === 'finished') ? true : false;
577
+ var slimSelectFinished = (Object.keys(j1.adapter.slimSelect.select).length) ? true : false;
578
+ var uiLoaded = (j1.xhrDOMState['#gemini_ui'] === 'success') ? true : false;
579
+
580
+ // check page ready state
581
+ if (j1CoreFinished && pageVisible && slimSelectFinished && uiLoaded && modulesLoaded) {
582
+ startTimeModule = Date.now();
353
583
 
354
- if (!logStartOnce) {
355
584
  _this.setState('started');
356
- logger.info('\n' + 'set module state to: ' + _this.getState());
357
- logger.info('\n' + 'module is being initialized');
358
- logStartOnce = true;
359
- }
585
+ logger.debug('\n' + 'set module state to: ' + _this.getState());
586
+ logger.info('\n' + 'initializing module: started');
360
587
 
361
- if (j1.getState() === 'finished' && pageVisible && moduleLoaded && uiLoaded) {
588
+ if (!validApiKey) {
589
+ logger.warn('\n' + 'Invalid API key detected: ' + apiKey);
590
+ logger.debug('\n' + 'disable|hide all UI buttons');
591
+ // disable all UI buttons
592
+ $("#send").hide();
593
+ $("#reset").hide();
594
+ $("#clear").hide();
595
+ }
362
596
 
363
- // Initialize|Hide UI Components
597
+ // initialize|hide Chatbot UI
364
598
  $("#gemini_ui_container").show();
365
599
  $("#spinner").hide();
366
600
  $("#response").hide();
367
601
 
368
- // Initialize|Empty the prompt (textarea)
369
- document.getElementById('prompt').value = '';
602
+ // get|clear textarea element (prompt)
603
+ textarea = document.getElementById(geminiOptions.prompt_id);
604
+ textarea.value = '';
370
605
 
371
- if (!validApiKey) {
372
- logger.warn('\n' + 'Invalid API key detected: ' + apiKey);
373
- $("#send").hide();
374
- $("#reset").hide();
375
- }
606
+ var dependencies_met_select_ready = setInterval(() => {
607
+ var selectState = $('#container_prompt_history_select_wrapper').length;
608
+ var selectReady = (selectState > 0) ? true : false;
376
609
 
377
- const sendButton = document.getElementById('send');
378
- sendButton.addEventListener('click', (event) => {
379
- // Prevent default actions
380
- event.preventDefault();
381
-
382
- // Clear UI elements
383
- document.getElementById('md_result').innerHTML = '';
384
- $("#result").hide();
385
- $("#spinner").show();
386
-
387
- // Run main processing
388
- runner();
389
- }); //END sendButton (click)
390
-
391
- // Clear input form|spinner|responses
392
- const resetButton = document.getElementById('reset');
393
- resetButton.addEventListener('click', (event) => {
394
- // Prevent default actions
395
- event.preventDefault();
396
- document.getElementById("prompt").value = '';
397
- document.getElementById("response").value = '';
398
- $("#spinner").hide();
399
- $("#response").hide();
400
- }); //END resetButton (click)
610
+ if (selectReady) {
611
+ logger.debug('\n' + 'initializing select data');
401
612
 
402
- _this.setState('finished');
403
- logger.debug('\n' + 'state: ' + _this.getState());
404
- logger.info('\n' + 'module initialized successfully');
613
+ // initialize history array from cookie
614
+ if (promptHistoryEnabled && promptHistoryFromCookie) {
615
+ // get slimSelect object for the history (placed by slimSelect adapter)
616
+ // selectList = document.getElementById('prompt_history');
617
+ $slimSelect = j1.adapter.slimSelect.select[geminiOptions.prompt_history_id];
405
618
 
406
- clearInterval(dependencies_met_page_ready);
407
- }
408
- }, 10);
619
+ // limit the prompt history
620
+ promptHistoryMax = geminiOptions.prompt_history_max;
409
621
 
410
- }, // END init
622
+ // allow|reject history updates if promptHistoryMax reached
623
+ allowPromptHistoryUpdatesOnMax = geminiOptions.allow_prompt_history_updates_on_max;
411
624
 
412
- // -------------------------------------------------------------------------
413
- // messageHandler()
414
- // manage messages send from other J1 modules
415
- // -------------------------------------------------------------------------
416
- messageHandler: function (sender, message) {
417
- var json_message = JSON.stringify(message, undefined, 2);
625
+ logger.debug('\n' + 'read prompt history from cookie');
626
+ var data = [];
627
+ var option = {};
628
+ chat_prompt = j1.existsCookie(cookie_names.chat_prompt)
629
+ ? j1.readCookie(cookie_names.chat_prompt)
630
+ : {};
418
631
 
419
- logText = '\n' + 'received message from ' + sender + ': ' + json_message;
420
- logger.debug(logText);
632
+ // convert chat prompt object to array
633
+ textHistory = Object.values(chat_prompt);
421
634
 
422
- // -----------------------------------------------------------------------
423
- // Process commands|actions
424
- // -----------------------------------------------------------------------
425
- if (message.type === 'command' && message.action === 'module_initialized') {
426
- //
427
- // Place handling of command|action here
428
- //
429
- logger.info('\n' + message.text);
430
- }
635
+ // remove duplicates from history
636
+ if (textHistory.length > 1) {
637
+ var textHistoryLenght = textHistory.length;
638
+ var uniqueArray = [...new Set(textHistory)]; // create a 'Set' from the history array to automatically remove duplicates
431
639
 
432
- //
433
- // Place handling of other command|action here
434
- //
640
+ textHistory = uniqueArray;
641
+ if (textHistoryLenght > textHistory.length) {
642
+ logger.debug('\n' + 'removed duplicates from history array: ' + (textHistoryLenght - textHistory.length) + ' element|s');
643
+ }
644
+ } // END if !allowHistoryDupicates
645
+
646
+ // update|set slimSelect data elements
647
+ var index = 1;
648
+ var data = [];
649
+ var option = {};
650
+ var html;
651
+ textHistory.forEach((historyText) => {
652
+ html = '<span id="opt_' + geminiOptions.prompt_history_id + '_' + index + '" class="ss-option-delete">' + '<i class="mdib mdib-close mdib-16px ml-1 mr-2"></i></span>' + historyText;
653
+ option = {
654
+ text: historyText,
655
+ html: html,
656
+ display: true,
657
+ selected: false,
658
+ disabled: false
659
+ }
660
+ data.push(option);
661
+ index++
662
+ }); // END forEach
663
+ $slimSelect.setData(data);
664
+
665
+ // display history container
666
+ if (textHistory.length > 0) {
667
+ $("#prompt_history_container").show();
668
+ }
435
669
 
436
- return true;
437
- }, // END messageHandler
670
+ // -------------------------------------------------------------
671
+ // setup Slim select eventHandlers
672
+ // -------------------------------------------------------------
673
+ //
674
+ _this.setupSlimSelectEventHandlers();
438
675
 
439
- // -------------------------------------------------------------------------
440
- // setState()
441
- // Sets the current (processing) state of the module
442
- // -------------------------------------------------------------------------
443
- setState: function (stat) {
444
- _this.state = stat;
445
- }, // END setState
676
+ } else {
677
+ // disable|hide clear history button
678
+ $("#clear").hide();
679
+ } // if promptHistoryEnabled
446
680
 
447
- // -------------------------------------------------------------------------
448
- // getState()
449
- // Returns the current (processing) state of the module
450
- // -------------------------------------------------------------------------
451
- getState: function () {
452
- return _this.state;
453
- }, // END getState
681
+ clearInterval(dependencies_met_select_ready);
682
+ } // END if modules loaded
683
+ }, 10); // END dependencies_met_select_ready
684
+
685
+ // -------------------------------------------------------------------
686
+ // setup UI button eventHandlers
687
+ // -------------------------------------------------------------------
688
+ //
689
+ _this.setupUIButtonEventHandlers()
690
+
691
+ _this.setState('finished');
692
+ logger.debug('\n' + 'state: ' + _this.getState());
693
+ logger.info('\n' + 'initializing module: finished');
694
+
695
+ endTimeModule = Date.now();
696
+ logger.info('\n' + 'module initializing time: ' + (endTimeModule-startTimeModule) + 'ms');
697
+
698
+ clearInterval(dependencies_met_page_ready);
699
+ } // END slimSelectFinished && uiLoaded && modulesLoaded
700
+ }, 10); // END dependencies_met_page_ready
701
+ }, // END init
454
702
 
455
703
  // -------------------------------------------------------------------------
456
704
  // loadModules()
457
- // Module loader
705
+ // load required modules
458
706
  // -------------------------------------------------------------------------
459
- loadModules: function () {
707
+ loadModules: () => {
460
708
 
461
- if (geminiOptions.detectGeoLocation) {
709
+ if (geminiOptions.detect_geo_location) {
462
710
  leafletScript.async = true;
463
711
  leafletScript.type = "script";
464
712
  leafletScript.id = 'leaflet-api';
@@ -472,40 +720,52 @@ const httpError500 = geminiOptions.errors.http500;
472
720
  document.head.appendChild(geocoderScript);
473
721
  }
474
722
 
723
+ // https://github.com/google/generative-ai-js/blob/main/docs/reference/generative-ai.md
475
724
  import('//esm.run/@google/generative-ai')
476
725
  .then((module) => {
477
726
  // Module is imported successfully
478
- apiKey = geminiOptions.apiKey;
727
+ logger = log4javascript.getLogger('j1.adapter.gemini');
728
+ apiKey = geminiOptions.api_options.apiKey;
479
729
  validApiKey = (apiKey.includes('your-')) ? false : true;
480
730
  genAI = new module.GoogleGenerativeAI(apiKey);
481
731
  HarmCategory = module.HarmCategory;
482
732
  HarmBlockThreshold = module.HarmBlockThreshold;
733
+ gemini_model = geminiOptions.api_options.model;
734
+
735
+ generationConfig = {
736
+ candidateCount: geminiOptions.api_options.generationConfig.candidateCount,
737
+ maxOutputTokens: geminiOptions.api_options.generationConfig.maxOutputTokens,
738
+ temperature: geminiOptions.api_options.generationConfig.temperature,
739
+ topK: geminiOptions.api_options.generationConfig.topK,
740
+ topP: geminiOptions.api_options.generationConfig.topP
741
+ };
483
742
 
484
743
  safetySettings = [
485
744
  {
486
745
  category: HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT,
487
- threshold: geminiOptions.safetyRatings.HARM_CATEGORY_DANGEROUS_CONTENT
746
+ threshold: geminiOptions.api_options.safetyRatings.HARM_CATEGORY_DANGEROUS_CONTENT
488
747
  },
489
748
  {
490
749
  category: HarmCategory.HARM_CATEGORY_HARASSMENT,
491
- threshold: geminiOptions.safetyRatings.HARM_CATEGORY_HARASSMENT
750
+ threshold: geminiOptions.api_options.safetyRatings.HARM_CATEGORY_HARASSMENT
492
751
  },
493
752
  {
494
753
  category: HarmCategory.HARM_CATEGORY_HATE_SPEECH,
495
- threshold: geminiOptions.safetyRatings.HARM_CATEGORY_HATE_SPEECH
754
+ threshold: geminiOptions.api_options.safetyRatings.HARM_CATEGORY_HATE_SPEECH
496
755
  },
497
756
  {
498
757
  category: HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT,
499
- threshold: geminiOptions.safetyRatings.HARM_CATEGORY_SEXUALLY_EXPLICIT
758
+ threshold: geminiOptions.api_options.safetyRatings.HARM_CATEGORY_SEXUALLY_EXPLICIT
500
759
  }
501
760
  ];
502
761
 
503
- console.debug('gemini: Importing module: successful');
504
- moduleLoaded = true;
762
+ logger.debug('\n' + 'Importing Gemini module: successful');
763
+ modulesLoaded = true;
505
764
  })
506
765
  .catch((error) => {
766
+ logger = log4javascript.getLogger('j1.adapter.gemini');
507
767
  // An error occurred during module import
508
- console.warn('gemini: Importing module failed: ', error);
768
+ logger.warn('\n' + 'Importing Gemini module failed: ' + error);
509
769
  });
510
770
  }, // END loadModules
511
771
 
@@ -513,7 +773,7 @@ const httpError500 = geminiOptions.errors.http500;
513
773
  // loadUI()
514
774
  // UI loader
515
775
  // -------------------------------------------------------------------------
516
- loadUI: function () {
776
+ loadUI: () => {
517
777
  j1.loadHTML ({
518
778
  xhr_container_id: geminiOptions.xhr_container_id,
519
779
  xhr_data_path: geminiOptions.xhr_data_path,
@@ -523,16 +783,390 @@ const httpError500 = geminiOptions.errors.http500;
523
783
  'null'
524
784
  );
525
785
 
526
- var dependencies_met_data_loaded = setInterval(function() {
527
- if (j1.xhrDOMState['#gemini_ui'] == 'success') {
528
- console.debug('gemini: Loading UI: successful');
786
+ var dependencies_met_data_loaded = setInterval(() => {
787
+ if (j1.xhrDOMState['#gemini_ui'] === 'success') {
788
+ logger.debug('\n' + 'Loading UI: successful');
789
+
529
790
  clearInterval(dependencies_met_data_loaded);
530
791
  } // END if xhrDOMState
531
792
  }, 10);
532
793
 
533
- } // END loadUI
794
+ }, // END loadUI
795
+
796
+ // -------------------------------------------------------------------------
797
+ // setupSlimSelectEventHandlers()
798
+ // sel all used select events
799
+ // see: https://slimselectjs.com/
800
+ // -------------------------------------------------------------------------
801
+ setupSlimSelectEventHandlers: () => {
802
+ var select = document.getElementById(geminiOptions.prompt_history_id);
803
+ var $select = select.slim;
804
+ var slimValues;
805
+ var data;
806
+ var prompt;
807
+
808
+ $select.events.beforeOpen = (e) => {
809
+ // get all options
810
+ const slimValues = $select.getData();
811
+ eventListenersReady = false;
812
+
813
+ logger.debug('\n' + 'slimSelect.beforeOpen, processing: started');
814
+
815
+ // re-read current history from cookie for initial values
816
+ if (promptHistoryFromCookie) {
817
+ var chatHistory = j1.existsCookie(cookie_names.chat_prompt)
818
+ ? j1.readCookie(cookie_names.chat_prompt)
819
+ : {};
820
+
821
+ // set textHistory array
822
+ textHistory = Object.values(chatHistory);
823
+
824
+ // create|set current slimSelect data elements
825
+ var index = 1;
826
+ var data = [];
827
+ var option = {};
828
+ var html;
829
+ textHistory.forEach ((historyText) => {
830
+ html = '<span id="opt_' + geminiOptions.prompt_history_id + '_' + index + '" class="ss-option-delete">' + '<i class="mdib mdib-close mdib-16px ml-1 mr-2"></i></span>' + historyText;
831
+ option = {
832
+ text: historyText,
833
+ html: html,
834
+ display: true,
835
+ selected: false,
836
+ disabled: false
837
+ }
838
+ data.push(option);
839
+ index++;
840
+ }); // END forEach
841
+ $slimSelect.setData(data);
842
+
843
+ } // END re-read current history from cookie
844
+
845
+ // set prompt history EventListeners (for option deletion)
846
+ if (slimValues.length) {
847
+ logger.debug('\n' + 'slimSelect.beforeOpen, number of eventListeners to process: #' + slimValues.length);
848
+ addPromptHistoryEventListeners(slimValues);
849
+ }
850
+
851
+ // wait until prompt history eventListener|s is|are placed
852
+ var listenerIndex = 1;
853
+ slimValues.forEach( () => {
854
+ var span = 'opt_prompt_history_' + listenerIndex;
855
+ var spanElement = document.getElementById(span);
856
+ var dependencies_met_listeners_ready = setInterval (() => {
857
+ var spanElementReady = (($(spanElement).length) !== 0) ? true : false;
858
+ if (spanElementReady) {
859
+ if (listenerIndex === slimValues.length) {
860
+ eventListenersReady = true;
861
+ logger.debug('\n' + 'slimSelect.beforeOpen, all eventListeners ready');
862
+ } // END if listenerIndex
863
+ } // END if spanElementReady
864
+ if (!eventListenersReady) {
865
+ listenerIndex++;
866
+ } else {
867
+ clearInterval(dependencies_met_listeners_ready);
868
+ }
869
+ }, 10);
870
+ }); // END forEach data
871
+
872
+ var dependencies_beforeOpen_met_ready = setInterval (() => {
873
+ if (eventListenersReady) {
874
+ logger.debug('\n' + 'slimSelect.beforeOpen, processing: finished');
875
+
876
+ clearInterval(dependencies_beforeOpen_met_ready);
877
+ }
878
+ }, 10);
879
+ } // END event beforeOpen
880
+
881
+ $select.events.afterClose = (e) => {
882
+ // get selected value (NOTE: one||no selection possible)
883
+ const slimValue = $select.getSelected();
884
+
885
+ // set prompt on selection
886
+ if (slimValue.length) {
887
+ prompt = slimValue[0];
888
+ document.getElementById('prompt').value = prompt;
889
+ logger.debug('\n' + 'slimSelect.afterClose, selection from history: ' + prompt);
890
+ } else {
891
+ logger.debug('\n' + 'slimSelect.afterClose, selection from history: empty');
892
+ document.getElementById('prompt').value = '';
893
+ }
894
+
895
+ // remove selection from select
896
+ $slimSelect.setSelected('', false);
897
+ } // END event afterClose
898
+
899
+ }, // END setupSlimSelectEventHandlers()
900
+
901
+ // -------------------------------------------------------------------------
902
+ // setupUIButtonEventHandlers())
903
+ // add events for all history elements for deletion
904
+ // -------------------------------------------------------------------------
905
+ setupUIButtonEventHandlers: () => {
906
+
907
+ // send request to generate results
908
+ const sendButton = document.getElementById('{{gemini_options.buttons.generate.id}}');
909
+ sendButton.addEventListener('click', (event) => {
910
+ // suppress default actions|bubble up
911
+ event.preventDefault();
912
+ event.stopPropagation();
913
+
914
+ if (promptHistoryEnabled) {
915
+ var historySet = false;
916
+
917
+ // re-read current history from cookie for initial values
918
+ if (promptHistoryFromCookie) {
919
+ var chatHistory = j1.existsCookie(cookie_names.chat_prompt)
920
+ ? j1.readCookie(cookie_names.chat_prompt)
921
+ : {};
922
+
923
+ // set textHistory array
924
+ textHistory = Object.values(chatHistory);
925
+ } // END re-read current history from cookie
926
+
927
+ // set initial prompt from input (textarea)
928
+ if (textarea.value.length === 0) {
929
+ // use default prompt
930
+ prompt = defaultPrompt.replace(/\s+$/g, '');
931
+ logger.debug('\n' + 'sendButton, use default prompt: ' + prompt);
932
+ } else {
933
+ prompt = textarea.value.replace(/\s+$/g, '');
934
+ }
935
+
936
+ // check if current prompt alreay exists in history
937
+ index = textHistory.indexOf(prompt);
938
+ itemExists = (index !== -1) ? true : false;
939
+ if (itemExists) {
940
+ logText = '\n' + `sendButton, prompt: "${prompt}"\n` + `already exists in history at index: ${index}`;
941
+ logger.debug(logText);
942
+ }
943
+
944
+ // update history on promptHistoryMax
945
+ if (textHistory.length === promptHistoryMax && allowPromptHistoryUpdatesOnMax && !itemExists && !historySet) {
946
+ // place the CURRENT history element FIRST for replacement
947
+ textHistory.reverse();
948
+ if (textarea.value.length > 0) {
949
+ // cleanup textarea value for trailing whitespaces
950
+ newItem = textarea.value.replace(/\s+$/g, '');
951
+ } else if (textarea.value.length === 0) {
952
+ // use default prompt
953
+ newItem = defaultPrompt.replace(/\s+$/g, '');
954
+ logger.debug('\n' + 'sendButton, use default prompt:\n' + newItem);
955
+ }
956
+
957
+ logger.debug('\n' + 'sendButton, update item in history:\n' + textHistory[0]);
958
+ // replace FIRST history element by NEW item
959
+ textHistory[0] = newItem;
960
+ logger.debug('\n' + 'sendButton, add new item to history:\n' + textHistory[0]);
961
+
962
+ historySet = true;
963
+ } // END update history on promptHistoryMax
964
+
965
+ // add new item to history
966
+ if (textHistory.length < promptHistoryMax && !itemExists && !historySet) {
967
+ if (textarea.value.length > 0) {
968
+ // cleanup textarea value for trailing whitespaces
969
+ newItem = textarea.value.replace(/\s+$/g, '');
970
+ } else if (textarea.value.length === 0) {
971
+ // use default prompt
972
+ newItem = defaultPrompt.replace(/\s+$/g, '');
973
+ logger.debug('\n' + 'sendButton, use default prompt:\n' + newItem);
974
+ }
975
+ logger.debug('\n' + 'sendButton, add new item to history:\n' + newItem);
976
+ textHistory.push(newItem);
977
+
978
+ historySet = true;
979
+ } // END add new item to history
980
+
981
+ // failsafe, cleanup history
982
+ if (textHistory.length > 0) {
983
+ // cleanup|add selected value
984
+ var p = 0;
985
+ textHistory.forEach ((elm) => {
986
+ prompt = elm.replace(/\s+$/g, '');
987
+ textHistory[p] = prompt;
988
+ p++;
989
+ }); // END forEach
990
+ logger.debug('\n' + 'sendButton, cleaned history for trailing whitespaces');
991
+ } // END failsafe, cleanup history
992
+
993
+ // remove duplicates from history
994
+ if (textHistory.length > 1) {
995
+ var textHistoryLenght = textHistory.length;
996
+ var uniqueArray = [...new Set(textHistory)]; // create a 'Set' from the history array to automatically remove duplicates
997
+
998
+ textHistory = uniqueArray;
999
+ if (textHistoryLenght > textHistory.length) {
1000
+ logger.debug('\n' + 'sendButton, removed duplicates from history array: ' + (textHistoryLenght - textHistory.length) + ' element|s');
1001
+ }
1002
+ } // END remove duplicates from history
1003
+
1004
+ // create|set slimSelect data elements
1005
+ var index = 1;
1006
+ var data = [];
1007
+ var option = {};
1008
+ var html;
1009
+ textHistory.forEach ((historyText) => {
1010
+ html = '<span id="opt_' + geminiOptions.prompt_history_id + '_' + index + '" class="ss-option-delete">' + '<i class="mdib mdib-close mdib-16px ml-1 mr-2"></i></span>' + historyText;
1011
+ option = {
1012
+ text: historyText,
1013
+ html: html,
1014
+ display: true,
1015
+ selected: false,
1016
+ disabled: false
1017
+ }
1018
+ data.push(option);
1019
+ index++;
1020
+ }); // END forEach
1021
+ $slimSelect.setData(data);
1022
+ // END create|set slimSelect data elements
1023
+
1024
+ // display history container
1025
+ if (textHistory.length > 0) {
1026
+ $("#prompt_history_container").show();
1027
+ }
1028
+
1029
+ // write current history to cookie
1030
+ if (promptHistoryFromCookie) {
1031
+ logger.debug('\n' + 'sendButton, save prompt history to cookie');
1032
+ j1.removeCookie({
1033
+ name: cookie_names.chat_prompt,
1034
+ domain: auto_domain,
1035
+ secure: secure
1036
+ });
1037
+ cookie_written = j1.writeCookie({
1038
+ name: cookie_names.chat_prompt,
1039
+ data: textHistory,
1040
+ secure: secure
1041
+ });
1042
+ } // END write current history to cookie
1043
+ } // END if promptHistoryEnabled
1044
+
1045
+ // clear results
1046
+ document.getElementById('md_result').innerHTML = '';
1047
+ $("#result").hide();
1048
+ $("#spinner").show();
1049
+
1050
+ // call Gemini API for processing
1051
+ runner();
1052
+ }); // END click sendButton
1053
+
1054
+ // clear input prompt and the spinner|responses
1055
+ const resetButton = document.getElementById('{{gemini_options.buttons.reset.id}}');
1056
+ resetButton.addEventListener('click', (event) => {
1057
+ // suppress default actions|bubble up
1058
+ event.preventDefault();
1059
+ event.stopPropagation();
1060
+
1061
+ logger.debug('\n' + 'resetButton, clear input prompt|response');
1062
+ document.getElementById("prompt").value = '';
1063
+ document.getElementById("response").value = '';
1064
+ $("#spinner").hide();
1065
+ $("#response").hide();
1066
+ }); // END click resetButton
1067
+
1068
+ // Clear history|cookie
1069
+ const clearButton = document.getElementById('{{gemini_options.buttons.clear.id}}');
1070
+ clearButton.addEventListener('click', (event) => {
1071
+ // suppress default actions|bubble up
1072
+ event.preventDefault();
1073
+ event.stopPropagation();
1074
+
1075
+ logStartOnce = false;
1076
+ $('#clearHistory').modal('show');
1077
+
1078
+ const confirmClearHistory = document.getElementById('clearHistory');
1079
+ const accecptClearHistory = document.getElementById('accecptClearHistory');
1080
+ const dismissClearHistory = document.getElementById('dismissClearHistory');
1081
+
1082
+ accecptClearHistory.addEventListener('click', (event) => {
1083
+ logStartOnce = false;
1084
+
1085
+ // suppress default actions|bubble up
1086
+ event.preventDefault();
1087
+ event.stopPropagation();
1088
+
1089
+ // clear history
1090
+ if (!logStartOnce) {
1091
+ logger.warn('\n' + 'resetButton, perform clearHistory');
1092
+ logStartOnce = true;
1093
+ }
1094
+
1095
+ // write empty history to cookie
1096
+ textHistory = [];
1097
+ if (promptHistoryFromCookie) {
1098
+ j1.removeCookie({
1099
+ name: cookie_names.chat_prompt,
1100
+ domain: auto_domain,
1101
+ secure: secure
1102
+ });
1103
+ cookie_written = j1.writeCookie({
1104
+ name: cookie_names.chat_prompt,
1105
+ data: {},
1106
+ secure: secure
1107
+ });
1108
+ }
1109
+ $("#prompt_history_container").hide();
1110
+ }); // END click accecptClearHistory
1111
+
1112
+ // skip clear history
1113
+ dismissClearHistory.addEventListener('click', (event) => {
1114
+ // suppress default actions|bubble up
1115
+ event.preventDefault();
1116
+ event.stopPropagation();
1117
+
1118
+ logger.debug('\n' + 'resetButton, skipped clearHistory');
1119
+ }); // END click dismissClearHistoryButton
1120
+
1121
+ }); // END click clearButton
1122
+ }, // END setupUIButtonEventHandlers
1123
+
1124
+ // -------------------------------------------------------------------------
1125
+ // messageHandler()
1126
+ // manage messages send from other J1 modules
1127
+ // -------------------------------------------------------------------------
1128
+ messageHandler: (sender, message) => {
1129
+ var json_message = JSON.stringify(message, undefined, 2);
1130
+
1131
+ logText = '\n' + 'received message from ' + sender + ': ' + json_message;
1132
+ logger.debug(logText);
1133
+
1134
+ // -----------------------------------------------------------------------
1135
+ // process commands|actions
1136
+ // -----------------------------------------------------------------------
1137
+ if (message.type === 'command' && message.action === 'module_initialized') {
1138
+
1139
+ //
1140
+ // place handling of command|action here
1141
+ //
1142
+
1143
+ logger.info('\n' + message.text);
1144
+ }
1145
+
1146
+ //
1147
+ // place handling of other command|action here
1148
+ //
1149
+
1150
+ return true;
1151
+ }, // END messageHandler
1152
+
1153
+ // -------------------------------------------------------------------------
1154
+ // setState()
1155
+ // sets the current (processing) state of the module
1156
+ // -------------------------------------------------------------------------
1157
+ setState: (stat) => {
1158
+ _this.state = stat;
1159
+ }, // END setState
1160
+
1161
+ // -------------------------------------------------------------------------
1162
+ // getState()
1163
+ // Returns the current (processing) state of the module
1164
+ // -------------------------------------------------------------------------
1165
+ getState: () => {
1166
+ return _this.state;
1167
+ } // END getState
534
1168
 
535
- }; // END return
1169
+ }; // END main (return)
536
1170
  })(j1, window);
537
1171
 
538
1172
  {% endcapture %}