банк

кофе закончился быстрее, чем хотелось бы — знакомое чувство. в долг здесь не наливают, но привести баланс в порядок можно всегда.

  • ты можешь перевести любую сумму со своего счёта на другой без комиссии.

  • правила покупки новых твинков читай в правилах и не забудь, что необходимо согласование в теме вопросов к амс.

  • спасаться от чистки за деньги нельзя две чистки подряд. откуп действует до следующей чистки (через 1 месяц).

  • выкуп имени действует только на ник профиля с принятой анкетой — сокращения или иные формы имени не покупаются, ники для твинков заранее не бронируются.

  • выкуп внешности осуществляется строго на две недели, сроки не суммируются. оплатить продление брони можно за день до даты, указанной в гостевой. выкупить можно только не занятую другим игроком внешность (в случае дублей действует только обычная бронь в гостевой на 3 дня).

  • позиция «аватар от амс» выполняется любым свободным админом, выбрать автора нельзя.

  • если сегодня твой день рождения, на услуги банка действует скидка 50% (не забудь указать ее в своем сообщении).

  • предыдущая тема: банк.

  • быстро посчитать сообщения, плюсы, посты и рекламу можно здесь: ссылка.

чтобы выбрать позицию, кликни по ней и заполни необходимую информацию. в конце нажми «отправить в форму ответа».

Код:
<!--HTML-->

<script>
(function(){
function init(){
const checkboxTypes={
quantity:{
template:(id)=>`
<div class="bank-checkbox-row">
<label for="${id}_quantity">количество:</label>
<input type="number" class="bank-number-input bank-quantity-input" id="${id}_quantity" value="1" min="1" step="1">
<label for="${id}_quantity"></label>
</div>`,
getValue:(details)=>{
const input=details.querySelector('.bank-quantity-input');
return input?parseInt(input.value)||1:1;
},
setDisabled:(details,disabled)=>{
const input=details.querySelector('.bank-quantity-input');
if(input)input.disabled=disabled;
}
},
doubleAll:{
template:(id)=>`
<div class="bank-checkbox-row">
<input type="checkbox" id="${id}_doubleAll" class="bank-double-all">
<label for="${id}_doubleAll">удвоение стоимости</label>
</div>`,
getValue:(details)=>details.querySelector('.bank-double-all')?.checked||false,
setDisabled:(details,disabled)=>{
const cb=details.querySelector('.bank-double-all');
if(cb)cb.disabled=disabled;
}
},
doubleX:{
template:(id)=>`
<div class="bank-checkbox-row">
<input type="checkbox" id="${id}_doubleX" class="bank-double-x">
<label for="${id}_doubleX">удвоение стоимости (поштучно)</label>
<input type="number" class="bank-number-input bank-double-count-input" id="${id}_doubleCount" value="1" min="1" step="1">
</div>`,
getValue:(details)=>{
const cb=details.querySelector('.bank-double-x');
const countInput=details.querySelector('.bank-double-count-input');
return{
enabled:cb?.checked||false,
count:countInput?parseInt(countInput.value)||1:1
};
},
setDisabled:(details,disabled)=>{
const cb=details.querySelector('.bank-double-x');
const count=details.querySelector('.bank-double-count-input');
if(cb)cb.disabled=disabled;
if(count)count.disabled=disabled;
}
},
discount:{
template:(id)=>`
<div class="bank-checkbox-row">
<input type="checkbox" id="${id}_discount" class="bank-discount">
<label for="${id}_discount">скидка</label>
<input type="number" class="bank-number-input bank-discount-value" id="${id}_discountValue" value="5" min="5" max="100" step="5">
<label for="${id}_discountValue">%</label>
</div>`,
getValue:(details)=>{
const cb=details.querySelector('.bank-discount');
const percentInput=details.querySelector('.bank-discount-value');
return{
enabled:cb?.checked||false,
percent:percentInput?parseInt(percentInput.value)||0:0
};
},
setDisabled:(details,disabled)=>{
const cb=details.querySelector('.bank-discount');
const percent=details.querySelector('.bank-discount-value');
if(cb)cb.disabled=disabled;
if(percent)percent.disabled=disabled;
}
}
};
const earnItems=[
{category:"за активность на форуме",items:[
{name:"написать анкету",price:100,commentPlaceholder:"ссылка на анкету",checkboxes:['quantity']},
{name:"прийти по заявке",price:50,commentPlaceholder:"ссылка на заявку",checkboxes:['quantity']},
{name:"забрать кого-то из «хочу к вам»",price:50,commentPlaceholder:"ссылка на сообщение",checkboxes:['quantity']},
{name:"написать заявку в «хотим видеть»",price:20,commentPlaceholder:"ссылка на заявку",checkboxes:['quantity']},
{name:"написать заявку в «нужных»",price:50,commentPlaceholder:"ссылка на заявку",checkboxes:['quantity']},
{name:"привести друга (каждому)",price:250,commentPlaceholder:"ссылка на профиль",checkboxes:['quantity']},
{name:"1 сообщение",price:1,commentPlaceholder:"доказательства",checkboxes:['quantity','doubleAll']},
{name:"1 плюс репутации",price:1,commentPlaceholder:"доказательства",checkboxes:['quantity','doubleAll']},
{name:"1 плюс позитива",price:1,commentPlaceholder:"доказательства",checkboxes:['quantity','doubleAll']},
{name:"1 реклама",price:5,commentPlaceholder:"ссылки на рекламу",checkboxes:['quantity','doubleAll']},
{name:"1 графический подарок",price:100,commentPlaceholder:"ссылка на сообщение",checkboxes:['quantity']},
{name:"каждый месяц на форуме (только для первого профиля, твинки не учитываются)",price:100,commentPlaceholder:"дата регистрации",checkboxes:['quantity']},
{name:"поставить баннер в профиле на рено/маяке (раз в месяц)",price:50,commentPlaceholder:"ссылка на профиль",checkboxes:['quantity']},
{name:"попасть в таблицу",price:100,commentPlaceholder:"ссылка на пост в теме активистов",checkboxes:['quantity']}
]},
{category:"за посты",items:[
{name:"1 пост",price:200,commentPlaceholder:"ссылка на пост",checkboxes:['quantity','doubleAll','doubleX']},
{name:"каждые 5 постов",price:500,commentPlaceholder:"доказательства",checkboxes:['quantity']},
{name:"бонус за ответный пост в тот же день (24 часа)",price:100,commentPlaceholder:"ссылка на пост",checkboxes:['quantity']},
{name:"открытый эпизод (каждому)",price:50,commentPlaceholder:"ссылка на эпизод",checkboxes:['quantity']},
{name:"завершенный эпизод (минимум 3 поста от каждого)",price:150,commentPlaceholder:"ссылка на эпизод",checkboxes:['quantity']}
]},
{category:"за снс",items:[
{name:"1 снс-пост",price:10,commentPlaceholder:"ссылка на пост",checkboxes:['quantity','doubleAll','doubleX']},
{name:"открытый снс-эпизод (каждому)",price:50,commentPlaceholder:"ссылка на эпизод",checkboxes:['quantity']},
{name:"завершенный снс-эпизод (минимум 10 постов от каждого)",price:100,commentPlaceholder:"ссылка на эпизод",checkboxes:['quantity']}
]}
];
const spendItems=[
{category:"выкупить",items:[
{name:"выкуп внешности на 2 недели",price:1500,commentPlaceholder:"комментарий (при наличии)",checkboxes:['quantity','discount']},
{name:"выкуп имени или фамилии",price:250,commentPlaceholder:"комментарий (при наличии)",checkboxes:['quantity','discount']}
]},
{category:"сменить персонажа",items:[
{name:"смена персонажа первая до первого поста",price:0,commentPlaceholder:"комментарий (при наличии)",checkboxes:['discount']},
{name:"смена персонажа первая при наличии постов + любые последующие",price:500,commentPlaceholder:"комментарий (при наличии)",checkboxes:['discount']}
]},
{category:"сменить внешность",items:[
{name:"смена внешности первая до первого поста",price:0,commentPlaceholder:"комментарий (при наличии)",checkboxes:['discount']},
{name:"смена внешности первая при наличии постов + любые последующие",price:500,commentPlaceholder:"комментарий (при наличии)",checkboxes:['discount']}
]},
{category:"сменить ник",items:[
{name:"смена ника первая до первого поста",price:0,commentPlaceholder:"комментарий (при наличии)",checkboxes:['discount']},
{name:"смена ника первая при наличии постов + любые последующие",price:200,commentPlaceholder:"комментарий (при наличии)",checkboxes:['discount']}
]},
{category:"дополнительно",items:[
{name:"второй персонаж",price:0,commentPlaceholder:"ссылки на рекламу и сообщение в теме вопросов к амс",checkboxes:['discount']},
{name:"третий и последующие персонажи",price:1500,commentPlaceholder:"ссылка на сообщение в теме вопросов к амс",checkboxes:['discount']},
{name:"реклама с нужным на 2 недели с листовкой от амс",price:500,commentPlaceholder:"ссылка на заявку",checkboxes:['quantity','discount']},
{name:"реклама с нужным на 2 недели со своей листовкой",price:100,commentPlaceholder:"ссылки на заявку и твою листовку",checkboxes:['quantity','discount']},
{name:"спасти себя из чистки",price:1000,commentPlaceholder:"комментарий (при наличии)",checkboxes:['discount']},
{name:"аватар от амс",price:1000,commentPlaceholder:"внешность, пожелания и другие комментарии"},
{name:"перевести деньги другому игроку",price:1,commentPlaceholder:"ссылка на профиль получателя",checkboxes:['quantity']}
]}
];
let selectedItems=new Map();
const totalDiv=document.querySelector('.bank-total');
const outputArea=document.querySelector('.admin-output');
function createCheckboxes(checkboxNames,id){
let html='';
checkboxNames.forEach(name=>{
if(checkboxTypes[name]){
html+=checkboxTypes[name].template(id);
}
});
return html;
}
function getCheckboxesData(details,checkboxNames){
const data={};
checkboxNames.forEach(name=>{
if(checkboxTypes[name]){
data[name]=checkboxTypes[name].getValue(details);
}
});
return data;
}
function setCheckboxesDisabled(details,checkboxNames,disabled){
checkboxNames.forEach(name=>{
if(checkboxTypes[name]&&checkboxTypes[name].setDisabled){
checkboxTypes[name].setDisabled(details,disabled);
}
});
}
function createBankItem(itemData,index){
const itemId=`item_${Date.now()}_${Math.random()}_${index}`;
const itemDiv=document.createElement('div');
itemDiv.className='bank-item';
itemDiv.setAttribute('data-price',itemData.price);
itemDiv.setAttribute('data-name',itemData.name);
itemDiv.setAttribute('data-checkboxes',JSON.stringify(itemData.checkboxes||[]));
const headerDiv=document.createElement('div');
headerDiv.className='bank-item-header';
const rowDiv=document.createElement('div');
rowDiv.className='bank-item-row';
rowDiv.innerHTML=`
<div class="bank-item-name">${itemData.name}</div>
<div class="bank-item-price"><span>${itemData.price}</span></div>
`;
headerDiv.appendChild(rowDiv);
const detailsDiv=document.createElement('div');
detailsDiv.className='bank-details';
detailsDiv.innerHTML=`
<textarea class="bank-textarea" placeholder="${itemData.commentPlaceholder||'вставь здесь ссылки на посты или свой комментарий, если нужно'}"></textarea>
${createCheckboxes(itemData.checkboxes||[],itemId)}
`;
itemDiv.appendChild(headerDiv);
itemDiv.appendChild(detailsDiv);
return{itemDiv,headerDiv};
}
function createCategory(title,itemsList,startIndex){
const fragment=document.createDocumentFragment();
const subtitleDiv=document.createElement('div');
subtitleDiv.className='bank-subtitle';
subtitleDiv.innerHTML='<span>'+title+'</span>';
fragment.appendChild(subtitleDiv);
itemsList.forEach((itemData,idx)=>{
const{itemDiv,headerDiv}=createBankItem(itemData,startIndex+idx);
fragment.appendChild(itemDiv);
itemDiv.headerElement=headerDiv;
});
return fragment;
}
const earnCol=document.getElementById('earn-col');
const spendCol=document.getElementById('spend-col');
if(!earnCol||!spendCol)return;
earnCol.setAttribute('data-type','earn');
spendCol.setAttribute('data-type','spend');
const earnTitle=document.createElement('div');
earnTitle.className='bank-col-title';
earnTitle.innerHTML='<span>заработать</span>';
earnCol.appendChild(earnTitle);
const spendTitle=document.createElement('div');
spendTitle.className='bank-col-title';
spendTitle.innerHTML='<span>потратить</span>';
spendCol.appendChild(spendTitle);
let itemCounter=0;
earnItems.forEach(cat=>{
earnCol.appendChild(createCategory(cat.category,cat.items,itemCounter));
itemCounter+=cat.items.length;
});
spendItems.forEach(cat=>{
spendCol.appendChild(createCategory(cat.category,cat.items,itemCounter));
itemCounter+=cat.items.length;
});
function saveItemData(item){
const details=item.querySelector('.bank-details');
if(!details)return;
const comment=details.querySelector('.bank-textarea')?.value||'';
const checkboxNames=JSON.parse(item.getAttribute('data-checkboxes')||'[]');
const checkboxesData=getCheckboxesData(details,checkboxNames);
if(selectedItems.has(item)){
let data=selectedItems.get(item);
data.comment=comment;
data.checkboxes=checkboxesData;
}
updateTotal();
}
function calculatePrice(basePrice,checkboxesData,quantity=1){
let finalPrice=basePrice*quantity;
if(checkboxesData.discount&&checkboxesData.discount.enabled&&checkboxesData.discount.percent>0){
finalPrice=finalPrice-(finalPrice*(checkboxesData.discount.percent/100));
}
if(checkboxesData.doubleAll&&checkboxesData.doubleAll===true){
finalPrice=finalPrice*2;
}
else if(checkboxesData.doubleX&&checkboxesData.doubleX.enabled){
const doubleCount=Math.min(checkboxesData.doubleX.count,quantity);
const normalCount=quantity-doubleCount;
finalPrice=(basePrice*doubleCount*2)+(basePrice*normalCount);
}
return Math.round(finalPrice);
}
function updateTotal(){
let earnTotal=0,spendTotal=0,earnDetails=[],spendDetails=[];
for(let[item,data]of selectedItems.entries()){
let basePrice=data.price;
let quantity=data.checkboxes.quantity||1;
let finalPrice=calculatePrice(basePrice,data.checkboxes,quantity);
let modifiersText='';
if(data.checkboxes.discount?.enabled)modifiersText+=` + [u]купон на скидку ${data.checkboxes.discount.percent}%[/u]`;
if(data.checkboxes.doubleAll)modifiersText+=` + [u]купон на удвоение (безлимит)[/u]`;
else if(data.checkboxes.doubleX?.enabled)modifiersText+=` + [u]купон на удвоение (${data.checkboxes.doubleX.count})[/u]`;
let quantityDisplay=(data.checkboxes.quantity&&data.checkboxes.quantity>1)?` x ${data.checkboxes.quantity}`:'';
let line=`- [i]${data.name} (${basePrice}[/i]${quantityDisplay}${modifiersText}) = ${finalPrice}`;
if(data.comment)line+=`\n${data.comment}`;
if(data.name==="выкуп имени или фамилии"){
line+=`\nукажи имя на латинице + имя на кириллице`;
}
if(data.type==='earn'){
earnTotal+=finalPrice;
earnDetails.push(line);
}else{
spendTotal+=finalPrice;
spendDetails.push(line);
}
}
let result='';
if(earnDetails.length){
result+=`[quote][b][size=13]дайте денег[/size][/b]\n\n`;
result+=earnDetails.join('\n\n')+`\n\n[b]заработано:[/b] ${earnTotal}\n[/quote]\n`;
}
if(spendDetails.length){
result+=`[quote][b][size=13]заберите мои доллары[/size][/b]\n\n`;
result+=spendDetails.join('\n\n')+`\n\n[b]потрачено:[/b] -${spendTotal}\n[/quote]\n`;
}
const total=earnTotal-spendTotal;
if(earnDetails.length||spendDetails.length){
result+=`[b]итого[/b]: ${total}`;
}else{
result+=`[b]итого[/b]: 0`;
}
if(outputArea)outputArea.value=result;
if(totalDiv)totalDiv.textContent=`итого: ${total}`;
}
function onItemClick(e){
e.stopPropagation();
const header=e.currentTarget;
const item=header.parentElement;
const details=item.querySelector('.bank-details');
if(!details)return;
const isSelected=selectedItems.has(item);
if(!isSelected){
const price=parseInt(item.getAttribute('data-price'));
const name=item.getAttribute('data-name');
const type=item.closest('.bank-col').getAttribute('data-type');
selectedItems.set(item,{price:price,name:name,type:type,comment:'',checkboxes:{}});
details.style.display='block';
const textarea=details.querySelector('.bank-textarea');
const saveHandler=()=>saveItemData(item);
if(textarea)textarea.addEventListener('input',saveHandler);
details.querySelectorAll('input').forEach(input=>{
input.addEventListener('change',saveHandler);
input.addEventListener('input',saveHandler);
});
const doubleAll=details.querySelector('.bank-double-all');
const doubleX=details.querySelector('.bank-double-x');
if(doubleAll&&doubleX){
doubleAll.addEventListener('change',function(){
if(this.checked&&doubleX){
doubleX.checked=false;
doubleX.dispatchEvent(new Event('change'));
}
});
doubleX.addEventListener('change',function(){
if(this.checked&&doubleAll){
doubleAll.checked=false;
doubleAll.dispatchEvent(new Event('change'));
}
});
}
}else{
selectedItems.delete(item);
details.style.display='none';
const textarea=details.querySelector('.bank-textarea');
if(textarea)textarea.value='';
details.querySelectorAll('input').forEach(input=>{
if(input.type==='checkbox')input.checked=false;
if(input.type==='number')input.value=input.min||1;
});
}
updateTotal();
}
setTimeout(()=>{
document.querySelectorAll('.bank-item').forEach(item=>{
const header=item.querySelector('.bank-item-header');
if(header&&!header.hasListener){
header.addEventListener('click',onItemClick);
header.hasListener=true;
}
const details=item.querySelector('.bank-details');
if(details)details.style.display='none';
});
},100);
}
if(document.readyState==='loading'){
document.addEventListener('DOMContentLoaded',init);
}else{
init();
}
})();
</script>


 <div class="bank-columns">
    <div class="bank-col" data-type="earn" id="earn-col"></div>
    <div class="bank-col" data-type="spend" id="spend-col"></div>
  </div>
  <div class="bank-total">итого: 0</div>
  <textarea class="admin-output" placeholder="здесь появится результат"></textarea>
<button class="admin-submit-btn">отправить в форму ответа</button>