MediaWiki:Common.js: различия между версиями
Страница интерфейса MediaWiki
Дополнительные действия
Add_particles_and_interactions |
Admin (обсуждение | вклад) Нет описания правки |
||
| (не показано 16 промежуточных версий 3 участников) | |||
| Строка 23: | Строка 23: | ||
function initParticles() { | function initParticles() { | ||
var hero = document.querySelector('.bc-hero'); | |||
if (!hero) { | |||
return; | |||
} | |||
var oldHost = document.getElementById('bc-particles'); | |||
if (oldHost) { | |||
oldHost.remove(); | |||
} | |||
var host = document.createElement('div'); | |||
host.id = 'bc-particles'; | |||
hero.insertBefore(host, hero.firstChild); | |||
loadScript( | |||
'https://cdn.jsdelivr.net/npm/particles.js@2.0.0/particles.min.js', | |||
function () { | |||
if (!window.particlesJS) { | if (!window.particlesJS) { | ||
return; | return; | ||
} | } | ||
window.particlesJS('bc-particles', { | window.particlesJS('bc-particles', { | ||
particles: { | particles: { | ||
number: { value: | number: { | ||
color: { value: ['#1d5f9f', '#e40046', '# | value: 110, | ||
shape: { type: 'circle' }, | density: { | ||
opacity: { value: 0. | enable: true, | ||
size: { value: | value_area: 850 | ||
} | |||
}, | |||
color: { | |||
value: [ | |||
'#1d5f9f', | |||
'#e40046', | |||
'#33c4ff', | |||
'#102033' | |||
] | |||
}, | |||
shape: { | |||
type: 'circle' | |||
}, | |||
opacity: { | |||
value: 0.38, | |||
random: true | |||
}, | |||
size: { | |||
value: 4.4, | |||
random: true | |||
}, | |||
line_linked: { | line_linked: { | ||
enable: true, | enable: true, | ||
distance: | distance: 180, | ||
color: '#1d5f9f', | color: '#1d5f9f', | ||
opacity: 0. | opacity: 0.38, | ||
width: 1 | width: 1.5 | ||
}, | }, | ||
move: { | move: { | ||
enable: true, | enable: true, | ||
speed: 1. | speed: 1.0, | ||
direction: 'none', | direction: 'none', | ||
random: true, | random: true, | ||
| Строка 60: | Строка 95: | ||
} | } | ||
}, | }, | ||
interactivity: { | interactivity: { | ||
detect_on: 'canvas', | detect_on: 'canvas', | ||
events: { | events: { | ||
onhover: { enable: true, mode: 'grab' }, | onhover: { | ||
onclick: { enable: true, mode: 'push' }, | enable: true, | ||
mode: 'grab' | |||
}, | |||
onclick: { | |||
enable: true, | |||
mode: 'push' | |||
}, | |||
resize: true | resize: true | ||
}, | }, | ||
modes: { | modes: { | ||
grab: { distance: | grab: { | ||
push: { particles_nb: | distance: 190, | ||
line_linked: { | |||
opacity: 0.4 | |||
} | |||
}, | |||
push: { | |||
particles_nb: 4 | |||
} | |||
} | } | ||
}, | }, | ||
retina_detect: true | retina_detect: true | ||
}); | }); | ||
}); | } | ||
); | |||
} | |||
function makeSearchInteractive() { | function makeSearchInteractive() { | ||
| Строка 87: | Строка 143: | ||
input.type = 'search'; | input.type = 'search'; | ||
input.autocomplete = 'off'; | input.autocomplete = 'off'; | ||
input.placeholder = slot.textContent.trim(); | input.placeholder = window.innerWidth < 560 ? 'страна, сервис или мера...' : slot.textContent.trim(); | ||
input.setAttribute('aria-label', 'Поиск по BRICSCompass'); | input.setAttribute('aria-label', 'Поиск по BRICSCompass'); | ||
input.placeholder = window.innerWidth < 560 ? '\u0441\u0442\u0440\u0430\u043d\u0430 \u0438\u043b\u0438 \u0441\u0435\u0440\u0432\u0438\u0441' : '\u043d\u0430\u0439\u0442\u0438 \u0441\u0442\u0440\u0430\u043d\u0443, \u0441\u0435\u0440\u0432\u0438\u0441 \u0438\u043b\u0438 \u043c\u0435\u0440\u0443'; | |||
input.setAttribute('aria-label', '\u041f\u043e\u0438\u0441\u043a \u043f\u043e BRICSCompass'); | |||
input.placeholder = window.innerWidth < 560 ? '\u0421\u0442\u0440\u0430\u043d\u0430 \u0438\u043b\u0438 \u0441\u0435\u0440\u0432\u0438\u0441' : '\u0421\u0442\u0440\u0430\u043d\u0430, \u0441\u0435\u0440\u0432\u0438\u0441 \u0438\u043b\u0438 \u043c\u0435\u0440\u0430'; | |||
slot.replaceChildren(input); | slot.replaceChildren(input); | ||
slot.classList.add('is-live'); | slot.classList.add('is-live'); | ||
| Строка 94: | Строка 153: | ||
var cards = Array.prototype.slice.call(document.querySelectorAll('.bc-card, .bc-country')); | var cards = Array.prototype.slice.call(document.querySelectorAll('.bc-card, .bc-country')); | ||
var tags = Array.prototype.slice.call(document.querySelectorAll('[data-bc-query]')); | var tags = Array.prototype.slice.call(document.querySelectorAll('[data-bc-query]')); | ||
var arrow = document.querySelector('.bc-arrow'); | |||
function filter(value) { | function filter(value) { | ||
| Строка 119: | Строка 179: | ||
}); | }); | ||
}); | }); | ||
function getCardLink(card) { | |||
var link = card.closest('a'); | |||
if (link && link.href) { | |||
return link.href; | |||
} | |||
return ''; | |||
} | |||
function submitSearch() { | |||
var query = input.value.trim().toLowerCase(); | |||
var target = null; | |||
if (!query) { | |||
input.focus(); | |||
return; | |||
} | |||
cards.some(function (card) { | |||
var titleNode = card.querySelector('strong'); | |||
var title = (titleNode || card).textContent.trim().toLowerCase(); | |||
var text = card.textContent.trim().toLowerCase(); | |||
if (title === query) { | |||
target = card; | |||
return true; | |||
} | |||
if (!target && text.indexOf(query) !== -1) { | |||
target = card; | |||
} | |||
return false; | |||
}); | |||
var href = target && getCardLink(target); | |||
if (href) { | |||
window.location.href = href; | |||
return; | |||
} | |||
window.location.href = (mw.config.get('wgScriptPath') || '') + '/index.php?search=' + encodeURIComponent(input.value.trim()); | |||
} | |||
input.addEventListener('keydown', function (event) { | |||
if (event.key === 'Enter') { | |||
event.preventDefault(); | |||
submitSearch(); | |||
} | |||
}); | |||
if (arrow) { | |||
arrow.setAttribute('role', 'button'); | |||
arrow.setAttribute('tabindex', '0'); | |||
arrow.setAttribute('aria-label', 'Найти раздел'); | |||
arrow.addEventListener('click', submitSearch); | |||
arrow.addEventListener('keydown', function (event) { | |||
if (event.key === 'Enter' || event.key === ' ') { | |||
event.preventDefault(); | |||
submitSearch(); | |||
} | |||
}); | |||
} | |||
} | } | ||
| Строка 157: | Строка 273: | ||
observer.observe(stat); | observer.observe(stat); | ||
}); | }); | ||
} | |||
function prioritizeMedia() { | |||
Array.prototype.forEach.call(document.querySelectorAll('.bc-photo img, .bc-section-photo img'), function (img) { | |||
img.loading = 'eager'; | |||
img.decoding = 'async'; | |||
img.setAttribute('fetchpriority', 'high'); | |||
}); | |||
} | |||
function removeNoopServiceWorker() { | |||
if (!('serviceWorker' in navigator) || !navigator.serviceWorker.getRegistrations) { | |||
return; | |||
} | |||
navigator.serviceWorker.getRegistrations().then(function (registrations) { | |||
registrations.forEach(function (registration) { | |||
var url = registration.active && registration.active.scriptURL; | |||
if (url && url.indexOf('skins.citizen.serviceWorker') !== -1) { | |||
registration.unregister(); | |||
} | |||
}); | |||
}).catch(function () {}); | |||
} | |||
function enhanceCards() { | |||
var cards = Array.prototype.slice.call(document.querySelectorAll('.bc-card, .bc-country, .bc-stat')); | |||
cards.forEach(function (card) { | |||
card.setAttribute('tabindex', '0'); | |||
card.addEventListener('mousemove', function (event) { | |||
var rect = card.getBoundingClientRect(); | |||
card.style.setProperty('--mx', Math.round(event.clientX - rect.left) + 'px'); | |||
card.style.setProperty('--my', Math.round(event.clientY - rect.top) + 'px'); | |||
}); | |||
card.addEventListener('keydown', function (event) { | |||
var link = card.closest('a'); | |||
if (link && (event.key === 'Enter' || event.key === ' ')) { | |||
event.preventDefault(); | |||
link.click(); | |||
} | |||
}); | |||
}); | |||
} | |||
function addCardFilter() { | |||
var grid = document.querySelector('.bc-card-grid'); | |||
if (!grid || document.querySelector('.bc-hero') || document.querySelector('.bc-local-filter')) { | |||
return; | |||
} | |||
var cards = Array.prototype.slice.call(grid.querySelectorAll('.bc-card')); | |||
if (cards.length < 3) { | |||
return; | |||
} | |||
var panel = document.createElement('div'); | |||
panel.className = 'bc-local-filter'; | |||
panel.innerHTML = | |||
'<div class="bc-local-filter-title">\u0411\u044b\u0441\u0442\u0440\u044b\u0439 \u0444\u0438\u043b\u044c\u0442\u0440</div>' + | |||
'<input type="search" class="bc-local-filter-input" placeholder="\u0424\u0438\u043b\u044c\u0442\u0440 \u043f\u043e \u044d\u0442\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435" aria-label="\u0424\u0438\u043b\u044c\u0442\u0440 \u043a\u0430\u0440\u0442\u043e\u0447\u0435\u043a">' + | |||
'<div class="bc-local-filter-count"></div>'; | |||
grid.parentNode.insertBefore(panel, grid); | |||
var input = panel.querySelector('.bc-local-filter-input'); | |||
var count = panel.querySelector('.bc-local-filter-count'); | |||
function update() { | |||
var query = input.value.trim().toLowerCase(); | |||
var visible = 0; | |||
cards.forEach(function (card) { | |||
var match = !query || card.textContent.toLowerCase().indexOf(query) !== -1; | |||
card.classList.toggle('is-hidden', !match); | |||
if (match) { | |||
visible += 1; | |||
} | |||
}); | |||
count.textContent = visible + ' / ' + cards.length; | |||
} | |||
input.addEventListener('input', update); | |||
update(); | |||
} | |||
function addReadingTools() { | |||
if (document.querySelector('.bc-read-progress')) { | |||
return; | |||
} | |||
var progress = document.createElement('div'); | |||
progress.className = 'bc-read-progress'; | |||
document.body.appendChild(progress); | |||
var top = document.createElement('button'); | |||
top.className = 'bc-top-button'; | |||
top.type = 'button'; | |||
top.setAttribute('aria-label', '\u041d\u0430\u0432\u0435\u0440\u0445'); | |||
top.textContent = '\u2191'; | |||
document.body.appendChild(top); | |||
top.addEventListener('click', function () { | |||
window.scrollTo({ top: 0, behavior: 'smooth' }); | |||
}); | |||
function update() { | |||
var doc = document.documentElement; | |||
var max = Math.max(1, doc.scrollHeight - window.innerHeight); | |||
var ratio = Math.min(1, Math.max(0, window.scrollY / max)); | |||
progress.style.transform = 'scaleX(' + ratio + ')'; | |||
top.classList.toggle('is-visible', window.scrollY > 520); | |||
} | |||
window.addEventListener('scroll', update, { passive: true }); | |||
window.addEventListener('resize', update); | |||
update(); | |||
} | |||
function revealContent() { | |||
var items = Array.prototype.slice.call(document.querySelectorAll('.bc-card, .bc-country, .bc-stat, .bc-section, .bc-section-grid, .bc-section-photo, .mw-parser-output > h2, .mw-parser-output > p')); | |||
if (!items.length || !('IntersectionObserver' in window)) { | |||
items.forEach(function (item) { item.classList.add('is-visible'); }); | |||
return; | |||
} | |||
items.forEach(function (item) { item.classList.add('bc-reveal'); }); | |||
var observer = new IntersectionObserver(function (entries) { | |||
entries.forEach(function (entry) { | |||
if (entry.isIntersecting) { | |||
entry.target.classList.add('is-visible'); | |||
observer.unobserve(entry.target); | |||
} | |||
}); | |||
}, { threshold: 0.12 }); | |||
items.forEach(function (item) { observer.observe(item); }); | |||
} | } | ||
onReady(function () { | onReady(function () { | ||
document.documentElement.classList.add('bc-ready'); | document.documentElement.classList.add('bc-ready'); | ||
removeNoopServiceWorker(); | |||
prioritizeMedia(); | |||
initParticles(); | initParticles(); | ||
makeSearchInteractive(); | makeSearchInteractive(); | ||
animateStats(); | animateStats(); | ||
enhanceCards(); | |||
addCardFilter(); | |||
addReadingTools(); | |||
revealContent(); | |||
}); | }); | ||
})(); | })(); | ||
Текущая версия от 04:10, 26 мая 2026
(function () {
'use strict';
function onReady(fn) {
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', fn);
return;
}
fn();
}
function loadScript(src, done) {
if (document.querySelector('script[src="' + src + '"]')) {
done();
return;
}
var script = document.createElement('script');
script.src = src;
script.async = true;
script.onload = done;
document.head.appendChild(script);
}
function initParticles() {
var hero = document.querySelector('.bc-hero');
if (!hero) {
return;
}
var oldHost = document.getElementById('bc-particles');
if (oldHost) {
oldHost.remove();
}
var host = document.createElement('div');
host.id = 'bc-particles';
hero.insertBefore(host, hero.firstChild);
loadScript(
'https://cdn.jsdelivr.net/npm/particles.js@2.0.0/particles.min.js',
function () {
if (!window.particlesJS) {
return;
}
window.particlesJS('bc-particles', {
particles: {
number: {
value: 110,
density: {
enable: true,
value_area: 850
}
},
color: {
value: [
'#1d5f9f',
'#e40046',
'#33c4ff',
'#102033'
]
},
shape: {
type: 'circle'
},
opacity: {
value: 0.38,
random: true
},
size: {
value: 4.4,
random: true
},
line_linked: {
enable: true,
distance: 180,
color: '#1d5f9f',
opacity: 0.38,
width: 1.5
},
move: {
enable: true,
speed: 1.0,
direction: 'none',
random: true,
straight: false,
out_mode: 'out',
bounce: false
}
},
interactivity: {
detect_on: 'canvas',
events: {
onhover: {
enable: true,
mode: 'grab'
},
onclick: {
enable: true,
mode: 'push'
},
resize: true
},
modes: {
grab: {
distance: 190,
line_linked: {
opacity: 0.4
}
},
push: {
particles_nb: 4
}
}
},
retina_detect: true
});
}
);
}
function makeSearchInteractive() {
var slot = document.querySelector('[data-bc-search]');
if (!slot) {
return;
}
var input = document.createElement('input');
input.className = 'bc-search-input';
input.type = 'search';
input.autocomplete = 'off';
input.placeholder = window.innerWidth < 560 ? 'страна, сервис или мера...' : slot.textContent.trim();
input.setAttribute('aria-label', 'Поиск по BRICSCompass');
input.placeholder = window.innerWidth < 560 ? '\u0441\u0442\u0440\u0430\u043d\u0430 \u0438\u043b\u0438 \u0441\u0435\u0440\u0432\u0438\u0441' : '\u043d\u0430\u0439\u0442\u0438 \u0441\u0442\u0440\u0430\u043d\u0443, \u0441\u0435\u0440\u0432\u0438\u0441 \u0438\u043b\u0438 \u043c\u0435\u0440\u0443';
input.setAttribute('aria-label', '\u041f\u043e\u0438\u0441\u043a \u043f\u043e BRICSCompass');
input.placeholder = window.innerWidth < 560 ? '\u0421\u0442\u0440\u0430\u043d\u0430 \u0438\u043b\u0438 \u0441\u0435\u0440\u0432\u0438\u0441' : '\u0421\u0442\u0440\u0430\u043d\u0430, \u0441\u0435\u0440\u0432\u0438\u0441 \u0438\u043b\u0438 \u043c\u0435\u0440\u0430';
slot.replaceChildren(input);
slot.classList.add('is-live');
var cards = Array.prototype.slice.call(document.querySelectorAll('.bc-card, .bc-country'));
var tags = Array.prototype.slice.call(document.querySelectorAll('[data-bc-query]'));
var arrow = document.querySelector('.bc-arrow');
function filter(value) {
var query = value.trim().toLowerCase();
cards.forEach(function (card) {
var text = card.textContent.toLowerCase();
var match = !query || text.indexOf(query) !== -1;
card.classList.toggle('is-match', !!query && match);
card.classList.toggle('is-dim', !!query && !match);
});
tags.forEach(function (tag) {
tag.classList.toggle('is-active', query && tag.getAttribute('data-bc-query').toLowerCase() === query);
});
}
input.addEventListener('input', function () {
filter(input.value);
});
tags.forEach(function (tag) {
tag.addEventListener('click', function () {
input.value = tag.getAttribute('data-bc-query') || '';
filter(input.value);
input.focus();
});
});
function getCardLink(card) {
var link = card.closest('a');
if (link && link.href) {
return link.href;
}
return '';
}
function submitSearch() {
var query = input.value.trim().toLowerCase();
var target = null;
if (!query) {
input.focus();
return;
}
cards.some(function (card) {
var titleNode = card.querySelector('strong');
var title = (titleNode || card).textContent.trim().toLowerCase();
var text = card.textContent.trim().toLowerCase();
if (title === query) {
target = card;
return true;
}
if (!target && text.indexOf(query) !== -1) {
target = card;
}
return false;
});
var href = target && getCardLink(target);
if (href) {
window.location.href = href;
return;
}
window.location.href = (mw.config.get('wgScriptPath') || '') + '/index.php?search=' + encodeURIComponent(input.value.trim());
}
input.addEventListener('keydown', function (event) {
if (event.key === 'Enter') {
event.preventDefault();
submitSearch();
}
});
if (arrow) {
arrow.setAttribute('role', 'button');
arrow.setAttribute('tabindex', '0');
arrow.setAttribute('aria-label', 'Найти раздел');
arrow.addEventListener('click', submitSearch);
arrow.addEventListener('keydown', function (event) {
if (event.key === 'Enter' || event.key === ' ') {
event.preventDefault();
submitSearch();
}
});
}
}
function animateStats() {
var stats = Array.prototype.slice.call(document.querySelectorAll('.bc-stat-value'));
if (!stats.length || !('IntersectionObserver' in window)) {
return;
}
var observer = new IntersectionObserver(function (entries) {
entries.forEach(function (entry) {
if (!entry.isIntersecting) {
return;
}
var node = entry.target;
var target = parseInt(node.textContent.replace(/\D/g, ''), 10);
if (!target || node.getAttribute('data-animated')) {
return;
}
node.setAttribute('data-animated', 'true');
var start = performance.now();
var duration = 900;
function tick(now) {
var progress = Math.min((now - start) / duration, 1);
var eased = 1 - Math.pow(1 - progress, 3);
node.lastChild.nodeValue = String(Math.round(target * eased));
if (progress < 1) {
requestAnimationFrame(tick);
}
}
node.textContent = '0';
requestAnimationFrame(tick);
observer.unobserve(node);
});
}, { threshold: 0.35 });
stats.forEach(function (stat) {
observer.observe(stat);
});
}
function prioritizeMedia() {
Array.prototype.forEach.call(document.querySelectorAll('.bc-photo img, .bc-section-photo img'), function (img) {
img.loading = 'eager';
img.decoding = 'async';
img.setAttribute('fetchpriority', 'high');
});
}
function removeNoopServiceWorker() {
if (!('serviceWorker' in navigator) || !navigator.serviceWorker.getRegistrations) {
return;
}
navigator.serviceWorker.getRegistrations().then(function (registrations) {
registrations.forEach(function (registration) {
var url = registration.active && registration.active.scriptURL;
if (url && url.indexOf('skins.citizen.serviceWorker') !== -1) {
registration.unregister();
}
});
}).catch(function () {});
}
function enhanceCards() {
var cards = Array.prototype.slice.call(document.querySelectorAll('.bc-card, .bc-country, .bc-stat'));
cards.forEach(function (card) {
card.setAttribute('tabindex', '0');
card.addEventListener('mousemove', function (event) {
var rect = card.getBoundingClientRect();
card.style.setProperty('--mx', Math.round(event.clientX - rect.left) + 'px');
card.style.setProperty('--my', Math.round(event.clientY - rect.top) + 'px');
});
card.addEventListener('keydown', function (event) {
var link = card.closest('a');
if (link && (event.key === 'Enter' || event.key === ' ')) {
event.preventDefault();
link.click();
}
});
});
}
function addCardFilter() {
var grid = document.querySelector('.bc-card-grid');
if (!grid || document.querySelector('.bc-hero') || document.querySelector('.bc-local-filter')) {
return;
}
var cards = Array.prototype.slice.call(grid.querySelectorAll('.bc-card'));
if (cards.length < 3) {
return;
}
var panel = document.createElement('div');
panel.className = 'bc-local-filter';
panel.innerHTML =
'<div class="bc-local-filter-title">\u0411\u044b\u0441\u0442\u0440\u044b\u0439 \u0444\u0438\u043b\u044c\u0442\u0440</div>' +
'<input type="search" class="bc-local-filter-input" placeholder="\u0424\u0438\u043b\u044c\u0442\u0440 \u043f\u043e \u044d\u0442\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435" aria-label="\u0424\u0438\u043b\u044c\u0442\u0440 \u043a\u0430\u0440\u0442\u043e\u0447\u0435\u043a">' +
'<div class="bc-local-filter-count"></div>';
grid.parentNode.insertBefore(panel, grid);
var input = panel.querySelector('.bc-local-filter-input');
var count = panel.querySelector('.bc-local-filter-count');
function update() {
var query = input.value.trim().toLowerCase();
var visible = 0;
cards.forEach(function (card) {
var match = !query || card.textContent.toLowerCase().indexOf(query) !== -1;
card.classList.toggle('is-hidden', !match);
if (match) {
visible += 1;
}
});
count.textContent = visible + ' / ' + cards.length;
}
input.addEventListener('input', update);
update();
}
function addReadingTools() {
if (document.querySelector('.bc-read-progress')) {
return;
}
var progress = document.createElement('div');
progress.className = 'bc-read-progress';
document.body.appendChild(progress);
var top = document.createElement('button');
top.className = 'bc-top-button';
top.type = 'button';
top.setAttribute('aria-label', '\u041d\u0430\u0432\u0435\u0440\u0445');
top.textContent = '\u2191';
document.body.appendChild(top);
top.addEventListener('click', function () {
window.scrollTo({ top: 0, behavior: 'smooth' });
});
function update() {
var doc = document.documentElement;
var max = Math.max(1, doc.scrollHeight - window.innerHeight);
var ratio = Math.min(1, Math.max(0, window.scrollY / max));
progress.style.transform = 'scaleX(' + ratio + ')';
top.classList.toggle('is-visible', window.scrollY > 520);
}
window.addEventListener('scroll', update, { passive: true });
window.addEventListener('resize', update);
update();
}
function revealContent() {
var items = Array.prototype.slice.call(document.querySelectorAll('.bc-card, .bc-country, .bc-stat, .bc-section, .bc-section-grid, .bc-section-photo, .mw-parser-output > h2, .mw-parser-output > p'));
if (!items.length || !('IntersectionObserver' in window)) {
items.forEach(function (item) { item.classList.add('is-visible'); });
return;
}
items.forEach(function (item) { item.classList.add('bc-reveal'); });
var observer = new IntersectionObserver(function (entries) {
entries.forEach(function (entry) {
if (entry.isIntersecting) {
entry.target.classList.add('is-visible');
observer.unobserve(entry.target);
}
});
}, { threshold: 0.12 });
items.forEach(function (item) { observer.observe(item); });
}
onReady(function () {
document.documentElement.classList.add('bc-ready');
removeNoopServiceWorker();
prioritizeMedia();
initParticles();
makeSearchInteractive();
animateStats();
enhanceCards();
addCardFilter();
addReadingTools();
revealContent();
});
})();