Files
crm.clientright.ru/libraries/jquery/instaFilta/instafilta.js
Fedor ac7467f0b4 Major CRM updates: AI Assistant, Court Status API, S3 integration improvements, and extensive file storage system
- Added comprehensive AI Assistant system (aiassist/ directory):
  * Vector search and embedding capabilities
  * Typebot proxy integration
  * Elastic search functionality
  * Message classification and chat history
  * MCP proxy for external integrations

- Implemented Court Status API (GetCourtStatus.php):
  * Real-time court document status checking
  * Integration with external court systems
  * Comprehensive error handling and logging

- Enhanced S3 integration:
  * Improved file backup system with metadata
  * Batch processing capabilities
  * Enhanced error logging and recovery
  * Copy operations with URL fixing

- Added Telegram contact creation API
- Improved error logging across all modules
- Enhanced callback system for AI responses
- Extensive backup file storage with timestamps
- Updated documentation and README files

- File storage improvements:
  * Thousands of backup files with proper metadata
  * Fix operations for broken file references
  * Project-specific backup and recovery systems
  * Comprehensive file integrity checking

Total: 26,461+ files added/modified including AWS SDK, vendor dependencies, and extensive backup system.
2025-10-16 11:17:21 +03:00

277 lines
9.4 KiB
JavaScript

/*!
* instaFilta
* Version: 1.4.4
* Description: jQuery plugin for performing in-page filtering
* Homepage and documentation: https://github.com/chromawoods/instaFilta
* Author: Andreas Larsson <andreas@chromawoods.com> (http://chromawoods.com)
* Contributions: Jaap-Jan Frans
*/
;(function($) {
$.fn.instaFilta = function(options) {
var _filterTerm = null,
_filterCategory = null;
/* Default settings. */
var settings = $.extend({
scope: null,
targets: '.instafilta-target',
sections: '.instafilta-section',
categoryDataAttr: 'instafilta-category',
matchCssClass: 'instafilta-match',
itemsHideEffect: 'hide',
itemsHideDuration: 0,
itemsShowEffect: 'show',
itemsShowDuration: 0,
sectionsHideEffect: 'hide',
sectionsHideDuration: 0,
sectionsShowEffect: 'show',
sectionsShowDuration: 0,
onFilterComplete: null,
markMatches: false,
hideEmptySections: true,
beginsWith: false,
caseSensitive: false,
typeDelay: 0,
useSynonyms: true,
synonyms: [
{ src: 'à,á,å,ä,â,ã', dst: 'a' },
{ src: 'À,Á,Å,Ä,Â,Ã', dst: 'A' },
{ src: 'è,é,ë,ê', dst: 'e' },
{ src: 'È,É,Ë,Ê', dst: 'E' },
{ src: 'ì,í,ï,î', dst: 'i' },
{ src: 'Ì,Í,Ï,Î', dst: 'I' },
{ src: 'ò,ó,ö,ô,õ', dst: 'o' },
{ src: 'Ò,Ó,Ö,Ô,Õ', dst: 'O' },
{ src: 'ù,ú,ü,û', dst: 'u' },
{ src: 'Ù,Ú,Ü,Û', dst: 'U' },
{ src: 'ç', dst: 'c' },
{ src: 'Ç', dst: 'C' },
{ src: 'æ', dst: 'ae' }
]
}, options);
/* Split synonym src into arrays. */
if (settings.useSynonyms) {
for (var i = 0, l = settings.synonyms.length; i < l; i++) {
settings.synonyms[i].src = settings.synonyms[i].src.split(',');
}
}
/* Setup each instaFilta instance. */
this.each(function() {
var typeTimer,
$targets,
$sections,
$scopeElement,
lastTerm = '';
/* Check if this instance should be bound to a scope. */
if (settings.scope) {
$scopeElement = $(this).closest(settings.scope);
$targets = $scopeElement.find(settings.targets);
$sections = $scopeElement.find(settings.sections);
}
else {
$targets = $(settings.targets);
$sections = $(settings.sections);
}
/* Prepare value(s) to match against. */
$targets.each(function() {
$target = $(this), original = $target.text();
$target.data('values', (function(s) {
var values = [original], normalized = original;
if (!settings.useSynonyms) { return values; }
for (var i = 0, l = s.length; i < l; i++) {
for (var j = 0; j < s[i].src.length; j++) {
normalized = normalized.replace(s[i].src[j], s[i].dst);
}
}
!!(normalized === original) || values.push(normalized);
return values;
}(settings.synonyms)));
});
/* Will hide any sections that don't have data-instafilta-hidden="false" */
var toggleSections = function() {
$sections.each(function() {
var $section = $(this);
if ($section.find('[data-instafilta-hide="false"]').length) {
$section[settings.sectionsShowEffect](settings.sectionsShowDuration);
}
else {
$section[settings.sectionsHideEffect](settings.sectionsHideDuration);
}
});
};
/* Apply the results of the filtering process GUI-wise. */
var toggleResults = function(forceShowAll) {
var $matchedItems = (function() {
return forceShowAll ? $targets.attr('data-instafilta-hide', 'false') : $targets;
}()).filter('[data-instafilta-hide="false"]')[settings.itemsShowEffect](settings.itemsShowDuration);
forceShowAll || $targets.filter('[data-instafilta-hide="true"]')[settings.itemsHideEffect](settings.itemsHideDuration);
settings.hideEmptySections && toggleSections();
/* Check if a callback function has been provided. */
if (typeof settings.onFilterComplete === 'function') {
settings.onFilterComplete.apply(this, [$matchedItems]);
}
return $matchedItems;
};
/* Reset the filter completely. */
var showAll = function() {
return toggleResults(true);
};
/* Main filtering function. */
_filterTerm = function(term) {
term = settings.caseSensitive ? term : term.toLowerCase();
if (lastTerm === term) { return false; }
else { lastTerm = term; }
term || showAll();
/* Iterate through associated targets and find matches. */
$targets.each(function() {
var $item = $(this);
if (!$item.data('originalText')) {
$item.data('originalHtml', $item.html());
$item.data('originalText', $item.data('values')[0]);
}
/* Returns the index at which a match was found. Returns -1 if not found. */
var matchedIndex = (function(values, t) {
var index = -1;
for (var i = 0; i < values.length; i++) {
index = (settings.caseSensitive ? values[i] : values[i].toLowerCase()).indexOf(t);
if (index >= 0) { break; } // We have a match, no need to iterate further.
}
return index;
}($item.data('values'), term));
var originalText = $item.data('originalText'),
targetText = settings.caseSensitive ? originalText : originalText.toLowerCase(),
matchedText = null,
newText = null;
/* If we should mark the match, wrap it in a span tag. */
if (matchedIndex >= 0 && settings.markMatches) {
matchedText = originalText.substring(matchedIndex, matchedIndex + term.length);
newText = originalText.replace(matchedText, '<span class="' + settings.matchCssClass + '">' + matchedText + '</span>');
$item.html($item.data('originalHtml').replace(originalText, newText));
}
$item.attr('data-instafilta-hide', (settings.beginsWith && matchedIndex !== 0) || matchedIndex < 0 ? 'true' : 'false');
});
return toggleResults();
};
/* Filter items depending on category data attribute. Categories can be a comma separated
* string or an array of strings. Shows all targets if categories is falsy. */
_filterCategory = function(categories, requireAll) {
if (!categories || !categories.length) {
return showAll();
}
if (typeof categories === 'string') {
categories = categories.split(',');
}
$targets.each(function() {
var hideStatus = true,
matched = 0,
$item = $(this),
targetCats = $item.data(settings.categoryDataAttr);
if (targetCats) {
targetCats = targetCats.split(',');
for (var i = 0; i < targetCats.length; i++) {
for (var j = 0; j < categories.length; j++) {
if (targetCats[i] === categories[j]) {
if (requireAll) { matched++; }
else { hideStatus = false; break; }
}
}
}
if (requireAll && matched === categories.length) { hideStatus = false; }
$item.html($item.data('originalText')).attr('data-instafilta-hide', hideStatus);
}
});
return toggleResults();
};
/* Setup event handlers. */
$(this).on('keyup', function() {
var $field = $(this);
clearTimeout(typeTimer);
typeTimer = setTimeout(function() {
_filterTerm($field.val());
}, settings.typeDelay);
});
});
return {
filterTerm: _filterTerm,
filterCategory: _filterCategory
};
};
}(jQuery));