Help
RSS
API
Feed
Maltego
Contact
Domain > grottbjorn.com
×
More information on this domain is in
AlienVault OTX
Is this malicious?
Yes
No
DNS Resolutions
Date
IP Address
2013-08-27
89.111.176.226
(
ClassC
)
2024-09-13
91.226.81.60
(
ClassC
)
Port 80
HTTP/1.1 301 Moved PermanentlyServer: nginx/1.18.0Date: Fri, 13 Sep 2024 15:35:42 GMTContent-Type: text/htmlContent-Length: 169Connection: keep-aliveLocation: https://grottbjorn.com/ html>head>title>301 Moved Permanently/title>/head>body>center>h1>301 Moved Permanently/h1>/center>hr>center>nginx/1.18.0/center>/body>/html>
Port 443
HTTP/1.1 200 OKServer: nginx/1.18.0Date: Fri, 13 Sep 2024 15:35:43 GMTContent-Type: text/html; charsetutf-8Content-Length: 129381Connection: keep-aliveX-Powered-By: ExpressETag: W/1f965-jQ7vbTkYCERFVzWLX3NEc+J+KSIExpires: Fri, 13 Sep 2024 15:35:42 GMTCache-Control: no-cache html> head> title> Брокерское обслуживание, услуги брокера | Финансовое ателье GrottBjörn /title> meta charsetutf-8> meta nameviewport contentwidthdevice-width,initial-scale1,minimum-scale1,maximum-scale1,user-scalableno> meta namedescription contentОткрытие индивидуального инвестиционного счета, валютно-конверсионные операции, покупка облигаций, страхование валютных рисков и другие финансовые услуги от GrottBjörn. Бесплатный звонок по России 8 800 250 44 20.> meta propertydescription contentБрокерские обслуживание, услуги брокера - финансовое ателье GrottBjörn> meta propertyog:title contentБрокерские обслуживание, услуги брокера - финансовое ателье GrottBjörn> meta propertyog:description contentБрокерские обслуживание, услуги брокера - финансовое ателье GrottBjörn> meta propertyog:image contenthttps://grottbjorn.com/upload/photos/60fdef1a-fe25-4229-a83e-c99c61e9a17f.jpg> meta propertyog:url contenthttps://grottbjorn.com/> link relapple-touch-icon sizes180x180 href/static/favicon/apple-touch-icon.png> link relicon typeimage/png sizes32x32 href/static/favicon/favicon-32x32.png> link relicon typeimage/png sizes16x16 href/static/favicon/favicon-16x16.png> link relmanifest href/static/favicon/manifest.json> link relmask-icon href/static/favicon/safari-pinned-tab.svg color#44505d> meta namemsapplication-TileColor content#44505d> meta namemsapplication-TileImage content/static/favicon/mstile-144x144.png> meta nametheme-color content#ffffff> meta nameyandex-verification content9a5ca1d1311d5bd3/> link href//fonts.googleapis.com/css?familyOpen+Sans:300,400,400i,600&subsetcyrillic relstylesheet> link relstylesheet href/static/plugins/swiper.min.css/> style> .features { flex-wrap: wrap; justify-content: center !important; gap: 1rem; } .features img { width: 60px; object-fit: contain; } .features a { width: 140px; } /style> link relstylesheet href/static/build/css/bundle.css?${GIT_REV}> noscript> img height1 width1 srchttps://www.facebook.com/tr?id237023163724661&evPageView &noscript1/> /noscript> noscript>img srchttps://vk.com/rtrg?pVK-RTRG-246656-fE6vr styleposition:fixed; left:-999px; alt/>/noscript> /head> body classpage_index > !-- Google Tag Manager (noscript) --> noscript> iframe srchttps://www.googletagmanager.com/ns.html?idGTM-WKQ5T3P height0 width0 styledisplay:none;visibility:hidden>/iframe> /noscript> !-- End Google Tag Manager (noscript) --> header classstatic > div classheader-inner> div classvcard> div classphone tel> label>Бесплатный звонок по России/label> a hreftel:88002504420>8 800 250 44 20/a> /div> /div> div classcenter> a href/ classlogo-link> img classlogo src/static/img/logo.svg> /a> /div> div classright> a classlang hrefhttps://company.grottbjorn.com/>ENGLISH VERSION/a> a href#modal_choice_account idbtn_footer-choice_account classbtn become-client hide-tablet bordered open-modal formodal_choice_account data-modalform-idchoice_account_footer>СТАТЬ КЛИЕНТОМ/a> a classbtn lk hrefhttps://lk.grottbjorn.com/signin>ВОЙТИ В КАБИНЕТ/a> /div> /div> a href#modal_choice_account idbtn_footer-choice_account classbtn become-client hide-desktop bordered open-modal formodal_choice_account data-modalform-idchoice_account_footer>СТАТЬ КЛИЕНТОМ/a> nav classmain-menu> a href/services class>Услуги и тарифы/a> a href/events class>События/a> a href/about class>О компании/a> a href/contacts class>Контакты/a> a href/about/news>Новости/a> /nav> /header> section classtop stylebackground-image: url(/upload/photos/60fdef1a-fe25-4229-a83e-c99c61e9a17f.jpg)> img src/static/img/logo.svg> h1 classslogan>Финансы с нордической точностью/h1> div classsubslogan>Нет одинаковых людей и нет одинаковых компаний, именно поэтому мы создаем и выстраиваем технические решения вокруг каждого клиента/div> button classopen-modal formodal_video stylevisibility:hidden> img src/static/img/show-video.svg>br>Смотреть видео /button> /section> div classcontainer> div classparallax rune-1>/div> div classparallax rune-2>/div> div classparallax rune-3>/div> div classparallax rune-4>/div> div classparallax rune-5>/div> div classparallax rune-6>/div> div classparallax rune-7>/div> div classparallax rune-8>/div> div classparallax rune-9>/div> a hrefhttps://grottbjorn.com/bonds classservice masonry> div> h2 classtitle>Выпуск облигационных займов/h2> div classclients>Для компаний сектора МСП+, крупного бизнеса и холдинговых структур/div> ul classfeatures> li>Привлечь долгосрочное инвестирование на выгодных условиях/li> li>Реструктуризировать имеющиеся долги/li> li>Укрепить публичный имидж компании/li> li>Получить денежные средства без залога/li> /ul> /div> div classimg stylebackground-image: url(/upload/photos/b0392873-ce4d-4438-9acc-6e84b64c66c6.jpg)>/div> /a> a hrefhttps://grottbjorn.com/services/strahovanie-valyutnyh-riskov-hedzhirovanie classservice masonry> div classimg stylebackground-image: url(/upload/photos/ebdfad47-b11f-46ec-a163-bd24856fcc50.jpg)>/div> div> h2 classtitle>Страхование валютных рисков (хеджирование)/h2> div classclients>Для юридических лиц, российских и иностранных компаний/div> ul classfeatures> li>Спланировать размер будущих расходов по валютным контрактам/li> li>Расширить рынок сбыта, предложив фиксированную цену/li> li>Получить запланированную выручку от будущих валютных поступлений, при этом заработать дополнительный доход/li> li>Сохранить стоимость складских остатков при укреплении курса рубля/li> /ul> /div> /a> a hrefhttps://grottbjorn.com/services/valyutno-konversionnye-operacii classservice masonry> div> h2 classtitle>Валютно-конверсионные операции/h2> div classclients>Для юридических лиц, российских и иностранных компаний/div> ul classfeatures> li>Заключать сделки, имея 10% от суммы/li> li>Самостоятельно выбирать курс валюты/li> li>Привлекать дополнительные средства под залог собственных активов/li> li>Прямой доступ к центру валютной ликвидности страны/li> /ul> /div> div classimg stylebackground-image: url(/upload/photos/242ef5cd-7d34-4bc8-9894-53a06bca4059.jpg)>/div> /a> div classservice full-width> a hrefhttps://grottbjorn.com/services/upravlenie-strategiyami-strahovaniya classcontent risks-block> h2 classtitle>Управление стратегиями страхования/h2> div classclients>Для компаний, которые ведут активную внешнеэкономическую деятельность, либо финансовый результат которых зависит от динамики курса иностранной валюты/div> div classfeatures> div styleflex-basis: 25%> img src/static/img/runes_1.svg> Экономия времени /div> div styleflex-basis: 25%> img src/static/img/runes_2.svg> Разработка стратегии /div> div styleflex-basis: 25%> img src/static/img/runes_3.svg> Динамическая корректировка /div> div styleflex-basis: 25%> img src/static/img/runes_4.svg> Удобство контроля /div> /div> /a> /div> div classplates-wrapper> a hrefhttps://grottbjorn.com/services/eto-vam-ne-kakoj-to-tam-depozit classservice plate> h2 classtitle>Это Вам не какой-то там депозит!/h2> div classclients>Юридическим и физическим лицам с временно свободным капиталом/div> ul classfeatures> li>Получить доход от размещения рублей выше, чем в банке/li> li>Размещать денежные средства с большей надёжностью, чем в обычном банке/li> li>Применять гибкие сроки/li> li>Свободно варьировать сумму размещаемых активов/li> /ul> /a> a hrefhttps://grottbjorn.com/services/pryamoj-dostup-na-birzhevoj-rynok-dlya-stran-sng-i-eaes classservice plate> h2 classtitle>Прямой доступ на биржевой рынок для стран СНГ и ЕАЭС/h2> div classclients>Для финансовых организаций стран СНГ и ЕАЭС, совершающих валютные операции с клиентскими или собственными денежными средствами/div> ul classfeatures> li>Высокая скорость исполнения транзакций денежных средств/li> li>Доступ ко всем рынкам через единое окно/li> li>Высокая надежность и сохранность денежных средств/li> /ul> /a> /div> div classservice full-width> div classcontent> h2 classtitle>Финансовый клуб/h2> div classclients> Практические встречи повышения финансовой грамотности для людей, нацеленных на личное развитие. Мы есть в различных городах России. Присоединяйтесь! /div> div classfeatures> a href/fclub/ekaterinburg classfclub> img src/upload/photos/fbdd86a7-bf9e-4912-b20f-f3bd8f6198bf.svg>Екатеринбург /a> a href/fclub/sankt-peterburg classfclub> img src/upload/photos/0bc5dfa2-d178-4c20-bd97-41728882b154.svg>Санкт-Петербург /a> a href/fclub/vladivostok classfclub> img src/upload/photos/2fc98698-7189-4a90-9b1b-9e32b3980879.svg>Владивосток /a> a href/fclub/krasnodar classfclub> img src/upload/photos/db772212-5ea6-4384-a29a-21344bee2451.svg>Краснодар /a> a href/fclub/novosibirsk classfclub> img src/upload/photos/2d00fee2-8ee6-4c22-a09c-ff1bc19ae188.svg>Новосибирск /a> a href/fclub/moskva classfclub> img src/upload/photos/a094c633-ad54-4aa2-ad8a-fda83991d0b5.png>Москва /a> a href/fclub/habarovsk classfclub> img src/upload/photos/00cb0592-1f57-4e4c-8d0f-c9dfe55a9ec9.jpg>Хабаровск /a> a href/fclub/perm classfclub> img src/upload/photos/d2966763-ea20-4cc0-8b65-74742967f419.png>Пермь /a> a href/fclub/krasnoyarsk classfclub> img src/upload/photos/19e1cacf-1acb-4222-811b-a7f7c420d052.png>Красноярск /a> /div> /div> /div> /div> div classwebinars swiper-container> div classswiper-wrapper> div classcontainer swiper-slide> div classspeaker> div classname>Евгений Антипин /div> div classpost>Управляющий директор по работе с эмитентами Финансового ателье GrottBjorn/div> /div> div classslide stylebackground-image: url(/upload/photos/3178be02-d0d2-454c-be2e-9fb754dcbbfb.jpg)> div classdate>В следующую среду, в 14:00 (МСК)/div> h2 classtitle>Извлекаем внутренние резервы или идем на открытый рынок? Как привлечь деньги в бизнес (ч.2)/h2> div classdescription>p>На 2-ой части вебинара Извлекаем внутренние резервы или идем на открытый рынок? Как привлечь деньги в бизнес strong>18 сентября в 14:00 МСК/strong> рассмотрим:/p>p>br>/p>p>strong>Биржевые облигации: беззалоговый источник финансирования для бизнеса/strong>/p>ul>li>Долгосрочное фондирование с учётом внутренней специфики денежных потоков./li>li>+100 к деловой репутации и маркетингу бренда на федеральном уровне/li>li>Первые и самые важные шаги на пути к IPO/li>li>Последние тенденции рынка/li>/ul>p>strong>Спикер: Евгений Антипин, em>Управляющий директор по работе с эмитентами Финансового ателье GrottBjorn/em>/strong>/p>p>_____________________________/p>p>*Услуга не является предложением финансового продукта. Не является индивидуальной инвестиционной рекомендацией. Возможен конфликт интересов. Детальная информация по ограничению ответственности и Информационное уведомление о финансовых инструментах, предусмотренное Внутренним стандартом НАУФОР доступна по a hrefhttps://grottbjorn.com/additional/Disclaimer relnoopener noreferrer target_blank>ссылке/a>./p>/div> a href#modal_webinar-reg classbtn open-modal js-webinar-reg-btn formodal_webinar-reg idbtn_main-webinar data-webinar-id5870c94f-28ae-4e49-b62d-d10402a5f482> ЗАПИСАТЬСЯ НА ВЕБИНАР /a> div classreviews> a href/webinars#reviews> /a> /div> /div> /div> div classcontainer swiper-slide> div classspeaker> div classname>Сергей Елисеев/div> div classpost>Президент Союза независимых экспертов и интерим менеджеров/div> /div> div classslide stylebackground-image: url(/upload/photos/a14d0a46-1223-456b-9233-015c421c5959.jpg)> div classdate>В следующую среду, в 14:00 (МСК)/div> h2 classtitle>Извлекаем внутренние резервы или идем на открытый рынок? Как привлечь деньги в бизнес (ч.1)/h2> div classdescription>p>На 1-ой части вебинара Извлекаем внутренние резервы или идем на открытый рынок? Как привлечь деньги в бизнес strong>18 сентября в 14:00 МСК/strong> рассмотрим:/p>p>br>/p>p>strong>Форсирование финансовой модели: лучшие финансовые результаты в худших условиях/strong>/p>ul>li>Стратегия форсирования прибыли вместо роста выручки (любой ценой)/li>li>Почему традиционные бюджеты не помогают управлять прибылью, а что работает вместо них/li>li>Как обеспечить достаточность оборотных средств если не увеличивать займы и собственный капитал/li>/ul>p>strong>Спикер: Сергей Елисеев, em>Президент Союза независимых экспертов и интерим менеджеров/em>/strong>/p>p>_____________________________/p>p>*Услуга не является предложением финансового продукта. Не является индивидуальной инвестиционной рекомендацией. Возможен конфликт интересов. Детальная информация по ограничению ответственности и Информационное уведомление о финансовых инструментах, предусмотренное Внутренним стандартом НАУФОР доступна по a hrefhttps://grottbjorn.com/additional/Disclaimer relnoopener noreferrer target_blank>ссылке/a>./p>/div> a href#modal_webinar-reg classbtn open-modal js-webinar-reg-btn formodal_webinar-reg idbtn_main-webinar data-webinar-id243d967b-585f-4366-a1e8-f731a62e3654> ЗАПИСАТЬСЯ НА ВЕБИНАР /a> div classreviews> a href/webinars#reviews> /a> /div> /div> /div> div classcontainer swiper-slide> div classspeaker> div classname>Артем Смирнов/div> div classpost>Консультант Уральского представительства Финансового ателье GrottBjorn/div> /div> div classslide stylebackground-image: url(/upload/photos/241c7dbe-eb7e-4a00-839a-a5f8ccf4e347.jpg)> div classdate>26 сентября в 14:00 (МСК)/div> h2 classtitle>Преимущества сделок РЕПО для юридических и физических лиц/h2> div classdescription>p>На вебинареstrong stylecolor: rgb(54, 54, 54);> 26 сентября августа в 14:00 МСК/strong> Вы рассмотрите:/p>ul>li>Особенности и условия банковского и биржевого овернайта/li>li>Доходность от размещения по ставкам межбанковского кредитования./li>li>Надежность и сохранность денежных средств при работе с Московской Биржей./li>li>Возможности сделок РЕПО при маржинальной торговле./li>/ul>p>br>/p>p>*Услуга не является предложением финансового продукта. Не является индивидуальной инвестиционной рекомендацией. Возможен конфликт интересов. Детальная информация по ограничению ответственности и Информационное уведомление о финансовых инструментах, предусмотренное Внутренним стандартом НАУФОР доступна по a hrefhttps://grottbjorn.com/additional/Disclaimer relnoopener noreferrer target_blank>ссылке/a>./p>/div> a href#modal_webinar-reg classbtn open-modal js-webinar-reg-btn formodal_webinar-reg idbtn_main-webinar data-webinar-id6b78bc66-649f-445a-9b93-df82dfb5c2cd> ЗАПИСАТЬСЯ НА ВЕБИНАР /a> div classreviews> a href/webinars#reviews> /a> /div> /div> /div> div classcontainer swiper-slide> div classspeaker> div classname>Георгий Красильников/div> div classpost>Замеcтитель руководителя отдела развития, сертифицированный специалист по финансам Финансового ателье GrottBjorn/div> /div> div classslide stylebackground-image: url(/upload/photos/f1183df0-9e0e-4b00-9557-ed002eb285c4.png)> div classdate>23 октября в 12:00 (МСК)/div> h2 classtitle>Возможности международных расчетов для экспортёров/h2> div classdescription>p>На вебинареstrong stylecolor: rgb(54, 54, 54);> 23 октября в 12:00 МСК/strong> обсудим:/p>p>br>/p>p>- Как получать оплаты от контрагентов всего за 1 день, даже если платежи не ходят. Подробно разберем альтернативные методы, которые позволяют минимизировать время ожидания и изменить привычные процессы./p>p>- Как выгодно продавать валютную выручку по курсу ЦБ или биржи, а не по курсу банка. /p>p>- Способы снижения рисков при работе с контрагентами на международной арене с точки зрения платежей. /p>p>br>/p>p>strong stylecolor: rgb(54, 54, 54);>Ждем Ваши вопросы: на почту pr@grottbjorn.com или в прямом эфире/strong>. /p>p>_/p>p>*Услуга не является предложением финансового продукта. Не является индивидуальной инвестиционной рекомендацией. Возможен конфликт интересов. Детальная информация по ограничению ответственности и Информационное уведомление о финансовых инструментах, предусмотренное Внутренним стандартом НАУФОР доступна по a hrefhttps://grottbjorn.com/additional/Disclaimer relnoopener noreferrer target_blank>ссылке/a>./p>/div> a href#modal_webinar-reg classbtn open-modal js-webinar-reg-btn formodal_webinar-reg idbtn_main-webinar data-webinar-id6f80d7b4-f707-4bb5-9244-4ea01c410e8a> ЗАПИСАТЬСЯ НА ВЕБИНАР /a> div classreviews> a href/webinars#reviews> /a> /div> /div> /div> /div> div classswiper-pagination>/div> /div> div classoffices service full-width container> div classcontent> h2 classtitle>Представительстваbr>GrottBjorn/h2> div classfeatures> a href/about?idekaterinburg> img src/upload/photos/b62a8637-02af-4d37-9436-1f384d2898b4.svg>Екатеринбург /a> a href/about?idkrasnodar> img src/upload/photos/58b6a08d-ca7b-4aec-bdff-38c6f843b0cf.svg>Краснодар /a> a href/about?idkazan> img src/upload/photos/801a0919-8264-4d78-9957-6f90599d61c8.svg>Казань /a> a href/about?idmoskva> img src/upload/photos/818b9bfe-b726-4731-b2b8-799a5356a21f.svg>Москва /a> a href/about?idsankt-peterburg> img src/upload/photos/7fceb50d-c4ad-4872-a95d-a9d62b8f2896.svg>Санкт-Петербург /a> a href/about?idnovosibirsk> img src/upload/photos/0079b5dc-2ff6-4903-8825-dfb8cea68e94.svg>Новосибирск /a> a href/about?idvladivostok> img src/upload/photos/34ec3da2-0c62-4348-ab54-e2465f61df2a.svg>Владивосток /a> a href/about?idrostov-na-donu> img src/upload/photos/37662b83-1553-46b2-98c5-921daf31d1e5.svg>Ростов-на-Дону /a> a href/about?idufa> img src/upload/photos/4f8261da-5cb0-4b92-a6ef-729ce6920590.jpg>Уфа /a> a href/about?idirkutsk> img src/upload/photos/f74e8cf8-4563-4c6c-a3c5-583c0ab4cc22.jpg>Иркутск /a> a href/about?idkrasnoyarsk> img src/upload/photos/4ee93cd6-bbba-4d01-83df-bd0b4effe67d.png>Красноярск /a> a href/about?idperm> img src/upload/photos/2fe90065-ba7b-4db7-b826-fdb441f5daf7.png>Пермь /a> /div> a href#modal_consultation idbtn_main-consultation classbtn open-modal data-modalform-idconsultation-form_index formodal_consultation> ОСТАВИТЬ ЗАЯВКУ НА КОНСУЛЬТАЦИЮ /a> div classphone> a hreftel:88002504420>8 800 250 44 20/a> label>Бесплатный звонок по России/label> /div> /div> /div> /section> footer classdesktop> div classcontainer top> div classleft vcard> a href/ classfn org relnofollow> img classlogo src/static/img/logo.svg> /a> a href#modal_choice_account idbtn_footer-choice_account classbtn open-modal formodal_choice_account data-modalform-idchoice_account_footer>СТАТЬ КЛИЕНТОМ/a> a href#modal_consultation data-modalform-idconsultation-form_services formodal_consultation classbtn open-modal> ПОЛУЧИТЬ КОНСУЛЬТАЦИЮ /a> div classphone tel> label>ЕДИНЫЙ БЕСПЛАТНЫЙ ТЕЛЕФОН/label> a hreftel:88002504420 relnofollow>8 800 250 44 20/a> /div> div classaddress adr>Екатеринбург, Проспект Ленина, 101/2/div> /div> div classright> div> a classlang hrefhttps://company.grottbjorn.com/ relnofollow>ENGLISH VERSION/a> a classsocial hrefhttp://vk.com/club44650535 relnoopener noreferrer target_blank> img src/static/img/social_vk.svg>span>VKontakte/span> /a> a classsocial hrefhttps://www.youtube.com/channel/UC1-q8krCjjvtfnMU_2sulOQ relnoopener noreferrer target_blank> img src/static/img/social_yt.svg>span>Youtube/span> /a> a classsocial hrefhttps://ok.ru/group/56012123078674 relnoopener noreferrer target_blank> img src/static/img/social_ok.svg>span>OK/span> /a> a classsocial hrefhttps://rutube.ru/channel/25105481/ relnoopener noreferrer target_blank> img src/static/img/social_rutube.svg>span>Rutube/span> /a> a classsocial hrefhttps://t.me/fagrottbjorn relnoopener noreferrer target_blank> img src/static/img/social_telegram.svg>span>Telegram/span> /a> /div> div> div classlinks> div> div classcaption>УСЛУГИ/div> a href/services/valyutno-konversionnye-operacii relnofollow>Валютно-конверсионные операции/a> a href/services/strahovanie-valyutnyh-riskov-hedzhirovanie relnofollow>Страхование валютных рисков (хеджирование)/a> a href/services/upravlenie-strategiyami-strahovaniya relnofollow>Управление стратегиями страхования/a> a href/services/eto-vam-ne-kakoj-to-tam-depozit relnofollow>Это Вам не какой-то там депозит!/a> a href/services/rynok-obligacij-dlya-chastnogo-investora relnofollow>Рынок облигаций для частного Инвестора /a> a href/services/pryamoj-dostup-na-birzhevoj-rynok-dlya-stran-sng-i-eaes relnofollow>Прямой доступ на биржевой рынок для стран СНГ и ЕАЭС/a> a href/services/strahovanie-procentnyh-riskov-hedzhirovanie relnofollow>Страхование процентных рисков (хеджирование)/a> /div> div> div classcaption> /div> a href/about/soft relnofollow>Софт/a> a href/about/soft#instruct relnofollow>Инструкции/a> a href/about/documents relnofollow>Документы/a> a href/about/documents relnofollow>Лицензии/a> a href/about/documents#disclosure1 relnofollow>Раскрытие информации/a> a href/about/documents#disclosure6 relnofollow>Информация депонентам/a> a classopen-modal formodal-report href#modal-report relnofollow>Направить предложение/жалобу/a> a classopen-modal formodal_claim-type href#modal_claim-type relnofollow>Участвовать в размещении/выкупе облигаций/a> /div> /div> /div> /div> /div> hr> div classcontainer info>p>Акционерное общество Финансовое ателье ГроттБьерн./p>p>a hrefhttps://grottbjorn.com/about/documents target_blank>Лицензия №166-02672-100000 /a>на осуществление брокерской деятельности, выдана ФКЦБ России 01.11.2000. Без ограничения срока действия. /p>p>a hrefhttps://grottbjorn.com/about/documents target_blank>Лицензия №166-02695-010000/a> на осуществление дилерской деятельности, выдана ФКЦБ России 01.11.2000. Без ограничения срока действия. /p>p>a hrefhttps://grottbjorn.com/about/documents target_blank>Лицензия №066-13298-001000/a> на осуществление деятельности по управлению ценными бумагами, выдана ФСФР России 02.09.2010. Без ограничения срока действия. /p>p>a hrefhttps://grottbjorn.com/about/documents target_blank>Лицензия №066-13299-000100/a> на осуществление депозитарной деятельности, выдана ФСФР России 02.09.2010. Без ограничения срока действия./p>/div>/footer> div idmodal_choice_account classmodal modal--rounded> div classcontent content--choice-account> button typebutton classclose hide-desktop>×/button> button typebutton classclose close--outside hide-tablet> img altClose src/static/img/close_light.svg /> /button> img classlogo src/static/img/logo_dark.svg> p classapplication__desc>Выберите подходящий Вам вариант /p> a href/setup-account classbtn btn--with-padding small dark>Физическое лицо – резидент РФ/a> a href#modal_request classbtn btn--with-padding small transparent open-modal formodal_request data-modalform-idrequest-form_footer>Физическое лицо – нерезидент РФ/a> a href#modal_request classbtn btn--with-padding small open-modal formodal_request data-modalform-idrequest-form_footer>Юридическое лицо/a> /div>/div> div idmodal_request classmodal> form classjs-service-form methodpost action/send-service-request enctypemultipart/form-data> input typehidden nametzOffset> button typebutton classclose>×/button> div classheading>Заявка в GrottBjorn/div> div classtextbox> label>Имя/label> input namefirstname placeholderПредставьтесь, пожалуйста required> /div> div classtextbox> label>Телефон/label> input namephone typetel placeholder+7 (xxx) xxx-xx-xx required> /div> div classtextbox> label>Город/label> input namecity placeholderВаш город required> /div> div classtextbox> label>Почта/label> input nameemail typeemail placeholderexample@gmail.com required> /div> div classinn-egrul> Для подачи заявки введите номер ИНН или загрузите выписку из ЕГРЮЛ. (необязательно) /div> div classtextbox> label>Номер ИНН/label> input nameTINNumber typenumber placeholderхххх хххх хххх/> /div> section classtextbox file> span classfile__egrul> Справка ЕГРЮЛ ( получить справку можно на сайтеbr> a href//egrul.nalog.ru/ target_blank>egrul.nalog.ru/a> или в налоговой) /span> label forfile-upload classfile-upload> input idegrul-file-input classfile-input nameegrul typefile> div classfile-upload__content> b>Загрузите/b> br> span classdrag-drop>или перетащите/span> сюда справку ЕГРЮЛbr>Форматы: .doc, .pdf /div> span classfile-return>/span> button typebutton classfile__close>×/button> /label> /section> div classg-recaptcha data-sitekey6LcEF-EUAAAAAKSY0kj1tQlBseFVnslP6oMHwHUo stylewidth: fit-content; margin: 20px auto 4px;>/div> div classcaptcha-alert styledisplay: none; color: red;>/div> button classbtn>СТАТЬ КЛИЕНТОМ/button> div classnotice> Нажимая на кнопку «Стать клиентом», я соглашаюсь с a href/upload/documents/aMf_T5NOQd/Политика обработки персональных данных.pdf target_blank>Политикой/a> защиты и обработки персональных данных и даю своё a href/upload/documents/ua_Fn-BuU/Согласие на обработку данных.pdf target_blank>Согласие/a> на их обработку /div> /form> /div> div idmodal_consultation classmodal> form classjs-consultation-form methodpost action/send-consultation-request> input typehidden nametzOffset> button typebutton classclose>×/button> div classheading>Заявка на консультацию/div> div classtextbox> label>Имя/label> input namefirstname placeholderПредставьтесь, пожалуйста required> /div> div classtextbox> label>Телефон/label> input namephone typetel placeholder+7 (xxx) xxx-xx-xx required> /div> div classtextbox> label>Город/label> input namecity placeholderВаш город required> /div> div classtextbox> label>Дата консультации/label> input namedate typedate langru date-formatmm/dd/yyyy required> /div> div classtextbox> label>Время консультации (МСК)/label> input nametime typetime placeholderхх:хх required> /div> div classbottom> div classg-recaptcha data-sitekey6LcEF-EUAAAAAKSY0kj1tQlBseFVnslP6oMHwHUo stylewidth: fit-content; margin: 20px auto 4px; padding-top: 20px>/div> div classcaptcha-alert styledisplay: none; color: red;>Мы должны убедиться, что вы живой человек/div> button classbtn stylemargin-top: 0px>ОТПРАВИТЬ ЗАЯВКУ/button> div classnotice> Нажимая на кнопку «Отправить заявку», я соглашаюсь с a href/upload/documents/aMf_T5NOQd/Политика обработки персональных данных.pdf target_blank>Политикой/a> защиты и обработки персональных данных и даю своё a href/upload/documents/ua_Fn-BuU/Согласие на обработку данных.pdf target_blank>Согласие/a> на их обработку /div> /div> /form> /div> div idmodal_webinar-reg classmodal> form idwebinar-reg-form classjs-webinar-reg-form> input typehidden nameid idwebinar-id-input> button typebutton classclose>×/button> div classheading>Регистрация на вебинар/div> div classtextbox> label>Имя/label> input placeholderВаше имя namefirstname required> /div> div classtextbox> label>Город/label> input placeholderВаш город namecity required> /div> div classtextbox> label>Телефон/label> input typetel placeholder+7 (xxx) xxx-xx-xx namephone required> /div> div classtextbox> label>Почта/label> input typeemail placeholderexample@gmail.com nameemail required> /div> div classbottom> button classbtn>ЗАРЕГИСТРИРОВАТЬСЯ/button> div classnotice> Нажимая на кнопку «Зарегистрироваться», я соглашаюсь с a href/upload/documents/aMf_T5NOQd/Политика обработки персональных данных.pdf target_blank>Политикой/a> защиты и обработки персональных данных и даю своё a href/upload/documents/ua_Fn-BuU/Согласие на обработку данных.pdf target_blank>Согласие/a> на их обработку /div> /div> /form> /div> div idmodal-alert classmodal> form classapplication-submit> button typebutton classclose>×/button> img src/static/img/done_icon.svg altЗаявка отправлена> div classapplication__heading>Сообщение отправлено/div> div classapplication__desc> Спасибо за ваше обращение, оно будет обработано в ближайшее время /div> /form> /div> div idmodal-report classmodal> form idreport-form> button typebutton classclose>×/button> div classheading>Предложение/жалоба/div> div classtextbox> label>ФИО/label> input placeholderВведите ФИО namefullname required> /div> div classtextbox> label>Телефон/label> input typetel placeholder+7 (xxx) xxx-xx-xx namephone required> /div> div classtextbox> label>Почта/label> input typeemail placeholderexample@gmail.com nameemail required> /div> div classtextbox> label>Текст/label> textarea classtextarea placeholderВведите текст nametextrequired>/textarea> /div> div classg-recaptcha data-sitekey6LcEF-EUAAAAAKSY0kj1tQlBseFVnslP6oMHwHUo stylewidth: fit-content; margin: 20px auto 4px;>/div> div classcaptcha-alert stylecolor: red;>/div> div classbottom> button classbtn>Отправить/button> div classnotice> Нажимая на кнопку «Отправить», я соглашаюсь с a href/upload/documents/aMf_T5NOQd/Политика обработки персональных данных.pdf target_blank>Политикой/a> защиты и обработки персональных данных и даю своё a href/upload/documents/ua_Fn-BuU/Согласие на обработку данных.pdf target_blank>Согласие/a> на их обработку /div> /div> /form> /div> div idmodal_claim-type classmodal> form> button typebutton classclose>×/button> div classheading>Выберите один из вариантов/div> div classbtn-wrapper> a href#modal_claim-add formodal_claim-add classbtn open-modal>Подать заявку/a> a href#modal_claim-update formodal_claim-update classbtn open-modal>Изменить или отменить заявку/a> a href#modal_claim-id formodal_claim-id classbtn open-modal>Подтвердить заявку/a> /div> /form> /div> link relstylesheet href/static/css/claim.css>script src/static/js/bowser.js>/script>div idmodal_claim-add classmodal> form classclaim_add novalidate> button typebutton classclose>×/button> div classtextbox> select nametitle_field classclaim_input select_input >/select> /div> div classheading>Подать заявку на участие в первичном размещении/div> p classsuccess_msg>/p> p classerror common_error>К сожалению, в настоящее время нет доступных заявок. Попробуйте позже/p> p classerror before_error>/p> p classerror after_error>К сожалению, сбор заявок уже окончен. Мы ждём вас в следующий раз!/p> p classerror send_email_error>При отправке письма по указанному Вами адресу электронной почты произошла ошибка./p> div classrest_fields> div classtextbox> label>Участвую как:/label> select nametype_field classclaim_input select_input > option valueindividual selected>Физическое лицо или ИП/option> option valueentity>Юридическое лицо/option> /select> p classpopup only_qualified_popup>/p> div classtype_box>/div> /div> div classtextbox styleoverflow: visible;> label>Телефон:/label> input typetel namephone_field classclaim_input placeholder+7 (xxx) xxx-xx-xx autocompleteoff required /> p classerror phone_error>Введите номер сотового телефона в формате +79876543210 или 89876543210/p> span classtooltip_wrapper> span classtooltip phone_tooltip>?/span> /span> p classpopup phone_popup>/p> /div> div classtextbox styleoverflow: visible;> label>Почта:/label> input typeemail nameemail_field classclaim_input placeholderАдрес электронной почты autocompleteoff required /> p classerror email_error>Введите правильный адрес электронной почты/p> span classtooltip_wrapper> span classemail_tooltip>?/span> /span> /div> div classtextbox> label>Количество:/label> input typenumber nameamount_field classclaim_input placeholder0 autocompleteoff required /> p classerror amount_error>/p> p classpopup amount_popup>Если вы хотите приобрести ценные бумаги на разные счета, например, на свой обычный брокерский счет и ИИС, то необходимо подать заявку для КАЖДОГО счета ОТДЕЛЬНО! Также обращаем ваше внимание, что заявку необходимо выставлять на планируемое количество, т.е. без «запаса»!/p> /div> div classtextbox> label classprice-label>Цена:/label> div classprice_box> input typenumber nameprice_field classclaim_input placeholder0.00 step0.01 autocompleteoff required /> span classpercent_symbol>%/span> /div> p classerror price_error>/p> span classtooltip_wrapper> span classtooltip price_tooltip>?/span> /span> /div> div classtextbox> label>Ставка (в процентах для облигаций):/label> input typenumber namerate_field classclaim_input placeholder0.00 step0.01 autocompleteoff required /> p classerror rate_error>/p> span classtooltip_wrapper> span classtooltip rate_tooltip>?/span> /span> /div> div classtextbox nooverflow> label>Минимальная аллокация:/label> input typenumber min1 max100 value1 placeholder1 nameallocation_field classclaim_input required /> span classallocation_symbol>%/span> p classerror allocation_error>Допускается ввод только значений в диапазоне от 1 до 100/p> span classtooltip_wrapper> span classtooltip allocation_tooltip>?/span> /span> /div> div classtextbox placeholder_dark> label>Брокер:/label> input listbrokers namebroker_field classclaim_input autocompleteoff required> datalist idbrokers classbroker_box>/datalist> p classerror broker_error>Допускается ввод только значений из выпадающего списка/p> span classtooltip_wrapper> span classtooltip broker_tooltip>?/span> /span> /div> div classtextbox> label>Откуда вы узнали о размещении/оферте:/label> select nameplace_field classclaim_input select_input > option value>/option> option valuetelegram>Телеграм/option> option valuefriends>Друзья/option> option valueinternet>Интернет/option> option valuemailing>Рассылка/option> option valueother>Укажите свой вариант, откуда вы узнали о размещении/оферте/option> /select> div classtextbox place_box> label>Укажите свой вариант:/label> input nameown_field autocompleteoff> /div> /div> p classerror max_error>По данной заявке превышена предельная сумма. Выберите другую заявку или попробуйте позже/p> div> div classnotice> Нажимая на кнопку «Получить смс-код», я соглашаюсь с a href/upload/documents/aMf_T5NOQd/Политика обработки персональных данных.pdf target_blank>Политикой/a> защиты и обработки персональных данных и даю своё a href/upload/documents/ua_Fn-BuU/Согласие на обработку данных.pdf target_blank>Согласие/a> на их обработку, а также Согласие на получение информационных материалов о будущих размещениях /div> button classbtn sms_btn>Получить смс-код/button> div classtextbox sms_box styledisplay: none;> label>Код подтверждения заявки на размещение/оферту: ХХХХ/label> input namesms_field placeholderКод autocompleteoff required /> /div> /div> div classbtn_wrapper styledisplay: none;> button classbtn join_btn disabled>Участвовать!/button> /div> /div> /form>/div>script>;(() > { const modalAddClaim document.querySelector(#modal_claim-add) const addClaimForm document.querySelector(.claim_add) const { title_field, type_field, phone_field, email_field, amount_field, price_field, rate_field, allocation_field, broker_field, place_field, own_field, sms_field, } addClaimForm const infoMsg addClaimForm.querySelector(.heading) const successMsg addClaimForm.querySelector(.success_msg) const typeBox addClaimForm.querySelector(.type_box) const brokerBox addClaimForm.querySelector(.broker_box) const placeBox addClaimForm.querySelector(.place_box) const priceTooltip addClaimForm.querySelector(.price_tooltip) const rateTooltip addClaimForm.querySelector(.rate_tooltip) const restFields addClaimForm.querySelector(.rest_fields) const commonError addClaimForm.querySelector(.common_error) const beforeError addClaimForm.querySelector(.before_error) const afterError addClaimForm.querySelector(.after_error) const emailError addClaimForm.querySelector(.email_error) const sendEmailError addClaimForm.querySelector(.send_email_error) const phoneError addClaimForm.querySelector(.phone_error) const amountError addClaimForm.querySelector(.amount_error) const priceError addClaimForm.querySelector(.price_error) const rateError addClaimForm.querySelector(.rate_error) const allocationError addClaimForm.querySelector(.allocation_error) const brokerError addClaimForm.querySelector(.broker_error) const maxError addClaimForm.querySelector(.max_error) const smsBtn addClaimForm.querySelector(.sms_btn) const smsBox addClaimForm.querySelector(.sms_box) const joinBtn addClaimForm.querySelector(.join_btn) const closeBtn addClaimForm.querySelector(.close) const percentSymbol addClaimForm.querySelector(.percent_symbol) const amountPopup addClaimForm.querySelector(.amount_popup) const onlyQualifiedPopup addClaimForm.querySelector(.only_qualified_popup) let fieldErrors {} let smsCode null const individualFieldTemplate /*html*/ ` div classtextbox> label>Фамилия:/label> input typetext namelastName_field classclaim_input placeholderФамилия autocompleteoff required /> /div> div classtextbox> label>Имя:/label> input typetext namefirstName_field classclaim_input placeholderИмя autocompleteoff required /> /div> div classtextbox> label>Отчество:/label> input typetext namemiddleName_field placeholderОтчество autocompleteoff /> /div> ` const entityFieldTemplate /*html*/ ` div classtextbox> label>Наименование организации:/label> input typetext nameentityName_field classclaim_input placeholderНаименование организации autocompleteoff required/> /div> ` modalAddClaim.onclick (e) > { if (e.target modalAddClaim) { e.stopImmediatePropagation() } } addClaimForm.onsubmit (e) > { e.preventDefault() } const getValueFromField (field) > field.value.replace(/\s{2,}/g, ).trim() const getValueFromBrokerField (brokerField) > brokerField.placeholder.replace(/\s{2,}/g, ).trim() const getDateInMs (date) > new Date(date).getTime() const isEmpty (fields) > fields.some((f) > f.name ! allocation_field && f.name ! broker_field && getValueFromField(f) ) const isEmail (email) > { // const regex /^(0-9a-zA-Z(-.\w*0-9a-zA-Z)*@(0-9a-zA-Z-\w*0-9a-zA-Z\.)+a-zA-Z{2,9})$/ const regex /\S+@\S+\.\S+/ return email.match(regex) } const isPhone (phone) > { const regex /^\+?\d{11}$/ return phone.match(regex) } let currentDataObj {} let brokers {} async function checkDates() { const allClaims await (await fetch(/claims)).json() const currentClaim allClaims.find(claim > claim.id currentDataObj.id) const { showDateTimeMin, showDateTimeMax } currentClaim const timeZone { timeZone: Europe/Moscow } const now Date.now() if ( getDateInMs(showDateTimeMin) > now ) { beforeError.textContent `Сбор заявок начнется ${new Date(showDateTimeMin).toLocaleDateString(ru-RU, timeZone)} в ${new Date(showDateTimeMin).toLocaleTimeString(ru-RU, timeZone)} МСК` afterError.style.display none beforeError.style.display block restFields.style.display none infoMsg.style.display none return false } else if (getDateInMs(showDateTimeMax) now) { beforeError.style.display none afterError.style.display block restFields.style.display none infoMsg.style.display none return true } else { beforeError.style.display none afterError.style.display none restFields.style.display block infoMsg.style.display block return true } } const getOnlyQualifiedPopupText ({ isOnlyForQualified, isTestingRequired }) > { if (isOnlyForQualified) { return Уважаемый Инвестор! Вы должны быть КВАЛИФИЦИРОВАННЫМ инвестором, чтобы участвовать в размещении! } if (isTestingRequired) { return Уважаемый Инвестор! Вы должны быть Квалифицированным инвестором или пройти ТЕСТИРОВАНИЕ у своего брокера, чтобы участвовать в размещении! } return null; } const onlyQualifiedPopupToggler { enable({ isOnlyForQualified false, isTestingRequired false }) { if (onlyQualifiedPopup) { onlyQualifiedPopup.textContent getOnlyQualifiedPopupText({ isOnlyForQualified, isTestingRequired }) onlyQualifiedPopup.style.display block } }, disable() { if (onlyQualifiedPopup) { onlyQualifiedPopup.style.display none } } } function start() { console.log(`current date is ${new Date(Date.now()).toUTCString()}`) fetch(/claims) .then((response) > response.json()) .then(async (claims) > { let index 0 Object.entries(claims).forEach( (key, { title, showDateTimeUntilMin, showDateTimeUntilMax }) > { if (getDateInMs(showDateTimeUntilMin) Date.now() && getDateInMs(showDateTimeUntilMax) > Date.now()) { console.log(new Date(showDateTimeUntilMin).toUTCString()) title_field.optionsindex new Option(title, key) index++ } } ) currentDataObj claimstitle_field.value if (!currentDataObj) { title_field.style.display none restFields.style.display none commonError.style.display block return } const response await fetch(/brokers) if (response.ok) { const _brokers await response.json() for (const broker of _brokers) { Promise.resolve(broker).then(({ brokerName, brokerNum }) > { const value brokerName + , + brokerNum brokersvalue value brokerBox.innerHTML + `option value${value}/>` }) } } title_field.onchange () > { currentDataObj claimstitle_field.value initFields() } initFields() }) } async function initFields() { const valid await checkDates() if (!valid) return const { type, priceMin, priceMax, rateMin, rateMax, allocation, showPercent, onlyForQualified, testingRequired } currentDataObj if (showPercent) { percentSymbol.style.display inline-block } else { percentSymbol.style.display none } infoMsg.textContent type initial ? Подать заявку на участие в первичном размещении : Подать заявку на участие в оферте type_field.value individual typeBox.innerHTML individualFieldTemplate if (onlyForQualified || testingRequired) { onlyQualifiedPopupToggler.enable({ isOnlyForQualified: onlyForQualified, isTestingRequired: testingRequired, }) } priceTooltip.dataset.content `Допускается ввод значений в диапазоне от ${priceMin} до ${priceMax}` if (priceMin priceMax) { price_field.value priceMin price_field.setAttribute(disabled, ) priceTooltip.parentElement.style.display none } else { price_field.value price_field.removeAttribute(disabled) priceTooltip.parentElement.style.display block } rateTooltip.dataset.content `Допускается ввод значений в диапазоне от ${rateMin} до ${rateMax}` if (rateMin rateMax) { rate_field.value rateMin rate_field.setAttribute(disabled, ) rateTooltip.parentElement.style.display none } else { rate_field.value rate_field.removeAttribute(disabled) rateTooltip.parentElement.style.display block } if (allocation) { allocation_field.parentElement.style.display block if (type buyout) { allocation_field.value 100 allocation_field.setAttribute(disabled, ) } else { allocation_field.removeAttribute(disabled) } } else { allocation_field.parentElement.style.display none allocation_field.value 100 } maxError.style.display none initHandlers() } function initHandlers() { const { amountMin, amountMax, priceMin, priceMax, rateMin, rateMax, mult, onlyForQualified, testingRequired } currentDataObj type_field.oninput () > { if (type_field.value individual) { typeBox.innerHTML individualFieldTemplate onlyQualifiedPopupToggler.enable({ isOnlyForQualified: onlyForQualified, isTestingRequired: testingRequired, }) } else { typeBox.innerHTML entityFieldTemplate onlyQualifiedPopupToggler.disable() } } email_field.onchange () > { if (!isEmail(getValueFromField(email_field))) { emailError.style.display block fieldErrors.email true } else { emailError.style.display none delete fieldErrors.email } } phone_field.onchange () > { if (!isPhone(getValueFromField(phone_field))) { phoneError.style.display block fieldErrors.phone true } else { phoneError.style.display none delete fieldErrors.phone } } const phonePopupText onlyForQualified ? ТОЛЬКО ДЛЯ КВАЛОВ : testingRequired ? НУЖНО ТЕСТИРОВАНИЕ : null phone_field.onfocus () > { if (phonePopupText) { phonePopup.textContent phonePopupText phonePopup.style.display block } } phone_field.onblur () > { phonePopup.style.display none } amount_field.oninput () > { amountError.textContent delete fieldErrors.amount const value getValueFromField(amount_field) if (!value) return if (value % mult ! 0 || value amountMin || value > amountMax) { amountError.textContent `Допускается ввод значений от ${amountMin} до ${amountMax} с кратностью ${mult}` amountError.style.display block fieldErrors.amount true } } amount_field.onfocus () > { amountPopup.style.display block } amount_field.onblur () > { amountPopup.style.display none } price_field.oninput () > { priceError.textContent delete fieldErrors.price const value getValueFromField(price_field) if (!value) return if (value priceMin || value > priceMax) { priceError.textContent `Допускается ввод значений в диапазоне от ${priceMin} до ${priceMax}` priceError.style.display block fieldErrors.price true } } price_field.onkeydown (e) > { const value getValueFromField(price_field) if (!value || !/\.,/.test(value)) return const floatNums value.includes(.) ? value.split(.)1 : value.split(,)1 if (floatNums?.length > 2 && e.key ! Backspace) { e.preventDefault() } } rate_field.oninput () > { rateError.textContent `` delete fieldErrors.rate const value getValueFromField(rate_field) if (!value) return if (value rateMin || value > rateMax) { rateError.textContent `Допускается ввод значений в диапазоне от ${rateMin} до ${rateMax}` rateError.style.display block fieldErrors.rate true } } rate_field.onkeydown (e) > { const value getValueFromField(rate_field) if (!value || !/\.,/.test(value)) return const floatNums value.includes(.) ? value.split(.)1 : value.split(,)1 if (floatNums?.length > 2 && e.key ! Backspace) { e.preventDefault() } } allocation_field.onkeydown (e) > { if (!/0-9+/.test(e.key) && e.key ! Backspace) { e.preventDefault() } const value getValueFromField(allocation_field) // if (value.length 3 && e.key ! Backspace) { // e.preventDefault() // } } allocation_field.oninput (e) > { const value getValueFromField(allocation_field) if (value 1 || value > 100) { fieldErrors.allocation true } else { allocationError.style.display none delete fieldErrors.allocation } } allocation_field.onchange () > { if (fieldErrors.allocation) { allocationError.style.display block } else { allocationError.style.display none } } place_field.oninput (e) > { if (e.target.value other) { placeBox.style.display block own_field.classList.add(claim_input) } else { placeBox.style.display none own_field.classList.remove(claim_input) } } broker_field.oninput (e) > { if (!brokerse.target.value) { brokerError.style.display block fieldErrors.broker true } else { broker_field.placeholder e.target.value broker_field.value brokerError.style.display none delete fieldErrors.broker } } closeBtn.addEventListener(click, () > { addClaimForm.reset() currentDataObj {} successMsg.style.display none smsBox.style.display none joinBtn.parentElement.style.display none title_field.style.display block restFields.style.display block typeBox.innerHTML individualFieldTemplate sendEmailError.style.display none broker_field.placeholder const errors addClaimForm.querySelectorAll(.error) errors.forEach(e > { e.style.display none }) smsBtn.setAttribute(disabled, ) smsCode null start() }) addClaimForm.oninput async () > { const inputs ...addClaimForm.querySelectorAll(.claim_input) const error isEmpty(inputs) || Object.keys(fieldErrors).length > 0 || broker_field.placeholder if (!error && !smsCode) { const valid await checkDates() if (!valid) return smsBtn.removeAttribute(disabled) } else if (smsCode) { smsBtn.removeAttribute(disabled) } else { smsBtn.setAttribute(disabled, ) } const value getValueFromField(sms_field) if (error || value ! smsCode) { joinBtn.setAttribute(disabled, ) } else { joinBtn.removeAttribute(disabled) } } smsBtn.onclick async () > { const response await checkSubmissionAppOperationData() if (response.ok) { maxError.style.display none sendSmsCode() } else { const { type } await response.json() if (type) { maxError.style.display block } else { maxError.style.display none } } } joinBtn.onclick async () > { joinBtn.setAttribute(disabled, ) await sendEmail() joinBtn.removeAttribute(disabled) } } start() async function checkSubmissionAppOperationData() { const brokerArr getValueFromBrokerField(broker_field).split(, ) const data { brokerName: brokerArr0, brokerNum: brokerArr1, issuerName: currentDataObj.title, minAllocation: getValueFromField(allocation_field).replace(%, ), price: getValueFromField(price_field), quantity: getValueFromField(amount_field), rate: getValueFromField(rate_field), sourseInformation: getValueFromField(own_field) ? getValueFromField(own_field) : getValueFromField(place_field), userEntityName: addClaimForm.entityName_field ? getValueFromField(addClaimForm.entityName_field) : , userName: addClaimForm.firstName_field ? getValueFromField(addClaimForm.firstName_field) : , userSurname: addClaimForm.lastName_field ? getValueFromField(addClaimForm.lastName_field) : , userMiddleName: addClaimForm.middleName_field ? getValueFromField(addClaimForm.middleName_field) : , userPhone: getValueFromField(phone_field), userPost: getValueFromField(email_field), userType: getValueFromField(type_field), userDeviceInfo: JSON.stringify(bowser.parse(window.navigator.userAgent)) } const response await fetch(/submission-app-operations/check-data, { method: POST, headers: { Content-Type: application/json, }, body: JSON.stringify(data), }) return response } async function sendSmsCode() { smsBtn.setAttribute(disabled, ) sms_field.value smsBox.style.display block joinBtn.parentElement.style.display block sms_field.focus() joinBtn.scrollIntoView() const response await fetch(/send-sms, { method: POST, headers: { Content-Type: application/json, }, body: JSON.stringify({ phone: getValueFromField(phone_field) }), }) if (response.ok) { smsCode await response.json() } let t 60 const timerId setInterval(() > { smsBtn.textContent `${t--}` if (t 0) { clearInterval(timerId) smsBtn.textContent Получить смс-код smsBtn.removeAttribute(disabled) } }, 1000) closeBtn.addEventListener(click, () > { clearInterval(timerId) smsBtn.textContent Получить смс-код }) } async function getCode() { const code Math.random().toString().substring(2, 8) const response await fetch(`/submission-app-operations/${code}`) if (response.ok) return getCode() return code } async function sendEmail() { const valid await checkDates() if (!valid) return const code await getCode() const title currentDataObj.title const typeText currentDataObj.type ? (currentDataObj.type initial ? первичном размещении : выкупе) : const text `Ваша заявка принята. Ей присвоен номер ${code}. Запомните его, он вам понадобится в дальнейшем для общения с нашими специалистами, а также для ввода подтверждения. Необходимые инструкции будут направлены на указанный вами ящик электронной почты. Благодарим вас за участие!` const success await sendSubmissionAppOperation(code) if (success) { fetch(/send-email, { method: POST, headers: { Content-Type: application/json, }, body: JSON.stringify({ allocation: getValueFromField(allocation_field), amount: getValueFromField(amount_field), broker: getValueFromBrokerField(broker_field), code, emailType: claim_success, subject: Заявка на участие в первичном размещении/выкупе, email: getValueFromField(email_field), price: getValueFromField(price_field), rate: getValueFromField(rate_field), title, typeText, phone: getValueFromField(phone_field) }) }).catch(() > { sendEmailError.style.display block }) successMsg.textContent text successMsg.style.display block title_field.style.display none restFields.style.display none } } async function sendSubmissionAppOperation(code) { const brokerArr getValueFromBrokerField(broker_field).split(, ) const data { brokerName: brokerArr0, brokerNum: brokerArr1, internalIdentifier: code, issuerName: currentDataObj.title, minAllocation: getValueFromField(allocation_field).replace(%, ), price: getValueFromField(price_field), quantity: getValueFromField(amount_field), rate: getValueFromField(rate_field), sourseInformation: getValueFromField(own_field) ? getValueFromField(own_field) : getValueFromField(place_field), userEntityName: addClaimForm.entityName_field ? getValueFromField(addClaimForm.entityName_field) : , userName: addClaimForm.firstName_field ? getValueFromField(addClaimForm.firstName_field) : , userSurname: addClaimForm.lastName_field ? getValueFromField(addClaimForm.lastName_field) : , userMiddleName: addClaimForm.middleName_field ? getValueFromField(addClaimForm.middleName_field) : , userPhone: getValueFromField(phone_field), userPost: getValueFromField(email_field), userType: getValueFromField(type_field), userDeviceInfo: JSON.stringify(bowser.parse(window.navigator.userAgent)) } const response await fetch(/submission-app-operations, { method: POST, headers: { Content-Type: application/json, }, body: JSON.stringify(data), }) if (!response.ok) { const { type } await response.json() if (type) { commonError.textContent По данной заявке превышена предельная сумма. Выберите другую заявку или попробуйте позже } else { commonError.textContent Что-то пошло не так. Попробуйте позже. Мы уверены, что всё получится! Но если через какое-то время ситуация не изменится, обратитесь к специалисту клиентского отдела, позвонив по телефону 8 800 250 44 20 } commonError.style.display block restFields.style.display none title_field.style.display none return false } return true }})()/script> link relstylesheet href/static/css/claim.css>div idmodal_claim-update classmodal> form classclaim_update novalidate> button typebutton classclose>×/button> div classtextbox> select nametitle_field classclaim_input select_input >/select> /div> div classheading>Изменение/отмена заявки на участие в первичном размещении/div> p classsuccess_msg>Параметры вашей заявки изменены. Спасибо вам за участие!/p> p classerror common_error>К сожалению, в настоящее время нет доступных заявок. Попробуйте позже/p> div classrest_fields> div classtextbox> label>Код заявки:/label> input typenumber nameid_field classclaim_input placeholderКод заявки autocompleteoff /> span classtooltip_wrapper> span classtooltip id_tooltip>?/span> /span> /div> div classtextbox> label>Последние 4 цифры номера телефона:/label> input typenumber namephone_field classclaim_input placeholderXXXX autocompleteoff /> span classtooltip_wrapper> span classtooltip phone_tooltip_last_digits>?/span> /span> p classerror phone_error>/p> /div> div classtextbox> label>Тип операции:/label> select nameaction_field classclaim_input select_input > /select> /div> div classupdate_fields styledisplay: none;> div classnot_broker_fields> div classtextbox> label>Количество:/label> input typenumber nameamount_field classclaim_input placeholder0 autocompleteoff required /> p classerror amount_error>/p> /div> div classtextbox> label>Цена:/label> div classprice_box> input typenumber nameprice_field classclaim_input placeholder0.00 step0.01 autocompleteoff required /> span classpercent_symbol>%/span> /div> p classerror price_error>/p> span classtooltip_wrapper> span classtooltip price_tooltip>?/span> /span> /div> div classtextbox> label>Ставка (в процентах для облигаций):/label> input typenumber namerate_field classclaim_input placeholder0.00 step0.01 autocompleteoff required /> p classerror rate_error>/p> span classtooltip_wrapper> span classtooltip rate_tooltip>?/span> /span> /div> div classtextbox> label>Минимальная аллокация:/label> input typenumber min1 max100 value1 placeholder1 nameallocation_field classclaim_input required /> span classallocation_symbol>%/span> p classerror allocation_error>Допускается ввод только значений в диапазоне от 1 до 100/p> span classtooltip_wrapper> span classtooltip allocation_tooltip>?/span> /span> /div> /div> div classtextbox placeholder_dark> label>Брокер:/label> input listbrokers namebroker_field classclaim_input autocompleteoff required> datalist idbrokers classbroker_box>/datalist> p classerror broker_error>Допускается ввод только значений из выпадающего списка/p> span classtooltip_wrapper> span classtooltip broker_tooltip>?/span> /span> /div> /div> p classerror max_error>По данной заявке превышена предельная сумма. Выберите другую заявку или попробуйте позже/p> div> div classnotice> Нажимая на кнопку «Получить смс-код», я соглашаюсь с a href/upload/documents/aMf_T5NOQd/Политика обработки персональных данных.pdf target_blank>Политикой/a> защиты и обработки персональных данных и даю своё a href/upload/documents/ua_Fn-BuU/Согласие на обработку данных.pdf target_blank>Согласие/a> на их обработку, а также Согласие на получение информационных материалов о будущих размещениях /div> button classbtn sms_btn disabled>Получить смс-код/button> div classtextbox sms_box styledisplay: none;> label>Код подтверждения заявки на размещение/оферту: ХХХХ/label> input namesms_field placeholderКод autocompleteoff required /> /div> /div> div classbtn_wrapper action_box styledisplay: none;> button classbtn action_btn disabled>Изменить условия заявки/button> /div> /div> /form>/div>script>;(() > { const modalUpdateClaim document.querySelector(#modal_claim-update) const updateClaimForm modalUpdateClaim.querySelector(.claim_update) const { title_field, id_field, phone_field, action_field, amount_field, price_field, rate_field, allocation_field, broker_field, sms_field } updateClaimForm const infoMsg updateClaimForm.querySelector(.heading) const successMsg updateClaimForm.querySelector(.success_msg) const commonError updateClaimForm.querySelector(.common_error) const phoneError updateClaimForm.querySelector(.phone_error) const amountError updateClaimForm.querySelector(.amount_error) const priceError updateClaimForm.querySelector(.price_error) const rateError updateClaimForm.querySelector(.rate_error) const allocationError updateClaimForm.querySelector(.allocation_error) const brokerError updateClaimForm.querySelector(.broker_error) const maxError updateClaimForm.querySelector(.max_error) const brokerBox updateClaimForm.querySelector(.broker_box) const actionBox updateClaimForm.querySelector(.action_box) const priceTooltip updateClaimForm.querySelector(.price_tooltip) const rateTooltip updateClaimForm.querySelector(.rate_tooltip) const restFields updateClaimForm.querySelector(.rest_fields) const updateFields updateClaimForm.querySelector(.update_fields) const smsBtn updateClaimForm.querySelector(.sms_btn) const smsBox updateClaimForm.querySelector(.sms_box) const actionBtn updateClaimForm.querySelector(.action_btn) const closeBtn updateClaimForm.querySelector(.close) const percentSymbol updateClaimForm.querySelector(.percent_symbol) const notBrokerFields updateClaimForm.querySelector(.not_broker_fields) const commonErrorText К сожалению, в настоящее время нет доступных заявок. Попробуйте позже const idErrorText Не найден указанный вами номер заявки или указаны неверные последние 4 цифры номера телефона или выбран не тот Выпуск. Уточните номер или свяжитесь с нами через электронную почту investor@grottbjorn.com или по телефону 8 800 250-44-20 const cancelErrorText Заявка с указанным Вами кодом была отменена какое-то время назад const phoneErrorText Введите последние 4 цифры const defaultErrorText Что-то пошло не так. Попробуйте позже. Мы уверены, что всё получится! Но если через какое-то время ситуация не изменится, обратитесь к специалисту клиентского отдела, позвонив по телефону 8 800 250 44 20 modalUpdateClaim.onclick (e) > { if (e.target modalUpdateClaim) { e.stopImmediatePropagation() } } updateClaimForm.onsubmit (e) > { e.preventDefault() } const getValueFromField (field) > field.value.replace(/\s/g, ) const getValueFromBrokerField (brokerField) > brokerField.placeholder.replace(/\s{2,}/g, ).trim() const getDateInMs (date) > new Date(date).getTime() const isEmpty (fields) > fields.some((f) > f.name ! broker_field && getValueFromField(f) ) let currentDataObj {} let currentSubmissionAppOperation {} let brokers {} let fieldErrors {} let smsCode null async function getSubmissionAppOperation(idValue, phoneValue) { const response await fetch(`/submission-app-operations/${idValue}`) if (response.ok) { const claims await (await fetch(/claims)).json() const selectedClaim claimstitle_field.value; commonError.style.display none delete fieldErrors.common const submissionAppOperation await response.json() currentSubmissionAppOperation submissionAppOperation const { quantity, price, rate, minAllocation, issuerName, brokerName, brokerNum, userPhone, changeType, isBrokerMutable } currentSubmissionAppOperation if (phoneValue ! userPhone.slice(-4) || issuerName ! selectedClaim.title) { return showCommonError() } if (changeType Отмена) { commonError.textContent cancelErrorText commonError.style.display block restFields.style.display none return } amount_field.value quantity price_field.value price rate_field.value rate allocation_field.value minAllocation broker_field.placeholder brokerName + , + brokerNum updateFields.style.display block smsBtn.removeAttribute(disabled) } else { showCommonError() } } function showCommonError() { commonError.textContent idErrorText commonError.style.display block fieldErrors.common true updateFields.style.display none } async function start() { const claims await (await fetch(/claims)).json() let index 0 Object.entries(claims).forEach( (key, { title, showDateTimeUntilMin, showDateTimeUntilMax }) > { if (getDateInMs(showDateTimeUntilMin) Date.now() && getDateInMs(showDateTimeUntilMax) > Date.now()) { title_field.optionsindex new Option(title, key) index++ } } ) currentDataObj claimstitle_field.value if (!currentDataObj) { title_field.style.display none restFields.style.display none commonError.textContent commonErrorText commonError.style.display block return } const _brokers await (await fetch(/brokers)).json() for (const broker of _brokers) { Promise.resolve(broker).then(({ brokerName, brokerNum }) > { const value brokerName + , + brokerNum brokersvalue value brokerBox.innerHTML + `option value${value}/>` }) } title_field.onchange () > { currentDataObj claimstitle_field.value initActionField() initFields() const idValue getValueFromField(id_field); const phoneValue getValueFromField(phone_field); if (phoneValue.length 4) { return; } getSubmissionAppOperation(idValue, phoneValue); } initFields() } start() function initActionField() { if (action_field.options.length > 0) { for (let i 0; i action_field.options.length; i++) { action_field.remove(i); } } const { claimUpdatingDateTime, isBrokerMutable } currentDataObj let index 0; if (getDateInMs(claimUpdatingDateTime) > Date.now() || isBrokerMutable) { action_field.optionsindex new Option(Изменение, update); index++; } action_field.optionsindex new Option(Отмена, cancel); } function initFields() { const { type, priceMin, priceMax, rateMin, rateMax, allocation, showPercent, claimUpdatingDateTime, isBrokerMutable } currentDataObj initActionField() if (getDateInMs(claimUpdatingDateTime) Date.now() && !isBrokerMutable) { notBrokerFields.style.display none } else { notBrokerFields.style.display block } if (action_field.value cancel) { broker_field.setAttribute(disabled, ) } infoMsg.textContent type buyout ? Изменение/отмена заявки на выкуп : Изменение/отмена заявки на участие в первичном размещении actionBtn.textContent Изменить условия заявки successMsg.textContent Параметры вашей заявки изменены. Спасибо вам за участие! priceTooltip.dataset.content `Допускается ввод значений в диапазоне от ${priceMin} до ${priceMax}` if (getDateInMs(claimUpdatingDateTime) Date.now() && isBrokerMutable) { amount_field.setAttribute(disabled, ); } else { amount_field.removeAttribute(disabled) } if (priceMin priceMax || getDateInMs(claimUpdatingDateTime) Date.now() && isBrokerMutable) { price_field.value priceMin price_field.setAttribute(disabled, ) priceTooltip.parentElement.style.display none } else { price_field.value price_field.removeAttribute(disabled) priceTooltip.parentElement.style.display block } rateTooltip.dataset.content `Допускается ввод значений в диапазоне от ${rateMin} до ${rateMax}` if (rateMin rateMax || getDateInMs(claimUpdatingDateTime) Date.now() && isBrokerMutable) { rate_field.value rateMin rate_field.setAttribute(disabled, ) rateTooltip.parentElement.style.display none } else { rate_field.value rate_field.removeAttribute(disabled) rateTooltip.parentElement.style.display block } if (allocation) { allocation_field.parentElement.style.display block if (type buyout || getDateInMs(claimUpdatingDateTime) Date.now() && isBrokerMutable) { allocation_field.value 100 allocation_field.setAttribute(disabled, ) } else { allocation_field.removeAttribute(disabled) } } else { allocation_field.parentElement.style.display none allocation_field.value } maxError.style.display none initHandlers() } function initHandlers() { const { mult, amountMin, amountMax, priceMin, priceMax, rateMin, rateMax, } currentDataObj action_field.onchange (e) > { if (e.target.value update) { if (getValueFromField(id_field) && getValueFromField(phone_field) && Object.keys(fieldErrors).length 1) { updateFields.style.display block } actionBtn.textContent Изменить условия заявки successMsg.textContent Параметры вашей заявки изменены. Спасибо вам за участие! } else { updateFields.style.display none actionBtn.textContent Отменить заявку successMsg.textContent Ваша заявка отменена. Спасибо вам за участие! } } phone_field.onkeydown (e) > { phoneError.style.display none delete fieldErrors.phone const value getValueFromField(phone_field) if (value.length > 3 && e.key ! Backspace) { e.preventDefault() } } phone_field.onchange (e) > { const phoneValue getValueFromField(phone_field) if (phoneValue.length ! 4) { phoneError.textContent phoneErrorText phoneError.style.display block fieldErrors.phone true return } } phone_field.oninput async (e) > { if (fieldErrors.common) { commonError.style.display none delete fieldErrors.common } const phoneValue getValueFromField(phone_field) if (phoneValue.length 4) return const idValue getValueFromField(id_field) if (!idValue) return await getSubmissionAppOperation(idValue, phoneValue) } id_field.onchange async (e) > { const idValue getValueFromField(id_field) const phoneValue getValueFromField(phone_field) if (!idValue || !phoneValue) return await getSubmissionAppOperation(idValue, phoneValue) } id_field.oninput (e) > { if (fieldErrors.common) { commonError.style.display none delete fieldErrors.common } } amount_field.oninput () > { amountError.textContent delete fieldErrors.amount const value getValueFromField(amount_field) if (!value) return if (value % mult ! 0 || value amountMin || value > amountMax) { amountError.textContent `Допускается ввод значений от ${amountMin} до ${amountMax} с кратностью ${mult}` amountError.style.display block fieldErrors.amount true } } price_field.oninput () > { priceError.textContent delete fieldErrors.price const value getValueFromField(price_field) if (!value) return if (value priceMin || value > priceMax) { priceError.textContent `Допускается ввод значений в диапазоне от ${priceMin} до ${priceMax}` priceError.style.display block fieldErrors.price true } } price_field.onkeydown (e) > { const value getValueFromField(price_field) if (!value || !/\.,/.test(value)) return const floatNums value.includes(.) ? value.split(.)1 : value.split(,)1 if (floatNums?.length > 2 && e.key ! Backspace) { e.preventDefault() } } rate_field.oninput () > { rateError.textContent `` delete fieldErrors.rate const value getValueFromField(rate_field) if (!value) return if (value rateMin || value > rateMax) { rateError.textContent `Допускается ввод значений в диапазоне от ${rateMin} до ${rateMax}` rateError.style.display block fieldErrors.rate true } } rate_field.onkeydown (e) > { const value getValueFromField(rate_field) if (!value || !/\.,/.test(value)) return const floatNums value.includes(.) ? value.split(.)1 : value.split(,)1 if (floatNums?.length > 2 && e.key ! Backspace) { e.preventDefault() } } allocation_field.onkeydown (e) > { const value getValueFromField(allocation_field) if (value.length 3 && e.key ! Backspace) { e.preventDefault() } } allocation_field.oninput (e) > { const value getValueFromField(allocation_field) if (value 1 || value > 100) { fieldErrors.allocation true } else { allocationError.style.display none delete fieldErrors.allocation } } allocation_field.onchange () > { if (fieldErrors.allocation) { allocationError.style.display block } else { allocationError.style.display none } } broker_field.oninput (e) > { if (!brokerse.target.value) { brokerError.style.display block fieldErrors.broker true } else { broker_field.placeholder e.target.value broker_field.value brokerError.style.display none delete fieldErrors.broker } } closeBtn.addEventListener(click, () > { updateClaimForm.reset() successMsg.style.display none smsBox.style.display none actionBox.style.display none title_field.style.display block infoMsg.style.display block restFields.style.display block updateFields.style.display none broker_field.placeholder const errors updateClaimForm.querySelectorAll(.error) errors.forEach(e > { e.style.display none }) smsBtn.setAttribute(disabled, ) smsCode null notBrokerFields.style.display block start() }) updateClaimForm.oninput () > { const inputs ...updateClaimForm.querySelectorAll(.claim_input) const error isEmpty(inputs) || Object.keys(fieldErrors).length > 0 || getValueFromField(phone_field).length ! 4 || broker_field.placeholder if (!error && !smsCode) { smsBtn.removeAttribute(disabled) } else { smsBtn.setAttribute(disabled, ) } actionBtn.removeAttribute(disabled); const value getValueFromField(sms_field) if (error || value ! smsCode) { actionBtn.setAttribute(disabled, ) } else { actionBtn.removeAttribute(disabled) } } smsBtn.onclick async () > { const response await checkSubmissionAppOperationData() if (response.ok) { maxError.style.display none sendSmsCode() } else { const { type } await response.json() if (type) { maxError.style.display block } else { maxError.style.display none } } } actionBtn.onclick async () > { actionBtn.setAttribute(disabled, ) await updateSubmisionAppOperation() actionBtn.removeAttribute(disabled) } } async function checkSubmissionAppOperationData() { const data Array.from(new FormData(updateClaimForm)).reduce( (acc, key, val) > { key key.split(_)0 if (key title) { acckey currentDataObj.title } else if (key sms) { return acc } else { acckey val.trim() } return acc }, {} ) data.internalIdentifier data.id data.price getValueFromField(price_field) data.rate getValueFromField(rate_field) data.allocation getValueFromField(allocation_field) const brokerArr getValueFromBrokerField(broker_field).split(,) data.broker `${brokerArr0}, ${brokerArr1}` const claims await (await fetch(/claims)).json() data.claimTitle claimstitle_field.value.title data.issuerName data.claimTitle data.quantity data.amount const response await fetch(/submission-app-operations/check-data, { method: POST, headers: { Content-Type: application/json, }, body: JSON.stringify(data), }) return response } async function sendSmsCode() { smsBtn.setAttribute(disabled, ) sms_field.value smsBox.style.display block actionBox.style.display block sms_field.focus() actionBtn.scrollIntoView() const response await fetch(/send-sms, { method: POST, headers: { Content-Type: application/json, }, body: JSON.stringify({ phone: currentSubmissionAppOperation.userPhone }), }) if (response.ok) { smsCode await response.json() } let t 60 const timerId setInterval(() > { smsBtn.textContent `${t--}` if (t 0) { clearInterval(timerId) smsBtn.textContent Получить смс-код smsBtn.removeAttribute(disabled) } }, 1000) closeBtn.addEventListener(click, () > { clearInterval(timerId) smsBtn.textContent Получить смс-код }) } async function updateSubmisionAppOperation() { const data Array.from(new FormData(updateClaimForm)).reduce( (acc, key, val) > { key key.split(_)0 if (key title) { acckey currentDataObj.title } else if (key sms) { return acc } else { acckey val.trim() } return acc }, {} ) data.price getValueFromField(price_field) data.rate getValueFromField(rate_field) data.allocation getValueFromField(allocation_field) const brokerArr getValueFromBrokerField(broker_field).split(,) data.broker `${brokerArr0}, ${brokerArr1}` const claims await (await fetch(/claims)).json() data.claimTitle claimstitle_field.value.title const response await fetch(/submission-app-operations, { method: PUT, headers: { Content-Type: application/json, }, body: JSON.stringify(data), }) const { type } await response.json() if (type) { commonError.textContent По данной заявке превышена предельная сумма. Выберите другую заявку или попробуйте позже commonError.style.display block restFields.style.display none title_field.style.display none return false } if (response.ok) { const claimType currentDataObj.type ? (currentDataObj.type initial ? первичном размещении : выкупе) : const emailType `claim_${data.action}` let emailData { emailType, subject: action_field.value cancel ? Отмена заявки на участие в первичном размещении/выкупе : Изменение условий заявки на участие в первичном размещении/выкупе, email: currentSubmissionAppOperation.userPost, claimType, title: data.title, id: data.id } if (data.action update) { const { amount, broker, price, rate, allocation } data emailData { ...emailData, amount, broker, price, rate, allocation, phone: currentSubmissionAppOperation.userPhone } } await fetch(/send-email, { method: POST, headers: { Content-Type: application/json, }, body: JSON.stringify(emailData), }) successMsg.style.display block commonError.style.display none title_field.style.display none infoMsg.style.display none restFields.style.display none } else { commonError.textContent defaultErrorText commonError.style.display block } }})()/script> link relstylesheet href/static/css/claim.css>div idmodal_claim-id classmodal> form classclaim_id> button typebutton classclose>×/button> div classtextbox> select nametitle_field classclaim_input select_input >/select> /div> div classheading>/div> p classsuccess_msg>Подтверждение получено. Спасибо вам за участие!/p> p classerror error_msg>/p> p classerror before_error>/p> p classerror after_error>К сожалению, подтверждение заявок уже окончено. Мы ждём вас в следующий раз!/p> div classrest-fields> div classtextbox> label>Код заявки:/label> input namecode_field classclaim_input placeholderКод заявки autocompleteoff required /> span classtooltip_wrapper> span classcode_tooltip>?/span> /span> /div> div classtextbox> label>Номер (ID) заявки в торговой системе:/label> input typenumber nameid_field classclaim_input placeholderНомер (ID) заявки в торговой системе autocompleteoff /> span classtooltip_wrapper> span classtooltip id_tooltip>?/span> /span> /div> div classtextbox> label>Время заявки в торговой системе:/label> input nametime_field classclaim_input placeholderЧЧ:ММ:СС autocompleteoff /> p classerror time_error>Введите время в формате ЧЧ:ММ:СС/p> span classtooltip_wrapper> span classtooltip time_tooltip>?/span> /span> /div> div classg-recaptcha data-sitekey6LcEF-EUAAAAAKSY0kj1tQlBseFVnslP6oMHwHUo stylewidth: fit-content; margin: 20px auto 4px;>/div> div classcaptcha-alert stylecolor: red;>/div> div classbtn_wrapper styledisplay: block;> button classbtn send_btn disabled>Отправить/button> div classnotice> Нажимая на кнопку «Отправить», я соглашаюсь с a href/upload/documents/aMf_T5NOQd/Политика обработки персональных данных.pdf target_blank>Политикой/a> защиты и обработки персональных данных и даю своё a href/upload/documents/ua_Fn-BuU/Согласие на обработку данных.pdf target_blank>Согласие/a> на их обработку /div> /div> /div> /form>/div>script>;(() > { const modalIdClaim document.querySelector(#modal_claim-id) const idClaimForm document.querySelector(.claim_id) const { title_field, code_field, id_field, time_field } idClaimForm const infoMsg idClaimForm.querySelector(.heading) const successMsg idClaimForm.querySelector(.success_msg) const errorMsg idClaimForm.querySelector(.error_msg) const timeError idClaimForm.querySelector(.time_error) const beforeError idClaimForm.querySelector(.before_error) const afterError idClaimForm.querySelector(.after_error) const restFields idClaimForm.querySelector(.rest-fields) const sendBtn idClaimForm.querySelector(.send_btn) const closeBtn idClaimForm.querySelector(.close) const captchaAlert idClaimForm.querySelector(.captcha-alert) const commonErrorText К сожалению, в настоящее время нет доступных заявок. Попробуйте позже const recaptchaErrorText Мы должны убедиться, что вы не робот const codeErrorText Неверный Код заявки. К сожалению, мы не нашли заявку по указанному вами коду. Уточните код заявки, пожалуйста! const idErrorText Неверный Номер (ID) заявки в торговой системе. Укажите корректный номер. Для дополнительной информации обратитесь к специалисту клиентского отдела, позвонив по телефону 8 800 250 44 20 const confirmErrorText Идентификация по данному ID заявки (времени заявки) уже проведена. Если вы не проводили данную идентификацию, просим связаться с нами по электронной почте investor@grottbjorn.com или по телефону 8 800 250-44-20 const claimErrorText Не удалось идентифицировать заявку в торговой системе по указанному вами времени и (или) Брокеру и (или) одобренному вам количеству. Укажите корректное время, а также убедитесь, что Брокер и одобренное вам количество, соответствует тем, что указаны в вашей заявке. Для дополнительной информации обратитесь к специалисту клиентского отдела, позвонив по телефону 8 800 250 44 20 const defaultErrorText Что-то пошло не так. Попробуйте позже. Мы уверены, что всё получится! Но если через какое-то время ситуация не изменится, обратитесь к специалисту клиентского отдела, позвонив по телефону 8 800 250 44 20 let captchaVerified false modalIdClaim.onclick (e) > { if (e.target modalIdClaim) { e.stopImmediatePropagation() } } idClaimForm.onsubmit (e) > { e.preventDefault() } const getValueFromField (field) > field.value.replace(/\s{2,}/g, ).trim() const getDateInMs (date) > new Date(date).getTime() const isEmpty (field) > getValueFromField(field) const isTime (time) > { const regex /\d\d:\d\d:\d\d/ return time.match(regex) } let currentDataObj {} async function checkDates() { const allClaims await (await fetch(/claims)).json() const currentClaim allClaims.find(claim > claim.id currentDataObj.id) const { proposalDateTimeMin, proposalDateTimeMax } currentClaim const timeZone { timeZone: Europe/Moscow } const now Date.now() if (getDateInMs(proposalDateTimeMin) > now) { infoMsg.style.display none beforeError.textContent `Подтверждение заявок начнется ${new Date(proposalDateTimeMin).toLocaleDateString(ru-RU, timeZone)} в ${new Date(proposalDateTimeMin).toLocaleTimeString(ru-RU, timeZone)} МСК` afterError.style.display none beforeError.style.display block restFields.style.display none return false } else if (getDateInMs(proposalDateTimeMax) now) { infoMsg.style.display none beforeError.style.display none afterError.style.display block restFields.style.display none return true } else { infoMsg.style.display block beforeError.style.display none afterError.style.display none restFields.style.display block return true } } function start() { fetch(/claims) .then((response) > response.json()) .then((claims) > { let index 0 Object.entries(claims).forEach( (key, { title, showDateTimeUntilMin, showDateTimeUntilMax }) > { if ((getDateInMs(showDateTimeUntilMin) Date.now() && getDateInMs(showDateTimeUntilMax) > Date.now()) ) { title_field.optionsindex new Option(title, key) index++ } } ) currentDataObj claimstitle_field.value if (!currentDataObj) { title_field.style.display none restFields.style.display none errorMsg.textContent commonErrorText errorMsg.style.display block return } title_field.onchange () > { currentDataObj claimstitle_field.value initFields() } initFields() }) } async function initFields() { const valid await checkDates() if (!valid) return const { type } currentDataObj infoMsg.textContent type buyout ? Ввести подтверждение заявки на участие в оферте : Ввести подтверждение заявки на участие в первичном размещении initHandlers() } function initHandlers() { id_field.oninput () > { if (isEmpty(id_field)) { time_field.removeAttribute(disabled) timeError.style.display none } else { time_field.setAttribute(disabled, ) } } time_field.oninput (e) > { if (isEmpty(time_field)) { id_field.removeAttribute(disabled) } else { id_field.setAttribute(disabled, ) } const value getValueFromField(time_field) if ((value.length 2 || value.length 5) && e.inputType insertText) { time_field.value + : } const digits value.match(/\d{3}/) && value.match(/\d{3}/)0 if (digits) { time_field.value value.replace(digits, (match) > { const f, s, t match.split() return f + s + : + t }) } } time_field.onkeydown (e) > { if (time_field.value.length 8 && e.key ! Backspace || !/0-9/.test(e.key) && e.key ! Backspace) { e.preventDefault() } } time_field.onchange () > { if (!isTime(getValueFromField(time_field))) { timeError.style.display block } else { timeError.style.display none } } idClaimForm.oninput async () > { const inputs ...idClaimForm.querySelectorAll(.claim_input) const error isEmpty(code_field) || (isEmpty(id_field) && isEmpty(time_field)) || (!isEmpty(time_field) && !isTime(getValueFromField(time_field))) if (!error) { const valid await checkDates() if (!valid) return sendBtn.removeAttribute(disabled) } else { sendBtn.setAttribute(disabled, ) } } closeBtn.onclick () > { idClaimForm.reset() successMsg.style.display none errorMsg.style.display none timeError.style.display none title_field.style.display block restFields.style.display block infoMsg.style.display block sendBtn.setAttribute(disabled, ) id_field.removeAttribute(disabled) time_field.removeAttribute(disabled) captchaAlert.textContent captchaVerified false start() } sendBtn.onclick async () > { sendBtn.setAttribute(disabled, ) await sendSubmissionOrder() sendBtn.removeAttribute(disabled) } } start() async function sendSubmissionOrder() { const valid await checkDates() if (!valid) return const data Array.from(new FormData(idClaimForm)).reduce( (acc, key, val) > { key key.split(_)0 if (key title) { acckey currentDataObj.title } else { acckey val.trim() } return acc }, {} ) data.captchaVerified captchaVerified try { const response await fetch(/submission-orders, { method: POST, headers: { Content-Type: application/json, }, body: JSON.stringify(data), }) if (!response.ok) throw response const updatedClaim await response.json() const claimType currentDataObj.type ? (currentDataObj.type initial ? первичном размещении : выкупе) : const confirmType updatedClaim.checkingType Номер ? номер заявки в торговой системе : время выставления заявки в торговую систему const emailData { allocation: updatedClaim.minAllocation, amount: updatedClaim.approvedQuantity, broker: `${updatedClaim.brokerName}, ${updatedClaim.brokerNum}`, claimType, confirmType, email: updatedClaim.userPost, emailType: claim_confirm, code: updatedClaim.internalIdentifier, price: updatedClaim.price, rate: updatedClaim.rate, title: currentDataObj.title, phone: updatedClaim.userPhone } try { await fetch(/send-email, { method: POST, headers: { Content-Type: application/json, }, body: JSON.stringify(emailData), }) successMsg.style.display block errorMsg.style.display none title_field.style.display none restFields.style.display none infoMsg.style.display none } catch (e) { console.error(e) } } catch (e) { let error try { error await e.json() } catch { error { type: general } } if (error.type ! recapcha) { captchaVerified true } const brokerApplicationType currentDataObj.type ? (currentDataObj.type initial ? размещении : выкупе) : размещении; switch (error.type) { case recaptcha: captchaAlert.textContent recaptchaErrorText break case code: errorMsg.textContent codeErrorText break case id: errorMsg.textContent idErrorText break case confirm: errorMsg.textContent confirmErrorText break case broker_quantity: errorMsg.textContent `Заявка в торговой системе выставлена с брокера, который отличается от указанного в ранее поданной вами заявки на участие в ${brokerApplicationType}, и вами указано количество, которое отличается от одобренного вам. Выставьте заявку в торговую систему с брокера, указанного вами при подаче заявки на участие в ${brokerApplicationType} или измените брокера, используя форму для Изменения/отмены заявки, если такое действие допускается условиями сбора заявок, указав одобренное вам количество! Для дополнительной информации обратитесь к специалисту клиентского отдела, позвонив по телефону 8 800 250 44 20` break; case broker: errorMsg.textContent `Заявка в торговой системе выставлена с брокера, который отличается от указанного в ранее поданной вами заявки на участие в ${brokerApplicationType}. Выставьте заявку в торговую систему с брокера, указанного вами при подаче заявки на участие в ${brokerApplicationType} или измените брокера, используя форму для Изменения/отмены заявки, если такое действие допускается условиями сбора заявок. Для дополнительной информации обратитесь к специалисту клиентского отдела, позвонив по телефону 8 800 250 44 20` break case quantity: const quantityApplicationType currentDataObj.type ? (currentDataObj.type initial ? размещение : выкуп) : размещении; errorMsg.textContent `Количество, указанное в заявке на ${quantityApplicationType} отличается от одобренного вам количества. Выставьте заявку в торговую систему именно с одобренным количеством! Для дополнительной информации обратитесь к специалисту клиентского отдела, позвонив по телефону 8 800 250 44 20` break case claim: errorMsg.textContent claimErrorText break default: errorMsg.textContent defaultErrorText break } errorMsg.style.display block } }})()/script> script src/static/build/js/plugins.js>/script> script typetext/javascript srchttps://ecosystemstoragewe.blob.core.windows.net/cdn/sourcebuster.js>/script> script> var page index; var contentPhone 88002504420; var currentLocation window.location.origin if (currentLocation.indexOf(grottbjorn) ! -1) { var sentryEnv currentLocation.indexOf(yellow.jetstyle.ru) ! -1 ? stage : prod; Raven .config( https://8ba833957c484dc783e63fbbc788694e@logs.corp.jetstyle.in/15, { environment: sentryEnv } ) .install() } /script> !-- Yandex.Metrika counter --> script typetext/javascript> (function (m, e, t, r, i, k, a) { mi mi || function () { (mi.a mi.a || ).push(arguments) }; mi.l 1 * new Date(); k e.createElement(t), a e.getElementsByTagName(t)0, k.async 1, k.src r, a .parentNode .insertBefore(k, a) })(window, document, script, https://mc.yandex.ru/metrika/tag.js, ym); ym(46290555, init, { clickmap: true, trackLinks: true, accurateTrackBounce: true }); /script> noscript> div>img srchttps://mc.yandex.ru/watch/46290555 styleposition:absolute; left:-9999px; alt/>/div> /noscript> !-- /Yandex.Metrika counter --> script srchttps://www.google.com/recaptcha/api.js asyncasync deferdefer>/script> script src/static/js/layout.js>/script> script src/static/plugins/swiper.min.js>/script> script src/static/build/js/index-min.js?${GIT_REV}>/script> /body>/html>
View on OTX
|
View on ThreatMiner
Please enable JavaScript to view the
comments powered by Disqus.
Data with thanks to
AlienVault OTX
,
VirusTotal
,
Malwr
and
others
. [
Sitemap
]