From 21e3c4051689318d887da6bd0fd5ff9eaf077ae2 Mon Sep 17 00:00:00 2001 From: mrpaulblack Date: Mon, 21 Feb 2022 22:18:48 +0100 Subject: [PATCH 1/2] [simple theme] replace Image_layout.js with flexbox CS impl. * drop image_layout.js from simple theme * move image_layout.js to oscar theme and delete common js dir (since its empty now) * align top position of image detail modal with bottom position of search header * use flexbox to display images; row height can be set via @results-image-row-height in defenitions.less * display span title underneath each image with a max width of 12rem * increase margin and padding around image article on desktop and tablet * make article height smaller on phone layout (height of 6rem) to display more content on current view * remove content from result, if the title and content matches * use a group that cotains the flex image article, if images are mixed with other categories * fix pylint issues in webapp.py * use the default.html result template in unit tests (thanks @return42) --- searx/results.py | 10 ++- searx/static/themes/oscar/gruntfile.js | 2 +- .../src}/js/image_layout.js | 6 +- searx/static/themes/simple/gruntfile.js | 1 - .../themes/simple/src/js/main/results.js | 5 -- .../themes/simple/src/less/definitions.less | 12 ++-- .../static/themes/simple/src/less/detail.less | 1 + .../themes/simple/src/less/style-rtl.less | 5 ++ .../static/themes/simple/src/less/style.less | 69 ++++++++++++------- searx/templates/simple/results.html | 10 ++- searx/webapp.py | 15 ++++ tests/unit/test_webapp.py | 6 +- 12 files changed, 91 insertions(+), 51 deletions(-) rename searx/static/themes/{__common__ => oscar/src}/js/image_layout.js (99%) diff --git a/searx/results.py b/searx/results.py index 1ac6a5ab5..ab242b838 100644 --- a/searx/results.py +++ b/searx/results.py @@ -278,12 +278,18 @@ class ResultContainer: result['parsed_url'] = result['parsed_url']._replace(scheme="http") result['url'] = result['parsed_url'].geturl() + # avoid duplicate content between the content and title fields + if result.get('content') == result.get('title'): + del result['content'] + + # make sure there is a template + if 'template' not in result: + result['template'] = 'default.html' + # strip multiple spaces and cariage returns from content if result.get('content'): result['content'] = WHITESPACE_REGEX.sub(' ', result['content']) - return True - def __merge_url_result(self, result, position): result['engines'] = set([result['engine']]) with self._lock: diff --git a/searx/static/themes/oscar/gruntfile.js b/searx/static/themes/oscar/gruntfile.js index 2f87e289f..988d42c3d 100644 --- a/searx/static/themes/oscar/gruntfile.js +++ b/searx/static/themes/oscar/gruntfile.js @@ -60,7 +60,7 @@ module.exports = function(grunt) { separator: ';' }, dist: { - src: ['src/js/*.js', '../__common__/js/image_layout.js'], + src: ['src/js/*.js'], dest: 'js/searxng.js' } }, diff --git a/searx/static/themes/__common__/js/image_layout.js b/searx/static/themes/oscar/src/js/image_layout.js similarity index 99% rename from searx/static/themes/__common__/js/image_layout.js rename to searx/static/themes/oscar/src/js/image_layout.js index 329fa46a8..c65351f7b 100644 --- a/searx/static/themes/__common__/js/image_layout.js +++ b/searx/static/themes/oscar/src/js/image_layout.js @@ -128,7 +128,7 @@ obj.trottleCallToAlign = null; }, 20); } - } + }; ImageLayout.prototype.align = function () { var i; @@ -183,7 +183,7 @@ img.classList.add('aligned'); } } - } + }; ImageLayout.prototype.watch = function () { var objthrottleAlign = this.throttleAlign.bind(this); @@ -216,7 +216,7 @@ subtree: true, attributes: false, characterData: false, - }) + }); }; w.searxng.ImageLayout = ImageLayout; diff --git a/searx/static/themes/simple/gruntfile.js b/searx/static/themes/simple/gruntfile.js index 52c460494..25883e384 100644 --- a/searx/static/themes/simple/gruntfile.js +++ b/searx/static/themes/simple/gruntfile.js @@ -108,7 +108,6 @@ module.exports = function (grunt) { 'js/searxng.head.min.js': ['src/js/head/*.js'], 'js/searxng.min.js': [ 'src/js/main/*.js', - '../__common__/js/*.js', './node_modules/autocomplete-js/dist/autocomplete.js' ] } diff --git a/searx/static/themes/simple/src/js/main/results.js b/searx/static/themes/simple/src/js/main/results.js index 609bd8ecd..4eae58435 100644 --- a/searx/static/themes/simple/src/js/main/results.js +++ b/searx/static/themes/simple/src/js/main/results.js @@ -7,9 +7,6 @@ } searxng.ready(function () { - searxng.image_thumbnail_layout = new searxng.ImageLayout('#urls', '#urls .result-images', 'img.image_thumbnail', 14, 6, 200); - searxng.image_thumbnail_layout.watch(); - d.querySelectorAll('#urls img.image').forEach( img => img.addEventListener( @@ -74,13 +71,11 @@ } } d.getElementById('results').classList.add('image-detail-open'); - searxng.image_thumbnail_layout.align(); searxng.scrollPageToSelected(); } searxng.closeDetail = function (e) { d.getElementById('results').classList.remove('image-detail-open'); - searxng.image_thumbnail_layout.align(); searxng.scrollPageToSelected(); } searxng.on('.result-detail-close', 'click', e => { diff --git a/searx/static/themes/simple/src/less/definitions.less b/searx/static/themes/simple/src/less/definitions.less index abda5e37c..7de0d7ef9 100644 --- a/searx/static/themes/simple/src/less/definitions.less +++ b/searx/static/themes/simple/src/less/definitions.less @@ -68,8 +68,8 @@ --color-result-search-url-border: #ddd; --color-result-search-url-font: #000; // Images Colors - --color-result-image-span-background-hover: rgba(0, 0, 0, 0.6); - --color-result-image-span-font: #fff; + --color-result-image-span-font: #444; + --color-result-image-span-font-selected: #fff; --color-result-image-background: #fff; /// Settings Colors --color-settings-tr-hover: #f7f7f7; @@ -179,8 +179,8 @@ --color-result-detail-loader-border: rgba(255, 255, 255, 0.2); --color-result-detail-loader-borderleft: rgba(0, 0, 0, 0); // Images Colors - --color-result-image-span-background-hover: rgba(0, 0, 0, 0.6); - --color-result-image-span-font: #fff; + --color-result-image-span-font: #bbb; + --color-result-image-span-font-selected: #222; --color-result-image-background: #222; /// Settings Colors --color-settings-tr-hover: #2d2d2d; @@ -230,9 +230,11 @@ @results-gap: 5rem; @results-margin: 0.125rem; @result-padding: 1rem; +@results-image-row-height: 12rem; +@results-image-row-height-phone: 6rem; @search-width: 40rem; // heigh of #search, see detail.less -@search-height: 7.75rem; +@search-height: 7.6rem; /// Device Size /// @desktop > @tablet diff --git a/searx/static/themes/simple/src/less/detail.less b/searx/static/themes/simple/src/less/detail.less index 5e3cfaca6..b63e65206 100644 --- a/searx/static/themes/simple/src/less/detail.less +++ b/searx/static/themes/simple/src/less/detail.less @@ -39,6 +39,7 @@ article.result-images .detail { border: none; object-fit: contain; width: inherit; + height: inherit; max-width: 100%; min-height: inherit; max-height: calc(100vh - 25rem - 7rem); diff --git a/searx/static/themes/simple/src/less/style-rtl.less b/searx/static/themes/simple/src/less/style-rtl.less index 6d3e9f525..bbaa48748 100644 --- a/searx/static/themes/simple/src/less/style-rtl.less +++ b/searx/static/themes/simple/src/less/style-rtl.less @@ -83,6 +83,11 @@ } } +// Image flexbox +#main_results div#results.only_template_images #urls { + direction: rtl; +} + // Image detail #results.image-detail-open article.result-images[data-vim-selected] .detail .result-images-labels p { direction: rtl; diff --git a/searx/static/themes/simple/src/less/style.less b/searx/static/themes/simple/src/less/style.less index 29cf554b0..7640b253c 100644 --- a/searx/static/themes/simple/src/less/style.less +++ b/searx/static/themes/simple/src/less/style.less @@ -143,6 +143,10 @@ article.result-images[data-vim-selected] { .image_thumbnail { filter: opacity(60%); } + + span.title { + color: var(--color-result-image-span-font-selected); + } } article[data-vim-selected].category-videos, @@ -284,6 +288,16 @@ article[data-vim-selected].category-social { } } +.template_group_images { + display: flex; + flex-wrap: wrap; +} + +.template_group_images::after { + flex-grow: 10; + content: ""; +} + .category-videos, .category-news, .category-map, @@ -357,40 +371,38 @@ article[data-vim-selected].category-social { } .result-images { - display: inline-block; - margin: 0; - padding: 0; - position: relative; - max-height: 200px; + flex-grow: 1; + padding: 0.5rem 0.5rem 2rem 0.5rem; + margin: 0.25rem; border: none !important; + height: @results-image-row-height; + + & > a { + position: relative; + } img { - float: inherit; - margin: 0.125rem; + margin: 0; padding: 0; border: none; - max-height: 200px; + height: 100%; + width: 100%; + object-fit: cover; + vertical-align: bottom; background: var(--color-result-image-background); } span.title { - display: none; - color: var(--color-result-image-span-font); - } - - &:hover span.title { display: block; position: absolute; - bottom: 0; - .ltr-right(0); - padding: 4px; - margin-top: 0; - .ltr-margin-right(0); - margin-bottom: 4px; - .ltr-margin-left(4px); - // color: @color-result-image-span-font; - background-color: var(--color-result-image-span-background-hover); - font-size: 0.7em; + + width: 100%; + font-size: 0.9rem; + color: var(--color-result-image-span-font); + padding: 0.5rem 0 0 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; } } @@ -785,8 +797,14 @@ article[data-vim-selected].category-social { } #urls { - width: inherit; margin: 0; + display: flex; + flex-wrap: wrap; + } + + #urls::after { + flex-grow: 10; + content: ""; } #backToTop { @@ -837,8 +855,7 @@ article[data-vim-selected].category-social { .result-images { margin: 0; - padding: 0; - border: none; + height: @results-image-row-height-phone; } } diff --git a/searx/templates/simple/results.html b/searx/templates/simple/results.html index 4149f83c3..ee47db662 100644 --- a/searx/templates/simple/results.html +++ b/searx/templates/simple/results.html @@ -15,7 +15,7 @@ {% if results and results|map(attribute='template')|unique|list|count == 1 %} {% set only_template = 'only_template_' + results[0]['template']|default('default')|replace('.html', '') %} {% else %} - {% set unique_template = '' %} + {% set only_template = '' %} {% endif %}
@@ -131,12 +131,10 @@
{% for result in results %} + {% if result.open_group and not only_template %}
{% endif %} {% set index = loop.index %} - {% if result['template'] %} - {% include get_result_template('simple', result['template']) %} - {% else %} - {% include 'simple/result_templates/default.html' %} - {% endif %} + {% include get_result_template('simple', result['template']) %} + {% if result.close_group and not only_template %}
{% endif %} {% endfor %} {% if not results and not answers %} {% include 'simple/messages/no_results.html' %} diff --git a/searx/webapp.py b/searx/webapp.py index 1314fc276..df717a7b1 100755 --- a/searx/webapp.py +++ b/searx/webapp.py @@ -726,6 +726,9 @@ def search(): # Server-Timing header request.timings = result_container.get_timings() # pylint: disable=assigning-non-slot + current_template = None + previous_result = None + # output for result in results: if output_format == 'html': @@ -762,6 +765,18 @@ def search(): else: result['publishedDate'] = format_date(result['publishedDate']) + # set result['open_group'] = True when the template changes from the previous result + # set result['close_group'] = True when the template changes on the next result + if current_template != result.get('template'): + result['open_group'] = True + if previous_result: + previous_result['close_group'] = True # pylint: disable=unsupported-assignment-operation + current_template = result.get('template') + previous_result = result + + if previous_result: + previous_result['close_group'] = True + if output_format == 'json': x = { 'query': search_query.query, diff --git a/tests/unit/test_webapp.py b/tests/unit/test_webapp.py index a50bd5c78..aed6f2dd4 100644 --- a/tests/unit/test_webapp.py +++ b/tests/unit/test_webapp.py @@ -33,7 +33,8 @@ class ViewsTestCase(SearxTestCase): 'engine': 'startpage', 'parsed_url': ParseResult( scheme='http', netloc='first.test.xyz', path='/', params='', query='', fragment='' - ), # noqa + ), + 'template': 'default.html', }, { 'content': 'second test content', @@ -43,7 +44,8 @@ class ViewsTestCase(SearxTestCase): 'engine': 'youtube', 'parsed_url': ParseResult( scheme='http', netloc='second.test.xyz', path='/', params='', query='', fragment='' - ), # noqa + ), + 'template': 'default.html', }, ] From e2a5dddf8e546821759f22f9f9097f33a80ba132 Mon Sep 17 00:00:00 2001 From: mrpaulblack Date: Sat, 26 Feb 2022 22:32:28 +0100 Subject: [PATCH 2/2] [build] /static --- .../oscar/css/logicodev-dark.min.css.map | Bin 11830 -> 11830 bytes searx/static/themes/oscar/js/searxng.js | 448 +++++++++--------- searx/static/themes/oscar/js/searxng.min.js | Bin 11017 -> 11021 bytes .../static/themes/oscar/js/searxng.min.js.map | Bin 10840 -> 10802 bytes .../themes/simple/css/searxng-rtl.min.css | Bin 59504 -> 59775 bytes .../themes/simple/css/searxng-rtl.min.css.map | Bin 98002 -> 98505 bytes .../static/themes/simple/css/searxng.min.css | Bin 58476 -> 58679 bytes .../themes/simple/css/searxng.min.css.map | Bin 96395 -> 96782 bytes searx/static/themes/simple/js/searxng.min.js | Bin 29011 -> 24878 bytes .../themes/simple/js/searxng.min.js.map | Bin 97156 -> 83951 bytes 10 files changed, 224 insertions(+), 224 deletions(-) diff --git a/searx/static/themes/oscar/css/logicodev-dark.min.css.map b/searx/static/themes/oscar/css/logicodev-dark.min.css.map index e9928c467685b813cbaf6cfbbf9c84246d8a7cb7..6cb083bcfd6a35dfbc0abd6659073df92a4f9616 100644 GIT binary patch delta 45 zcmV+|0Mh@qT((@0d6Rzv7O{x;0g-tRlWYPBqn-jG0Yj6YBW?j?vkoMH0|8~Tk0+-F DoqP~r delta 50 zcmV-20L}llT((@0d6R|$50OI?k;Wvk#=rrQc@~lZ38S6@Apv5OpCfJoW3vtExample usage of searxng.ImageLayout class. +* searxng.image_thumbnail_layout = new searxng.ImageLayout( +* '#urls', // container_selector +* '#urls .result-images', // results_selector +* 'img.image_thumbnail', // img_selector +* 14, // verticalMargin +* 6, // horizontalMargin +* 200 // maxHeight +* ); +* searxng.image_thumbnail_layout.watch(); +*/ + + +(function (w, d) { + function ImageLayout (container_selector, results_selector, img_selector, verticalMargin, horizontalMargin, maxHeight) { + this.container_selector = container_selector; + this.results_selector = results_selector; + this.img_selector = img_selector; + this.verticalMargin = verticalMargin; + this.horizontalMargin = horizontalMargin; + this.maxHeight = maxHeight; + this.trottleCallToAlign = null; + this.alignAfterThrotteling = false; + } + + /** + * Get the height that make all images fit the container + * + * width = w1 + w2 + w3 + ... = r1*h + r2*h + r3*h + ... + * + * @param {[type]} images the images to be calculated + * @param {[type]} width the container witdth + * @param {[type]} margin the margin between each image + * + * @return {[type]} the height + */ + ImageLayout.prototype._getHeigth = function (images, width) { + var i, img; + var r = 0; + + for (i = 0; i < images.length; i++) { + img = images[i]; + if ((img.naturalWidth > 0) && (img.naturalHeight > 0)) { + r += img.naturalWidth / img.naturalHeight; + } else { + // assume that not loaded images are square + r += 1; + } + } + + return (width - images.length * this.verticalMargin) / r; // have to round down because Firefox will automatically roundup value with number of decimals > 3 + }; + + ImageLayout.prototype._setSize = function (images, height) { + var i, img, imgWidth; + var imagesLength = images.length, resultNode; + + for (i = 0; i < imagesLength; i++) { + img = images[i]; + if ((img.naturalWidth > 0) && (img.naturalHeight > 0)) { + imgWidth = height * img.naturalWidth / img.naturalHeight; + } else { + // not loaded image : make it square as _getHeigth said it + imgWidth = height; + } + img.setAttribute('width', Math.round(imgWidth)); + img.setAttribute('height', Math.round(height)); + img.style.marginLeft = Math.round(this.horizontalMargin) + 'px'; + img.style.marginTop = Math.round(this.horizontalMargin) + 'px'; + img.style.marginRight = Math.round(this.verticalMargin - 7) + 'px'; // -4 is the negative margin of the inline element + img.style.marginBottom = Math.round(this.verticalMargin - 7) + 'px'; + resultNode = img.parentNode.parentNode; + if (!resultNode.classList.contains('js')) { + resultNode.classList.add('js'); + } + } + }; + + ImageLayout.prototype._alignImgs = function (imgGroup) { + var isSearching, slice, i, h; + var containerElement = d.querySelector(this.container_selector); + var containerCompStyles = window.getComputedStyle(containerElement); + var containerPaddingLeft = parseInt(containerCompStyles.getPropertyValue('padding-left'), 10); + var containerPaddingRight = parseInt(containerCompStyles.getPropertyValue('padding-right'), 10); + var containerWidth = containerElement.clientWidth - containerPaddingLeft - containerPaddingRight; + + while (imgGroup.length > 0) { + isSearching = true; + for (i = 1; i <= imgGroup.length && isSearching; i++) { + slice = imgGroup.slice(0, i); + h = this._getHeigth(slice, containerWidth); + if (h < this.maxHeight) { + this._setSize(slice, h); + // continue with the remaining images + imgGroup = imgGroup.slice(i); + isSearching = false; + } + } + if (isSearching) { + this._setSize(slice, Math.min(this.maxHeight, h)); + break; + } + } + }; + + ImageLayout.prototype.throttleAlign = function () { + var obj = this; + if (obj.trottleCallToAlign) { + obj.alignAfterThrotteling = true; + } else { + obj.alignAfterThrotteling = false; + obj.align(); + obj.trottleCallToAlign = setTimeout(function () { + if (obj.alignAfterThrotteling) { + obj.align(); + } + obj.alignAfterThrotteling = false; + obj.trottleCallToAlign = null; + }, 20); + } + }; + + ImageLayout.prototype.align = function () { + var i; + var results_selectorNode = d.querySelectorAll(this.results_selector); + var results_length = results_selectorNode.length; + var previous = null; + var current = null; + var imgGroup = []; + + for (i = 0; i < results_length; i++) { + current = results_selectorNode[i]; + if (current.previousElementSibling !== previous && imgGroup.length > 0) { + // the current image is not connected to previous one + // so the current image is the start of a new group of images. + // so call _alignImgs to align the current group + this._alignImgs(imgGroup); + // and start a new empty group of images + imgGroup = []; + } + // add the current image to the group (only the img tag) + imgGroup.push(current.querySelector(this.img_selector)); + // update the previous variable + previous = current; + } + // align the remaining images + if (imgGroup.length > 0) { + this._alignImgs(imgGroup); + } + }; + + ImageLayout.prototype._monitorImages = function () { + var i, img; + var objthrottleAlign = this.throttleAlign.bind(this); + var results_nodes = d.querySelectorAll(this.results_selector); + var results_length = results_nodes.length; + + function img_load_error (event) { + // console.log("ERROR can't load: " + event.originalTarget.src); + event.originalTarget.src = w.searxng.static_path + w.searxng.theme.img_load_error; + } + + for (i = 0; i < results_length; i++) { + img = results_nodes[i].querySelector(this.img_selector); + if (img !== null && img !== undefined && !img.classList.contains('aligned')) { + img.addEventListener('load', objthrottleAlign); + // https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onerror + img.addEventListener('error', objthrottleAlign); + img.addEventListener('timeout', objthrottleAlign); + if (w.searxng.theme.img_load_error) { + img.addEventListener('error', img_load_error, {once: true}); + } + img.classList.add('aligned'); + } + } + }; + + ImageLayout.prototype.watch = function () { + var objthrottleAlign = this.throttleAlign.bind(this); + + // https://developer.mozilla.org/en-US/docs/Web/API/Window/pageshow_event + w.addEventListener('pageshow', objthrottleAlign); + // https://developer.mozilla.org/en-US/docs/Web/API/FileReader/load_event + w.addEventListener('load', objthrottleAlign); + // https://developer.mozilla.org/en-US/docs/Web/API/Window/resize_event + w.addEventListener('resize', objthrottleAlign); + + this._monitorImages(); + + var obj = this; + + let observer = new MutationObserver(entries => { + let newElement = false; + for (let i = 0; i < entries.length; i++) { + if (entries[i].addedNodes.length > 0 && entries[i].addedNodes[0].classList.contains('result')) { + newElement = true; + break; + } + } + if (newElement) { + obj._monitorImages(); + } + }); + observer.observe(d.querySelector(this.container_selector), { + childList: true, + subtree: true, + attributes: false, + characterData: false, + }); + }; + + w.searxng.ImageLayout = ImageLayout; + +}(window, document)); ;/** * @license * (C) Copyright Contributors to the SearXNG project. @@ -368,227 +592,3 @@ $(document).ready(function(){ }); }); -;/** -* -* Google Image Layout v0.0.1 -* Description, by Anh Trinh. -* Heavily modified for searx -* https://ptgamr.github.io/2014-09-12-google-image-layout/ -* https://ptgamr.github.io/google-image-layout/src/google-image-layout.js -* -* @license Free to use under the MIT License. -* -* @example Example usage of searxng.ImageLayout class. -* searxng.image_thumbnail_layout = new searxng.ImageLayout( -* '#urls', // container_selector -* '#urls .result-images', // results_selector -* 'img.image_thumbnail', // img_selector -* 14, // verticalMargin -* 6, // horizontalMargin -* 200 // maxHeight -* ); -* searxng.image_thumbnail_layout.watch(); -*/ - - -(function (w, d) { - function ImageLayout (container_selector, results_selector, img_selector, verticalMargin, horizontalMargin, maxHeight) { - this.container_selector = container_selector; - this.results_selector = results_selector; - this.img_selector = img_selector; - this.verticalMargin = verticalMargin; - this.horizontalMargin = horizontalMargin; - this.maxHeight = maxHeight; - this.trottleCallToAlign = null; - this.alignAfterThrotteling = false; - } - - /** - * Get the height that make all images fit the container - * - * width = w1 + w2 + w3 + ... = r1*h + r2*h + r3*h + ... - * - * @param {[type]} images the images to be calculated - * @param {[type]} width the container witdth - * @param {[type]} margin the margin between each image - * - * @return {[type]} the height - */ - ImageLayout.prototype._getHeigth = function (images, width) { - var i, img; - var r = 0; - - for (i = 0; i < images.length; i++) { - img = images[i]; - if ((img.naturalWidth > 0) && (img.naturalHeight > 0)) { - r += img.naturalWidth / img.naturalHeight; - } else { - // assume that not loaded images are square - r += 1; - } - } - - return (width - images.length * this.verticalMargin) / r; // have to round down because Firefox will automatically roundup value with number of decimals > 3 - }; - - ImageLayout.prototype._setSize = function (images, height) { - var i, img, imgWidth; - var imagesLength = images.length, resultNode; - - for (i = 0; i < imagesLength; i++) { - img = images[i]; - if ((img.naturalWidth > 0) && (img.naturalHeight > 0)) { - imgWidth = height * img.naturalWidth / img.naturalHeight; - } else { - // not loaded image : make it square as _getHeigth said it - imgWidth = height; - } - img.setAttribute('width', Math.round(imgWidth)); - img.setAttribute('height', Math.round(height)); - img.style.marginLeft = Math.round(this.horizontalMargin) + 'px'; - img.style.marginTop = Math.round(this.horizontalMargin) + 'px'; - img.style.marginRight = Math.round(this.verticalMargin - 7) + 'px'; // -4 is the negative margin of the inline element - img.style.marginBottom = Math.round(this.verticalMargin - 7) + 'px'; - resultNode = img.parentNode.parentNode; - if (!resultNode.classList.contains('js')) { - resultNode.classList.add('js'); - } - } - }; - - ImageLayout.prototype._alignImgs = function (imgGroup) { - var isSearching, slice, i, h; - var containerElement = d.querySelector(this.container_selector); - var containerCompStyles = window.getComputedStyle(containerElement); - var containerPaddingLeft = parseInt(containerCompStyles.getPropertyValue('padding-left'), 10); - var containerPaddingRight = parseInt(containerCompStyles.getPropertyValue('padding-right'), 10); - var containerWidth = containerElement.clientWidth - containerPaddingLeft - containerPaddingRight; - - while (imgGroup.length > 0) { - isSearching = true; - for (i = 1; i <= imgGroup.length && isSearching; i++) { - slice = imgGroup.slice(0, i); - h = this._getHeigth(slice, containerWidth); - if (h < this.maxHeight) { - this._setSize(slice, h); - // continue with the remaining images - imgGroup = imgGroup.slice(i); - isSearching = false; - } - } - if (isSearching) { - this._setSize(slice, Math.min(this.maxHeight, h)); - break; - } - } - }; - - ImageLayout.prototype.throttleAlign = function () { - var obj = this; - if (obj.trottleCallToAlign) { - obj.alignAfterThrotteling = true; - } else { - obj.alignAfterThrotteling = false; - obj.align(); - obj.trottleCallToAlign = setTimeout(function () { - if (obj.alignAfterThrotteling) { - obj.align(); - } - obj.alignAfterThrotteling = false; - obj.trottleCallToAlign = null; - }, 20); - } - } - - ImageLayout.prototype.align = function () { - var i; - var results_selectorNode = d.querySelectorAll(this.results_selector); - var results_length = results_selectorNode.length; - var previous = null; - var current = null; - var imgGroup = []; - - for (i = 0; i < results_length; i++) { - current = results_selectorNode[i]; - if (current.previousElementSibling !== previous && imgGroup.length > 0) { - // the current image is not connected to previous one - // so the current image is the start of a new group of images. - // so call _alignImgs to align the current group - this._alignImgs(imgGroup); - // and start a new empty group of images - imgGroup = []; - } - // add the current image to the group (only the img tag) - imgGroup.push(current.querySelector(this.img_selector)); - // update the previous variable - previous = current; - } - // align the remaining images - if (imgGroup.length > 0) { - this._alignImgs(imgGroup); - } - }; - - ImageLayout.prototype._monitorImages = function () { - var i, img; - var objthrottleAlign = this.throttleAlign.bind(this); - var results_nodes = d.querySelectorAll(this.results_selector); - var results_length = results_nodes.length; - - function img_load_error (event) { - // console.log("ERROR can't load: " + event.originalTarget.src); - event.originalTarget.src = w.searxng.static_path + w.searxng.theme.img_load_error; - } - - for (i = 0; i < results_length; i++) { - img = results_nodes[i].querySelector(this.img_selector); - if (img !== null && img !== undefined && !img.classList.contains('aligned')) { - img.addEventListener('load', objthrottleAlign); - // https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onerror - img.addEventListener('error', objthrottleAlign); - img.addEventListener('timeout', objthrottleAlign); - if (w.searxng.theme.img_load_error) { - img.addEventListener('error', img_load_error, {once: true}); - } - img.classList.add('aligned'); - } - } - } - - ImageLayout.prototype.watch = function () { - var objthrottleAlign = this.throttleAlign.bind(this); - - // https://developer.mozilla.org/en-US/docs/Web/API/Window/pageshow_event - w.addEventListener('pageshow', objthrottleAlign); - // https://developer.mozilla.org/en-US/docs/Web/API/FileReader/load_event - w.addEventListener('load', objthrottleAlign); - // https://developer.mozilla.org/en-US/docs/Web/API/Window/resize_event - w.addEventListener('resize', objthrottleAlign); - - this._monitorImages(); - - var obj = this; - - let observer = new MutationObserver(entries => { - let newElement = false; - for (let i = 0; i < entries.length; i++) { - if (entries[i].addedNodes.length > 0 && entries[i].addedNodes[0].classList.contains('result')) { - newElement = true; - break; - } - } - if (newElement) { - obj._monitorImages(); - } - }); - observer.observe(d.querySelector(this.container_selector), { - childList: true, - subtree: true, - attributes: false, - characterData: false, - }) - }; - - w.searxng.ImageLayout = ImageLayout; - -}(window, document)); diff --git a/searx/static/themes/oscar/js/searxng.min.js b/searx/static/themes/oscar/js/searxng.min.js index e0573b8886ce7d2de94dbf519a14f8d5a1777245..ab130cdad30b19f47dcd98f16e6ab4fc248b0325 100644 GIT binary patch delta 403 zcmYk2PfG$p6u=p?h=d?26Y{V-*|KBXW(T9xu~XP#Eke*kco^)}F6k=cC`5LS4qlpW zeTAT4gP>y{Am{@G(dP(iG?FgA_wV=M@vh4K^201z>@u!_1ytCz4(H&DQjL2p(d(HY zO|*nSI*2HC5mkIdtBRi}jUb4HB9l8n6Q)?fT3+*xIcoqWmY`rWA-IX#yoO1(+w_jK zluoHI41IkNd%gdL1%W$N84C*W_wa#FQ#q4SaoDU9+h?M~S-s*N3D+=EIri7t1@FWa z+mIY}hR)ik{1q}_G1<}eai0*C-RcHn@SBp!g<7kd+bf1tc(*L$qt^P zj&Qwpa6=p<3!%PzjXA;f^w9a9yPFw0oH}-cwM-xu$fx;dwcm-pDef&tWp&{)p$3j! kYx;sW>vo-;0dJejmLEy-1A0${Hvj+t delta 322 zcmWm8PfG$p9L8}*HwpU#xh7aty4p5t<5EzO)>tn<2@>qkrD2(9NoQsJb*Q!%(4o^D zI(6zA5zHmL^dfo*b&#Mgy@967=lDF|yUuOr#YVG0!4EE^D3bJs1d7b)d&3_b&p*cr&c zA)rP2D5<{OcU@ZuQx=gFtH;vQBx(9R*2moQNTg26L(5EI#mafLvHXgN`d)rmi9B-c z9JE`77VC@f+^I)5-cHjGA^|e$`dxO(~2~5ZR*2HGrG2m1%=~Cjb=&-UQyGT zr6eap{bq_|%$y08w_POEzFjk3+1o~K*Ns1R0|{Nt{#P>7az7_i1kS>Nr?c}-q&_R& EA5L{;bN~PV diff --git a/searx/static/themes/oscar/js/searxng.min.js.map b/searx/static/themes/oscar/js/searxng.min.js.map index 6156eea02f118070e1d59c0622256422e26d8d0c..8fe21b87a2dd2e63b5018427d3713615734ac34c 100644 GIT binary patch delta 4788 zcma)AOK&4t71q%7D>Ks#>Pcs!>2y!0HKUp7LXP8v#EKBQ_g1A`EcLWrqZ-5dyJ+k&xKW8nHx32qEzY*svIc;5+A*(@FP;A&YX|bMHC# zJiha&{Av5Q+dus7EBzl$?)~PY+!g(=Yo9)D1Yx}~ShNAlKOs zm|m?1{Y=oV>$w|$eEoPB^iGRGE2s@RJ^l9^znkd?gYEDr=nMz?%h&JdU)}uZYA_1g z1D%;!TBz>tJG97z{Xx(UdJx!Y*GO(F80hcJJiLz0UKsTC&t`V@KdyXovtR3VTCMF) zSO58o@9G;@xAe2C&#oL*yZZN6zox%*?E}Bo0ZXSvGODLRuaB2}G5dD5+HHqTEO6&` z2fy{8lkRugct)Bl`#B9hATgeoY@5q6rM zqL`+q<6Ctp)Yc{~N+~8O>sShLEUmIo1L+X0;OcL`x+r)*?^#tLs#YI-ZKa4`gpO4d zqG4y~@bth54)l~`<-wmb8~SgrE?nO>?;l@%Eqh~SjblaPjE7VgG zUkq8xs;hsp@ZO}SEMEw}uB;>0RzRwX%Z4F`$_hco7LmvD(2$#obPt%=#YHUQNLc|) zFh>WnZK$0WBylfZeM$2Z?9$OZU*q)T3j5I`noF)&5MG`ZwJiv6lm#wUPZ>lBK%8I=B&b6`92S*LkR1x72f81Vz#TTC z=r8GCJbZ6^#ByE6l^U54AIXHt-jx(WB5GrYRYZDpkcMM*%3}I5mLlNg>mKJvC{wUg zC6%WiE$&WO(@++nBl!mR4yB79r)ATkB^gJ>!<2>SRxBl)xP+>B|6fUF|&u1 zgim*)R19r)YDecEJ(xfk%!^9~GxS3~wTL7eZ;|a@ExkwZV#zT3=VRx1ybWP;Icn&T@_9EJS22v=w0v*dXfgB~E z&wOQgS?#hzOZ2*9pj1Y{oSmNW99hjpOLzv-b%_vAno6jK%@X&uV>yEVmkA{+$~r~m zSjL?QJmP>uEosCNCX2$0+fnIlI{N4DEKGns>Mg8f;ZR;oD0GlOIA@U|WxCSk`p}X_ zTLW{odoGdVLXh#g)EIDkp-W2*(^1FjhNA>5c?EE_F2>d)k8=TSQ7w(lS_Dy znel%>z>TTLY`fEUrnaLHRM_^|)P(1I=YC1NyhlR?@lD{g2y++}Fc>-1ypbjsN}01W zbeYJAEl003bAoUT=Z7>03FosKDhe*Ojx&2*|NH%~+-z|Y0w_B1!J`>7(Ym6rqs6URee}llulLDl zWxU9?ppgOIJ$aVq6kJM^DN7QzP)08EFq2Q1)k<1_{Km%pn8|Q1W~Z|5Q_~wL8vK-q zrS)sG59UJ}STMCfwG_`@St_r&QCi!x?|xyJ(yiIICac`?cT5}3<3=*_guJ8n#;lw} zbtyRZp$m<;#tjj;`aY#rp0+UOe%2NbGJe%)0v)?*bn(~~+4uF$yYabkhP_5%Ty2~2ls|l$@`#h7 zYQ|3*wlJeMHc_C|s?%XyR84K?dKOFRpanawN0SH;^kTt7^^Hzn)9X4LM42 z!)oegD3iW^c>B(6YNbgzWNk_@rrkox7|9buYGmk`A)PX*e8{BR2*+5WM?i+lMU*hlV8c|`T33IsB|$?mPbmb z0Aa#A0LJ{MD37?l!W5n?oRa?L{PHcIpe(#S#$!o;GQT=Gb2!8CP-#>`{3s5Nm*obq zOS?3N;xo0#U_z{%jG6Gznqj~JX`vLSH9m5veMPDe>Y)k&Bbo)csuUe4=_HtALf=LI z2MgWWC2l8GBkeu@NaGfh-!mp+`X@o;t4y9W-s3OP+Ag&5$`yv%9!Y4Z9sH2v9ekiT z7+i@DgBTSr%*upGI_Mv&HJ;F21JwM`C&T=aGX;KWBzxWlnQ61P9Ofk_?k`htg@>

&r5vQ_Z6wKVCDyWhYFdDnad-v) zIv{y$0ERHGOhiCA087$Ff#K`9z#xRIKiQdugM>QqC$x|30Vho-6e>(2$A3P71m5?(`0}aW}38}$e1rjWnxnhZsX2BjtNGy=}*})1V7Dy~$h4_(>W(U$N_|Ca@eySNn7S4O; zp8xZmbME`e?jLu*_wDyTczvoN0BJ!tm2dVc2dX4+5Q zNfug-N)>0tW}^$0c&bg<3(ueLHbE!_&3LETz*FO2bo6g#?&yy%eWG8v{MMC9y_Bmw*EcW!PXGJzNBU=1eyV#@k3ZLJ6a)Q> zsk{0gQ(67@nVlzLr7TAXe~W${&niiwo-!%B%_LEzyB2Lfg zgjEotV09qZfG)_3ievdglSVSHD&%0l_wa#)0O9{25NJSEUs#MF-_ZA+!+EhBR@aES}l;sMw zw0d3(U2nZi{M$l! zuI*YGWGrh{k-zu~vn1Owy?k%+jT}5xQ0WOLo+Vpe-_eKn-W>JF1Cg_trp`T6?4n3w z1N+$~|GA=2meJTIIX84I<1AMRnRTLaF!l<9`C*K5lOQO(I4emIHY`WVN+NShDrvZ& zN*yH0heC~$nqYKPWtEdvNEx;!($kcVl@%%q01~@m%T1C{t{75hR&!r zUrFo#EN(umN$v%QGzc$+-^8;L11!&!9mlY7J=6bR$32ikQ@Y%um>_-ox2p(;a zqr$}Z=@%_Sc&JG7Df^60^MvlM%;>3y^COp!tCGRR+RALzfdnC;&u>13Cw$7R6G42W z^8b`UZJid0J6j2sYf8eQzegl*M7|v4Xmk|!Vcx4r6Dha|?j}(?WIgXQss@q-%V=9v z*|_5L40D){L}4h;7!!x8#qPQWlxZLr2?p692ZJWtmurNa+0ptICx8prk#M{uyYkRu zcdH(w(CWe8J`t%LH0(r2;*9W)+`ibNr@oAlbE0gxCNpIP%&WjRMbE+2Z3BEFL}J!8 z$ZXihjF1l6P5<)IjnOK zZ<;MRZCN)hNivE?&#mnE=^`HZt7?+(Q+|J&h6Rm$ z2jkHbwm9CV;ELqWZkxU13E>Kk89Ao%8nG;RDR{7a%(m53bfo}(hmr_>JBLdCnRcdSVqNobzz>kIIJ}JDX?njDp+p#cO?7C5#Wgn^fJrw9dw_On}wX(YjMJIRLk-61ZNar zhdHreX)34Lu+6FKY zQaBPWnO0lS0e19yg45VDy^hICNzG7=BC5*M7Fpo&;(SKx2dAk|lgeT_g~U4zzR&v= z7A;AvCSA1Amu(q+{6k4cOnYf9?Dr*q#O zSe*!IO^zKoJH$lu`4GT)`EW$KbLKQEBNrk+4U(Lx$ub|FGfH|fv=9ddff7Q|3c!d% zuzkC2xW~?q=YByX1{df4D2o*jDe5xxCS-+I=Oq3QDC8oD1i|ja&2`Ob*po!ih210~ zG>PWykS-7AFfutDot@GZ%ABrEP*_TkUMEqe$eg`p^SNQ}SvmGqjSb_|8MC2=HBJ%W z+J&kXkQ&@~h>}2*bYO=2IgpGzQ_D#gKDk<6;S`~>h@FW1 zzjVfYeRUo-RAsu&uElV(pZIoQCG~gi%)HAJ$y?v1S?%s{i~Amf|BzegQ#UV7PAELF Wd-@M|9#2Om{h?>>-g|Z7oBst~><)wg diff --git a/searx/static/themes/simple/css/searxng-rtl.min.css b/searx/static/themes/simple/css/searxng-rtl.min.css index 64c1ac234ee66cf0db11449d80c1b973cba01ff1..267545e7ccecff78ba12b8075a00e660ae791c97 100644 GIT binary patch delta 767 zcmaJ;&ubGw6edk=t?>smRJLABVlB3H*Uf?fXQ3d{iyjJ|yw%C>%VuPEXPKQeNn={Y zi+Ixqp1kPQi)Hm{Z+dC*$4PIIQoLIH19aAeP({ixk2mwa_a5K({rH&u^*Q_MsfI63 zPvZRS3H+cow4Mn_Wd|MnIA$<4k6^6Wm!pa_D$~a`pwaVSH`bq zDoLw3Ju+4Y=GA5Luzhz4Z?#It;)sTZWYP!heLACd=1$dkD2Hq2y12YGlN7h)(G3Yf zj+d>GfNf4bsU^S~r%BJn8tq@95 zDs>Gow*>d~xtjUcO(?ZX9T`BkH;=^oVg;Kv3vMYna*r6&?$TVWnle%7qJp zggk^I3nDHg4W-@JgOt;@t|1_9_)_mPTcn+c$4oLF5&?=hTZL}^Z%ly&UI+KT=JDBX zZgDuxG|$^j=E}Narcz$Lqij`dByspE2wPpr9O~=TXI@CETuL5b=DLRKZ^u*P@yND; zkG3`Kz?8l(Yz>HUMd0%&Bsb8rqU6N=*JqP=yV(pr=v^93hv34VNEY^% GvcCcE0U^Zz delta 536 zcmex=iTT3?<_*&%l#>#Zv(t<6OY>56GxEz)i>!*$lM*!ybQGXS&rEajduF| zWX7{P(n&`Ep&-W~*ne%m7o-!=nHI diff --git a/searx/static/themes/simple/css/searxng-rtl.min.css.map b/searx/static/themes/simple/css/searxng-rtl.min.css.map index b4ce34408752bf7ee8742c3aea7028e3893e14db..b8828a7d8600907ec9fa1c2bcf700c91ff39759a 100644 GIT binary patch delta 2272 zcmah}T})F~9M8c4$|#CO5EkH0Ge5?uw1|8a(R<772eq`f9}KjBE!>uNZEruNKt%Vl zWm`fPPnMI#Y$WQNi*suXF)=e{51S7&i`gEwY!5yyS(a$BWInmWhLEzQyxAbcucF;=nic3A+`#Xu&BeC_dO0NRxt7Efnk`oMK>W%4UTjwiGiq z5z1;cPO5X|ss+Yuyu|_?wBWQ3ZuW^fN^=dYfk`VN=*_3Gs|wfDuqkxaXU2T-jrudJ@1q< z9)||tEj)Cq{cNM~ZNVG&RL&*|N>$B!c=K!@`pkQDz%d330&fwa#6+TP0_w`92ylRG zr3JM@q~ukUjdxqoZ(gge=;O=OdVR>~d!ozwMa?{^;73D#LrZbOs$I^Pd5e;90>*E!F4?Lp8cK zU8^TZHE8q<%ZnQs0&VBmJz5Wu}J9#sK`5h+mnl&4^mvH<$%ElhPc z@3g?2;7w0zj>uAOQdHfF3Osrk2p>pIj%mY51+tf6JlKp5Z*g;P04+^)?CB0^ot;uF ztT`Zh`$;uKM{-GBrJEDARl0aYdkhZWVg!9ZiF8Mzf~V|Q7fMdO-;j!t_s0e%@rq~2f@$n=``ujPP(LAT5y$vNDi?cPH%Tc7*{7F%(DccHt_b- zx;9xdi&m$sxb5R+>Nmu2t+h8wwz4qs$PEutY^%j@PteiB) z>fe#HM5{fc-YorPUOOe@lAu^%l4K<%KqK)nLcFK8IFa%6n=rdf=2GJ=EiDUEFiMaU z>R*)0YkF#TU>Uu8+NVz#1@Z#R4v~gXx)5waJAC?|PkdqVgTwb0ptzY?Z$F_))$`5gS z!(nv(@-7P4S_YudwI=OU4Z3|rhd#Z!we;{tqGmKJ=L(5@&Jat6qOu{YEE*Q%SagB( zG4*8Sq&b*6{xXOmy`ZGzA+8VkZv{YK>FTXv^R`GrE{2t2Fon0TfL46H2%4++7P5&P zYJ1#SdhmEn2Nv*Z2()Y{)u7vs@eF9j2Nj^lvvq*6!beS@1;Z1d4Idi^bsOKh!1=me zc{!O*g!1xiG^-TSvuxZP^8DG37VqioXM?F=>d*@@LqnlRUe0nW!4${Q=?tX9BB5s_ z+&FHIXeLwHf_s8{%p1ohL07fyX&6JLL-X^oRCI_l9y&r)DgRJ~v^9ezL)mC7MNvHz zhVM>;P7}wK6@96ato3HPuccF<#Q>gPPO_O*F>Dv@x2R_+X7OnwU18xhyosHiOg$_|cZhoiJ= zn}RVc&?yH^6LhYE@^ogH<#}4PfOs^t$!mMu}xdJ!tuiYtDRb*r+AuwGMeuV|i=4+5}+z8M<_8Iy)I=qSiBr%e)E zkwv#FN}oL9oR7l{Dl0oXLz`jUn_8yeys5=p@_bY5g@PL9& zC+^l46M{PxxSBv`5B0S8$D?jmwjx@9!Etos&_0h{mx{oM4_y>$1`}2t39C$J(w1e{ zpJD}PlU#Dr8P{W55S$=$LU;t3{= zl<5ndgBfnbof^~@IMH=0{T6O#5a2)tRUf(R^=CP&!7LdF3}%se*v>k9J* zdS|B1+piPI&C#u+Z)dK=N(SMwqa?@}oK)#oW&CkP&vT<2Rpv>AL!c~JxT|6%k8V7D zZF{yrYOu-T&?peW5asv#%-5b-18t6yjg=8ta`~A9%5n)MlTABTN<>-UfTCMpx1}da z=zNl6^i@J?mqsqnDmUfsjs2gHl+u0P;3_$sKyY6Z+NOpZ(q(RG<0>0vG_7`TUoPL* z161Rh+S1TBp@wbYYNWwiA2 z5EWpUr4oMYC}Saw{ysDDgGk~ zoeRU|6TmMr9H{0-! dErk2$0`RWOr@+x_97%!>TxGIUB!!Ar-a! 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 diff --git a/searx/static/themes/simple/js/searxng.min.js b/searx/static/themes/simple/js/searxng.min.js index 7a74e677fbb8cf624e06c155a595aeffbdba4d4e..ebf718f301b3b80efd7423b5d283dfd9bda1b87e 100644 GIT binary patch delta 3329 zcmai1TWl298P?bsFuq{p3&s~bUhHMYJ3GE$Zr&ZoT+DT`jg0}bUEp|qygo2HXPKD= zyK9#!RUVq6rpXcQLm~wwQXh~4L@PyoN>Gui_KlXdQlbipw5cK`QmQ_rNgtAaGwU^k zR_e>YXa4h_^Iy;R|NH1;>CUgEpZ!r{@BXPqk{t1OX{SPrYs{ME*K~&xd%;RAE#;OY zMCX<9*L6xLp&5a{yy6oT-1 zr!30KCpHru0myJ>xdv6#h)vzBZOJ5Wm2+tmGiG@*>$w>5ymt&HzSuC0(?=^_tmFzW z1cicKQ`I8=S>Z+ZVRgG0sO-gxR{jpOrm9WEs+!k0D$;wYsuQeNe2R4?((8xK_BQ`k z)eVC;R)-;CRKEuLu=)}Vj%@tJajqz;F_hK$j6?0KRAKs+EVUOWsY#PAw-r;>h>8TN zk^dvJyezJlx8(QKyd*){`?Y@ty}4-&%0Ah2Ov;Gfx?w3RuGF0beNZ>yuj|DR>s!U4 z`XIj2^=C?xN?7zYw2Hsh$E2j_ZQ!`$R>LvS&l-+MrWk1SqJ5=tk2EiCHx7e-)_7EM z#m>$9rBr@lv#Rww^Q@vUG&9)V%A}VK!z9<#$^O;%0>FNi&*UtvZ+rQr)3M>~^vryx&<_CrXAyOOfP3TGD zh62$Zj}u|y+P3Z2lQP3&TsdvBq3Goq91M|oGNE6li=MQ{kylu=)bUslTv5}LHH&(B zTwf)iA-l8$eDam|xSmA?lX{BYQ=M5BwU3-SQ5`eb(`cr|eYr!#I)7A=RuK6D5g&EF zjd1>;O9lkL*`-S2%V3-MBv>nci{HBK=lj!zn7KwwH;EgwQc4=mYUy}?LiIysJ-gF~ z9r5;d9e4g=`yi52rJSyF42xcqWBMs((imB!w!+14^*erTnsqPk2z>KDY4i+*~l~iQ6TG3*#Yn-T|^oMCqC{D>~VC!_3WZjEFV<1 zNnM%yfF3DwWx!+(XMpqtpm#(xv=`=H4fRxTwQ$CR#CIcg;z8&nOlilXn*K0+`C>ztNcOjgH~afnzW&v}6<^I_e8-pI93Dvc{ATgN zz-@Ts+F7bGBXA|4IZvZX#EU!Ql9PYDGb^2d(a*P6So~iZP;*3a00G7v!Sqmw4T>50 zTt&02;^c4bepFJ5^FlgSFaC0Dy?AXfj7;1gtOtD(t`naQ)>J$C99o?N$G!9UwUNpa zalgAFpN*xZAc_Xo0H^2>#W8~;UhTE<)n8WPCz$v_M z(?sQdINGwuXZ0oGG*N81rs6IwdE*Y(xV~~)OKJtx%d42HjSbh3A|O!!lBtmV(pZy( z3cEReu#7D&Vf1-CE+gjOj%PqKC$F{<#UG`f0bAQ3dYalPst{2+u?KR|i4N4#`H6iJ zK5k7KppPfpHZlG9$n?~>ssV2>(OH8&8`?srY>52+bhG%?DKr;U{8y)TlyF1To~aYV zQ5_@9M32Spk1sYIQIb*R(6$oFXHRdp)EY2YED75ff=o64PJ+Frg@uZ zi)ScusvjVxIYW|{0nA7o#cbwXO~m)loPl#sO6%HD$5g*?1T*Og>dy07#k(4uDI0xJ zBVx_jk#)qMaF`fB+pyaKw9e9nu{kC1LO?~8hWpfY4mFM zqnV%LgC#TNWgPvNi^rzi&b{7kt#-DULE}83$H)vdBlyQ4`Z8T>H1P6=(oH3vQM{pr fYySSAJI@?s8MBq?%~uMVfBqG|;OSa_<@kR9QgCOM delta 7302 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