Страницы

Поиск по вопросам

пятница, 21 февраля 2020 г.

Почему родительский объект не приводится к типу дочернего?

#cpp #функции #наследование


1) Пытаюсь запустить такой код:

#include 

struct A
{
    virtual void m() {
        std::cout << "A" ;
    }
};

struct B : public A
{
    void m() {
        std::cout << "B";
    }
};

int main()
{
    A a;
    B *b;

    b = &(B)a;
    b->m();

    return 0;
}


Если в main прописать:

int main()
{
    A *a;
    B b;

    a = &b;
    a->m();

    return 0;
}


то все ожидаемо работает. Но вот вопрос, почему нельзя привести тип родителя к типу
наследника, а наоборот можно? Как здесь работает механизм приведения типов? Или все
же можно привести тип родителя к типу наследника?

1) Еще такой вопрос, если написать так:

struct A
{
     void m() {
        std::cout << "A" ;
    }
};

struct B : public A
{
    void m() {
        std::cout << "B";
    }
};

int main()
{
    A *a;
    B b;

    a = &b;
    a->m();

    return 0;
}


то вызывается m() у обьекта A. Но объекта А как бы не существует. Мне не понятно,
где же тогда вызывается эта m(), у какого объекта типа A если обьекта типа A не существует?
    


Ответы

Ответ 1



Дочерний объект содержит в себе родительский объект, поэтому приведение дочернего объекта к родительскому объекту не вызывает проблем и может быть осуществлено неявно. С другой стороны, родительский объект ничего не знает о том, какие и как могут быть определены дочерние от него объекты. Он такой информацией не обладает. А потому нет неявного преобразования из родительского объекта в какой-либо дочерний. Когда нет виртуальных функций, то происходит статическое связывание вызываемых функций с типом объекта на этапе компиляции. В этой программе #include struct A { void m() { std::cout << "A" ; } }; struct B : public A { void m() { std::cout << "B"; } }; int main() { A *a; B b; a = &b; a->m(); return 0; } статическим типом указателя a является тип struct A, поэтому компилятор связывает функцию, объявленную в этом типе. На самом деле то же самое происходит и для виртуальных функций, то есть компилятор осуществляет поиск имени функции в соответствии со статическим типом указателя или ссылки на объект. Другое дело, что вызов функции осуществляется с помощью механизма, использующего таблицу виртуальных функций. Адрес этой таблицы разрешается динамически на этапе выполнения программы, хотя в некоторых простых случаях, когда статический и динамический типы совпадают, то может это делать на этапе компиляции.

Ответ 2



привидение родителя к наследнику выполнять разрешается и это называется downcast, которое можно делать, например, так b = static_cast(&a); А в вашем первом примере будет ошибка компиляции ввиду некорректного с точки зрения синтаксиса языка С++ кода b = &(B)a; вероятно, вы хотели написать так b = (B*)&a; edit ошибка компиляции будет, как отметил Ant, не с точки зрения синтаксиса а с точки зрения семантики языка С++ это каст в стиле С - которого лучше избегать, а в случае с downcast подавно - предпочтительнее применять специальные и более безопасные операторы явного приведения типов из С++ (как написано выше до этого) А вобще, подобный downcast в некоторых случаях может приводить к неопределённому поведению по поводу третьего вопроса - выводится A так как эта функция в родительском классе не виртуальна - в этом и основной смысл виртуальных функий - обеспечение вызова переопределённого в наследнике родительского метода через указатель на базовый класс (родительский класс), соответственно если в базовом классе функция не виртуальна то он и вызовется

Ответ 3



Спасибо, ampawd! Я прозрел! Код ниже выводит ВВ, как и типа ожидалось #include class A {public: virtual void m() { std::cout << "A" ; } }; class B : public A {public: void m() { std::cout << "B"; } }; int main() { A *a; B b; a = &b; a->m(); b.m(); return 0; }

Переход на OpenSource

#linux #active_directory #opensource #samba


Доброго дня. Работаю системным администратором в гос. структуре. Нам поставили задачу
"перенести" инфраструктуру на опенсорсные решения, а именно AD и Exchange. Более 1500
пользователей. С линухами работаю относительно недавно, и соответственно, малоопытный. 
Для решения задачи пытался поставить Samba4 в роли контроллера домена и привязать
всех пользователей к OpenLDAP на Debian 8. Ничего не вышло. Эти двое видимо не дружат,
так по крайней мере написано на Samba Wiki.
А вообще, что нам требуется от контроллера домена:


Пользователи (Win 7 и XP, планируется в будущем постепенный перевод пользователей
на линукс машины) распределены по поддоменам (region.asdf.com,
city.asdf.com, office.asdf.com и т.д.)
Доступ к сетевым принтерам в домене.
Общие папки и расшаренные папки на компах пользователей (доступ через "Сетевое окружение"
на винде)
Групповые политики.


Samba вроде как всё это умеет, по описанию.. но без LDAP он не нужен..

А вместо Exchange хотим поставить почтовик с веб клиентом и отучить пользователей
от Outlook. 

Так вот, в связи с этим вопрос... Это осущесвимо на линуксе или всё это волшебный
мир с единорогами? Начальство ясно дало понять, что денег на лицензию майкрософту не
дадут, из-за этого и переход на опенсорс... -_-
    


Ответы

Ответ 1



Я не сисадмин, но на люнихе живу уже почти 20 лет и моё мнение таково: Когда кто-то пытается перейти на "опенсорсные решения", то самое первое и (казалось бы) самое естественное - попытаться перенести всё, как есть, используя аналоги из люниха. В первую очередь - самбу. Т.е. смоделировать винду на люнихе. Я убеждён, что это - самый тяжёлый и неэффективный путь. Рабочие группы, AD и прочие "гениальные" изобретения Билла Гейтса никак не вписываются в идеологию *NIX систем. Достаточно вспомнить такие проблемы, как : Разный подход к использованию имён файлов и каталогов Разных подход к понятию "пользователь" и его права Разный подход к понятию "свойства (режим)" файла / каталога. Ну и так далее... Выполнить адекватный перенос очень сложно! Гораздо проще забить на все эти рабочие группы и AD и использовать нативные возможности люниха - файловую систему NFS (которая позволит создавать сетевые структуры гораздо более простыми методами) и права пользователей, предоставляемые самим люнихом. Если у Вас какая-то супер-безопасная контора, можно использовать Linux SE (Например: https://xakep.ru/2015/09/15/astra-linux-se/). Это даст Вам уровень безопасности намного превышающий виндовозный. Если Вам нужен стандартный набор сетевых сервисов, сделайте один сервер под nas4free (https://www.gotoadm.ru/network-storage-using-nas4free-part-1-installation/) - там одним щелчком запускаются все типовые сервисы: Файловая помойка с любым уровнем RAID FTP сервер WEB сервер Самба контроллер Почтовый сервер ... Я не помню, что там ещё. Короче : продумайте структуру системы и сделайте всё с нуля!

Ответ 2



Добрый день! То что пишу - сугубо мое мнение. На вашем месте я бы использовал Samba(https://wiki.samba.org/index.php/Setting_up_Samba_as_an_Active_Directory_Domain_Controller) в качестве контроллера домена управлять можно из mmc консоли установив RSAT для windows. Если на сервере то для создания\удаления и редактирования пользователей phpldapadmin можно использовать. С exchange посложнее но есть вариант развернуть на схему SAMBA AD DC - openchange (правда проект вроде как закрылся) или как вариант посмотреть в сторону SOGo (https://sogo.nu/) в качестве фронтенда для postfix(или exim кому как удобнее)\dovecot. Есть еще kolab (https://kolab.org/) он в себе содержит DirSrv(это реализация LDAP) почтовик(postfix\dovecot\spamassasin\postgrey) и в качестве фронтенда - roundcube Но самый простой вариант для вас взять Zentyal он на убунте с самбой все в нем и почтовик и прокси и сого и файерволл. А вообще начинание крутое! успехов! (подумайте сразу чем можно MS Office заменить)

Как сделать option по ширине как select?

#html #css #веб_программирование




#wgtmsr{
 width:150px;   
}

#wgtmsr option{
 width:100px;   
}





Как сделать так, чтобы слово, которое больше по ширине делает опцию чем селект, переносилось
на вторую строку(то-есть не выходило за рамки род. селекта)
    


Ответы

Ответ 1



Одним css - никак. Либо плагин использовать, либо самому скрипт написать. Например я таким иногда пользуюсь: $('.select').each(function(){ // Variables var $this = $(this), selectOption = $this.find('option'), selectOptionLength = selectOption.length, selectedOption = selectOption.filter(':selected'), dur = 500; $this.hide(); // Wrap all in select box $this.wrap('
'); // Style box $('
',{ class: 'select__gap', text: 'Please select' //Placeholder }).insertAfter($this); var selectGap = $this.next('.select__gap'), caret = selectGap.find('.caret'); // Add ul list $('
    ',{ class: 'select__list' }).insertAfter(selectGap); var selectList = selectGap.next('.select__list'); // Add li - option items for(var i = 0; i < selectOptionLength; i++){ $('
  • ',{ class: 'select__item', html: $('',{ text: selectOption.eq(i).text() }) }) .attr('data-value', selectOption.eq(i).val()) .appendTo(selectList); } // Find all items var selectItem = selectList.find('li'); selectList.slideUp(0); selectGap.on('click', function(){ if(!$(this).hasClass('on')){ $(this).addClass('on'); selectList.slideDown(dur); selectItem.on('click', function(){ var chooseItem = $(this).data('value'); $('select').val(chooseItem).attr('selected', 'selected'); selectGap.text($(this).find('span').text()); selectList.slideUp(dur); selectGap.removeClass('on'); }); } else { $(this).removeClass('on'); selectList.slideUp(dur); } }); }); /* #wgtmsr{ width:150px; } #wgtmsr option{ width:100px; } */ /* Стилизация селекта для примера: */ *, *:before, *:after { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } /* Выпадающий список: */ .select ul { padding: 0; margin: 0; list-style-type: none; border: 1px solid #0095ff; width:100px; } /* Пункт списка: */ .select ul li { padding: 5px; } /* Наведение на пункт списка: */ .select ul li:hover { background: #0095ff; color: #fff; } /* Выбор option "Please Select": */ .select__gap { position: relative; padding: 5px; width:150px; border: 1px solid #ccc; padding-right: 10px; } /* Стрелочка: */ .select__gap:after { content: ''; position: absolute; right: 5px; top: 10px; border-top: 5px solid #000; border-left: 3px solid transparent; border-right: 3px solid transparent; }

Как работает авторизация на сервере (логин/пароль)?

#android #https #auth


Клиент-серверное приложение. 
Решили сделать на сервере авторизацию по логину-паролю.
Мне не понятен сам механизм как это работает. Каков должен быть мой алгоритм действий
в этом случае.
Более-менее разобрался как подключиться к серверу по http, получить данные json,
распарсить и показать в листвью.
А вот с авторизацией затык вышел.
Буду рад конструктивному ответу.
    


Ответы

Ответ 1



Допустим, что get/post уже умеете делать (post нужно объязательно научиться, так как get запросы могут кешироваться и все запросы, которые изменяют данные - не должны использовать get). Итак, при старте приложение должно проверить, если в настройках сохранненный ключ (у нас это будет просто строка). Если есть, то пробуем им выполнить тестовый запрос, передав его как то на сервер. Если это get запрос, то можно передать в параметрах урла: http://example.com/rest/init?key=123123123&data=testtest здесь 123123123 - это ключ (как его получить - будет ниже). а data = testtest - какие то произвольные данные. Ну мало чего нам понадобиться. Но для этого запроса может и не быть больше данных. Другие запросы выглядят точно также, только урл изменяется. Например, выбрать из базы данные по продавцу boo может выглядеть так http://example.com/rest/vendor?key=123123123&name=boo на стороне сервера нужно прочитать этот ключ. И проверить. Сами ключи можно хранить в базе. Допустим, что на сервере у нас php (а он там обычно и есть). Поэтому, нужна функция проверки ключа function check_key($key) { # делаем запрос к базе, # проверяем и возвращаем return true; # false } а в начало каждой защищенной функции вставляем такое if (!check_key(_GET['key']) { header("HTTP/1.0 401 Unauthorized"); return; } # все ок, можно сделать запрос и отдать данные я специально возвращают 401 код, который значит то, что ключ плохой или не верный. По хорошему, эти две ситуации нужно различать. Но "и так сойдет(с)". Клиент, получив ошибку, должен либо прекратить попытки, либо попросить пользователя ввести имя пароль (и потереть старый ключ, если он был). Теперь осталось последнее - нужно по имени-паролю получить ключ. Со стороны клиента все просто - передаем в каком-то виде их на сервер. Очень хочется это все запихнуть в get запрос: http://example.com/rest/get_key?login=user&password=pass Но это НЕПРАВИЛЬНО. Правильно передавать внутри post запроса. Тут есть много способов, например, передать как json или как обычную форму. На стороне сервера этот конткретный урл не должен быть защищен кодом выше (как бы это не казалось очевидным, но многие делают подобную ошибку и долго удивляются). Как вычитать имя пароль, проверить их по базе - это просто - обычно один запрос. Если все ок - просто возвращаем назад ключ (который нужно не забыть запомнить в базе, а то как проверять?). Но где же взять сам ключ? Самое простое - сгенерировать его случайным образом. самый простой-простой вариант - md5 от текущего времени (но это плохой вариант - злоумышленник может попробовать угадать его). Да, описанное здесь слишком примитивно и для многих покажется слишком утрированным. Но оно нужно для того, что бы понять базу. Многие думают, что для мобильного приложения нужны какие то особые технологии/методы. Это не правильно. При правильном подходе, серверу все равно, кто к нему подключается (но это не значит, что мобильному клиенту можно отправить пару гигов json просто так). Поэтому, с серверной стороны не нужно искать "особого специалиста". Что нужно научиться делать на клиенте: объязательно: http get/post запросы сохранять данные в локальной базе/конфигах желательно: генерировать/парсить json/xml освоить потоки или async

Ответ 2



Опишу стандартный механизм авторизации через пару login/password: Нужен https - если его нет, то все делается по другому Формируем json строку содержащую пару login/password и шлем серверу Сервер генерирует hash(password+salt) - hash() - обычно что-то типа PBKDF2 Сервер смотрит у себя в БД по ключу login и находит хэш password+salt сравнивает его с вычисленным на шаге 3. Если авторизация успешная, сервер генерирует случайный token, который отдает обратно клиенту Далее клиент все свои запросы сопровождает полученным от сервера токеном, если запрос приходит без токена или токен просроченный - запрос отклоняется.

Ответ 3



Для авторизации клиента и идентификации его как пользователя, за частую используют куки (Cookie). В них передает "ключ", как правило session_id - который генерируется при подключении клиента к вашему http серверу. так же value данной куки передается в БД, storage ( по вашему желанию ) как идентификатор пользователя. Само собой, у каждого клиента свой уникальный session_id

Уничтожить Window после завершения потока

#c_sharp #wpf #многопоточность


Есть метод Something я его запускаю 100500 раз, однако объект System.Windows.Window
не исчезает из памяти. 

private void Something()
{
  Thread t = new Thread(()=> {
    Window w = new Window() { Width = 1024, Height = 768 };
    w.Show();
    Thread.Sleep(1000);
    w.Close();
  });
  t.SetApartmentState(ApartmentState.STA);
  t.Priority = ThreadPriority.Normal;
  t.Start();
  GC.Collect();
}

    


Ответы

Ответ 1



Открывать окно в собственном потоке - не очень хорошая идея, обычно в поток выделяют только вычисления. Однако, в данном примере память будет освобождаться, если подписаться на событие Closed окна и вызвать Dispatcher.CurrentDispatcher.BeginInvokeShutdown, а после закрытия окна вызвать Dispatcher.Run. В реальном использовании Dispatcher.Run вызывается после открытия окна, а закрытие происходит по действию пользователя, а не программно. private void Something() { var t = new Thread(() => { var w = new Window() { Width = 1024, Height = 768 }; w.Show(); w.Closed += (s, ex) => Dispatcher.CurrentDispatcher.BeginInvokeShutdown(DispatcherPriority.Background); Thread.Sleep(1000); w.Close(); Dispatcher.Run(); }); t.SetApartmentState(ApartmentState.STA); t.Priority = ThreadPriority.Normal; t.Start(); GC.Collect(); } Информация отсюда.

Вопрос по указателям в Golang

#golang #указатели #типы_данных


Недавно начал изучать язык программирования Golang, не очень по началу хотелось,
но по работе нужно было, после программирования на Java чуток сложновато.
Появилось пару вопросов, в языке Golang простые типы передаются по значению, так
же к простому типу относятся и массивы, maps и slices передаются по ссылке, структуры
я понял можно передавать как по ссылке так и по значению, все зависит от разработчика,
но часто натыкаюсь на примеры в нете где слайсы и мапы передают через взятие адреса,
зачем это нужно, если по умолчанию, они все равно так и возвращаются, тем более если
передать слайс явно по ссылке то его уже нельзя итерировать, если я что-то не правильно
понял объясните, очень мало документации на русском.
    


Ответы

Ответ 1



В golang нет передачи параметров по ссылке - параметры всегда передаются по значению, т.е. копируются. Оператор & - это взятие адреса переменной, т.е. передача указателя, а не передача параметра по ссылке, т.е. как частный случай по значению передаются указатели. map, slice - тоже передаются по значению, просто у них внутри указатели и происходит копирование указателей, а не содержимого таблицы/среза. Проще всего это продемонстрировать на примере slice (среза). Внутри slice представляет собот структуру: https://github.com/golang/go/blob/master/src/runtime/slice.go type slice struct { array unsafe.Pointer len int cap int } т.е. при передаче по значению - можно изменять элементы внутри slice.array, т.к. указатель после копирования будет указывать на ту же область памяти что и исходный, но вот изменить длину или вместимость срезу уже не получится. Точнее эти изменения не будут видны снаружи вызываемой функции, т.к. длина, вместимость и (возможно) указатель array изменятся только в копии среза. Вот наглядный пример: https://play.golang.org/p/SpFFDdzeXR package main import ( "fmt" ) func f_slice_item(s []int) { s[0] = 1 } func f_slice_size(s []int) { s = append(s, 1) } func f_slice_pointer_item(s *[]int) { (*s)[0] = 3 } func f_slice_pointer_size(s *[]int) { *s = append(*s, 5) } func f_iter(s *[]int) { for i, v := range *s { fmt.Println(i, "-", v) } } func main() { var s []int fmt.Println("slice by value") s = []int{0} f_slice_item(s) fmt.Println(s) s = []int{0} f_slice_size(s) fmt.Println(s) fmt.Println() fmt.Println("slice by pointer") s = []int{0} f_slice_pointer_item(&s) fmt.Println(s) s = []int{0} f_slice_pointer_size(&s) fmt.Println(s) fmt.Println() fmt.Println("iter") f_iter(&s) } Результат выполнения: slice by value [1] [0] slice by pointer [3] [0 5] iter 0 - 0 1 - 5

Не работает .hasClass

#javascript #jquery #bootstrap


Мой скрипт:

$(document).ready(function(){
  if ( $("#menu-xs" ).hasClass('in') ) {
    $( ".main-bg" ).css("height","500px");
  }
});


Айди #menu-xs - это меню, которое появляется с помощью бутстраповского collapse.
Когда оно появляется - ему присваивается класс .in. Данный скрипт почему-то не хочет
видеть этого. Отдельно строка с действием после ифа выполняется. Стоит задача выполнять
эту строку при появлении #menu-xs. Подскажите, будьте добры, в чем может быть проблема.
Благодарю.
    


Ответы

Ответ 1



Ваш скрипт выполняется только один раз - при загрузке страницы. Задача, как я понял, стоит другая - запускать скрипт при появлении collapse. Для этого вам нужно привязаться к событию collapse у bootstrap. Вот список этих событий. Вам, вероятно, нужно shown.bs.collapse. Код будет таким: $(document).ready(function(){ $('#menu-xs').on('shown.bs.collapse', function(){ $( '.main-bg' ).css('height', '500px'); }) });

Напечатать минор матрицы определитель которого наибольший

#cpp


В общем у меня есть матрица 4х4 и мне нужно напечатать минор матрицы определитель
которого Наибольший. Пока я знаю как заполнить матрицу рандомно цифрами и найти ее
определитель но проблемы в том, что я не знаю как найти все миноры матрицы. Кто-то
может помочь с кодом? 

#include 
#include  

using std::cin;
using std::cout;

int main(int argc, char const *argv[]) {
    int n; cin >> n;
    int** matrix = new int*[n];
    for (int i = 0; i < n; i ++)
    {
        matrix[i] = new int [n];
    }

    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j ++) {
            matrix[i][j] = rand() % 10;
        }
    }
    return 0;
}


Ищу  определитель формулой d = d + (pow(-1 ,c) * mat[0][c] * det(n - 1 ,submat))
    


Ответы

Ответ 1



Лобовое решение данной задачи пугает своей переборностью, но если решать задачу в лоб, т.е. через вычисление всех возможных миноров (1, то вам понадобится способ перечисления всех возможных квадратных подматриц. Минор определяется одинаковыми по мощности подмножествами строк и столбцов матрицы. Вот такие подмножества вам и надо генерировать, во всех возможных их вариантах. Например, для каждого возможного подмножества строк мощности 1 надо сгенерировать все возможные подмножества столбцов мощности 1. Для каждого возможного подмножества строк мощности 2 надо сгенерировать все возможные подмножества столбцов мощности 2. И т.д. до мощности n - 1 (2. Задавать такие подмножества можно парой упорядоченных по возрастанию векторов целых чисел, т.е. наборами индексов строк и столбцов матрицы. Числа берутся из диапазона [0, n), а размер вектора задает рассматриваемый в данный момент порядок минора m. Тогда функция, перечисляющая все возможные подмножества, может выглядеть, например, так bool next_subset(std::vector &subset, unsigned n) { unsigned overflow = n; auto it = subset.end(); do { --it; if (++*it < overflow || it == subset.begin()) break; --overflow; } while (true); assert(*it <= overflow); if (*it == overflow) return false; for (++it, ++overflow; it != subset.end(); ++it, ++overflow) { *it = *(it - 1) + 1; assert(*it < overflow); } return true; } В качестве самого первого подмножества используется вектор { 0, 1, ..., m-1 }, а далее последовательные вызовы этой функции будут генерировать вам всевозможные подмножества длины m, пока функция не вернет false. Таким образом, общая структура переборного алгоритма будет такой (2 int main() { unsigned n = 0; std::cin >> n; // `n` - размер матрицы ... for (unsigned m = 1; m < n; ++m) { // `m` - порядок минора std::vector rows(m); std::iota(rows.begin(), rows.end(), 0); do { std::vector columns(m); std::iota(columns.begin(), columns.end(), 0); do { // А сюда вставляем вычисление определителя для минора // образованного строками из `rows` и столбцами из `columns` /* for (unsigned i : rows) std::cout << i << " "; std::cout << "- "; for (unsigned i : columns) std::cout << i << " "; std::cout << std::endl; */ } while (next_subset(columns, n)); } while (next_subset(rows, n)); } } Я пока что вставил в "тело" алгоритма отладочную печать, которая продемонстрирует вам, какие генерируются наборы строк и столбцов минора. А дальше - дело техники. Вам надо лишь модифицировать вашу функцию вычисления определителя так чтобы она работала не напрямую с исходной матрицей, а с "виртуальной" подматрицей, задаваемой индексными массивами rows и columns. Или, если вам так больше нравится, вы можете явно формировать отдельную временную подматрицу из rows и columns и напускать на нее вашу готовую функцию вычисления определителя. 1) Минор - это по определению и есть определитель, т.е. "определитель минора" - это уже "масло масляное". 2) Диапазон порядков миноров и, соответственно, внешнего цикла будет зависеть от того, считаете ли вы минором определитель всей матрицы (минор порядка n). Лирическое отступление: Остроумным "хакерским" способом перечисления всех подмножеств размера m для данного множества размера n является bit-twiddling техника, основанная на функции unsigned next_combination(unsigned x) { unsigned u = x & -x; unsigned v = u + x; x = v + (((v ^ x) / u) >> 2); return x; } Эта функция перечисляет в порядке возрастания все двоичные числа, содержащие одно и то же количество единичных битов в своем представлении. Как бы мне ни хотелось, я, однако, не вижу необходимости притягивать за уши этот подход в решение данной задачи. Хотя можно заметить, что на тех размерностях, на которых эту задачу имеет смысл решать перебором, перечисление разнообразных битовых подмножеств для построения подматриц можно выполнить просто как for (unsigned rows = 1; rows < (1u << n) - 1; ++rows) for (unsigned columns = 1; columns < (1u << n) - 1; ++columns) if (count_bits(rows) == count_bits(columns)) { // Одинаковое количество единичных битов // Считаем минор }

Проверка на тип приложения

#cpp #winapi


Как можно проверить консольное ли приложение или оконное? Может в winapi есть какое-то
описание процесса, его свойств?
    


Ответы

Ответ 1



Если вы используете майкрософтовский SDK, то начиная с версии 10 для проверки "самого себя" у вас есть [недокументированная или полу-документированная] возможность сделать #include ... _crt_app_type type = _query_app_type(); с возвращаемыми значениями _crt_console_app и _crt_gui_app. Аналогичные возможности есть и в более ранних версиях SDK, но интерфейс варьируется.

Ответ 2



В текущем процессе проверить, является ли приложение консольным, можно так: #include #pragma comment(lib, "Dbghelp") extern "C" const IMAGE_DOS_HEADER __ImageBase; ... bool isConsole(){ PIMAGE_NT_HEADERS nt = ImageNtHeader((void*)&__ImageBase); return nt->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI; }

Сравнение множества значений

#cpp #c


Как коротко сравнить много значений на равенство? Надо такое поведение:

type value_1, value_2, value_3, ...
if (value_1 == value_2 && value_2 == value_3 && value_3 == ...)

    


Ответы

Ответ 1



Если они просто так записаны, как отдельные переменные - толку особого не будет. Если же это, скажем, элементы в контейнере - то можно воспользоваться алгоритмом типа all_of - например, пусть у вас vector v - то что-то типа (не компилирую, просто набросок) if (all_of(v.begin(),v.end(),[&v](auto x){ return x == v[0]; })) Ну, словом, где-то так.

Ответ 2



Развивая ответ @Harry, можно предложить вариант для vector v - if(count(v.begin(),v.end(),v[0])==v.size()) {}

Simple HTML DOM Parser найти элемент с двумя классами одновременно

#php #html #парсер #dom


Парсю архив Ленты.ру. Нужно выбрать только новости за день, без категорий,
то есть нужны все div, у которых присутствуют одновременно классы item и news, внутри
всех этих div'ов нужно выбрать элемент a и, условно говоря, вывести/получить href.

Версия, которая работает, НО работает неправильно, выглядит так:

$news = $html->find( 'div[class=news] a' );
foreach( $news as $element ):
    echo $element->href . "\n";
endforeach;


Неправильно потому что выборка идёт только по div'ам с классом news, а надо выборку
по div'ам с классами item и news вместе.

Пробовал так:

$news = $html->find( 'div[class=item news] a' );


...и так:

$news = $html->find( 'div.item.news a' );


...и так:

$news = $html->find( 'div[class="item news"] a' );


Не работает. Варианты эти нашёл соответственно здесь и здесь. Принципиально ли использовать
Simple HTML DOM Parser? Нет, не принципиально. Но с ним я уже знаком и имел опыт использования,
поэтому выбор пал на него.

Была ещё такая мысль: сначала найти все div с class=item, потом среди них найти все
div с class=news, потом в каждом из них найти a, но у меня не получилось. Как я понял,
цепочка методов а-ля

$news = $html->find( 'div[class=item]' )->find( 'div[class=news] a' );


не сработает (у меня не работает). Как быть?

P.S. Добавлю. Сейчас глянул ещё здесь, да, решение рабочее, всё нормально работает.
Если полностью прописать все классы:

$news = $html->find( 'div[class=item news b-tabloid__topic_news] a' );


Но дело в том, что последний класс b-tabloid__topic_news там присутствует не везде,
то есть его наличие не обязательно. Да, можно наговнокодить алгоритм с массивами, ищем
сначала такие, потом другие, склеиваем, сортируем и т.д, но это ИМХО криво. В общем,
вопрос можно переформулировать так: как найти все элементы, у которых среди классов
есть нужные?
    


Ответы

Ответ 1



В целом понятно, что данная библиотека не умеет корректно обрабатывать селекторы, где перечисляются два и более класса подряд. Тем не менее, вы в целом смотрите в нужном направлении, используя форму записи div[class=...]. Рассмотрим исходный тестовый пример: $txt = <<
HTML; $html = str_get_html($txt); пусть наша задача найти div.news.items и вывести значение текста ссылки zxc123. Как вы и написали, вызов вида $html->find('.news.items a); Возвращает пустой набор. Однако, в целом это эквивалентно записи div[class="news items"]. Как известно помимо непосредственного равенства атрибута =, возможны и другие формы записи, например, *=. Если глянуть во внутренности Simple HTML DOM, то вы обнаружите там следующую функцию тестирования селекторов (код приведен не полностью): protected function match($exp, $pattern, $value) { switch ($exp) { case '=': return ($value===$pattern); ...... case '*=': if ($pattern[0]=='/') { return preg_match($pattern, $value); } return preg_match("/".$pattern."/i", $value); } return false; } Отсюда видно, что при указании непосредственного равенества, используется обычное сравнение строк (они ранее приводятся к одному регистру). А вот при указании вхождения *= используются регулярные выражения. Следовательно, использование подобного селектора решит искомую проблему. Более того, мы можем указать непосредственно регулярное выражение в селекторе. Поэтому код $html->find("div[class*=news items] a"); для данного исходного примера успешно найдет экземлпяр ссылки zxc123. Как было упомянуто выше, допустимо использование регулярного выражения, поэтому, если исходный текст будет иметь более сложный набор классов zxc news asd items qwe, но подходящий нам: то написание следующего селектора разрешит эту ситуацию: $html->find("div[class*=news.+items] a"); либо если порядок следования классов items и news может изменится, то возможно следующее выражение: $html->find("div[class*=news.+items|items.+news] a"); зы: такое поведение, вроде, недокументировано, но вроде как и хаком-багом не является, ибо в коде явно прописано условие, проверки первого символа регулярки.

Как создать общий List<> для всех форм?(WinForms, C#)

#c_sharp #winforms #list


У меня есть две формы, одна добавляет в лист данные, вторая считывает, как можно
это реализовать?
    


Ответы

Ответ 1



как-то так static class InnerData { static public List AllData = new List(); } добавление InnerData.AllData.Add(data); чтение foreach(Data data in InnerData.AllData) { //something }

Ответ 2



Насколько я понимаю, Вам нужно создать некий объект, функцией которого будет хранить данные, которыми могут пользоваться другие объекты Вашего приложения. Следовательно Вам нужен объект, экземпляр которого будет единым для всего приложения, и будет создан единожды. А если ожидается работа из нескольких потоков с полями, свойствами и методами этого класса, то этот класс должен ещё и обеспечивать потокобезопасность. Для решения этой задачи отлично подходит такой паттерн, как Singleton (Одиночка). using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; namespace ConsoleApplication { public class MyDataClass { public String MyProperty { get; set; } } public sealed class ConcurrentDataSingleton { /// /// Объект для обеспечения потокобезопасного доступа к полям одиночки /// private readonly static object _lockObject = new object(); /// /// Коллекция данных /// private List _data; /// /// Статическое поле, хранящее ссылку на объект одиночки в управляемой куче /// private static ConcurrentDataSingleton instance; /// /// Метод получения ссылки на объект-одиночку /// /// public static ConcurrentDataSingleton GetInstance() { if (instance == null) instance = new ConcurrentDataSingleton(); return instance; } /// /// Закрытый конструктор, инициализирующий поля класса /// private ConcurrentDataSingleton() { this._data = new List(); } /// /// Метод добавления объекта в коллекцию (потокобезопасно) /// /// Объект данных public void AddData(MyDataClass data) { lock (_lockObject) { this._data.Add(data); } } /// /// Метод получения данных (потокобезопасно) /// /// Условие, по которому следует выбирать объекты из коллекции /// public List GetData(Expression> predicate) { lock (_lockObject) { return this._data.AsQueryable().Where(predicate).ToList(); } } } class Program { public static void Main() { //получаем ссылку на хранилище данных ConcurrentDataSingleton dataStore = ConcurrentDataSingleton.GetInstance(); //Добавление данных dataStore.AddData(new MyDataClass() { MyProperty = "value" }); //Получение данных List dataThatINeed = dataStore.GetData(mdc => mdc.MyProperty == "value"); } } }

Вызвать BSOD в 64-битном приложении

#delphi #ассемблер


unit BSOD;

interface

uses
  WinAPI.Windows;

procedure Crash;

function RtlSetProcessIsCritical(unu: Cardinal; proc: Pointer; doi: Cardinal): Integer;
stdcall; external 'ntdll.dll';
function RtlAdjustPrivilege(Privilege: Cardinal; Enable: Boolean; CurrentThread:
Boolean; out OldPrivilege: Boolean): Cardinal; stdcall; external 'ntdll';

implementation

procedure Crash;
asm
  lea eax, dword[esp+12]
  //invoke RtlAdjustPrivilege, 20, 1, 0, eax
  push eax
  push 0
  push 1
  push 20
  call RtlAdjustPrivilege
  //invoke RtlSetProcessIsCritical, 1, 0, 0
  push 0
  push 0
  push 1
  call RtlSetProcessIsCritical
  call ExitProcess
end;

end.


В 32-битном приложении, если вызвать Crash, то винда крашится.

Как заставить этот код работать в 64-битном приложении?
    


Ответы

Ответ 1



Если не знаете, как написать код на ассемблере, то пишите вначале код на Delphi, смотрите, какой код генерирует компилятор (ставите брекпоинт в функции и когда дойдёте до него, открывайте окно дизассемблера Ctrl+Alt+D), берёте его за основу и улучшаете. Вот для такого Delphi кода: procedure Crash; var VOldPrivilege: Boolean; begin RtlAdjustPrivilege(20, True, False, VOldPrivilege); RtlSetProcessIsCritical(1, nil, 0); ExitProcess(1); end; при компиляции в 64-битном режиме, генерируется вот такой ассемблерный код: push rbp sub rsp,$30 mov rbp,rsp mov ecx,$00000014 mov dl,$01 xor r8,r8 lea r9,[rbp+$2f] call RtlAdjustPrivilege mov ecx,$00000001 xor edx,edx xor r8,r8 call RtlSetProcessIsCritical mov ecx,$00000001 call ExitProcess lea rsp,[rbp+$30] pop rbp ret А вот такой код для 32-битного режима, можете сравнить со своим: push ebp mov ebp,esp push ecx lea eax,[ebp-$01] push eax push $00 push $01 push $14 call RtlAdjustPrivilege push $00 push $00 push $01 call RtlSetProcessIsCritical push $01 call ExitProcess pop ecx pop ebp ret Отличие кода для разных платформ в том, что для x32 используется соглашение вызовов stdcall (параметры передаются через стек), а в x64 - fastcall (первые 4 параметра передаются через регистры, остальные через стек). При разработке соглашений по вызовам (calling conventions) для архитектуры x86-64 решили положить конец существованию различных вариантов вызова функций. В Win32 существовал целый ряд соглашений о вызове: stdcall, cdecl, fastcall, thiscall и так далее. В Win64 только одно «родное» соглашение по вызовам. Модификаторы подобные __cdecl компилятором игнорируются. Думаю, что все согласятся в благородстве такого резкого сокращение числа соглашений. Соглашение по вызовам на платформе x86-64 похоже на соглашение fastcall, существующее в x86. В x64-соглашении первые четыре целочисленных аргумента (слева направо) передаются в 64-битных регистрах, выбранных специально для этой цели: RCX: 1-й целочисленный аргумент RDX: 2-й целочисленный аргумент R8: 3-й целочисленный аргумент R9: 4-й целочисленный аргумент Остальные целочисленные аргументы передаются через стек. Указатель «this» считается целочисленным аргументом, поэтому он всегда помещается в регистр RCX. Если передаются значения с плавающей точкой, то первые четыре из них передаются в регистрах XMM0-XMM3, а последующие — через стек. Цитата отсюда: https://habrahabr.ru/company/intel/blog/94340/

Ответ 2



Приведенный выше код - это код, главная задача которого сделать BSOD. Если кратко - если процесс помечен как критический функцией RtlSetProcessIsCritical и он завершился (все равно как), то винда также делать себе харакири (например, через bsod). По хорошему нужно вызвать RtlSetProcessIsCritical но с тремя нулями, что бы снять с себя этот флажок. UPD Вышеуказанная функция хочет прав админа. Иначе сделать процесс "критическим" нельзя. И это правильно. Если хочется именно бсода (я правда не понимаю, зачем оно нужно нормальному человеку), то можно написать свой драйвер, главной задачей которого будет вызвать его по желанию. Но если хочется бсод, что бы напугать пользователя, прав админа не хватает - можно использовать скринсейвер от MS - https://technet.microsoft.com/en-us/sysinternals/bluescreen.aspx

Отследить изменение свойств объекта

#c_sharp #wpf


Есть коллекция вида ObservableCollection Project {get;set;}. 

Задача в следующем: 

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

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

Существует ли какая-нибудь лаконичная альтернатива?
    


Ответы

Ответ 1



Альтернативой ручной реализации INotifyPropertyChanged будет либо использование сниппетов, либо использование специализированных инструментов для инъекции IL-кода в сборку при компиляции. Общепризнанным лидером в этой области является PostSharp, но он, естественно, платный. Тем не менее существует опенсурс проект для изменения сборок при компиляции под названием Fody, одно из дополнений которого позволяет делать как раз реализацию INF. Кстати, советую ознакомиться с полным списком дополнений для Fody на странице в GitHub, там много интересного. Также можно писать свои дополнения, схема разработки не очень дружелюбная, но зато есть множество примеров (все существующие дополнения также лежат на GitHub).

Ответ 2



Можете попробовать как-то так: Создаёте коллекцию, все элементы коллекции при таком подходе должны реализовывать INPC. ObservableCollection items = new ObservableCollection(); Вешаете обработчик на событие изменений в коллекции: items.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler( items_CollectionChanged); В делегате пробегаемся по старым/новым элементам и убираем/добавляем обработчики изменения свойств в объектах: static void items_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) { foreach (INotifyPropertyChanged item in e.OldItems) item.PropertyChanged -= new PropertyChangedEventHandler(item_PropertyChanged); foreach (INotifyPropertyChanged item in e.NewItems) item.PropertyChanged += new PropertyChangedEventHandler(item_PropertyChanged); } Собственно внутри этого метода напишите код уведомления: static void item_PropertyChanged(object sender, PropertyChangedEventArgs e) { throw new NotImplementedException(); } Ну и каждое свойство самого объекта, входящего в коллекцию должно быть связано с интерфейсом INPC. Для более ёмкой и читаемой реализации свойств внутри объекта воспользуйтесь сторонними библиотеками, например MVVM Light.

Скрыть panel если курсор за ее пределами

#c_sharp #net #winforms


Panel1 открывается по нажатию на button. Нужно чтобы panel1 скрылась когда курсор
выходит за ее границы.
    


Ответы

Ответ 1



У Panel есть событие MouseLeave. Его и используйте: private void panel1_MouseLeave(object sender, EventArgs e) { panel1.Visible = false; }

Не удается создать стек в теле класса

#cpp #классы #стек


Хочу создать стек с элементами класса Disk в классе Pole, но получаю ошибку: синтаксическая
ошибка: отсутствие ";" перед "<"

Pole.h

#pragma once
#include 
#include "Disk.h"


class Pole
{
private:
    char num;

    stack  pole; //здесь ошибка

public:
    Pole();

    ~Pole();

    void Number(int n);

    int Get_Number();

};

    


Ответы

Ответ 1



stack у вас указывает на ::stack. Не знаю, где конкретно он у вас определён, но похоже, что определён, и не имеет шаблонной формы(иначе была бы другая ошибка). Варианты решения: Указать namespace: std::stack Импортировать namespace полностью: using namespace std; Импортировать из namespace нужный символ: using std::stack;

Не могу задать правильное поведение hover

#html #css #html5 #css3 #hover


Всем привет.
Почти сделал рейтинг со звездами, как вдруг проблема с наведением по ним...
Вот код - https://jsfiddle.net/dokgkxza/

С левой стороны на правую нормально работает, но если наоборот вести курсор то будет подсвечиваться только первый элемент на который навел... Добавил z-index: 20; к спан ховер, а к обычному спан z-index: 30; ... но это далеко не идеал... Код дубль 2 - https://jsfiddle.net/dokgkxza/1/


Ответы

Ответ 1



Вот работающий пример (только вместо звездочек кружочки) .star-item span:hover ~ span label, .star-item span:hover label, .star-item span.checked label, .star-item span.checked ~ span label { background:#F90; color:#FFF; } Как сделать звездочки без картинок на чистом css А вобще как я понимаю это типовая задачка (даже в яндексе ее дают), есть смысл посмотреть готовое решение и его повторить, не изобретая свой велосипед.

Ответ 2



Еще раз всем привет))) Сделал я как нужно))) Большое спасибо Алексею Обухову, автору первого ответа. Вся фишка оказалась во float: right; для класса star-item и в селекторе ~. Вот код дубль 3 - https://jsfiddle.net/yhLrur49/ * { margin: 0; padding: 0; box-sizing: border-box; } .rating-new { position: relative; overflow: hidden; } .rating-new::after { content: ""; display: block; padding-bottom: 10%; } .rating-new > ul { background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgaWQ9InN2ZzgiCiAgIHZlcnNpb249IjEuMSIKICAgdmlld0JveD0iMCAwIDUyLjkxNjY2NyA1LjI5MTY2NjciCiAgIGhlaWdodD0iMjAiCiAgIHdpZHRoPSIyMDAiPgogIDxkZWZzCiAgICAgaWQ9ImRlZnMyIiAvPgogIDxtZXRhZGF0YQogICAgIGlkPSJtZXRhZGF0YTUiPgogICAgPHJkZjpSREY+CiAgICAgIDxjYzpXb3JrCiAgICAgICAgIHJkZjphYm91dD0iIj4KICAgICAgICA8ZGM6Zm9ybWF0PmltYWdlL3N2Zyt4bWw8L2RjOmZvcm1hdD4KICAgICAgICA8ZGM6dHlwZQogICAgICAgICAgIHJkZjpyZXNvdXJjZT0iaHR0cDovL3B1cmwub3JnL2RjL2RjbWl0eXBlL1N0aWxsSW1hZ2UiIC8+CiAgICAgICAgPGRjOnRpdGxlPjwvZGM6dGl0bGU+CiAgICAgIDwvY2M6V29yaz4KICAgIDwvcmRmOlJERj4KICA8L21ldGFkYXRhPgogIDxnCiAgICAgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwtMjkxLjcwODMyKSIKICAgICBpZD0ibGF5ZXIxIj4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0ic3Ryb2tlLXdpZHRoOjAuMTY3NDMyNzkiCiAgICAgICBkPSJtIDUuMTU5Mzc1LDI5My43Mjk2IC0xLjc4MjU2NDcsLTAuMjc5NDEgLTAuNzk3MTIzLC0xLjc0MTg3IC0wLjc5NzEyNCwxLjc0MTg3IEwgMCwyOTMuNzI5NiBsIDEuMjg5ODQyLDEuMzU1ODYgLTAuMzA0NTYxNSwxLjkxNDUzIDEuNTk0NDA2OCwtMC45MDM5OCAxLjU5NDQwODcsMC45MDM5OCAtMC4zMDQ1NjQ1LC0xLjkxNDUzIHogbSAtMi41Nzk2ODc3LDEuOTM2NzcgLTEuMTI1ODcyNSwwLjYzODI5IDAuMjE1MDgyOSwtMS4zNTIwMyAtMC45MTA5NTMyNCwtMC45NTc1MiAxLjI1ODg4NzY0LC0wLjE5NzE5IDAuNTYzMDE2NywtMS4yMzAxNCAwLjU2MzAxNjYsMS4yMzAxNCAxLjI1ODcyNjcsMC4xOTcxOSAtMC45MTA5NTE5LDAuOTU3NTIgMC4yMTUwODEsMS4zNTIwMyAtMS4xMjU4NzI0LC0wLjYzODI5IHoiCiAgICAgICBpZD0icGF0aDM3MDIiIC8+CiAgICA8cGF0aAogICAgICAgc3R5bGU9InN0cm9rZS13aWR0aDowLjE2NzQzMjc3IgogICAgICAgZD0ibSAxNS43NDI3MDgsMjkzLjcyOTYgLTEuNzgyNTY0LC0wLjI3OTQxIC0wLjc5NzEyMywtMS43NDE4NyAtMC43OTcxMjQsMS43NDE4NyAtMS43ODI1NjQsMC4yNzk0MSAxLjI4OTg0MiwxLjM1NTg2IC0wLjMwNDU2MSwxLjkxNDUzIDEuNTk0NDA3LC0wLjkwMzk4IDEuNTk0NDA5LDAuOTAzOTggLTAuMzA0NTY1LC0xLjkxNDUzIHogbSAtMi41Nzk2ODcsMS45MzY3NyAtMS4xMjU4NzMsMC42MzgyOSAwLjIxNTA4MywtMS4zNTIwMyAtMC45MTA5NTMsLTAuOTU3NTIgMS4yNTg4ODcsLTAuMTk3MTkgMC41NjMwMTcsLTEuMjMwMTQgMC41NjMwMTcsMS4yMzAxNCAxLjI1ODcyNiwwLjE5NzE5IC0wLjkxMDk1MSwwLjk1NzUyIDAuMjE1MDgxLDEuMzUyMDMgLTEuMTI1ODczLC0wLjYzODI5IHoiCiAgICAgICBpZD0icGF0aDM3MDItNiIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0ic3Ryb2tlLXdpZHRoOjAuMTY3NDMyNzciCiAgICAgICBkPSJtIDEwLjQ1MTA0MiwyOTMuNzI5NiAtMS43ODI1NjUxLC0wLjI3OTQxIC0wLjc5NzEyMjksLTEuNzQxODcgLTAuNzk3MTI0LDEuNzQxODcgLTEuNzgyNTYzMywwLjI3OTQxIDEuMjg5ODQyLDEuMzU1ODYgLTAuMzA0NTYxNSwxLjkxNDUzIDEuNTk0NDA2OCwtMC45MDM5OCAxLjU5NDQwODgsMC45MDM5OCAtMC4zMDQ1NjQ2LC0xLjkxNDUzIHogbSAtMi41Nzk2ODgsMS45MzY3NyAtMS4xMjU4NzI1LDAuNjM4MjkgMC4yMTUwODI5LC0xLjM1MjAzIC0wLjkxMDk1MzIsLTAuOTU3NTIgMS4yNTg4ODc2LC0wLjE5NzE5IDAuNTYzMDE2NywtMS4yMzAxNCAwLjU2MzAxNjUsMS4yMzAxNCAxLjI1ODcyNjcsMC4xOTcxOSAtMC45MTA5NTE3LDAuOTU3NTIgMC4yMTUwODA4LDEuMzUyMDMgLTEuMTI1ODcyMywtMC42MzgyOSB6IgogICAgICAgaWQ9InBhdGgzNzAyLTgiIC8+CiAgICA8cGF0aAogICAgICAgc3R5bGU9InN0cm9rZS13aWR0aDowLjE2NzQzMjc3IgogICAgICAgZD0ibSAyMS4wMzQzNzUsMjkzLjcyOTYgLTEuNzgyNTY1LC0wLjI3OTQxIC0wLjc5NzEyMywtMS43NDE4NyAtMC43OTcxMjQsMS43NDE4NyAtMS43ODI1NjMsMC4yNzk0MSAxLjI4OTg0MiwxLjM1NTg2IC0wLjMwNDU2MiwxLjkxNDUzIDEuNTk0NDA3LC0wLjkwMzk4IDEuNTk0NDA5LDAuOTAzOTggLTAuMzA0NTY1LC0xLjkxNDUzIHogbSAtMi41Nzk2ODgsMS45MzY3NyAtMS4xMjU4NzIsMC42MzgyOSAwLjIxNTA4MiwtMS4zNTIwMyAtMC45MTA5NTMsLTAuOTU3NTIgMS4yNTg4ODgsLTAuMTk3MTkgMC41NjMwMTcsLTEuMjMwMTQgMC41NjMwMTYsMS4yMzAxNCAxLjI1ODcyNywwLjE5NzE5IC0wLjkxMDk1MiwwLjk1NzUyIDAuMjE1MDgxLDEuMzUyMDMgLTEuMTI1ODcyLC0wLjYzODI5IHoiCiAgICAgICBpZD0icGF0aDM3MDItMiIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0ic3Ryb2tlLXdpZHRoOjAuMTY3NDMyNzciCiAgICAgICBkPSJtIDI2LjMyNjA0MiwyOTMuNzI5NiAtMS43ODI1NjUsLTAuMjc5NDEgLTAuNzk3MTIzLC0xLjc0MTg3IC0wLjc5NzEyNCwxLjc0MTg3IC0xLjc4MjU2MywwLjI3OTQxIDEuMjg5ODQyLDEuMzU1ODYgLTAuMzA0NTYyLDEuOTE0NTMgMS41OTQ0MDcsLTAuOTAzOTggMS41OTQ0MDksMC45MDM5OCAtMC4zMDQ1NjUsLTEuOTE0NTMgeiBtIC0yLjU3OTY4OCwxLjkzNjc3IC0xLjEyNTg3MywwLjYzODI5IDAuMjE1MDgzLC0xLjM1MjAzIC0wLjkxMDk1MywtMC45NTc1MiAxLjI1ODg4OCwtMC4xOTcxOSAwLjU2MzAxNiwtMS4yMzAxNCAwLjU2MzAxNywxLjIzMDE0IDEuMjU4NzI3LDAuMTk3MTkgLTAuOTEwOTUyLDAuOTU3NTIgMC4yMTUwODEsMS4zNTIwMyAtMS4xMjU4NzMsLTAuNjM4MjkgeiIKICAgICAgIGlkPSJwYXRoMzcwMi0zIiAvPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJzdHJva2Utd2lkdGg6MC4xNjc0MzI3NyIKICAgICAgIGQ9Im0gMzEuNjE3NzA5LDI5My43Mjk2IC0xLjc4MjU2NiwtMC4yNzk0MSAtMC43OTcxMjIsLTEuNzQxODcgLTAuNzk3MTI0LDEuNzQxODcgLTEuNzgyNTYzLDAuMjc5NDEgMS4yODk4NDIsMS4zNTU4NiAtMC4zMDQ1NjIsMS45MTQ1MyAxLjU5NDQwNywtMC45MDM5OCAxLjU5NDQwOCwwLjkwMzk4IC0wLjMwNDU2NSwtMS45MTQ1MyB6IG0gLTIuNTc5Njg4LDEuOTM2NzcgLTEuMTI1ODczLDAuNjM4MjkgMC4yMTUwODMsLTEuMzUyMDMgLTAuOTEwOTUzLC0wLjk1NzUyIDEuMjU4ODg4LC0wLjE5NzE5IDAuNTYzMDE2LC0xLjIzMDE0IDAuNTYzMDE3LDEuMjMwMTQgMS4yNTg3MjcsMC4xOTcxOSAtMC45MTA5NTMsMC45NTc1MiAwLjIxNTA4MiwxLjM1MjAzIC0xLjEyNTg3MywtMC42MzgyOSB6IgogICAgICAgaWQ9InBhdGgzNzAyLTUiIC8+CiAgICA8cGF0aAogICAgICAgc3R5bGU9InN0cm9rZS13aWR0aDowLjE2NzQzMjc3IgogICAgICAgZD0ibSAzNi45MDkzNzUsMjkzLjcyOTYgLTEuNzgyNTY1LC0wLjI3OTQxIC0wLjc5NzEyMywtMS43NDE4NyAtMC43OTcxMjQsMS43NDE4NyAtMS43ODI1NjMsMC4yNzk0MSAxLjI4OTg0MiwxLjM1NTg2IC0wLjMwNDU2MiwxLjkxNDUzIDEuNTk0NDA3LC0wLjkwMzk4IDEuNTk0NDA5LDAuOTAzOTggLTAuMzA0NTY1LC0xLjkxNDUzIHogbSAtMi41Nzk2ODgsMS45MzY3NyAtMS4xMjU4NzMsMC42MzgyOSAwLjIxNTA4MywtMS4zNTIwMyAtMC45MTA5NTMsLTAuOTU3NTIgMS4yNTg4ODgsLTAuMTk3MTkgMC41NjMwMTYsLTEuMjMwMTQgMC41NjMwMTcsMS4yMzAxNCAxLjI1ODcyNywwLjE5NzE5IC0wLjkxMDk1MiwwLjk1NzUyIDAuMjE1MDgxLDEuMzUyMDMgLTEuMTI1ODczLC0wLjYzODI5IHoiCiAgICAgICBpZD0icGF0aDM3MDItMzIiIC8+CiAgICA8cGF0aAogICAgICAgc3R5bGU9InN0cm9rZS13aWR0aDowLjE2NzQzMjc3IgogICAgICAgZD0ibSA0Mi4yMDEwNDIsMjkzLjcyOTYgLTEuNzgyNTY1LC0wLjI3OTQxIC0wLjc5NzEyMywtMS43NDE4NyAtMC43OTcxMjQsMS43NDE4NyAtMS43ODI1NjMsMC4yNzk0MSAxLjI4OTg0MiwxLjM1NTg2IC0wLjMwNDU2MiwxLjkxNDUzIDEuNTk0NDA3LC0wLjkwMzk4IDEuNTk0NDA5LDAuOTAzOTggLTAuMzA0NTY1LC0xLjkxNDUzIHogbSAtMi41Nzk2ODgsMS45MzY3NyAtMS4xMjU4NzMsMC42MzgyOSAwLjIxNTA4MywtMS4zNTIwMyAtMC45MTA5NTMsLTAuOTU3NTIgMS4yNTg4ODgsLTAuMTk3MTkgMC41NjMwMTYsLTEuMjMwMTQgMC41NjMwMTcsMS4yMzAxNCAxLjI1ODcyNywwLjE5NzE5IC0wLjkxMDk1MiwwLjk1NzUyIDAuMjE1MDgxLDEuMzUyMDMgLTEuMTI1ODczLC0wLjYzODI5IHoiCiAgICAgICBpZD0icGF0aDM3MDItNyIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0ic3Ryb2tlLXdpZHRoOjAuMTY3NDMyNzciCiAgICAgICBkPSJtIDQ3LjQ5MjcwOSwyOTMuNzI5NiAtMS43ODI1NjUsLTAuMjc5NDEgLTAuNzk3MTIzLC0xLjc0MTg3IC0wLjc5NzEyNCwxLjc0MTg3IC0xLjc4MjU2MywwLjI3OTQxIDEuMjg5ODQyLDEuMzU1ODYgLTAuMzA0NTYyLDEuOTE0NTMgMS41OTQ0MDcsLTAuOTAzOTggMS41OTQ0MDksMC45MDM5OCAtMC4zMDQ1NjUsLTEuOTE0NTMgeiBtIC0yLjU3OTY4OCwxLjkzNjc3IC0xLjEyNTg3MiwwLjYzODI5IDAuMjE1MDgzLC0xLjM1MjAzIC0wLjkxMDk1NCwtMC45NTc1MiAxLjI1ODg4OCwtMC4xOTcxOSAwLjU2MzAxNywtMS4yMzAxNCAwLjU2MzAxNiwxLjIzMDE0IDEuMjU4NzI3LDAuMTk3MTkgLTAuOTEwOTUyLDAuOTU3NTIgMC4yMTUwODEsMS4zNTIwMyAtMS4xMjU4NzIsLTAuNjM4MjkgeiIKICAgICAgIGlkPSJwYXRoMzcwMi0xIiAvPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJzdHJva2Utd2lkdGg6MC4xNjk1NjU3NSIKICAgICAgIGQ9Im0gNTIuOTE2NjY3LDI5My43Mjk2IC0xLjgyODI3MiwtMC4yNzk0MSAtMC44MTc1NjIsLTEuNzQxODcgLTAuODE3NTYzLDEuNzQxODcgLTEuODI4MjcsMC4yNzk0MSAxLjMyMjkxNSwxLjM1NTg2IC0wLjMxMjM3MSwxLjkxNDUzIDEuNjM1Mjg5LC0wLjkwMzk4IDEuNjM1MjkxLDAuOTAzOTggLTAuMzEyMzc0LC0xLjkxNDUzIHogbSAtMi42NDU4MzQsMS45MzY3NyAtMS4xNTQ3NDEsMC42MzgyOSAwLjIyMDU5NywtMS4zNTIwMyAtMC45MzQzMTEsLTAuOTU3NTIgMS4yOTExNjgsLTAuMTk3MTkgMC41Nzc0NTMsLTEuMjMwMTQgMC41Nzc0NTIsMS4yMzAxNCAxLjI5MTAwMiwwLjE5NzE5IC0wLjkzNDMwOSwwLjk1NzUyIDAuMjIwNTk2LDEuMzUyMDMgLTEuMTU0NzQxLC0wLjYzODI5IHoiCiAgICAgICBpZD0icGF0aDM3MDItMCIgLz4KICA8L2c+Cjwvc3ZnPg=='); background-repeat: no-repeat; background-size: cover; position: absolute; z-index: 1; width: 100%; height: 100%; list-style: none; } .rating-new > ul > li:first-child { background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgaWQ9InN2ZzgiCiAgIHZlcnNpb249IjEuMSIKICAgdmlld0JveD0iMCAwIDUyLjkxNjY2NSA1LjI5MTY2NjgiCiAgIGhlaWdodD0iMjAiCiAgIHdpZHRoPSIyMDAiPgogIDxkZWZzCiAgICAgaWQ9ImRlZnMyIiAvPgogIDxtZXRhZGF0YQogICAgIGlkPSJtZXRhZGF0YTUiPgogICAgPHJkZjpSREY+CiAgICAgIDxjYzpXb3JrCiAgICAgICAgIHJkZjphYm91dD0iIj4KICAgICAgICA8ZGM6Zm9ybWF0PmltYWdlL3N2Zyt4bWw8L2RjOmZvcm1hdD4KICAgICAgICA8ZGM6dHlwZQogICAgICAgICAgIHJkZjpyZXNvdXJjZT0iaHR0cDovL3B1cmwub3JnL2RjL2RjbWl0eXBlL1N0aWxsSW1hZ2UiIC8+CiAgICAgICAgPGRjOnRpdGxlPjwvZGM6dGl0bGU+CiAgICAgIDwvY2M6V29yaz4KICAgIDwvcmRmOlJERj4KICA8L21ldGFkYXRhPgogIDxnCiAgICAgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwtMjkxLjcwODMyKSIKICAgICBpZD0ibGF5ZXIxIj4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0ic3Ryb2tlLXdpZHRoOjAuMTY3NDMyNjg7ZmlsbDojMDA2MmI1O2ZpbGwtb3BhY2l0eToxIgogICAgICAgZD0iTSA1LjE1OTM3NSwyOTMuNzI5NiAzLjM3NjgxMDksMjkzLjQ1MDE4IDIuNTc5Njg3NSwyOTEuNzA4MzIgMS43ODI1NjQsMjkzLjQ1MDE4IDAsMjkzLjcyOTYgbCAxLjI4OTg0MzgsMS4zNTU4NiAtMC4zMDQ1NjQ0MywxLjkxNDUzIDEuNTk0NDA4MTMsLTAuOTAzOTcgMS41OTQ0MDgxLDAuOTAzOTcgLTAuMzA0NTY0MywtMS45MTQ1MyB6IgogICAgICAgaWQ9InBhdGgxMiIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojMDA2MmI1O2ZpbGwtb3BhY2l0eToxO3N0cm9rZS13aWR0aDowLjE2NzQzMjY4IgogICAgICAgZD0ibSAxMC40NTEwNDEsMjkzLjcyOTYgLTEuNzgyNTYzOCwtMC4yNzk0MiAtMC43OTcxMjMsLTEuNzQxODYgLTAuNzk3MTIzNiwxLjc0MTg2IC0xLjc4MjU2NCwwLjI3OTQyIDEuMjg5ODQzOCwxLjM1NTg2IC0wLjMwNDU2NDQsMS45MTQ1MyAxLjU5NDQwODIsLTAuOTAzOTcgMS41OTQ0MDgsMC45MDM5NyAtMC4zMDQ1NjQsLTEuOTE0NTMgeiIKICAgICAgIGlkPSJwYXRoMTItOCIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojMDA2MmI1O2ZpbGwtb3BhY2l0eToxO3N0cm9rZS13aWR0aDowLjE2NzQzMjY4IgogICAgICAgZD0ibSAxNS43NDI3MDgsMjkzLjcyOTYgLTEuNzgyNTY1LC0wLjI3OTQyIC0wLjc5NzEyMywtMS43NDE4NiAtMC43OTcxMjMsMS43NDE4NiAtMS43ODI1NjQsMC4yNzk0MiAxLjI4OTg0MywxLjM1NTg2IC0wLjMwNDU2NCwxLjkxNDUzIDEuNTk0NDA4LC0wLjkwMzk3IDEuNTk0NDA4LDAuOTAzOTcgLTAuMzA0NTY0LC0xLjkxNDUzIHoiCiAgICAgICBpZD0icGF0aDEyLTQiIC8+CiAgICA8cGF0aAogICAgICAgc3R5bGU9ImZpbGw6IzAwNjJiNTtmaWxsLW9wYWNpdHk6MTtzdHJva2Utd2lkdGg6MC4xNjc0MzI2OCIKICAgICAgIGQ9Im0gMjEuMDM0Mzc1LDI5My43Mjk2IC0xLjc4MjU2NSwtMC4yNzk0MiAtMC43OTcxMjMsLTEuNzQxODYgLTAuNzk3MTIzLDEuNzQxODYgLTEuNzgyNTY0LDAuMjc5NDIgMS4yODk4NDMsMS4zNTU4NiAtMC4zMDQ1NjQsMS45MTQ1MyAxLjU5NDQwOCwtMC45MDM5NyAxLjU5NDQwOCwwLjkwMzk3IC0wLjMwNDU2NCwtMS45MTQ1MyB6IgogICAgICAgaWQ9InBhdGgxMi0wIiAvPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiMwMDYyYjU7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlLXdpZHRoOjAuMTY3NDMyNjgiCiAgICAgICBkPSJtIDI2LjMyNjA0MiwyOTMuNzI5NiAtMS43ODI1NjQsLTAuMjc5NDIgLTAuNzk3MTIzLC0xLjc0MTg2IC0wLjc5NzEyNCwxLjc0MTg2IC0xLjc4MjU2NCwwLjI3OTQyIDEuMjg5ODQ0LDEuMzU1ODYgLTAuMzA0NTY1LDEuOTE0NTMgMS41OTQ0MDksLTAuOTAzOTcgMS41OTQ0MDgsMC45MDM5NyAtMC4zMDQ1NjUsLTEuOTE0NTMgeiIKICAgICAgIGlkPSJwYXRoMTItNiIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojMDA2MmI1O2ZpbGwtb3BhY2l0eToxO3N0cm9rZS13aWR0aDowLjE2NzQzMjY4IgogICAgICAgZD0ibSAzMS42MTc3MDgsMjkzLjcyOTYgLTEuNzgyNTY0LC0wLjI3OTQyIC0wLjc5NzEyMywtMS43NDE4NiAtMC43OTcxMjQsMS43NDE4NiAtMS43ODI1NjQsMC4yNzk0MiAxLjI4OTg0NCwxLjM1NTg2IC0wLjMwNDU2NCwxLjkxNDUzIDEuNTk0NDA4LC0wLjkwMzk3IDEuNTk0NDA4LDAuOTAzOTcgLTAuMzA0NTY1LC0xLjkxNDUzIHoiCiAgICAgICBpZD0icGF0aDEyLTciIC8+CiAgICA8cGF0aAogICAgICAgc3R5bGU9ImZpbGw6IzAwNjJiNTtmaWxsLW9wYWNpdHk6MTtzdHJva2Utd2lkdGg6MC4xNjc0MzI2OCIKICAgICAgIGQ9Im0gMzYuOTA5Mzc1LDI5My43Mjk2IC0xLjc4MjU2NSwtMC4yNzk0MiAtMC43OTcxMjMsLTEuNzQxODYgLTAuNzk3MTIzLDEuNzQxODYgLTEuNzgyNTY0LDAuMjc5NDIgMS4yODk4NDMsMS4zNTU4NiAtMC4zMDQ1NjQsMS45MTQ1MyAxLjU5NDQwOCwtMC45MDM5NyAxLjU5NDQwOCwwLjkwMzk3IC0wLjMwNDU2NCwtMS45MTQ1MyB6IgogICAgICAgaWQ9InBhdGgxMi01IiAvPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiMwMDYyYjU7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlLXdpZHRoOjAuMTY3NDMyNjgiCiAgICAgICBkPSJtIDQyLjIwMTA0MiwyOTMuNzI5NiAtMS43ODI1NjQsLTAuMjc5NDIgLTAuNzk3MTIzLC0xLjc0MTg2IC0wLjc5NzEyNCwxLjc0MTg2IC0xLjc4MjU2NCwwLjI3OTQyIDEuMjg5ODQ0LDEuMzU1ODYgLTAuMzA0NTY0LDEuOTE0NTMgMS41OTQ0MDgsLTAuOTAzOTcgMS41OTQ0MDgsMC45MDM5NyAtMC4zMDQ1NjQsLTEuOTE0NTMgeiIKICAgICAgIGlkPSJwYXRoMTItNjIiIC8+CiAgICA8cGF0aAogICAgICAgc3R5bGU9ImZpbGw6IzAwNjJiNTtmaWxsLW9wYWNpdHk6MTtzdHJva2Utd2lkdGg6MC4xNjc0MzI2OCIKICAgICAgIGQ9Im0gNDcuNDkyNzA4LDI5My43Mjk2IC0xLjc4MjU2NCwtMC4yNzk0MiAtMC43OTcxMjQsLTEuNzQxODYgLTAuNzk3MTIzLDEuNzQxODYgLTEuNzgyNTY0LDAuMjc5NDIgMS4yODk4NDQsMS4zNTU4NiAtMC4zMDQ1NjUsMS45MTQ1MyAxLjU5NDQwOCwtMC45MDM5NyAxLjU5NDQwOSwwLjkwMzk3IC0wLjMwNDU2NSwtMS45MTQ1MyB6IgogICAgICAgaWQ9InBhdGgxMi00NiIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojMDA2MmI1O2ZpbGwtb3BhY2l0eToxO3N0cm9rZS13aWR0aDowLjE2OTU2NTY2IgogICAgICAgZD0ibSA1Mi45MTY2NjcsMjkzLjcyOTYgLTEuODI4MjcyLC0wLjI3OTQyIC0wLjgxNzU2MiwtMS43NDE4NiAtMC44MTc1NjIsMS43NDE4NiAtMS44MjgyNzEsMC4yNzk0MiAxLjMyMjkxNiwxLjM1NTg2IC0wLjMxMjM3MywxLjkxNDUzIDEuNjM1MjksLTAuOTAzOTcgMS42MzUyOSwwLjkwMzk3IC0wLjMxMjM3MywtMS45MTQ1MyB6IgogICAgICAgaWQ9InBhdGgxMi02NyIgLz4KICA8L2c+Cjwvc3ZnPg=='); background-repeat: no-repeat; background-size: cover; position: absolute; z-index: 2; height: 100%; } .star-item { float: right; display: block; width: 10%; height: 100%; } .star-item > span { display: block; width: 10%; height: 100%; position: absolute; z-index: 20; cursor: pointer; } .star-item > span:hover { background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgaWQ9InN2ZzgiCiAgIHZlcnNpb249IjEuMSIKICAgdmlld0JveD0iMCAwIDUyLjkxNjY2NSA1LjI5MTY2NjgiCiAgIGhlaWdodD0iMjAiCiAgIHdpZHRoPSIyMDAiPgogIDxkZWZzCiAgICAgaWQ9ImRlZnMyIiAvPgogIDxtZXRhZGF0YQogICAgIGlkPSJtZXRhZGF0YTUiPgogICAgPHJkZjpSREY+CiAgICAgIDxjYzpXb3JrCiAgICAgICAgIHJkZjphYm91dD0iIj4KICAgICAgICA8ZGM6Zm9ybWF0PmltYWdlL3N2Zyt4bWw8L2RjOmZvcm1hdD4KICAgICAgICA8ZGM6dHlwZQogICAgICAgICAgIHJkZjpyZXNvdXJjZT0iaHR0cDovL3B1cmwub3JnL2RjL2RjbWl0eXBlL1N0aWxsSW1hZ2UiIC8+CiAgICAgICAgPGRjOnRpdGxlPjwvZGM6dGl0bGU+CiAgICAgIDwvY2M6V29yaz4KICAgIDwvcmRmOlJERj4KICA8L21ldGFkYXRhPgogIDxnCiAgICAgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwtMjkxLjcwODMyKSIKICAgICBpZD0ibGF5ZXIxIj4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0ic3Ryb2tlLXdpZHRoOjAuMTY3NDMyNjg7ZmlsbDojZmYwMDAwO2ZpbGwtb3BhY2l0eToxIgogICAgICAgZD0iTSA1LjE1OTM3NSwyOTMuNzI5NiAzLjM3NjgxMDksMjkzLjQ1MDE4IDIuNTc5Njg3NSwyOTEuNzA4MzIgMS43ODI1NjQsMjkzLjQ1MDE4IDAsMjkzLjcyOTYgbCAxLjI4OTg0MzgsMS4zNTU4NiAtMC4zMDQ1NjQ0MywxLjkxNDUzIDEuNTk0NDA4MTMsLTAuOTAzOTcgMS41OTQ0MDgxLDAuOTAzOTcgLTAuMzA0NTY0MywtMS45MTQ1MyB6IgogICAgICAgaWQ9InBhdGgxMiIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmYwMDAwO2ZpbGwtb3BhY2l0eToxO3N0cm9rZS13aWR0aDowLjE2NzQzMjY4IgogICAgICAgZD0ibSAxMC40NTEwNDEsMjkzLjcyOTYgLTEuNzgyNTYzOCwtMC4yNzk0MiAtMC43OTcxMjMsLTEuNzQxODYgLTAuNzk3MTIzNiwxLjc0MTg2IC0xLjc4MjU2NCwwLjI3OTQyIDEuMjg5ODQzOCwxLjM1NTg2IC0wLjMwNDU2NDQsMS45MTQ1MyAxLjU5NDQwODIsLTAuOTAzOTcgMS41OTQ0MDgsMC45MDM5NyAtMC4zMDQ1NjQsLTEuOTE0NTMgeiIKICAgICAgIGlkPSJwYXRoMTItOCIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmYwMDAwO2ZpbGwtb3BhY2l0eToxO3N0cm9rZS13aWR0aDowLjE2NzQzMjY4IgogICAgICAgZD0ibSAxNS43NDI3MDgsMjkzLjcyOTYgLTEuNzgyNTY1LC0wLjI3OTQyIC0wLjc5NzEyMywtMS43NDE4NiAtMC43OTcxMjMsMS43NDE4NiAtMS43ODI1NjQsMC4yNzk0MiAxLjI4OTg0MywxLjM1NTg2IC0wLjMwNDU2NCwxLjkxNDUzIDEuNTk0NDA4LC0wLjkwMzk3IDEuNTk0NDA4LDAuOTAzOTcgLTAuMzA0NTY0LC0xLjkxNDUzIHoiCiAgICAgICBpZD0icGF0aDEyLTQiIC8+CiAgICA8cGF0aAogICAgICAgc3R5bGU9ImZpbGw6I2ZmMDAwMDtmaWxsLW9wYWNpdHk6MTtzdHJva2Utd2lkdGg6MC4xNjc0MzI2OCIKICAgICAgIGQ9Im0gMjEuMDM0Mzc1LDI5My43Mjk2IC0xLjc4MjU2NSwtMC4yNzk0MiAtMC43OTcxMjMsLTEuNzQxODYgLTAuNzk3MTIzLDEuNzQxODYgLTEuNzgyNTY0LDAuMjc5NDIgMS4yODk4NDMsMS4zNTU4NiAtMC4zMDQ1NjQsMS45MTQ1MyAxLjU5NDQwOCwtMC45MDM5NyAxLjU5NDQwOCwwLjkwMzk3IC0wLjMwNDU2NCwtMS45MTQ1MyB6IgogICAgICAgaWQ9InBhdGgxMi0wIiAvPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNmZjAwMDA7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlLXdpZHRoOjAuMTY3NDMyNjgiCiAgICAgICBkPSJtIDI2LjMyNjA0MiwyOTMuNzI5NiAtMS43ODI1NjQsLTAuMjc5NDIgLTAuNzk3MTIzLC0xLjc0MTg2IC0wLjc5NzEyNCwxLjc0MTg2IC0xLjc4MjU2NCwwLjI3OTQyIDEuMjg5ODQ0LDEuMzU1ODYgLTAuMzA0NTY1LDEuOTE0NTMgMS41OTQ0MDksLTAuOTAzOTcgMS41OTQ0MDgsMC45MDM5NyAtMC4zMDQ1NjUsLTEuOTE0NTMgeiIKICAgICAgIGlkPSJwYXRoMTItNiIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmYwMDAwO2ZpbGwtb3BhY2l0eToxO3N0cm9rZS13aWR0aDowLjE2NzQzMjY4IgogICAgICAgZD0ibSAzMS42MTc3MDgsMjkzLjcyOTYgLTEuNzgyNTY0LC0wLjI3OTQyIC0wLjc5NzEyMywtMS43NDE4NiAtMC43OTcxMjQsMS43NDE4NiAtMS43ODI1NjQsMC4yNzk0MiAxLjI4OTg0NCwxLjM1NTg2IC0wLjMwNDU2NCwxLjkxNDUzIDEuNTk0NDA4LC0wLjkwMzk3IDEuNTk0NDA4LDAuOTAzOTcgLTAuMzA0NTY1LC0xLjkxNDUzIHoiCiAgICAgICBpZD0icGF0aDEyLTciIC8+CiAgICA8cGF0aAogICAgICAgc3R5bGU9ImZpbGw6I2ZmMDAwMDtmaWxsLW9wYWNpdHk6MTtzdHJva2Utd2lkdGg6MC4xNjc0MzI2OCIKICAgICAgIGQ9Im0gMzYuOTA5Mzc1LDI5My43Mjk2IC0xLjc4MjU2NSwtMC4yNzk0MiAtMC43OTcxMjMsLTEuNzQxODYgLTAuNzk3MTIzLDEuNzQxODYgLTEuNzgyNTY0LDAuMjc5NDIgMS4yODk4NDMsMS4zNTU4NiAtMC4zMDQ1NjQsMS45MTQ1MyAxLjU5NDQwOCwtMC45MDM5NyAxLjU5NDQwOCwwLjkwMzk3IC0wLjMwNDU2NCwtMS45MTQ1MyB6IgogICAgICAgaWQ9InBhdGgxMi01IiAvPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNmZjAwMDA7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlLXdpZHRoOjAuMTY3NDMyNjgiCiAgICAgICBkPSJtIDQyLjIwMTA0MiwyOTMuNzI5NiAtMS43ODI1NjQsLTAuMjc5NDIgLTAuNzk3MTIzLC0xLjc0MTg2IC0wLjc5NzEyNCwxLjc0MTg2IC0xLjc4MjU2NCwwLjI3OTQyIDEuMjg5ODQ0LDEuMzU1ODYgLTAuMzA0NTY0LDEuOTE0NTMgMS41OTQ0MDgsLTAuOTAzOTcgMS41OTQ0MDgsMC45MDM5NyAtMC4zMDQ1NjQsLTEuOTE0NTMgeiIKICAgICAgIGlkPSJwYXRoMTItNjIiIC8+CiAgICA8cGF0aAogICAgICAgc3R5bGU9ImZpbGw6I2ZmMDAwMDtmaWxsLW9wYWNpdHk6MTtzdHJva2Utd2lkdGg6MC4xNjc0MzI2OCIKICAgICAgIGQ9Im0gNDcuNDkyNzA4LDI5My43Mjk2IC0xLjc4MjU2NCwtMC4yNzk0MiAtMC43OTcxMjQsLTEuNzQxODYgLTAuNzk3MTIzLDEuNzQxODYgLTEuNzgyNTY0LDAuMjc5NDIgMS4yODk4NDQsMS4zNTU4NiAtMC4zMDQ1NjUsMS45MTQ1MyAxLjU5NDQwOCwtMC45MDM5NyAxLjU5NDQwOSwwLjkwMzk3IC0wLjMwNDU2NSwtMS45MTQ1MyB6IgogICAgICAgaWQ9InBhdGgxMi00NiIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmYwMDAwO2ZpbGwtb3BhY2l0eToxO3N0cm9rZS13aWR0aDowLjE2OTU2NTY2IgogICAgICAgZD0ibSA1Mi45MTY2NjcsMjkzLjcyOTYgLTEuODI4MjcyLC0wLjI3OTQyIC0wLjgxNzU2MiwtMS43NDE4NiAtMC44MTc1NjIsMS43NDE4NiAtMS44MjgyNzEsMC4yNzk0MiAxLjMyMjkxNiwxLjM1NTg2IC0wLjMxMjM3MywxLjkxNDUzIDEuNjM1MjksLTAuOTAzOTcgMS42MzUyOSwwLjkwMzk3IC0wLjMxMjM3MywtMS45MTQ1MyB6IgogICAgICAgaWQ9InBhdGgxMi02NyIgLz4KICA8L2c+Cjwvc3ZnPg=='); background-repeat: no-repeat; background-size: cover; } .star-item:hover ~ .star-item > span { background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgaWQ9InN2ZzgiCiAgIHZlcnNpb249IjEuMSIKICAgdmlld0JveD0iMCAwIDUyLjkxNjY2NSA1LjI5MTY2NjgiCiAgIGhlaWdodD0iMjAiCiAgIHdpZHRoPSIyMDAiPgogIDxkZWZzCiAgICAgaWQ9ImRlZnMyIiAvPgogIDxtZXRhZGF0YQogICAgIGlkPSJtZXRhZGF0YTUiPgogICAgPHJkZjpSREY+CiAgICAgIDxjYzpXb3JrCiAgICAgICAgIHJkZjphYm91dD0iIj4KICAgICAgICA8ZGM6Zm9ybWF0PmltYWdlL3N2Zyt4bWw8L2RjOmZvcm1hdD4KICAgICAgICA8ZGM6dHlwZQogICAgICAgICAgIHJkZjpyZXNvdXJjZT0iaHR0cDovL3B1cmwub3JnL2RjL2RjbWl0eXBlL1N0aWxsSW1hZ2UiIC8+CiAgICAgICAgPGRjOnRpdGxlPjwvZGM6dGl0bGU+CiAgICAgIDwvY2M6V29yaz4KICAgIDwvcmRmOlJERj4KICA8L21ldGFkYXRhPgogIDxnCiAgICAgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwtMjkxLjcwODMyKSIKICAgICBpZD0ibGF5ZXIxIj4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0ic3Ryb2tlLXdpZHRoOjAuMTY3NDMyNjg7ZmlsbDojZmYwMDAwO2ZpbGwtb3BhY2l0eToxIgogICAgICAgZD0iTSA1LjE1OTM3NSwyOTMuNzI5NiAzLjM3NjgxMDksMjkzLjQ1MDE4IDIuNTc5Njg3NSwyOTEuNzA4MzIgMS43ODI1NjQsMjkzLjQ1MDE4IDAsMjkzLjcyOTYgbCAxLjI4OTg0MzgsMS4zNTU4NiAtMC4zMDQ1NjQ0MywxLjkxNDUzIDEuNTk0NDA4MTMsLTAuOTAzOTcgMS41OTQ0MDgxLDAuOTAzOTcgLTAuMzA0NTY0MywtMS45MTQ1MyB6IgogICAgICAgaWQ9InBhdGgxMiIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmYwMDAwO2ZpbGwtb3BhY2l0eToxO3N0cm9rZS13aWR0aDowLjE2NzQzMjY4IgogICAgICAgZD0ibSAxMC40NTEwNDEsMjkzLjcyOTYgLTEuNzgyNTYzOCwtMC4yNzk0MiAtMC43OTcxMjMsLTEuNzQxODYgLTAuNzk3MTIzNiwxLjc0MTg2IC0xLjc4MjU2NCwwLjI3OTQyIDEuMjg5ODQzOCwxLjM1NTg2IC0wLjMwNDU2NDQsMS45MTQ1MyAxLjU5NDQwODIsLTAuOTAzOTcgMS41OTQ0MDgsMC45MDM5NyAtMC4zMDQ1NjQsLTEuOTE0NTMgeiIKICAgICAgIGlkPSJwYXRoMTItOCIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmYwMDAwO2ZpbGwtb3BhY2l0eToxO3N0cm9rZS13aWR0aDowLjE2NzQzMjY4IgogICAgICAgZD0ibSAxNS43NDI3MDgsMjkzLjcyOTYgLTEuNzgyNTY1LC0wLjI3OTQyIC0wLjc5NzEyMywtMS43NDE4NiAtMC43OTcxMjMsMS43NDE4NiAtMS43ODI1NjQsMC4yNzk0MiAxLjI4OTg0MywxLjM1NTg2IC0wLjMwNDU2NCwxLjkxNDUzIDEuNTk0NDA4LC0wLjkwMzk3IDEuNTk0NDA4LDAuOTAzOTcgLTAuMzA0NTY0LC0xLjkxNDUzIHoiCiAgICAgICBpZD0icGF0aDEyLTQiIC8+CiAgICA8cGF0aAogICAgICAgc3R5bGU9ImZpbGw6I2ZmMDAwMDtmaWxsLW9wYWNpdHk6MTtzdHJva2Utd2lkdGg6MC4xNjc0MzI2OCIKICAgICAgIGQ9Im0gMjEuMDM0Mzc1LDI5My43Mjk2IC0xLjc4MjU2NSwtMC4yNzk0MiAtMC43OTcxMjMsLTEuNzQxODYgLTAuNzk3MTIzLDEuNzQxODYgLTEuNzgyNTY0LDAuMjc5NDIgMS4yODk4NDMsMS4zNTU4NiAtMC4zMDQ1NjQsMS45MTQ1MyAxLjU5NDQwOCwtMC45MDM5NyAxLjU5NDQwOCwwLjkwMzk3IC0wLjMwNDU2NCwtMS45MTQ1MyB6IgogICAgICAgaWQ9InBhdGgxMi0wIiAvPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNmZjAwMDA7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlLXdpZHRoOjAuMTY3NDMyNjgiCiAgICAgICBkPSJtIDI2LjMyNjA0MiwyOTMuNzI5NiAtMS43ODI1NjQsLTAuMjc5NDIgLTAuNzk3MTIzLC0xLjc0MTg2IC0wLjc5NzEyNCwxLjc0MTg2IC0xLjc4MjU2NCwwLjI3OTQyIDEuMjg5ODQ0LDEuMzU1ODYgLTAuMzA0NTY1LDEuOTE0NTMgMS41OTQ0MDksLTAuOTAzOTcgMS41OTQ0MDgsMC45MDM5NyAtMC4zMDQ1NjUsLTEuOTE0NTMgeiIKICAgICAgIGlkPSJwYXRoMTItNiIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmYwMDAwO2ZpbGwtb3BhY2l0eToxO3N0cm9rZS13aWR0aDowLjE2NzQzMjY4IgogICAgICAgZD0ibSAzMS42MTc3MDgsMjkzLjcyOTYgLTEuNzgyNTY0LC0wLjI3OTQyIC0wLjc5NzEyMywtMS43NDE4NiAtMC43OTcxMjQsMS43NDE4NiAtMS43ODI1NjQsMC4yNzk0MiAxLjI4OTg0NCwxLjM1NTg2IC0wLjMwNDU2NCwxLjkxNDUzIDEuNTk0NDA4LC0wLjkwMzk3IDEuNTk0NDA4LDAuOTAzOTcgLTAuMzA0NTY1LC0xLjkxNDUzIHoiCiAgICAgICBpZD0icGF0aDEyLTciIC8+CiAgICA8cGF0aAogICAgICAgc3R5bGU9ImZpbGw6I2ZmMDAwMDtmaWxsLW9wYWNpdHk6MTtzdHJva2Utd2lkdGg6MC4xNjc0MzI2OCIKICAgICAgIGQ9Im0gMzYuOTA5Mzc1LDI5My43Mjk2IC0xLjc4MjU2NSwtMC4yNzk0MiAtMC43OTcxMjMsLTEuNzQxODYgLTAuNzk3MTIzLDEuNzQxODYgLTEuNzgyNTY0LDAuMjc5NDIgMS4yODk4NDMsMS4zNTU4NiAtMC4zMDQ1NjQsMS45MTQ1MyAxLjU5NDQwOCwtMC45MDM5NyAxLjU5NDQwOCwwLjkwMzk3IC0wLjMwNDU2NCwtMS45MTQ1MyB6IgogICAgICAgaWQ9InBhdGgxMi01IiAvPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNmZjAwMDA7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlLXdpZHRoOjAuMTY3NDMyNjgiCiAgICAgICBkPSJtIDQyLjIwMTA0MiwyOTMuNzI5NiAtMS43ODI1NjQsLTAuMjc5NDIgLTAuNzk3MTIzLC0xLjc0MTg2IC0wLjc5NzEyNCwxLjc0MTg2IC0xLjc4MjU2NCwwLjI3OTQyIDEuMjg5ODQ0LDEuMzU1ODYgLTAuMzA0NTY0LDEuOTE0NTMgMS41OTQ0MDgsLTAuOTAzOTcgMS41OTQ0MDgsMC45MDM5NyAtMC4zMDQ1NjQsLTEuOTE0NTMgeiIKICAgICAgIGlkPSJwYXRoMTItNjIiIC8+CiAgICA8cGF0aAogICAgICAgc3R5bGU9ImZpbGw6I2ZmMDAwMDtmaWxsLW9wYWNpdHk6MTtzdHJva2Utd2lkdGg6MC4xNjc0MzI2OCIKICAgICAgIGQ9Im0gNDcuNDkyNzA4LDI5My43Mjk2IC0xLjc4MjU2NCwtMC4yNzk0MiAtMC43OTcxMjQsLTEuNzQxODYgLTAuNzk3MTIzLDEuNzQxODYgLTEuNzgyNTY0LDAuMjc5NDIgMS4yODk4NDQsMS4zNTU4NiAtMC4zMDQ1NjUsMS45MTQ1MyAxLjU5NDQwOCwtMC45MDM5NyAxLjU5NDQwOSwwLjkwMzk3IC0wLjMwNDU2NSwtMS45MTQ1MyB6IgogICAgICAgaWQ9InBhdGgxMi00NiIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmYwMDAwO2ZpbGwtb3BhY2l0eToxO3N0cm9rZS13aWR0aDowLjE2OTU2NTY2IgogICAgICAgZD0ibSA1Mi45MTY2NjcsMjkzLjcyOTYgLTEuODI4MjcyLC0wLjI3OTQyIC0wLjgxNzU2MiwtMS43NDE4NiAtMC44MTc1NjIsMS43NDE4NiAtMS44MjgyNzEsMC4yNzk0MiAxLjMyMjkxNiwxLjM1NTg2IC0wLjMxMjM3MywxLjkxNDUzIDEuNjM1MjksLTAuOTAzOTcgMS42MzUyOSwwLjkwMzk3IC0wLjMxMjM3MywtMS45MTQ1MyB6IgogICAgICAgaWQ9InBhdGgxMi02NyIgLz4KICA8L2c+Cjwvc3ZnPg=='); background-repeat: no-repeat; background-size: cover }
Еще раз спасибо)))

Как создать прозрачный градиент маски с использованием фильтра SVG

#html #css #html5 #css3 #svg


В настоящее время я использую градиент SVG, чтобы применить эффект fade-out для патчей.
Это позволяет начать путь с непрозрачностью 100% в точке x0 и постепенно уменьшать
непрозрачность до 0% в точке x1, где бы они не находились для конкретного пути,  к
которому  применяется градиент:   


    
    
       


Это прекрасно работает при применении к стилю обводки контура:  

    


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

Я бы хотел, чтобы стиль обводки был выполнен с использованием любого цвета, который
я назначу, а затем применить градиент к непрозрачности обводки или применить фильтр
SVG для создания эффекта fade-out.    

Я попытался использовать фильтры SVG - feComponentTransfer с feFuncA, но не смог
получить то, что сработало бы.  

Цвет обводки необходимо отдельно рассчитывать для каждого пути. Таким образом, решение
установить цвет в градиенте не будет масштабироваться.   

Перевод ответа: How to create a transparency gradient mask using an SVG filter @drarmstr 
    


Ответы

Ответ 1



Должен ли он быть градиентом или фильтром? Я бы предложил использовать , который содержит прямоугольник с примененным градиентом, но я не уверен правильно ли я понял ваши требования. Instant Web 2.0 Смотрите аналогичный пример Перевод ответа: How to create a transparency gradient mask using an SVG filter @Erik Dahlström

Ответ 2



Пример анимации SVG Код взят из примера ниже. Добавлены последовательные анимации букв с помощью команд skewX() и skewY() реализующие вращение букв вокруг осей Xи Y соответственно. Instant Web 2.0 Код взят из примера ниже. Добавлены последовательные анимации букв с помощью команд skewX() и skewY()

Как сделать срезанные углы у кнопки (градиент)?

#css




Кнопка на фоне из двух прозрачных цветов, before & after:

background-color: rgba(0, 0, 0, 0.3)
background-color: rgba(0, 64, 139, 0.62)


У самой кнопки цвет: #e72e2e

Возможно так сделать?
    


Ответы

Ответ 1



*, *::before, *::after { box-sizing: border-box; } div { display: inline-block; margin: 0 10px; padding: 0 5px; line-height: 38px; background: silver; position: relative; filter: drop-shadow(5px 5px blue); } div::before, div:after { content: ""; display: inline-block; position: absolute; top: 0; bottom: 0; } div::before { right: 100%; border-right: 10px solid silver; border-bottom: 10px solid transparent; } div::after { left: 100%; border-left: 10px solid silver; border-top: 10px solid transparent; }
Just some text


Ответ 2



Можно градиентами и псевдоэлементом. body{ background-color: #d7e0ff; } button { position: relative; width: 250px; height: 50px; border: none; background-color: transparent; background-image: linear-gradient(45deg, transparent 9px, red 10px, red 202px, transparent 203px, transparent); } button:before { position: absolute; content: ''; width: inherit; height: inherit; top: 5px; left: 5px; background-color: transparent; background-image: linear-gradient(45deg, transparent 9px, #8e0808 10px, #8e0808 202px, transparent 203px, transparent); z-index: -1; }

При form.submit() опускается проверка полей на required

#javascript #submit #required


Есть форма с инпутом, который обьязателен для заполнения

И если через javascript сделать submit, то форма отправляется, без проверки на required document.getElementById("go").submit(); А если нажать на кнопку "Отправить" - тогда проверка есть, и не отправляет форму пока не заполнишь... Почему так происходит, почему js не проверяет поля формы? Chrome 57.0.2987.133 Firefox 52


Ответы

Ответ 1



При вызове метода .submit() проверка на валидность не осуществляется. Предполагается, что при ручной отправке это сделано самостоятельно. Потому не забываем вызывать метод .checkValidity() перед отправкой: let $form = document.getElementById('form'), $submitBtn = document.getElementById('submit'); $submitBtn.addEventListener('click', function() { if( $form.checkValidity() ) { $form.submit(); } else { // ваша обработка ошибок } }); Источник: Метод submit

Ответ 2



Можно не вызывать событие submit, а имитировать событие нажатия кнопки, тогда проверка должна быть. С помощью jQuery это можно сделать так: $("#go input[type=submit]").click();

Javascript: как удалять результат выполнения функции при следующем вызове

#javascript #vkontakte_api #адаптивность


Прикрутил на сайте виджет ВК "Сообщества". Стояла задача сделать его адаптивным,
при этом ширина должна не просто подстраиваться под родительский блок при перезагрузке
страницы, а именно тянуться при изменении размера экрана.

Решил использовать window.onresize:





Задача с адаптивностью решена, но появилась проблема: при каждом изменении размера экрана функция VK.Widgets.Group вызывается с новой шириной, при этом прежний блок с виджетом (со старыми размерами) остаётся на странице. И так их число растёт... Как сделать, чтобы при изменении размера экрана результаты предыдущего вызова VK.Widgets.Group удалялись?


Ответы

Ответ 1



Вроде работает. Попробуй так. JS Bin


Как создать переменные, которые будут видимы в SASS, JavaScript и Jade(Pug)

#javascript #sass #jade #pug


Каким наиболее простым образом можно создать переменные, которые будут видимы в:


SASS
JavaScript-файлах (с использованием Webpack и возможностей ES6)
Jade-шаблонах


Зачем это надо, думаю понятно: меняем имя, например, CSS-класса в одном месте, и
оно автоматически подставляется везде. Без этой возможности изменить имя класса в крупном
проекте - целая проблема.
    


Ответы

Ответ 1



создаете файл .env и в нем переменную SOME_ENV_VAR к примеру SASS_ENV=blabla читаем переменную в компиляторе SASS или JS: var ENV = process.env.SOME_ENV_VAR || 'default'; асайним переменную для Jade: const express = require('express'); var app = express(); app.locals.env = process.env; и читаем переменную в Jade #{env.SOME_ENV_VAR} Дополнение #1 var sass = encodeURIComponent(jsonToSassVars(sassGlobals)); var webpackConfig = { module: { loaders:[ {test: /.scss$/, loader: "style!css!sass!prepend?data=" + sass} ] }, } jsonToSassVars - https://gist.github.com/Kasu/ea4f4861a81e626ea308 Update: the previous link is not available anymore, prefer to use https://gist.github.com/ali-master/cb54a3501c0ea29a88a0297cb9533be9

Как сделать спрайт SVG, чтобы при добавлении его в адаптивную страничку HTML, иконки не выходили за границы своих контейнеров.

#html #css #css3 #svg #svg_спрайт


Более развернуто, что я хочу получить в результате:     


Как выбирать и дорабатывать изображения SVG (иконки в частности) 
для включения в спрайт.
Какая должна быть структура и настройки спрайта, для того чтобы:
была возможность при однократном добавлении спрайта использовать его
компоненты во многих местах HTML страниц
была возможность стилизации иконок из внешней таблицы CSS

Требования к иконкам:   
Иконки SVG должны быть масштабируемыми, то есть должны уменьшаться,
увеличиваться  при уменьшении, увеличении окна просмотра гаджета, при
этом не выходить за границы своего контейнера.
Иконки должны менять цвет при наведении курсора
Иконки должны при необходимости выступать в роли ссылки


На картинке ниже макет того, что я хочу получить в результате 


    


Ответы

Ответ 1



Как выбирать и дорабатывать изображения SVG Иконки нарисованные в векторных редакторах: Inkscape, Adobe Illustrator и других, как правило требуют оптимизации для уменьшения веса и получения более понятного кода для последующей ручной доработки. Мне нравится svg-editor от Peter Collingridge, который очень прост для освоения и работает очень эффективно, снижая вес файла иконки в несколько раз. Для спрайта лучше всего подбирать иконки с одинаковыми параметрами: одноцветные, с линиями выполненными с помощью только или только . и необходимо преобразовывать в . Также необходимо, чтобы у выбранных иконок были одинаковые viewBox Например: viewBox="0 0 126 126" Пример иконки, которая будет использована в спрайте, смотри ниже В шапке SVG файла необходимо убрать - width="126" height="126" - это viewport, который мешает иконке была адаптивной. То есть иконка должна целиком занимать родительский контейнер
.... и всё вместе размещается в секции ... Код каждой иконки оборачивается тегами ... с присвоением уникального идентификатора, по которому в дальнейшем будет вызов иконки командой Чаще пользуются вторым способом. Пример структуры спрайта.
Как видим убраны все атрибуты для последующей стилизации иконок из внешнего файла CSS. И обратите внимание, что к иконке с id="wordpress" добавлен дополнительный viewBox Это делается для выравнивания размеров иконки, отличающимися от размеров других иконок. Параметр необязательный, но очень полезный, не только для подгонки размеров, но и центрирования иконки внутри. Добавление файла спрайта в HTML Есть несколько способов добавления файлов SVG в HTML, но самым надежным является добавление посредством тега Your browser does not support SVG Добавление иконок из спрайта
Блок SVG обернут дивом контейнера. Для надежности добавляйте всегда Namespace SVG - xmlns:xlink="http://www.w3.org/1999/xlink" Иконки в качестве ссылок Для этого в SVG, в отличии от HTML, своя форма записи: Поэтому надо добавлять Namespace SVG, без этой строчки работать не будет. Стилизация иконок При использовании команды иконка попадает в shadow DOM и её атрибуты ведут себя странно,- экземпляр иконки есть, но она не поддается управлению извне. Кроме того атрибуты иконки например: style="fill:grey; stroke:cromson;" имеют наивысший приоритет. Поэтому мы удалили эти атрибуты. см. пример спрайта выше. Для решения проблемы наследования родительских свойств объектами в shadow Dom необходимо применить принудительное наследование inherit svg path{ fill:inherit; stroke:inherit; } и далее к иконкам уже можно применять правила CSS из внешней таблицы svg path:hover{fill:yellow;} #picasa{fill:black;} /* greenyellow */ #apple{fill:purple;} #twitter{fill:black;} /* dodgerblue */ #wordpress{fill:blue;} Теперь собираем всё вместе:
-->
Ссылки на иконках рабочие, при клике будет осуществлен переход на соответствующий ресурс. (видимо политика безопасности сниппета запрещает переход на внешние ресурсы из окна выполнения сниппета) Только в FF при наведении ссылки подсвечиваются страничка адаптивна, пробуйте изменять величину окна просмотра

Блокировка с двойной проверкой

#cpp #многопоточность


В книге Энтони Уильямса "Параллельное программирование на C++ в действии" рекомендуется
заменять использование упомянутого в заголовке паттерна использованием std::call_once.
Немного погуглив, обнаружил, что в других языках, например, Java и C# подобная проблема
решается объявление переменной как volatile для предотвращение оптимизаций компилятором.
Является ли использование volatileрешением и в C++ ? Или же здесь она работает как-то
иначе? 
    


Ответы

Ответ 1



нет, не является. Дело в том, что даже в этом случае можно сделать "обход". Детально расписано на хабре. Суть в том, что мы думаем, что в коде, одна строка атомарна, а это далеко не так. template T& single() { static T* pt; if (pt == 0) // первая проверка, вне мьютекса { StaticLock lock; if (pt == 0) // вторая проверка, под мьютексом pt = new T; // вот здесь на самом деле две строки. } return *pt; } создание объекта это обычно две операции - собственно выделение память и вызов конструктора. И в этом случае может так оказаться, что память уже выделили, а по адресу ещё не создали объект. И самая первая проверка теперь отработает по другому.

Ответ 2



Мейерс пишет, что volatile применяется для памяти, чтения и записи которой не должны удаляться при оптимизации, и что надо четко отличать volatile и std::atomic, который применяется для обращения нескольких потоков к данным без использования мьютексов. Если это не в тему - извините :(

Ответ 3



Может вы уже видели эту статью, если "гуглили" :), но там указано: Если вы укажете перед переменной volatile, то оптимизиации не будет. Хотя, использовать volotile для доступа к переменным из разных потоков - не корректно , т.к. предназначено оно для для работы с memory mapped Подробнее: Описание volatile c++ P.S. Если я правильно понял вопрос.

Ответ 4



В случае MSVC, под volatile потокобезопасность подразумевается (за исключением архитектуры ARM). Конкретно, MSVC генерирует дополнительный исполняемый код для обеспечения особого порядка доступа к переменной из разных потоков. Такое поведение задается ключом компилятора /volatile:ms. Напротив ключ /volatile:iso задает поведение по стандарту, то есть квалификатор volatile отключает оптимизации и к потокобезопасности явного отношения не имеет. При этом по умолчанию, в MSVC подразумевается /volatile:ms, то есть поведение MSVC в отношении volatile не является стандартным по умолчанию!