<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;A0ABQ3c7fyp7ImA9WxBbEU8.&quot;"><id>tag:blogger.com,1999:blog-4226383850373882540</id><updated>2010-03-09T12:15:52.907+02:00</updated><title>blog.ad.by</title><subtitle type="html" /><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://blog.ad.by/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://blog.ad.by/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Павел</name><uri>http://www.blogger.com/profile/15160195043765368557</uri><email>noreply@blogger.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>29</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/adby" /><feedburner:info uri="adby" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;AkUAQX44cSp7ImA9WxBbEE0.&quot;"><id>tag:blogger.com,1999:blog-4226383850373882540.post-1844559161003414605</id><published>2010-03-08T02:30:00.001+02:00</published><updated>2010-03-08T02:30:40.039+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-08T02:30:40.039+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="памятка" /><category scheme="http://www.blogger.com/atom/ns#" term="xslt" /><title>XSLT/XPATH Tips &amp; Tricks</title><content type="html">&lt;p&gt;Это пост-памятка про различные нюансы XSLT/XPATH. Ничего секретного, просто компиляция из разных источников. Примеры использовал в основном чужие.&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Поиск предка лучше реализовывать не через &lt;em&gt;../../../&lt;/em&gt; а через &lt;em&gt;ancestor::foo[1] &lt;/em&gt;— такой подход будет работать и в случае, если искомый элемент изменил своё положение.&lt;/li&gt;    &lt;li&gt;По возможности, не следует пользоваться конструкцией // так как её использование ведет к потере производительности. Процессор вынужден будет просмотреть всё дерево документа целиком.&lt;/li&gt;    &lt;li&gt;По возможности, не следует пользоваться конструкцией &lt;em&gt;.//&lt;/em&gt; так она часто употребляется неверно. Пример – требуется найти первого потомка с именем foo в текущем элементе. Ответ &lt;em&gt;.//foo[1]&lt;/em&gt; неверен. Запись &lt;em&gt;.//foo &lt;/em&gt;является короткой формой &lt;em&gt;self::node()/descendant-or-self::node()/child::foo&lt;/em&gt; соответственно &lt;em&gt;.//foo[1]&lt;/em&gt; означает “все потомки с именем foo, каждый из которых первый у своего родителя”. Т.е. возможен возврат более одного элемента. Правильный ответ — &lt;em&gt;descendant::foo[1]&lt;/em&gt;. В большинстве случаев именно это и требуется. Другое возможное решение проблемы получения лишних узлов — всегда использовать скобки если в xpath-выражении есть хоть один слеш и оно применяется вне конструкции &lt;em&gt;&amp;lt;xsl:value-of select=&amp;quot;&amp;quot; /&amp;gt;&lt;/em&gt;. Т.е. второй правильный ответ — &lt;em&gt;(.//foo)[1]&lt;/em&gt;. Конструкция &lt;em&gt;&amp;lt;xsl:value-of select=&amp;quot;&amp;quot; /&amp;gt;&lt;/em&gt; вызывает функцию &lt;em&gt;string&lt;/em&gt;, которая возвращает текстовое представление только первого узла из отобранных.&lt;/li&gt;    &lt;li&gt;Существует &lt;a href="http://habrahabr.ru/blogs/xslt/52680/"&gt;красивый способ применения оси self&lt;/a&gt;. Например &lt;em&gt;following-sibling::*[1][name() = 'foo']&lt;/em&gt; можно заменить на &lt;em&gt;following-sibling::*[1]/self::foo&lt;/em&gt;. Т.е. убираем предикат.&lt;/li&gt;    &lt;li&gt;Достаточно распространена ошибка с непониманием работы оператора !=. Особенно при попытке эмулировать ветку &lt;em&gt;else &lt;/em&gt;для &lt;em&gt;xsl:if&lt;/em&gt;. Это не отрицание, это условие отбора всех узлов для которых не выполняется некоторое условие. А узлов ведь может и не быть. Отрицание корректно задается функций &lt;em&gt;not()&lt;/em&gt;. &lt;/li&gt;    &lt;li&gt;Также многие не понимают оператор =. Это не только проверка на равенство, но и проверка на наличие в списке. &lt;a href="http://habrahabr.ru/blogs/xslt/70181/#comment_2006947"&gt;Хороший пример&lt;/a&gt;: &lt;em&gt;person[@name = &lt;/em&gt;&lt;em&gt;$vip/person/@name&lt;/em&gt;&lt;em&gt;]&lt;/em&gt; позволяет найти людей, у которых имя встречается в списке &lt;em&gt;$vip&lt;/em&gt; (а не равно всему списку сразу, как кажется).&lt;/li&gt;    &lt;li&gt;Как проверить, что два узла есть один и тот же узел. Первый вариант — &lt;em&gt;count($foo | $bar) = 1&lt;/em&gt;. Второй вариант — &lt;em&gt;generate-id($foo) = generate-id($bar)&lt;/em&gt;. &lt;/li&gt;    &lt;li&gt;Как элегантно писать шаблоны с внутренними условиями без громоздкого &lt;em&gt;xsl:choose&lt;/em&gt;. &lt;a href="http://sreznikov.blogspot.com/2008/10/xsl.html"&gt;Говорящий пример&lt;/a&gt;:      &lt;br /&gt;&amp;lt;xsl:template match=&amp;quot;Brands&amp;quot; /&amp;gt;      &lt;br /&gt;      &lt;br /&gt;&amp;lt;xsl:template match=&amp;quot;Brands[Brand]&amp;quot;&amp;gt;      &lt;br /&gt;&amp;#160; &amp;lt;h2&amp;gt;Производители&amp;lt;/h2&amp;gt;      &lt;br /&gt;&amp;#160; &amp;lt;ul&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;xsl:apply-templates select=&amp;quot;Brand&amp;quot; /&amp;gt;      &lt;br /&gt;&amp;#160; &amp;lt;/ul&amp;gt;      &lt;br /&gt;&amp;lt;/xsl:template&amp;gt;      &lt;br /&gt;      &lt;br /&gt;&amp;lt;xsl:template match=&amp;quot;Brands[count(Brand) &amp;gt; 10]&amp;quot;&amp;gt;      &lt;br /&gt;&amp;#160; &amp;lt;h2&amp;gt;Много производителей&amp;lt;/h2&amp;gt;      &lt;br /&gt;&amp;#160; &amp;lt;!-- Выводим бренды в три колонки --&amp;gt;      &lt;br /&gt;&amp;lt;/xsl:template&amp;gt;&lt;/li&gt;    &lt;li&gt;Как посчитать среднее. &lt;em&gt;&amp;lt;xsl:variable name=&amp;quot;avg&amp;quot; select=&amp;quot;sum(/list/item) div count(/list/item)&amp;quot;/&amp;gt;&lt;/em&gt;&lt;/li&gt;    &lt;li&gt;Как найти минимум/максимум — отсортировать по возрастанию/убыванию и взять первую.     &lt;br /&gt;&amp;lt;xsl:variable name=&amp;quot;min&amp;quot;&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160; &amp;lt;xsl:for-each select=&amp;quot;/list/item&amp;quot;&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;xsl:sort data-type=&amp;quot;number&amp;quot; order=&amp;quot;ascending&amp;quot;/&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;xsl:if test=&amp;quot;position() = 1&amp;quot;&amp;gt;&amp;lt;xsl:value-of select=&amp;quot;.&amp;quot; /&amp;gt;&amp;lt;/xsl:if&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160; &amp;lt;/xsl:for-each&amp;gt;      &lt;br /&gt;&amp;lt;/xsl:variable&amp;gt;&lt;/li&gt;    &lt;li&gt;&lt;em&gt;current()&lt;/em&gt; в предикате позволяет вернуться к контексту текущего узла. То есть вместо того, чтобы создавать переменную:      &lt;br /&gt;&amp;lt;xsl:template match=&amp;quot;navigation&amp;quot;&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160; &amp;lt;xsl:variable name=&amp;quot;status&amp;quot; select=&amp;quot;@status&amp;quot; /&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160; &amp;lt;xsl:value-of select=&amp;quot;/captions/caption[@status = $status]&amp;quot; /&amp;gt;      &lt;br /&gt;&amp;lt;/xsl:template&amp;gt;      &lt;br /&gt;гораздо удобнее писать      &lt;br /&gt;&amp;lt;xsl:template match=&amp;quot;navigation&amp;quot;&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160; &amp;lt;xsl:value-of select=&amp;quot;/captions/caption[@status = current()/@status]&amp;quot; /&amp;gt;      &lt;br /&gt;&amp;lt;/xsl:template&amp;gt;&lt;/li&gt;    &lt;li&gt;Вместо того чтобы писать несколько xsl:value-of подряд, можно использовать &lt;em&gt;concat(). &lt;/em&gt;Например &lt;em&gt;&amp;lt;xsl:value-of select=&amp;quot;concat(@Name, ' ', @Surname)&amp;quot; /&amp;gt;&lt;/em&gt;&lt;/li&gt;    &lt;li&gt;Нужно помнить, что всегда выполняется следующий порядок:     &lt;br /&gt;preceding-sibling[last()]      &lt;br /&gt;...      &lt;br /&gt;preceding-sibling[2]      &lt;br /&gt;preceding-sibling[1]      &lt;br /&gt;current item      &lt;br /&gt;following-sibling[1]      &lt;br /&gt;following-sibling[2]      &lt;br /&gt;...      &lt;br /&gt;following-sibling[last()]      &lt;br /&gt;Но! &lt;em&gt;position()&lt;/em&gt; после &lt;em&gt;&amp;lt;xsl:sort&amp;gt;&lt;/em&gt; возвращает позицию в отсортированном дереве.&lt;/li&gt;    &lt;li&gt;Также нужно помнить что call-template, в отличие от apply-templates, не меняет контекстный (текущий) узел.&lt;/li&gt;    &lt;li&gt;При написании тестов узлов важно не забывать о богатстве возможностей предикатов. Вот &lt;a href="http://toivonen.ru/notes/function-string-xslt.html"&gt;хороший пример&lt;/a&gt;. &amp;lt;xsl:template match=&amp;quot;news[region/person[starts-with(., 'A')]]&amp;quot; /&amp;gt;. Или вот — &amp;lt;xsl:apply-template select=&amp;quot;comment[@status = 'real'][position() &amp;amp;lt;= 3]&amp;quot; /&amp;gt;&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Prathit Bondre написал интересный документ &lt;a href="http://www.xml.org/sites/www.xml.org/files/xslt_efficient_programming_techniques.pdf"&gt;XSLT – Efficient Programming Techniques&lt;/a&gt;. Есть &lt;a href="http://toivonen.ru/books-articles/xslt-articles/efficient_programming_techniques.html"&gt;перевод&lt;/a&gt;. В этом документе рассмотрены весьма полезные приемы:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Подключение внешних файлов с данными. Через DOCTYPE ENTITY, через функцию document(). Я сам применяю первый способ для подключения мелких файлов, нужно только помнить, что на эти файлы распространяется ряд неприятных ограничений. Например, при подключении js-скрипта в файле не должно быть символа &amp;amp;.&lt;/li&gt;    &lt;li&gt;Пересечение, разность и дизъюнкция множеств.&lt;/li&gt;    &lt;li&gt;Нерекурсивные циклы.&lt;/li&gt;    &lt;li&gt;Условная выборка в xpath.&lt;/li&gt;    &lt;li&gt;Классическая группировка по Мюнху.&lt;/li&gt;    &lt;li&gt;Библиотека готовых функций &lt;a href="http://xsltsl.sourceforge.net/"&gt;&lt;font color="#0066cc"&gt;http://xsltsl.sourceforge.net/&lt;/font&gt;&lt;/a&gt;. Это не EXSLT.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&lt;a href="http://chikuyonok.ru/2009/05/entities-in-xsl/"&gt;Подключение ENTITY&lt;/a&gt; также интересно рассмотрено у Сергея Чикуенка. Он применяет их для эмуляции переменных в тестах узлов шаблонов.&lt;/p&gt;  &lt;p&gt;Ну и на закуску. &lt;a href="http://dpcarlisle.blogspot.com/2007/05/exslt-node-set-function.html"&gt;Как получить кросс-процессорную функцию node-set&lt;/a&gt;. Использую этот метод давно, отлично работает.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4226383850373882540-1844559161003414605?l=blog.ad.by' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ad.by/feeds/1844559161003414605/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4226383850373882540&amp;postID=1844559161003414605" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/1844559161003414605?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/1844559161003414605?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/adby/~3/HMSzGIneF5Y/xsltxpath-tips-tricks.html" title="XSLT/XPATH Tips &amp;amp; Tricks" /><author><name>Павел</name><uri>http://www.blogger.com/profile/15160195043765368557</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08937323532063115147" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.ad.by/2010/03/xsltxpath-tips-tricks.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0YEQHk-eCp7ImA9WxBTGE8.&quot;"><id>tag:blogger.com,1999:blog-4226383850373882540.post-76766487930512075</id><published>2009-12-14T00:07:00.002+02:00</published><updated>2009-12-14T23:11:41.750+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-14T23:11:41.750+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="памятка" /><category scheme="http://www.blogger.com/atom/ns#" term="adsl" /><title>D-LINK DSL-2500U/BRU/D &amp; PPTP</title><content type="html">&lt;p&gt;ADSL-провайдер, &lt;a href="http://adsl.by/"&gt;услугами которого я сейчас пользуюсь&lt;/a&gt;, использует VPN-туннель через PPTP. На практике это проявляется в том, что невозможно получить интернет просто включив модем. Нужно ещё создать подключение на компьютере и включать его, когда модем соединится. Раздражает страшно. Техподдержка прикидывается валенком, мол, мелочь, “пропишите ярлык в автозагрузку” или уверяют, что ради заботы о клиентах, ведь “это так удобно, трафик лишний не набежит”. Они, видимо, не подозревают, что компьютеры последние лет пять не перезагружаются месяцами, а просто впадают в гибернацию. А гибернация рвёт VPN-туннель. Да и байтики экономить ни к чему, хотя доступных безлимитных тарифов в Беларуси и нет, но есть доступные тарифы с большим количеством трафика. Кроме того, техподдержка прописывает статические маршруты на свои подсети прямо на компьютере. Совсем обленились, а в модеме такая функция зачем? И dns-сервера прописывают ещё и в ярлыке соединения. В общем устал я от этого. &lt;/p&gt;  &lt;p&gt;Проблему можно решить используя ADSL-модем с внутренней поддержкой PPTP-соединений. Из закромов был извлечен &lt;a href="http://www.dlink.ru/ru/products/3/745_b.html"&gt;D-LINK DSL-2500U/BRU/D&lt;/a&gt;. Путем долгой борьбы модем таки удалось отконфигурировать и запустить с поддержкой PPTP.&lt;/p&gt;  &lt;p&gt;Алгоритм такой:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Модем придется &lt;a href="http://dlink.ru/ru/faq/160/766.html"&gt;перепрошить&lt;/a&gt;. Нужна прошивка &lt;a href="ftp://ftp.dlink.ru/pub/ADSL/DSL-2500U_BRU_D/Firmware/RU_1.50_02162009/DSL-2500U_BRU_D_RU_1.50_02162009.zip"&gt;RU_1.50_02162009&lt;/a&gt; и никакая другая, т.к. в этой уже &lt;a href="http://forum.dlink.ru/viewtopic.php?p=432588&amp;amp;sid=8d75d9a1c5cf2c324a85fe1b0442d6f2#432588"&gt;отключили шифрование для PPTP&lt;/a&gt; (провайдер не дает соединиться с шифрованием), а во всех последующих прошивках PPTP нет совсем.&lt;/li&gt;    &lt;li&gt;После перепрошивки модем нужно сбросить аппаратно. Сзади есть кнопка сброса, её нужно зажать на секунд 10 и включить питание. После этого модем действительно сбросит все настройки в заводские. Как ни странно, но аналогичная кнопка в веб-интерфейсе модема таким действием не обладает.&lt;/li&gt;    &lt;li&gt;Теперь нужно настроить WAN. Заходим через веб-интерфейс. &lt;em&gt;Advanced Setup &amp;gt; WAN&lt;/em&gt;. Тут никаких отклонений от того, что настраивают люди из техподдержки. Ровно так и прописываем, в конце нажимаем &lt;em&gt;Save/Reboot&lt;/em&gt;.&lt;/li&gt;    &lt;li&gt;А теперь нужно прописать статическую маршрутизацию. &lt;em&gt;Advanced Setup &amp;gt; Routing &amp;gt; Static Route&lt;/em&gt;. Берем за образец командный &lt;a href="http://adsl.by/sites/default/files/filedoc/rout.bat"&gt;файл от техподдержки&lt;/a&gt;, только в качестве Gateway прописываем ip-адрес гейта по умолчанию из предыдущего шага.&lt;/li&gt;    &lt;li&gt;И только теперь заходим в &lt;em&gt;Advanced Setup &amp;gt; PPTP&lt;/em&gt;. Там пишем &lt;em&gt;Enable: да, Tunnel Name: vpn.adsl.by&lt;/em&gt;, &lt;em&gt;PPTP Server IP Address: vpn.adsl.by&lt;/em&gt;, &lt;em&gt;User Name&lt;/em&gt; и &lt;em&gt;Password&lt;/em&gt; берете из пямятки от провайдера, &lt;em&gt;Authentication Method: MSCHAPv2&lt;/em&gt;, &lt;em&gt;Default Route: да&lt;/em&gt;. Обращаю внимание на то, что вместо ip-адреса можно сразу имя сервера вписать. Нажимаем &lt;em&gt;Save/Apply&lt;/em&gt;.&lt;/li&gt;    &lt;li&gt;Теперь идем в &lt;em&gt;Management &amp;gt; Save/Reboot&lt;/em&gt;. После перезагрузки идем в &lt;em&gt;Device Info &amp;gt; WAN&lt;/em&gt; и смотрим на &lt;em&gt;PPTP Info&lt;/em&gt; — там через минуту появится информация о PPTP-соединении. Всё. Больше рекомендую ничего не трогать. Ну разве что SNMP отключить.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Итоги борьбы:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Включил модем — есть интернет. Без всяких дополнительных телодвижений. Это удобно. &lt;/li&gt;    &lt;li&gt;К модему можно подсоединить любой компьютер, ничего конфигурировать не нужно. Это удобно.&lt;/li&gt;    &lt;li&gt;Упала скорость скачивания! Линия включена как 8Мбит. Реальная скорость была 6.6Мбит. После переноса PPTP на модем стало 3.6Мбит! А скорость закачки как была 0.6Мбит, так и осталась. Модем-то тормозной, оказывается. То-то я думаю, почему это D-LINK убрал PPTP-из прошивки. &lt;/li&gt;    &lt;li&gt;Вот так. Приходится выбирать. Или скорость или отсутствие геморроя. Видимо придется купить нормальную технику, Linksys или Cisco.&lt;/li&gt;&lt;li&gt;Update по предварительным результатам эксплуатации: при организации VPN-туннелей поверх модемного PPTP возникают глюки с потерей пакетов, соединение часто рвется, в общем неприятно. Вдвойне понятно почему PPTP удален из современных прошивок.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Несмотря на то, что технически у Белинфонета всё сделано исключительно бездарно с точки зрения клиента, это сейчас единственная контора дающая и нормальную скорость и 30ГБ трафика одновременно за 50$. У остальных такого нет при схожих ценах.   &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4226383850373882540-76766487930512075?l=blog.ad.by' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ad.by/feeds/76766487930512075/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4226383850373882540&amp;postID=76766487930512075" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/76766487930512075?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/76766487930512075?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/adby/~3/Nhst00jxwRA/d-link-dsl-2500ubrud-pptp.html" title="D-LINK DSL-2500U/BRU/D &amp;amp; PPTP" /><author><name>Павел</name><uri>http://www.blogger.com/profile/15160195043765368557</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08937323532063115147" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.ad.by/2009/12/d-link-dsl-2500ubrud-pptp.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkQASH8yfSp7ImA9WxNVEk4.&quot;"><id>tag:blogger.com,1999:blog-4226383850373882540.post-4358572058229314109</id><published>2009-10-22T18:48:00.002+02:00</published><updated>2009-10-22T18:52:29.195+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-22T18:52:29.195+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="памятка" /><title>DNS, Hosting, Panel, Redirect, Email for Free</title><content type="html">&lt;p&gt;Сегодня расскажу как получить быстрый и при этом полностью бесплатный в обслуживании сайт. Ноль рублей, ноль копеек в год. Но нужно быть программистом, хотя бы начинающим.&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;strong&gt;Имя.&lt;/strong&gt; Нужно купить доменное имя второго уровня ) Ну да, немного обманул ) На имени сэкономить, наверное, не удастся. Но бывают акции у разных регистраторов. Так что вероятность получить бесплатное доменное имя всё-таки есть. У меня один раз получилось. Для работы домена нужно сообщить регистратору, какие DNS-сервера будут обслуживать записи о вашем домене. Сразу же при регистрации уведомляем своего регистратора, чтобы прописал сервера &lt;em&gt;freedns1.registrar-servers.com&lt;/em&gt;, &lt;em&gt;freedns2.registrar-servers.com &lt;/em&gt;и &lt;em&gt;freedns3.registrar-servers.com &lt;/em&gt;в качестве наших первичных/вторичных DNS-серверов. Через несколько часов/дней эта информация разойдется по миру и ваш будущий домен станет доступен всем.&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;DNS-сервера. &lt;/strong&gt;Регистраторы обычно дают такой сервис за деньги, предоставляя свои DNS-сервера. На этот трюк покупаться не стоит. А стоит найти того кто предоставляет сервис FreeDNS. Таких мест много, но все они, по разному ущербны. Кроме одного - &lt;a href="http://www.namecheap.com?aff=3882"&gt;namecheap.com&lt;/a&gt;! Именно его сервера мы использовали на предыдущем шаге. Итак, идем, регистрируемся, потом заходим в пункт &lt;a href="https://www.namecheap.com/freedns/free-manage-dns.aspx"&gt;Free DNS Hosting&lt;/a&gt; и добавляем свой домен.&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Панель управления.&lt;/strong&gt; К доменному имени большая часть регистраторов дает готовую панель управления DNS-записями. Тем, кому как и мне, не повезло, &lt;a href="http://www.namecheap.com?aff=3882"&gt;namecheap.com&lt;/a&gt; дает свою. Заходим в &lt;a href="https://www.namecheap.com/myaccount/hosteddomainslist.aspx"&gt;Free DNS –&amp;gt; Your Hosted Domains&lt;/a&gt;, щелкаем по своему, добавленному на предыдущем шаге, домену и приступаем к редактированию DNS-записей. Это будет долго и нудно, но стоит того. Кстати, на этой странице, возможно будет кнопка “подтвердить владение”, так вот её нужно нажать, и namecheap отправит на почтовый адрес администратора (который вы указали при регистрации домена) специальную ссылку, пройдете по ссылке, и namecheap будет считать вас владельцем вашего домена.&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Почта. &lt;/strong&gt;Без почты никуда ) Идем на &lt;a href="http://www.google.com/a/cpanel/domain/new"&gt;Google Apps For Domain&lt;/a&gt; и регистрируем там свой домен как администратор. Кстати, там же и купить можно, но не пробовал. Регистрируемся как некоммерческий пользователь, а не триальный на 30 дней, как это предлагается по умолчанию! Бесплатная ссылка запрятана где-то сбоку. Перейти с коммерческого на бесплатный потом нельзя! Гугл предложит подтвердить владение доменом и сообщит код. Идем в панель и прописываем там специальную запись: в первую колонку строчку с кодом от гугла, во вторую колонку “ghs.google.com.” (без кавычек и точкой!) в третьей выбираем “CNAME (alias)”. Сохраняем. Возвращаемся на гугл и нажимаем на кнопку проверки. Гугл проверит и поверит, что этот аккаунт действительно от администратора домена. В аккаунте включаем SSL, включаем почту, создаем нужные почтовые ящики. У почты прописываем Web Address какой нравится. У меня, например, это &lt;a class="greenlink" id="emailLink" href="http://mail.ad.by/" target="_blank"&gt;&lt;font color="#0000ff"&gt;mail.ad.by&lt;/font&gt;&lt;/a&gt;. Через этот адрес будете заходить в свою почту. Потом идем в панель управления DNS и прописываем там строку “mail”, “ghs.google.com.”, “ghs.google.com.”. Кроме того, чтобы никто не рассылал спам от вашего имени можно прописать SPF-запись - строку “@” “v=spf1 +a include:aspmx.googlemail.com +mx -all” “TXT Record”. Это не всё. Самое главное, выбрать в панели пункт “User (Mail Server's Host Name Required)” и &lt;a href="http://www.google.com/support/a/bin/answer.py?hl=ru&amp;amp;answer=87127"&gt;прописать туда семь строк&lt;/a&gt;. Если строк не хватает, сохраняетесь, после этого на странице появятся ещё поля для ввода. Всё, почта работает. Идем на адрес &lt;em&gt;mail.вашдомен.com&lt;/em&gt; или что вы там указывали, и наслаждаемся нормальной почтой.&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Уведомления о новой почте/GoogleTalk/Jabber. &lt;/strong&gt;Ставим GoogleTalk и он будет уведомлять нас новых письмах. Идем в гугловую панель, включаем сервис Chat, качаем и ставим GoogleTalk. Идем в namecheap-панель и долго и нудно прописываем там 15 строчек в разделе &lt;em&gt;SRV SETTINGS&lt;/em&gt;. Параметры можно посмотреть много где. Основные 10 строк &lt;a href="http://www.google.com/support/a/bin/answer.py?hl=ru&amp;amp;answer=60227"&gt;описаны у гугла&lt;/a&gt;. Остальные 5 строк нужны для тех кто собирается использовать &lt;a href="http://m.habrahabr.ru/post/50370/"&gt;сторонний jabber-клиент&lt;/a&gt;. Это самая нудная часть.&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Хостинг. &lt;/strong&gt;Нужно же сайт к домену привинтить. Идем на &lt;a href="https://appengine.google.com/"&gt;Google App Engine&lt;/a&gt;, регистрируемся (понадобится мобильный телефон – на него придет SMS с кодом подтверждения, причем в Беларусь не отправляют), регистрируем новое приложение. Писать можно на языках Python и Java. Но программировать не обязательно, если сайт статический. Качаем выбранный SDK, разбираемся и программируем сайт, или гуглим и качаем уже готовый. Заливаем код на App Engine. Привязывает его к имени www.вашсайт.ком. Потом идем в гугловую панель своего домена и подключаем сайт как сервис. Теперь идем в namecheap-панель и в двух верхних строках пишем следующее. Первая строка - “http://www.вашдомен.ком/?” (вопросительный знак важен) и “URL Redirect (301)”. Вторая строка “&lt;span class="Apple-style-span" style="word-spacing: 0px; font: medium &amp;#39;Times New Roman&amp;#39;; text-transform: none; color: rgb(0,0,0); text-indent: 0px; white-space: normal; letter-spacing: normal; border-collapse: separate; orphans: 2; widows: 2; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px"&gt;&lt;span class="Apple-style-span" style="font-size: 13px; font-family: arial; white-space: pre"&gt;&lt;font face="Georgia" color="#333333" size="2"&gt;ghs.google.com.&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;” и “CNAME (Alias)”. Сохраняем. Всё. Теперь при заходе на ваш сайт пользователи будут видеть чего вы там напрограммировали.&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;DynamicDNS.&lt;/strong&gt; Если кому-то нужно, то имейте виду, что namecheap дает и такую возможность.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Всё. Имеем полноценный сайт с почтой. Быстрый, бесплатный. Если он статический, так ему ещё и DDOS не страшен – гугл раздает статику через свой CDN.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4226383850373882540-4358572058229314109?l=blog.ad.by' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ad.by/feeds/4358572058229314109/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4226383850373882540&amp;postID=4358572058229314109" title="Комментарии: 1" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/4358572058229314109?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/4358572058229314109?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/adby/~3/8MLWB2txgTs/dns-hosting-panel-redirect-email-for.html" title="DNS, Hosting, Panel, Redirect, Email for Free" /><author><name>Павел</name><uri>http://www.blogger.com/profile/15160195043765368557</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08937323532063115147" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://blog.ad.by/2009/10/dns-hosting-panel-redirect-email-for.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkECQn44fyp7ImA9WxNTFko.&quot;"><id>tag:blogger.com,1999:blog-4226383850373882540.post-533181092637711828</id><published>2009-08-19T12:44:00.001+02:00</published><updated>2009-08-19T12:44:23.037+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-19T12:44:23.037+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="mssql" /><title>MS SQL Server Documentation</title><content type="html">&lt;p&gt;Это пост праведного гнева, направленного против разного рода копипастеров и лиц, не желающих читать документацию производителя.&lt;/p&gt; &lt;span style="widows: 2; text-transform: none; text-indent: 0px; border-collapse: separate; font: medium &amp;#39;Times New Roman&amp;#39;; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(0,0,0); word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" class="Apple-style-span"&gt;&lt;span style="text-align: left; line-height: 25px; font-family: cambria, &amp;#39;Times New Roman&amp;#39;, serif; color: rgb(34,34,34); font-size: 17px; -webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px" class="Apple-style-span"&gt;     &lt;p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px"&gt;Меня всегда неприятно поражало желание людей своими словами пересказывать системную документацию. А чтоб умным показаться добавлять какого-нибудь бреда пару строк. И не лень же?&lt;/p&gt;      &lt;p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;      &lt;p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px"&gt;И ведь их читают и на них ссылаются. Это болезнь какая-то. Что только люди делать не будут, лишь бы документацию не читать.&lt;/p&gt;      &lt;p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;      &lt;p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px"&gt;&lt;em&gt;Для MS SQL Server написана, пожалуй, лучшая в мире документация! &lt;/em&gt;Она краткая, она простая, она понятная и она небольшая по объему. Её можно прочитать за несколько дней и не парить себе и окружающим мозги.&lt;/p&gt;      &lt;p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;      &lt;p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px"&gt;Нет, блин, будут цитировать всякий рак мозга, иногда ещё и криво переведенный.&lt;/p&gt;      &lt;p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;      &lt;p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px"&gt;Я ещё могу понять когда такой подход работает. Для оракла такой подход работает, потому что там много всего, физически трудно прочитать и усвоить хотя бы начало - первые пару трехтомников по полторы тысячи страниц каждый том, написанный дебильным языком инструкций роботов из 70-х годов. На это реально нужно много времени, это лучше делать на курсах, под присмотром опытного разработчика, который подскажет, как обойти тысячи оракловых подводных камней и посоветует читать Кайта.&lt;/p&gt;      &lt;p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;      &lt;p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px"&gt;Но SQL Server не такой. &lt;em&gt;Он молодой, он простой, он логичный, он стабильный, он разработан командой высококлассных специалистов. &lt;/em&gt;И из-за этого у него простая и понятная документация. Найдите два-три дня и прочитайте её. За выходные можно успеть.&lt;/p&gt;   &lt;/span&gt;&lt;/span&gt;  &lt;p&gt;Всё. За рецептами всяких практических хитростей потом можно сходить почитать &lt;a href="http://sql.ru/"&gt;sql.ru&lt;/a&gt;. Могу ещё порекомендовать книги Артемова и сборник от того-же sql.ru. Больше можно ничего не читать.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4226383850373882540-533181092637711828?l=blog.ad.by' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ad.by/feeds/533181092637711828/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4226383850373882540&amp;postID=533181092637711828" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/533181092637711828?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/533181092637711828?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/adby/~3/YJs1l7jH85o/ms-sql-server-documentation.html" title="MS SQL Server Documentation" /><author><name>Павел</name><uri>http://www.blogger.com/profile/15160195043765368557</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08937323532063115147" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.ad.by/2009/08/ms-sql-server-documentation.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEcMQXk5fyp7ImA9WxNTEUs.&quot;"><id>tag:blogger.com,1999:blog-4226383850373882540.post-5926421418878266906</id><published>2009-08-13T13:14:00.001+02:00</published><updated>2009-08-13T13:14:40.727+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-13T13:14:40.727+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="GAE" /><category scheme="http://www.blogger.com/atom/ns#" term="decompile" /><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><title>Java &amp; Decompilation &amp; GAE SDK</title><content type="html">&lt;p&gt;При работе с любой программой может возникнуть непреодолимое желание заглянуть в её исходники. Вот и при работе с Google App Engine SDK for Java я неоднократно ловил себя на мысли: насколько проще было бы работать, смотря прямо в его код.&amp;#160; Как заглянуть в исходники любого Java-класса?&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;На текущий момент существует один, самый лучший бесплатный декомпилятор Java. &lt;a href="http://www.reversed-java.com/fernflower/"&gt;Fernflower&lt;/a&gt;. Это ограниченная бета в виде онлайн-сервиса. Сразу предупреждаю, в Google Chrome не работает. Дефект верстки, используйте другие браузеры.&lt;/li&gt;    &lt;li&gt;Итак, декомпилятор есть. Но он не принимает файлы размером более 5Мб, а в SDK файлы больше. Обойти это ограничение достаточно просто. Jar-файлы это просто zip-архивы. Причем плохо сжатые. Берем лучший бесплатный архиватор &lt;a href="http://www.7-zip.org/"&gt;7-zip&lt;/a&gt; и пережимаем jar-файлы. Результат впечатляет – 7-zip жмет в два раза сильнее.&lt;/li&gt;    &lt;li&gt;Скармливаем новый архив декомпилятору и через три минуты скачиваем результат декомпиляции, тоже в виде архива. Открываем, поражаемся качеству декомпиляции, подключаем к эклипсу.&lt;/li&gt;    &lt;li&gt;Profit!&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Пока нашел два интересных момента:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Неполная реализация JCache: CacheEntry ничего не умеет. Пришлось написать обертку для getLastUpdateTime().&lt;/li&gt;    &lt;li&gt;Внутри SDK лежит очень интересная библиотека &lt;a href="http://code.google.com/p/google-collections/"&gt;google-collections&lt;/a&gt; в виде пакета com.google.appengine.repackaged.com.google.*&lt;/li&gt; &lt;/ol&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4226383850373882540-5926421418878266906?l=blog.ad.by' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ad.by/feeds/5926421418878266906/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4226383850373882540&amp;postID=5926421418878266906" title="Комментарии: 3" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/5926421418878266906?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/5926421418878266906?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/adby/~3/T3BNzPSlR-A/java-decompilation-gae-sdk.html" title="Java &amp;amp; Decompilation &amp;amp; GAE SDK" /><author><name>Павел</name><uri>http://www.blogger.com/profile/15160195043765368557</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08937323532063115147" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total><feedburner:origLink>http://blog.ad.by/2009/08/java-decompilation-gae-sdk.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkUNR3syeip7ImA9WxJaFUQ.&quot;"><id>tag:blogger.com,1999:blog-4226383850373882540.post-1949548837038661891</id><published>2009-07-28T22:45:00.003+02:00</published><updated>2009-08-06T22:24:56.592+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-06T22:24:56.592+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="GAE" /><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="xslt" /><title>XSLT &amp; Google App Engine/Java</title><content type="html">&lt;p&gt;Поставил целью запустить простейший XSLT-фреймворк на GAE/J. Требования к процессору:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;XSLT 1.0 в полном объеме. А неплохо бы и 2.0 на всякий случай; &lt;/li&gt;    &lt;li&gt;Скорость; &lt;/li&gt;    &lt;li&gt;Поддержка EXSLT. Хотя-бы частичная, но node-set обязательно. &lt;/li&gt;    &lt;li&gt;Расширяемость внешними Java-функциями. Возможность вызова методов класса; &lt;/li&gt;    &lt;li&gt;Лицензия на коммерческое применение; &lt;/li&gt;    &lt;li&gt;Желательна бесплатность и исходные тексты; &lt;/li&gt;    &lt;li&gt;Желательна поддержка TrAX - transformation API for XML. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Вначале долго искал хоть какие результаты тестов производительности. Все найденные данные либо безбожно устарели, либо составлены так, что понять что-либо абсолютно невозможно. Любимый прием авторов сравнений – утаить подробности. Например, пишут “Saxon X.X.X.X”. Что за Saxon? Saxon-B или Saxon-SA? Для дотнета или для явы? И так везде. В общем путем долгих мучений выяснилось что известными более-менее быстрыми процессорами, написанными на яве, являются Gregor, Xalan/XSLTC, XT, Saxon 6.5/Saxon-B/Saxon-SA.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Gregor&lt;/strong&gt; декларировался как фантастически быстрый &lt;em&gt;компилятор&lt;/em&gt; нового поколения. На деле оказался заброшенным коммерческим проектом, абсолютно недоступным для отдельного скачивания. Жаль.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Xalan/XSLTC.&lt;/strong&gt; Входит в JDK. Правда какой-то древней версии. Попробовал использовать свежий xalan-j 2.7.1. Сразу выяснилось, что по сути XSLTC не поддерживает внешние нестатические функции, да и без их использования валится на GAE с криками “Illegal type in constant pool”. Без использования режима компиляции xalan на GAE работоспособен, но загаживает лог криками “Failed calling setMethod method” и “Failed calling setIndent method”. Т.е. не понимает тег &amp;lt;xsl:output&amp;gt;. Да и самый медленный он из всех перечисленных. Короче – в сад.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;XT&lt;/strong&gt;-20051206. По отзывам – очень быстр. Похоже, что проект заброшен. Не смог обработать мой шаблон даже локально, до GAE не дошел. В брак.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Saxon-SA&lt;/strong&gt; это коммерческий продукт. Значит и пробовать нужно когда проект работает под нагрузкой и приносит прибыль. Не проверял. Но похоже его и не нужно как-то особо проверять ибо полностью внешне совместим с Saxon-B.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Saxon 6.5.5 &lt;/strong&gt;сейчас подзаброшен. Не проверял, т.к. каких-либо преимуществ перед Saxon-B не имеет, скорее наоборот.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Saxon-B 9.1.0.7 j. &lt;/strong&gt;Завелся с полпинка как локально, так и на GAE. Оказался быстрее xalan’а на моем простом примере. Работает стабильно. На нем и остановился.&lt;/p&gt;  &lt;p&gt;Единственный замеченный глюк – в некоторых случаях xml-файлы могут самопроизвольно искаться в каталоге “/base/” (и не находиться, естественно). Чтобы этого не происходило, нужно использовать классы FileInputStream и File. В них с обработкой путей всё в порядке.&lt;/p&gt;  &lt;p&gt;В итоге получился краткий и лаконичный код. Ключевые моменты выделены жирным.&lt;/p&gt; &lt;b&gt;&lt;font color="#7f0055"&gt;&lt;font color="#7f0055"&gt;       &lt;p align="left"&gt;&lt;/p&gt;     &lt;/font&gt;&lt;/font&gt;&lt;/b&gt;&lt;b&gt;&lt;font color="#7f0055"&gt;&lt;font color="#7f0055"&gt;&lt;/font&gt;&lt;/font&gt;&lt;/b&gt;  &lt;p&gt;&lt;font face="Consolas"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Consolas"&gt;public class XstlServlet      &lt;br /&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&amp;#160; extends HttpServlet      &lt;br /&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;{      &lt;br /&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&amp;#160; @Override      &lt;br /&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&amp;#160; public void doGet(final HttpServletRequest req,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; final HttpServletResponse resp)       &lt;br /&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; throws IOException, ServletException      &lt;br /&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&amp;#160; {      &lt;br /&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; request = req;      &lt;br /&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; resp.setContentType(&amp;quot;text/html; charset=UTF-8&amp;quot;);      &lt;br /&gt;      &lt;br /&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; try {&amp;#160; &lt;br /&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;strong&gt;getTransformer(&amp;quot;default&amp;quot;).transform&lt;/strong&gt;(       &lt;br /&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; new StreamSource(new &lt;strong&gt;FileInputStream&lt;/strong&gt;(&amp;quot;default.xml&amp;quot;)),       &lt;br /&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; new StreamResult(resp.getOutputStream()));      &lt;br /&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; } catch (TransformerException e) {      &lt;br /&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; throw new ServletException(e);      &lt;br /&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; }      &lt;br /&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&amp;#160; }      &lt;br /&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;     &lt;br /&gt;&amp;#160; public Transformer getTransformer(final String xsltName)       &lt;br /&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; throws FileNotFoundException, TransformerException,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; MalformedURLException       &lt;br /&gt;&amp;#160; &lt;/font&gt;&lt;font face="Consolas"&gt;{      &lt;br /&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; if (!transformers.containsKey(xsltName)) {      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font face="Consolas"&gt;final Transformer newXslt = &lt;strong&gt;xsltFactory.newTransformer&lt;/strong&gt;(       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font face="Consolas"&gt;new StreamSource(new &lt;strong&gt;FileInputStream&lt;/strong&gt;(xsltName + &amp;quot;.xslt&amp;quot;)));       &lt;br /&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;strong&gt;newXslt.setParameter(&amp;quot;this&amp;quot;, this);&lt;/strong&gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font face="Consolas"&gt;transformers.put(xsltName, newXslt);      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font face="Consolas"&gt;}      &lt;br /&gt;      &lt;br /&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; return transformers.get(xsltName);      &lt;br /&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&amp;#160; }      &lt;br /&gt;      &lt;br /&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&amp;#160; //      &lt;br /&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&amp;#160; // callback methods for xslt transformation      &lt;br /&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&amp;#160; //      &lt;br /&gt;      &lt;br /&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&amp;#160; &lt;strong&gt;public static String getServletPath(final Object context)&lt;/strong&gt;       &lt;br /&gt;&amp;#160; &lt;/font&gt;&lt;font face="Consolas"&gt;{      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font face="Consolas"&gt;return ((XstlServlet) context).request.getServletPath();      &lt;br /&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&amp;#160; }      &lt;br /&gt;      &lt;br /&gt;&amp;#160; &lt;/font&gt;&lt;font face="Consolas"&gt;&lt;strong&gt;public static String getParameter(final Object context,        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; final String paramName)&lt;/strong&gt;       &lt;br /&gt;&amp;#160; &lt;/font&gt;&lt;font face="Consolas"&gt;{      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font face="Consolas"&gt;return ((XstlServlet) context).request.getParameter(paramName);      &lt;br /&gt;&amp;#160; &lt;/font&gt;&lt;font face="Consolas"&gt;}      &lt;br /&gt;      &lt;br /&gt;&amp;#160; &lt;/font&gt;&lt;font face="Consolas"&gt;//      &lt;br /&gt;&amp;#160; &lt;/font&gt;&lt;font face="Consolas"&gt;// private declarations      &lt;br /&gt;&amp;#160; &lt;/font&gt;&lt;font face="Consolas"&gt;//      &lt;br /&gt;      &lt;br /&gt;&amp;#160; &lt;/font&gt;&lt;font face="Consolas"&gt;private HttpServletRequest request;      &lt;br /&gt;&amp;#160; &lt;/font&gt;&lt;font face="Consolas"&gt;private final Map&amp;lt;String, Transformer&amp;gt; transformers =      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font face="Consolas"&gt;new Hashtable&amp;lt;String, Transformer&amp;gt;();      &lt;br /&gt;&amp;#160; &lt;/font&gt;&lt;font face="Consolas"&gt;private final static TransformerFactory xsltFactory =      &lt;br /&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;strong&gt;TransformerFactory.newInstance();&lt;/strong&gt;       &lt;br /&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;}&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;В xslt-шаблоне для вызова внешних методов применяется классический прием – объявление специального пространства имен, ссылка на наш объект через параметр в корневом узле и передача ссылки на объект как первый параметр вызываемой функции.&lt;/p&gt;  &lt;p align="left"&gt;&lt;font face="Consolas"&gt;&amp;lt;xsl:stylesheet version=&amp;quot;1.0&amp;quot;     &lt;br /&gt;xmlns:xsl=”http://www.w3.org/1999/XSL/Transform”&amp;#160; &lt;br /&gt; &lt;strong&gt;xmlns:this&lt;/strong&gt;=”http://xml.apache.org/xalan/&lt;strong&gt;java/com.test.XstlServlet”       &lt;br /&gt;&lt;/strong&gt;exclude-result-prefixes=&amp;quot;this&amp;quot;&amp;gt;       &lt;br /&gt;      &lt;br /&gt;&amp;#160; &lt;/font&gt;&lt;font face="Consolas"&gt;&lt;strong&gt;&amp;lt;xsl:param name=&amp;quot;this&amp;quot; /&amp;gt;        &lt;br /&gt;        &lt;br /&gt;&lt;/strong&gt;&amp;#160; &amp;lt;xsl:template match=&amp;quot;/&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;xsl:value-of select=&amp;quot;&lt;strong&gt;this:getParameter($this, @параметр)&lt;/strong&gt;&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;xsl:value-of select=&amp;quot;&lt;strong&gt;this:getServletPath($this)&lt;/strong&gt;&amp;quot; /&amp;gt;      &lt;br /&gt;…      &lt;br /&gt;&amp;#160; &amp;lt;/xsl:template&amp;gt;       &lt;br /&gt;…      &lt;br /&gt;&amp;lt;/xsl:stylesheet&amp;gt;&lt;/font&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;/p&gt; Осталось еще кеширование нормальное и многопоточность добавить - и фундамент готов.&lt;br /&gt;&lt;p&gt;UPDATE: Статья обновлена. В настоящее время GAE не имеет своего xslt-процессора. Это моя случайная ошибка – в каталоге lib был забыт saxon9.jar, чего оказалось достаточно чтобы гугл его подхватил.&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4226383850373882540-1949548837038661891?l=blog.ad.by' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ad.by/feeds/1949548837038661891/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4226383850373882540&amp;postID=1949548837038661891" title="Комментарии: 1" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/1949548837038661891?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/1949548837038661891?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/adby/~3/l4-AFkAPO4g/xslt-google-app-enginejava.html" title="XSLT &amp;amp; Google App Engine/Java" /><author><name>Павел</name><uri>http://www.blogger.com/profile/15160195043765368557</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08937323532063115147" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://blog.ad.by/2009/07/xslt-google-app-enginejava.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEMDR3c8fyp7ImA9WxJbFUw.&quot;"><id>tag:blogger.com,1999:blog-4226383850373882540.post-8003183188794913199</id><published>2009-07-25T12:07:00.001+02:00</published><updated>2009-07-25T12:07:56.977+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-25T12:07:56.977+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="svn" /><title>Free Private SVN</title><content type="html">&lt;p&gt;Если кто-то ищет бесплатное хранилище для своего кода, то большой выбор по разным параметрам доступен на сайте с весьма неинтуитивным названием &lt;a href="http://www.svnhostingcomparison.com/"&gt;http://www.svnhostingcomparison.com/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Из бесплатных хостингов для для закрытого ПО там указан только один - &lt;a href="http://www.myversioncontrol.com/"&gt;http://www.myversioncontrol.com/&lt;/a&gt;, от себя могу добавить что использую &lt;a href="http://sliksvn.com/"&gt;http://sliksvn.com/&lt;/a&gt;, но у My Version Control предложение получше. Нужно будет попробовать.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4226383850373882540-8003183188794913199?l=blog.ad.by' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ad.by/feeds/8003183188794913199/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4226383850373882540&amp;postID=8003183188794913199" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/8003183188794913199?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/8003183188794913199?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/adby/~3/BJZEOdZ4qjo/free-private-svn.html" title="Free Private SVN" /><author><name>Павел</name><uri>http://www.blogger.com/profile/15160195043765368557</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08937323532063115147" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.ad.by/2009/07/free-private-svn.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUMBRng-fip7ImA9WxNRFUQ.&quot;"><id>tag:blogger.com,1999:blog-4226383850373882540.post-6757773302363695576</id><published>2009-07-07T23:54:00.002+02:00</published><updated>2009-09-10T16:37:37.656+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-10T16:37:37.656+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="speed" /><category scheme="http://www.blogger.com/atom/ns#" term="xml" /><category scheme="http://www.blogger.com/atom/ns#" term="mssql" /><title>MSSQL – fast data upload</title><content type="html">&lt;p&gt;Хочу поделиться одним удобным рецептом по загрузке большого количества строк в БД MSSQL.&lt;/p&gt;  &lt;p&gt;Вообще для этой задачи обычно используют bcp, bulk insert, IRowsetFastLoad или XML Bulk Load. Все эти способы неплохи и задачу выполняют. Но столько ограничений и столько дополнительный телодвижений нужно сделать, что весь энтузиазм пропадает. Я уже несколько лет как придумал (явно не первый) и использую простой как валенок, достаточно элегантный способ, обеспечивающий сравнимую производительность с вышеперечисленными методами.&lt;/p&gt;  &lt;p&gt;Суть способа — передача XML с клиента в хранимую процедуру и последующая обработка упрощенным способом.&lt;/p&gt;  &lt;p&gt;Пример процедуры:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier"&gt;create procedure [dbo].[DataInsert]      &lt;br /&gt;&amp;#160; @xmlData xml       &lt;br /&gt;as       &lt;br /&gt;begin       &lt;br /&gt;&amp;#160; set nocount on       &lt;br /&gt;&amp;#160; declare @result int&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier"&gt;&amp;#160; insert into [TempData]      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ([date], [seriesid], [value])       &lt;br /&gt;&amp;#160; select       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; -- cast добавить по вкусу       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; node.value(&lt;/font&gt;&lt;a href="mailto:'@dateTime'"&gt;&lt;font face="Courier"&gt;'@dateTime'&lt;/font&gt;&lt;/a&gt;&lt;font face="Courier"&gt;, 'varchar(100)') [date],      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; node.value(&lt;/font&gt;&lt;a href="mailto:'@seriesId'"&gt;&lt;font face="Courier"&gt;'@seriesId'&lt;/font&gt;&lt;/a&gt;&lt;font face="Courier"&gt;, 'varchar(10)') [seriesid],      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; node.value(&lt;/font&gt;&lt;a href="mailto:'@value'"&gt;&lt;font face="Courier"&gt;'@value'&lt;/font&gt;&lt;/a&gt;&lt;font face="Courier"&gt;, 'varchar(100)') [value]      &lt;br /&gt;&amp;#160; from       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; @xmlData.nodes('/root/value') Temp(node)       &lt;br /&gt;      &lt;br /&gt;&lt;/font&gt;&lt;font face="Courier"&gt;&amp;#160; set @result = @@error      &lt;br /&gt;&amp;#160; if @result &amp;lt;&amp;gt; 0 return @result       &lt;br /&gt;      &lt;br /&gt;&lt;font face="Courier"&gt;&amp;#160; // post processing…        &lt;br /&gt;&lt;/font&gt;end&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Исходные данные – это XML-документ с большим количеством&amp;#160; узлов вида &amp;lt;value seriesId=&amp;quot;200007&amp;quot; dateTime=&amp;quot;2009-06-01T00:00:00.0&amp;quot; value=&amp;quot;1.0&amp;quot; /&amp;gt;. Корневой элемент не обязателен, хотя в примере и присутствует.&lt;/p&gt;  &lt;p&gt;Ключевой момент процедуры - работа с XML напрямую безо всякого дополнительного мусора типа OPENXML, sp_xml_preparedocument/sp_xml_removedocument. &lt;/p&gt;  &lt;p&gt;Просто, удобно, быстро.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;UPDATE:&lt;/strong&gt; должен предупредить, что производительность этого решения для SQL 2008 ENT и SQL 2008 EXPRESS различается как минимум на три (!) порядка на одной и той же машине. По непонятным причинам экспресс конкретно тормозит. Такое впечатление, что он XPATH-парсер для каждого выражения заново загружает.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4226383850373882540-6757773302363695576?l=blog.ad.by' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ad.by/feeds/6757773302363695576/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4226383850373882540&amp;postID=6757773302363695576" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/6757773302363695576?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/6757773302363695576?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/adby/~3/EGn7eB-Au64/mssql-fast-data-upload.html" title="MSSQL – fast data upload" /><author><name>Павел</name><uri>http://www.blogger.com/profile/15160195043765368557</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08937323532063115147" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.ad.by/2009/07/mssql-fast-data-upload.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkEHSHw8eCp7ImA9WxNVE0w.&quot;"><id>tag:blogger.com,1999:blog-4226383850373882540.post-394895423281594056</id><published>2009-07-03T17:24:00.003+02:00</published><updated>2009-10-23T17:10:39.270+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-23T17:10:39.270+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="GAE" /><category scheme="http://www.blogger.com/atom/ns#" term="памятка" /><title>Google App Engine Datastore</title><content type="html">&lt;p&gt;Это пост-памятка — попытка собрать в одном месте факты о хранилище данных, которое предоставляет Google для разработчиков GAE.&lt;/p&gt;  &lt;p&gt;Они, конечно везде кричат что это, мол, bigtable, но конкретной технической информации на самом деле кот наплакал, в основе всего лежит &lt;a href="http://code.google.com/intl/ru/events/io/sessions/BuildingScalableComplexApps.html"&gt;две&lt;/a&gt; &lt;a href="http://sites.google.com/site/io/under-the-covers-of-the-google-app-engine-datastore"&gt;презентации&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Итак, что мы знаем о лисе:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Разработчик GAE получает кусок дискового пространства для хранения данных в &lt;strong&gt;Datastore&lt;/strong&gt;, которое называется &lt;strong&gt;the entities table&lt;/strong&gt;. &lt;/li&gt;    &lt;li&gt;Эта, гм, “таблица” условно делится на две “колонки”: ключ (&lt;strong&gt;entity key&lt;/strong&gt;) и сущность (&lt;strong&gt;serialized entity&lt;/strong&gt;). Т.е. это и близко не реляционное хранилище, это скорее persistence storage. &lt;/li&gt;    &lt;li&gt;Формат данных внутри этой таблицы называется &lt;strong&gt;&lt;a href="http://code.google.com/p/protobuf/"&gt;protocol buffers&lt;/a&gt;&lt;/strong&gt;. Он же используется в низкоуровневом API. &lt;/li&gt;    &lt;li&gt;Ключ имеет определенную структуру. Полный ключ каждой сущности имеет название (&lt;strong&gt;kind&lt;/strong&gt;), значение и может ссылаться на родительскую сущность (&lt;strong&gt;parent/ancestor entity&lt;/strong&gt;). Так что если мы храним иерархию из объектов, то ключи могут выглядеть так:       &lt;br /&gt;/Client:Bob       &lt;br /&gt;/Client:Bob/Contract:1       &lt;br /&gt;/Client:Bob/Contract:2       &lt;br /&gt;/Client:Alice/       &lt;br /&gt;/Client:Alice/Contract:1 &lt;/li&gt;    &lt;li&gt;Данные в &lt;strong&gt;the entities table &lt;/strong&gt;не лежат просто так. Их физическая укладка отсортирована по ключу: сущность без родителя (&lt;strong&gt;root entity&lt;/strong&gt;), её дочерний объект (&lt;strong&gt;child&lt;/strong&gt;), другая сущность без родителя и т.д. Это дает возможность сгруппировать обрабатываемые данные рядом и сильно экономить время чтения. &lt;/li&gt;    &lt;li&gt;Всё что относится к одной корневой сущности называется &lt;strong&gt;entity group&lt;/strong&gt;. В нашем примере их две: Bob и Alice. &lt;/li&gt;    &lt;li&gt;Запись с хранилищем осуществляется только в транзакции (&lt;strong&gt;txn&lt;/strong&gt;), зато можно читать без транзакций. И что ещё интереснее, обычные транзакции (&lt;strong&gt;local txns&lt;/strong&gt;)осуществляются именно в пределах &lt;strong&gt;entity group&lt;/strong&gt;, а если нужно обновить сущности в нескольких &lt;strong&gt;entity group&lt;/strong&gt;, то это уже издевательски именуется гугловцами как &lt;strong&gt;distributed transaction&lt;/strong&gt;. О, честь им и хвала! &lt;/li&gt;    &lt;li&gt;Транзакции двухфазные. После первой фазы обновлены все сущности, а после второй обновлены все индексы. Причем блокировок по сути нет - после первой фазы новые данные становятся доступны для чтения. Что дает разработчику уникальную возможность &lt;em&gt;запросить одни данные, а прочитать совсем другие&lt;/em&gt;! &lt;/li&gt;    &lt;li&gt;В случае физических сбоев самого хранилища транзакции накатываются (&lt;strong&gt;rolled forvard&lt;/strong&gt;)! Очень странное решение. Очень. Остается надеяться что этого на практике не бывает. &lt;/li&gt;    &lt;li&gt;Локальная транзакция вообще работает на журнальном принципе: каждая сущность хранит дату своей записи, а root entity хранит дату последнего обновления всей entity group. Обновление сущности просто делает копию этой сущности с измененными параметрами и новым временем записи, а первая фаза транзакции обновляет время в root entity. При перестроении индекса (вторая фаза) просто игнорируются сущности со старым временем. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;По хранилищу автоматически и вручную строятся индексы:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Само собой есть индекс по полному ключу. И везде подчеркивается что такой доступ самый быстрый. &lt;/li&gt;    &lt;li&gt;Есть индекс по &lt;strong&gt;kind&lt;/strong&gt;. Именно на него опирается эмуляция запросов вида &lt;em&gt;select * from Client&lt;/em&gt;. &lt;/li&gt;    &lt;li&gt;Есть индексы по одному свойству сущности (&lt;strong&gt;single-property index&lt;/strong&gt;). Такие индексы исходно двунаправлены и могут обрабатывать операции сравнения: больше, меньше и равно. На этих же индексах делается сортировка &lt;em&gt;order by. &lt;/em&gt;Такие индексы автоматически строятся для простых типов данных строк и чисел. &lt;/li&gt;    &lt;li&gt;А вот составные индексы (&lt;strong&gt;composite index&lt;/strong&gt;) нужно определять самостоятельно. Такие индексы могут включать несколько свойств и ссылку на предка (ancestor). &lt;/li&gt;    &lt;li&gt;Движок умеет делать слияние (&lt;strong&gt;merge join)&lt;/strong&gt;. Т.е. может использовать несколько single-property index и пересечь результаты отбора. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Проблемы хранилища: &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Бывают таймауты. Причины непонятны, отрапортовано давно, толку ноль. Т.е. приложение должно уметь обработать таймаут в любой момент. &lt;/li&gt;    &lt;li&gt;Иногда бывает техническое обслуживание: доступ только для чтения, отключение доступа. Т.е. приложение должно уметь обработать ограничения доступа в любой момент. &lt;/li&gt;    &lt;li&gt;&lt;strike&gt;И самое главное — непонятно как это обрабатывать на Яве, т.к. нужные исключения существуют только для питона. Т.е. API для java в принципе не содержит средств для обработки вышеописанных ситуаций.&lt;/strike&gt; Update: в последних SDK нужные исключения появились. &lt;/li&gt; &lt;li&gt;Update: Блокировки. При записи даже одного объекта блокируется запись во весь entity group. Так что entity groups должны быть маленькие. И желательно не иметь одних и тех же постоянно обновляемых мест. Именно поэтому разработчики упирают на технику называемую sharded counters.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Разные замечания:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt; Update: О скорости: на практике Native Datastore API на минимум порядок быстрее JDO/JPA. 46ms на одну запись одного объекта в хранилище. &lt;/li&gt;    &lt;li&gt;Долгая инициализация хранилища: у меня первый запрос занимает 2 секунды. &lt;/li&gt;    &lt;li&gt;Есть ряд приколов в работе с индексами. Например &lt;a href="http://appengine-cookbook.appspot.com/recipe/how-to-query-by-date-range/"&gt;попадание в диапазон&lt;/a&gt;. &lt;/li&gt; &lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4226383850373882540-394895423281594056?l=blog.ad.by' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ad.by/feeds/394895423281594056/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4226383850373882540&amp;postID=394895423281594056" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/394895423281594056?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/394895423281594056?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/adby/~3/mxdCChhM2Z4/google-app-engine-datastore.html" title="Google App Engine Datastore" /><author><name>Павел</name><uri>http://www.blogger.com/profile/15160195043765368557</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08937323532063115147" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.ad.by/2009/07/google-app-engine-datastore.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0EHQ3s9cCp7ImA9WxJVE0o.&quot;"><id>tag:blogger.com,1999:blog-4226383850373882540.post-4005304526377153988</id><published>2009-06-30T18:33:00.001+02:00</published><updated>2009-06-30T18:33:52.568+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-30T18:33:52.568+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="64-bit" /><category scheme="http://www.blogger.com/atom/ns#" term="windows" /><category scheme="http://www.blogger.com/atom/ns#" term="vpn" /><title>Free Cisco VPN client for Windows 7 64-bit</title><content type="html">&lt;p&gt;Итак, господа, свершилось. Несмотря на исключительное нежелание фирмы Cisco выпускать 64-битные клиенты к своему оборудованию, мир не без добрых людей.&lt;/p&gt;  &lt;p&gt;Встречаем нашего героя – &lt;a href="http://www.shrew.net/download/vpn/vpn-client-2.2.0-alpha-8.exe"&gt;Shrew vpn-client-2.2.0-alpha-8&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Именно он единственный без ошибок заработал на Windows 7 64-bit build 7100 в связке с CiscoASA. В тестировании в разное время также участвовали: предыдущие альфы этой фирмы, openvpn-2.1_rc15, vpncfe-0.7.1 и ещё ряд коммерческих участников. Все были забракованы как полный неработоспособный или неконфигурируемый бред. Наш выбор тоже не идеален, но он заработал, он бесплатен, его оказалось возможно отконфигурировать после чтения документации и его интерфейс не вызывает рвотных рефлексов.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4226383850373882540-4005304526377153988?l=blog.ad.by' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ad.by/feeds/4005304526377153988/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4226383850373882540&amp;postID=4005304526377153988" title="Комментарии: 1" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/4005304526377153988?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/4005304526377153988?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/adby/~3/VWcUSDnVk1Q/free-cisco-vpn-client-for-windows-7-64.html" title="Free Cisco VPN client for Windows 7 64-bit" /><author><name>Павел</name><uri>http://www.blogger.com/profile/15160195043765368557</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08937323532063115147" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://blog.ad.by/2009/06/free-cisco-vpn-client-for-windows-7-64.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0EDQnk7fip7ImA9WxVSGU4.&quot;"><id>tag:blogger.com,1999:blog-4226383850373882540.post-6909463658982121439</id><published>2009-01-14T15:27:00.001+02:00</published><updated>2009-01-14T15:27:53.706+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-01-14T15:27:53.706+02:00</app:edited><title>VML &amp; IE8b2</title><content type="html">Майкрософт сильно взялся за браузер. Изменений очень много. В том числе и касающихся VML.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Подключение&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;Подключение VML теперь выполняется только специальной строкой в head-секции&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="font-style: italic;"&gt;&amp;lt;?import namespace="v" urn="urn:schemas-microsoft-com:vml" implementation="#default#VML" declareNamespace ?&amp;gt;&lt;br /&gt;&lt;/span&gt;Эта же строка отлично работает и в IE 6-7. Т.е. обнаружился единый простой способ подключения VML, что хорошо.&lt;span style="font-style: italic;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;CSS&lt;/span&gt;&lt;br /&gt;Про &lt;span style="font-style: italic;"&gt;*:\&lt;/span&gt; в CSS&amp;nbsp; для IE8 можно забыть - такой синтаксис нестандартен и более не поддерживается. Для IE6-7 по прежнему необходимо указывать  &lt;span style="font-style: italic;"&gt;что-то вроде v\:shape { display: inline-block; }&lt;/span&gt;, но для IE8 это не нужно.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Баги&lt;br /&gt;&lt;/span&gt;Самое неприятное изменение, возможно это баг и будет исправлен в релизе браузера — VML-теги не желают брать свои размеры из браузера автоматически. Теперь требуется точное указание размера, процентами не отделаться. Это обесценивает техники основанные на смеси html- и vml-тегов. Т.е., например, невозможно сделать резиновую рамку на теге v:roundrect как я это &lt;a href="http://blog.ad.by/2008/03/nice-rounded-corners-for-ie-safari.html"&gt;делал ранее&lt;/a&gt;. Впрочем, повторюсь, возможно это ещё будет изменено.&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;Также присутствует непонятный баг с загрузкой изображений через v:image - иногда изображение не загружается. Закономерности не уловил.&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4226383850373882540-6909463658982121439?l=blog.ad.by' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ad.by/feeds/6909463658982121439/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4226383850373882540&amp;postID=6909463658982121439" title="Комментарии: 2" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/6909463658982121439?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/6909463658982121439?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/adby/~3/R0YSykFsRUw/vml-ie8b2.html" title="VML &amp;amp; IE8b2" /><author><name>Павел</name><uri>http://www.blogger.com/profile/15160195043765368557</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08937323532063115147" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://blog.ad.by/2009/01/vml-ie8b2.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEACQH46fyp7ImA9WxRUEEw.&quot;"><id>tag:blogger.com,1999:blog-4226383850373882540.post-3346390553447209173</id><published>2008-11-18T15:59:00.001+02:00</published><updated>2008-11-18T15:59:21.017+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-11-18T15:59:21.017+02:00</app:edited><title>jQuery &amp; JavaScript Memory Leaks</title><content type="html">&lt;font style="font-family: Arial;" size="3"&gt;Перебирал я как-то старые закладки. Накопилось же всякого. Ну, например, куча ссылок по борьбе с утечками памяти:&lt;br /&gt;&lt;/font&gt;&lt;ol style="font-family: Arial;"&gt;&lt;li&gt;&lt;font size="3"&gt;&lt;a href="http://webo.in/articles/habrahabr/18-solving-internet-explorer-memory-leaks/"&gt;Практический JS: избавляемся от утечек памяти в IE&lt;/a&gt;&lt;/font&gt;&lt;/li&gt;&lt;li&gt;&lt;font size="3"&gt;&lt;a href="http://web-log.ru/?p=21"&gt;Как избавиться от утечки памяти при использовании Javascript в Internet Explorer&lt;/a&gt;&lt;/font&gt;&lt;/li&gt;&lt;li&gt;&lt;font size="3"&gt;&lt;a href="http://blogs.msdn.com/gpde/pages/javascript-memory-leak-detector.aspx"&gt;JavaScript Memory Leak Detector&lt;/a&gt;&lt;/font&gt;&lt;/li&gt;&lt;li&gt;&lt;font size="3"&gt;&lt;a href="http://outofhanwell.com/ieleak/index.php?title=Main_Page"&gt;IE Memory Leaks&lt;/a&gt;&lt;/font&gt;&lt;/li&gt;&lt;/ol&gt;&lt;font style="font-family: Arial;" size="3"&gt;Да только с тех пор как я это прочел и попробовал, я нашел, как мне кажется, универсальный рецепт борьбы с утечками. И имя ему - &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt;. Мой код по большей части превратился в код без постоянных ссылок на DOM, которые и являются источником проблем.&lt;br /&gt;Типичный пример кода:&lt;/font&gt;&lt;br /&gt;&lt;div style="font-family: Courier;"&gt;&lt;font size="2"&gt;&amp;lt;script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js" type="text/javascript"&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;script type="text/javascript"&amp;gt;&lt;br /&gt;&amp;nbsp; $("#gmap").load(function() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; $("#loading").hide();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; $(this).show();&lt;br /&gt;&amp;nbsp; });&lt;br /&gt;&lt;br /&gt;&amp;nbsp; $("#hmap").load(function() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; $(this).show();&lt;br /&gt;&amp;nbsp; }).attr("src", "hs.png");&lt;br /&gt;&lt;br /&gt;&amp;nbsp; $("#hublist").bind("change keyup", function() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; with ($("#gmap")) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var newurl = 'http://maps.google.com/staticmap?zoom=5&amp;amp;size=640x640&amp;amp;format=png8&amp;amp;center=' +&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ["57,40", "50,41", "57,42", "57,43", "57,48", "57,49"][this.value - 1];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (attr("src") != newurl) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $("#loading").show();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; attr("src", newurl);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; }).focus().change();&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;font size="3"&gt;&lt;span style="font-family: Arial;"&gt;В общем, применение jQuery дает чистый, стабильный код.&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4226383850373882540-3346390553447209173?l=blog.ad.by' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ad.by/feeds/3346390553447209173/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4226383850373882540&amp;postID=3346390553447209173" title="Комментарии: 1" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/3346390553447209173?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/3346390553447209173?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/adby/~3/Mw05wpSTb5Y/jquery-javascript-memory-leaks.html" title="jQuery &amp;amp; JavaScript Memory Leaks" /><author><name>Павел</name><uri>http://www.blogger.com/profile/15160195043765368557</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08937323532063115147" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://blog.ad.by/2008/11/jquery-javascript-memory-leaks.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkUMSHczeip7ImA9WxNXGEw.&quot;"><id>tag:blogger.com,1999:blog-4226383850373882540.post-8451356033355036729</id><published>2008-10-02T11:40:00.002+02:00</published><updated>2009-10-06T09:31:29.982+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-06T09:31:29.982+02:00</app:edited><title>Extreme PNG optimizing and compressing</title><content type="html">На этот раз поговорим о такой затертой теме, как уменьшение размера PNG-файлов. Казалось бы — куча информации, множество утилит. Даже в &lt;a href="http://www.artlebedev.ru/tools/technogrette/img/png-4/"&gt;техногрете&lt;/a&gt; тему достаточно подробно обсудили. Осталось только подвести внятный итог. Итак,&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Задача&lt;br /&gt;&lt;/span&gt;Найти лучшие бесплатные утилиты для сжатия PNG и научиться качественно ими пользоваться.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Теория&lt;/span&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;PNG-файл состоит из нескольких информационных блоков. Многие из них содержит вспомогательную информацию о изображении и для отображения не нужны. Т.е можно просто выбросить необязательные блоки.&lt;/li&gt;&lt;li&gt;Можно оптимизировать тип изображения, хранимого в файле. PNG понимает их аж пять штук: от ЧБ до полноцветного с прозрачностью.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Можно оптимизировать палитру изображения или снизить количество бит на пиксель: даже в полноцветных изображениях цветов может оказаться немного.&lt;/li&gt;&lt;li&gt;Можно поиграться с дельта-фильтрами сжатия. У PNG их опять-таки пять.&lt;/li&gt;&lt;li&gt;Можно поиграться с алгоритмами сжатия. И тут есть, где разыграться.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;Решение&lt;br /&gt;&lt;/span&gt;Путем экспериментов было выяснено, что лучше всего использовать пару утилит - &lt;a href="http://optipng.sourceforge.net/"&gt;optipng&lt;/a&gt; и &lt;a href="http://advsys.net/ken/utils.htm"&gt;pngout&lt;/a&gt;. Optipng умеет понижать битность и перебирать дельта-фильтры. Pngout умеет удалять ненужные блоки и имеет непревзойденную степень сжатия. Правда чтобы добиться этого приходится перебирать её параметры, а работает pngout крайне медленно. Pngout имеет и более серьезную версию - PngoutWin. Эта умеет перебирать ключи автоматически, но стоит денег. Что не подходит.&lt;br /&gt;Путем экспериментов определился достаточно быстрый алгоритм работы:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Сначала запускаем &lt;span style="font-style: italic;"&gt;optipng&lt;/span&gt; с ключами &lt;span style="font-style: italic;"&gt;-o4 -full -force&lt;/span&gt;. Этим мы заставляем утилиту быстро перебрать самые оптимальные варианты сжатия и оптимизировать палитру/битность изображения.&lt;/li&gt;&lt;li&gt;Потом мы запускаем &lt;span style="font-style: italic;"&gt;pngout&lt;/span&gt; с ключами /k0 /fX. На место X нужно подставить значение параметра "f", выданное &lt;span style="font-style: italic;"&gt;optipng&lt;/span&gt;. Такая подстановка сильно сэкономит нам время, почти избавив нас от необходимости перебирать ключи у &lt;span style="font-style: italic;"&gt;pngout.&lt;/span&gt; Кстати, также имеет смысл поэкспериментировать с ключом /n.&lt;span style="font-style: italic;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-weight: bold;"&gt;Итог&lt;br /&gt;&lt;/span&gt;Указанная комбинация проигрывает платному &lt;span style="font-weight: bold;"&gt;&lt;/span&gt;PngoutWin на считанные байты. А при использовании ключа /n даже неплохо выигрывает у него.&lt;br /&gt;Ну и завершающий штрих - &lt;a href="http://www.ad.by/png-test/crunch.cmd"&gt;cmd-файл для автоматизации этого процесса&lt;/a&gt;:&lt;br /&gt;&lt;div style="margin-left: 40px; font-family: Courier;"&gt;&lt;font size="2"&gt;@echo off&lt;br /&gt;optipng -o4 -full -force %1 &amp;gt; optipng.log || exit 1&lt;br /&gt;for /f "delims==,IDAT tokens=5" %%i in (optipng.log) do (&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; set f=%%i&lt;br /&gt;)&lt;br /&gt;set f=%f:~1,1%&lt;br /&gt;del optipng.log&lt;br /&gt;pngout /k0 /n2 /f%f% %1 || exit 3&lt;br /&gt;&lt;/font&gt;&lt;/div&gt;&lt;font size="3"&gt;Как легко заметить, мне подошел параметр &lt;/font&gt;&lt;font size="2"&gt;&lt;font size="3"&gt;/n2. Не факт что на ваших файлах это будет оптимально, но у меня исключений не нашлось.&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;/font&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4226383850373882540-8451356033355036729?l=blog.ad.by' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ad.by/feeds/8451356033355036729/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4226383850373882540&amp;postID=8451356033355036729" title="Комментарии: 2" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/8451356033355036729?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/8451356033355036729?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/adby/~3/zqJ6OhAkBsc/extreme-png-optimizing-and-compressing.html" title="Extreme PNG optimizing and compressing" /><author><name>Павел</name><uri>http://www.blogger.com/profile/15160195043765368557</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08937323532063115147" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://blog.ad.by/2008/10/extreme-png-optimizing-and-compressing.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak4BRnc8cSp7ImA9WxRRFkQ.&quot;"><id>tag:blogger.com,1999:blog-4226383850373882540.post-3386896622658281458</id><published>2008-09-25T11:17:00.002+02:00</published><updated>2008-09-29T16:35:57.979+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-09-29T16:35:57.979+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="SWF" /><category scheme="http://www.blogger.com/atom/ns#" term="AS3" /><category scheme="http://www.blogger.com/atom/ns#" term="Flex" /><title>SWF compilation date</title><content type="html">Бывают случаи, когда разработчикам нужно решить достаточно простую, я бы сказал даже, банальную задачу: вставить в код программы номер версии или дату компиляции приложения. Эта информация чрезвычайно полезна при последующем сопровождении: ведь всегда нужно знать, с какой версией имеешь дело.&lt;br /&gt;&lt;br /&gt;Столкнувшись с этой задачей, я с удивлением обнаружил, что готовых средств для её решения во Flex3/Flex4 нет. Это крайне странно. Не могли же профессиональные разработчики забыть о такой необходимой вещи! И действительно, расследование показало, что внутри SWF-файлов всегда присутствуют определенные части, изменяющиеся при каждой компиляции. Именно этим и объясняется тот факт, что при перекомпиляции проекта результат часто имеет другой размер — файлы SWF сжаты, а результат работы упаковщика зависит от входных данных, которые, как я уже говорил, меняются всегда. Более пристальный взгляд показал, что в файле изменяется часть структуры, которая именуется декомпиляторами не иначе как &lt;span style="font-style: italic;"&gt;SERIALNUMBER&lt;/span&gt;. Эта структура не документирована, но исследование показало, что в конце её лежит целое число 8-ми байт длиной. Число это - количество миллисекунд с начала 1970-года. Т.е. это ровно то, что возвращает свойство &lt;span style="font-style: italic;"&gt;time&lt;/span&gt; у объекта &lt;span style="font-style: italic;"&gt;Date&lt;/span&gt;. Осталась самая малость - прочесть из SWF своё код, найди в нем эту структуру и прочитать её последние 8 байт. Вопрос доступа к собственному коду — это, безусловно, интересная головоломка, но решилась достаточно быстро:&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; LoaderInfo.getLoaderInfoByDefinition(this).bytes;&lt;/span&gt;&lt;br /&gt;Структура SWF-файла документирована, так что далее было легко. &lt;br /&gt;&lt;br /&gt;Готовый код выложен на &lt;a href="http://code.google.com/p/flex-ad-by/"&gt;http://code.google.com/p/flex-ad-by/&lt;/a&gt;&lt;br /&gt;Достаточно просто вызвать метод SWF.readCompilationDate().&lt;br /&gt;Лицензия — BSD, что, по моему, свободнее некуда. Проверено во Flex3/Flex4. Пользуйтесь на здоровье.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4226383850373882540-3386896622658281458?l=blog.ad.by' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ad.by/feeds/3386896622658281458/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4226383850373882540&amp;postID=3386896622658281458" title="Комментарии: 6" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/3386896622658281458?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/3386896622658281458?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/adby/~3/IRmVggFUNCY/swf-compilation-date.html" title="SWF compilation date" /><author><name>Павел</name><uri>http://www.blogger.com/profile/15160195043765368557</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08937323532063115147" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">6</thr:total><feedburner:origLink>http://blog.ad.by/2008/09/swf-compilation-date.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkQDRn04fCp7ImA9WxNXGEw.&quot;"><id>tag:blogger.com,1999:blog-4226383850373882540.post-5055915264510648109</id><published>2008-08-11T01:32:00.002+02:00</published><updated>2009-10-06T09:32:57.334+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-06T09:32:57.334+02:00</app:edited><title>Easy Way to Embed Transparent PNG24 into IE6 without JavaScript (vml xhtml)</title><content type="html">Итак, есть задача - отобразить полупрозрачный png24:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Способ должен работать везде, в том числе и в IE6 (и IE5 тоже было бы неплохо);&lt;/li&gt;&lt;li&gt;Код должен быть семантичным;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Картинка не является фоновой, но подумать о фоновом PNG не помешает;&lt;/li&gt;&lt;li&gt;Желательно обойтись без яваскрипта;&lt;/li&gt;&lt;li&gt;Посторонние визуальные эффекты недопустимы;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Тормоза недопустимы;&lt;/li&gt;&lt;li&gt;Лишние запросы на сервер и лишний трафик крайне нежелательны;&lt;/li&gt;&lt;li&gt;Код должен быть валидным;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;При невозможности соблюдения всех вышеперечисленных условий должен соблюдаться принцип graceful degradation.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-weight: bold;"&gt;Решение&lt;/span&gt;&lt;br /&gt;И, как всем известно, есть одна маленькая проблема - версии IE младше седьмой полупрозрачный PNG отобразить не в силах. Решений множество, но все они мне не нравятся по причине плохого качества - в них не соблюдается принцип graceful degradation [9] или [2, 4, 6, 7].&lt;br /&gt;По сути нужно решить две задачи:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Выделить IE6-, оставив остальным просто тег img.&lt;br /&gt;Это достаточно просто реализуется через условные комментарии для IE. Это просто волшебная вещь. &lt;br /&gt;&lt;span style="font-style: italic;"&gt;[if (lt IE 7)&amp;amp;vml]&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Вылечить IE6-.&lt;br /&gt;Обычно все используют фильтры и JS, что и приводит к [5, 6]. Но есть способ лучше! Это VML! Поддерживается начиная с IE5.&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&amp;lt;v:image src="flower.png" style="width:85px;height:88px;" /&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;В очередной раз убеждаюсь, что тестировать нужно только в реальном окружении! Что эмуляторы IE врут безбожно. Забудьте по MultipleIEs и IETester. Поставьте &lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=28C97D22-6EB8-4A09-A7F7-F6C7A1F000B5&amp;amp;displaylang=en"&gt;официально бесплатную виртуальную машину&lt;/a&gt; от майкрософт с &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=21EABB90-958F-4B64-B5F1-73D0A413C8EF&amp;amp;displaylang=en"&gt;официально бесплатным образом нужной винды&lt;/a&gt; и увидите разницу.&lt;br /&gt;Кстати, валидатор от W3C таки научился понимать пространства имен. Это позволяет не использовать условные комментарии для включения VML.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Особенности метода&lt;/span&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Картинка должна иметь указанный размер, иначе не будет показана;&lt;/li&gt;&lt;li&gt;Картинка должна иметь точно указанный размер, иначе будет отмасштабирована;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Бывают непонятные смещения в 1px. Лечится через margin;&lt;/li&gt;&lt;li&gt;До работы с фоновым изображением у меня руки не дошли, теоретически это тоже можно эмулировать через v:image. Когда понадобится - решу и эту проблему.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-weight: bold;"&gt;Глюки &lt;/span&gt;&lt;ol&gt;&lt;li&gt;Неполноценное кеширование [7]. IE6 всегда будет посылать лишние запросы If-Modified-Since. В IE7 это залечили, кстати, но нам это сейчас бесполезно. Решить эту проблему в IE6 мне не удалось;&lt;/li&gt;&lt;li&gt;Значок и контур на месте загружаемой картинки [5]. Очень неприятно. Очень. Т.е. не работает нормальная интеграция в DOM и браузер не в состоянии определить загружена картинка или нет. Решить эту проблему мне не удалось.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-weight: bold;"&gt;Заключение&lt;/span&gt;&lt;br /&gt;Я считаю, что эти глюки не противоречат [9]. Доля IE6 падает и проблема уходит. А пока она не ушла совсем, то можно и потерпеть, если пользуешься устаревшим браузером. Безусловно, всем этот метод не всем подходит, но на моих проектах доля IE6 уже менее 15%. Прогресс идет.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.ad.by/png-test/ie6_transparent_png24.html"&gt;Демонстрация&lt;/a&gt;. Обратите внимание на лечение однопиксельного сдвига. А также на включение VML и на условные комментарии, если ранее не сталкивались.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Похоже, я первый, кто опубликовал такой метод. На мой взгляд это достаточно красивое решение. Я был бы очень благодарен за любые отзывы, критику и сообщения об ошибках.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4226383850373882540-5055915264510648109?l=blog.ad.by' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ad.by/feeds/5055915264510648109/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4226383850373882540&amp;postID=5055915264510648109" title="Комментарии: 3" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/5055915264510648109?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/5055915264510648109?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/adby/~3/PrYeMWw-e5Y/easy-way-to-embed-transparent-png24.html" title="Easy Way to Embed Transparent PNG24 into IE6 without JavaScript (vml xhtml)" /><author><name>Павел</name><uri>http://www.blogger.com/profile/15160195043765368557</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08937323532063115147" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total><feedburner:origLink>http://blog.ad.by/2008/08/easy-way-to-embed-transparent-png24.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkMARXY5fyp7ImA9WxNXGEw.&quot;"><id>tag:blogger.com,1999:blog-4226383850373882540.post-5155591617441324607</id><published>2008-08-10T22:49:00.002+02:00</published><updated>2009-10-06T09:34:04.827+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-06T09:34:04.827+02:00</app:edited><title>The Best Way to Embed Flash 9 into XHTML without JavaScript, part I</title><content type="html">Я тут совершенно случайно ввязался в масштабное исследование, посвященное внедрению флеша в страницы. Точнее, я просто не подозревал, что вокруг столь небольшой темы написано просто умопомрачительное количество некорректной информации.&lt;br /&gt;&lt;br /&gt;Итак, необходимо внедрить Flash 9 (AVM2) и при этом достигнуть баланса со следующим списком требований:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Должно играть до полной загрузки ролика (streaming);&lt;/li&gt;&lt;li&gt;Должна работать коммуникация Flash с браузером, в обе стороны;&lt;/li&gt;&lt;li&gt;Должно работать во всех более-менее заметных браузерах;&lt;/li&gt;&lt;li&gt;Должно работать с типом контента application/xhtml+xml для xhtml;&lt;/li&gt;&lt;li&gt;Нежелательны лишние запросы на сервер;&lt;/li&gt;&lt;li&gt;Категорически нежелательны посторонние визуальные эффекты;&lt;/li&gt;&lt;li&gt;Решение должно быть валидным;&lt;/li&gt;&lt;li&gt;Если плагина нет - должен ставиться, если плагин устарел - должен обновляться;&lt;/li&gt;&lt;li&gt;Очень хотелось бы обойтись без яваскрипта;&lt;/li&gt;&lt;li&gt;Желательна отдача referer при загрузке swf, а то ходят слухи, что иногда не отдается;&lt;/li&gt;&lt;li&gt;Желательна работа при режиме высокой безопасности в IE и при отключенном ActiveX;&lt;/li&gt;&lt;li&gt;Отсутствие глюков - чтобы параметры передавались, прозрачность работала и т.д.;&lt;/li&gt;&lt;li&gt;Семантичность - отсутствие лишних сущностей в коде;&lt;/li&gt;&lt;li&gt;Отсутствие необходимости щелкать для активации в IE и Opera;&lt;/li&gt;&lt;li&gt;При невозможности соблюдения всех вышеперечисленных условий должен соблюдаться принцип graceful degradation.&lt;/li&gt;&lt;/ol&gt;Изучение темы показало, что используются следующие основные способы внедрения флеша в страницу:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;через тег embed;&lt;/li&gt;&lt;li&gt;через тег object;&lt;/li&gt;&lt;li&gt;также можно воспользоваться JS-библиотекой типа SWFObject2;&lt;/li&gt;&lt;li&gt;комбинация вложенных тегов object или object&amp;amp;embed. &lt;/li&gt;&lt;/ol&gt;&lt;span style="font-weight: bold;"&gt;Начнем с JS [9]&lt;/span&gt;&lt;br /&gt;Честно говоря, смысл использования SWFObject от меня ускользнул. Если не вкладывать никакого дополнительного смысла в море статей о нем, то все речи сводятся к &lt;a href="http://en.wikipedia.org/wiki/Eolas"&gt;щелчку для активации&lt;/a&gt;, невнятному "упрощению интеграции" и "определении версии плеера". Первое быстро становится неактуально, т.к. майкрософт &lt;a href="http://blogs.msdn.com/ie/archive/2008/04/08/ie-automatic-component-activation-now-available.aspx"&gt;убрал эту необходимость&lt;/a&gt;. Второе - простно враньё, ведь процесс только замедляется [5, 9], становится менее надежным [3] и работает не всегда [4, 9]. Третье - тема необычайно сложная и не от SWFObject в ней всё зависит. А нужно, чтобы работало [8]. &lt;br /&gt;Поэтому, по возможности, сторонние JS-библиотеки я постараюсь не использовать.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Режим высокой безопасности в IE [11]&lt;/span&gt;&lt;br /&gt;В этом случае всё печально - Flash работать не будет. Совсем, как не исхитряйся.&lt;br /&gt;Нюансы в IE:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Embed не работает (работает только noembed), но IE ничего не сообщает и не предлагает. Что плохо. И, кстати, атрибут PLUGINSPAGE в IE не работает [8];&lt;/li&gt;&lt;li&gt;При использовании object IE7 выдает желтую полосу с предупреждение, что ActiveX отключен и ссылку на справку. Что неплохо.&lt;/li&gt;&lt;/ol&gt;Т.е. [11] из списка требований исключается ввиду нереализуемости.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;embed&lt;/span&gt;&lt;br /&gt;Это тег старый, на данный момент абсолютно нестандартный, но зато поддерживаемый почти всем чем только можно. Кстати, имеет все шансы &lt;a href="http://dev.w3.org/html5/spec/#embed"&gt;реинкарнироваться в html5&lt;/a&gt;. Всем хорош, только есть у него несколько родовых травм: сейчас невалиден [7] и, главное, совсем не работает мост JS-to-AVM2 [2] во всех версиях IE. Работает только SetVariable для AVM1. Также есть вышеописанная проблема с [11]. Т.е. применение этого тега возможно, но только в некоторых случаях: не нужен JS или не нужен IE. Увы, это не ко мне. Копаем дальше.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Комбинация вложенных тегов object или object&amp;amp;embed&lt;/span&gt;&lt;br /&gt;На мой взгляд, вложенные теги - бестолковая комбинация [13], права на жизнь не имеет. Лишняя возня с определением реально используемого тега ID для JS не добавляет привлекательности. object&amp;amp;embed - это вообще не пойми что по причине вышеописанных проблем у embed. Изначально, наверное, идея была в том, чтобы обойти браузеры не поддерживающие тег object, но такие экземпляры вымерли ещё 10 лет назад даже на мобильных устройствах.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;  &lt;br /&gt;А вот пара тегов object и условных комментариев явно имеет право на жизнь, хотя и усложняет код.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;object&lt;/span&gt;&lt;br /&gt;Тег рекомендован W3C, так что в теории всё должно быть хорошо. Но на практике имеется миллион глюков и куча устаревшей и мусорной информации вокруг его использования. Честно говоря, умаялся я этот мусор разгребать, всё описывать не буду, только основные находки и соображения:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Указывать атрибут classid для IE нет необходимости. Отлично работает и просто type="application/x-shockwave-flash";&lt;/li&gt;&lt;li&gt;Наличие атрибута data убивает streaming в IE [1]! Кроме того, IE ещё и уродливую рамку на месте объекта отображает, пока всё не загрузит [6];&lt;/li&gt;&lt;li&gt;Отсутствие атрибута data приводит к незагрузке ролика в Firefox! А вот всем остальным браузерам достаточно параметра movie;&lt;/li&gt;&lt;li&gt;Атрибут STANDBY, позволяющий разместить комментарий типа "Идет загрузка" пока грузится swf не работает в IE. В остальных не проверял, т.к. во всех остальных всегда работает streaming;&lt;/li&gt;&lt;li&gt;Атрибут codebase="http://fpdownload.adobe.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,124,0" отлично работает в IE, но не работает в остальных браузерах. А IE предлагает загрузить новую версию плеера, если текущая устарела. Наверное лучше, по возможности, использовать "#version=9,0,0,0" т.к. майкрософт распространяет версию 9,0,115,0 в составе SP3. Этим мы несколько уменьшим кол-во загрузок, т.е. будем меньше беспокоить наших пользователей;&lt;/li&gt;&lt;li&gt;Атрибут codetype можно не использовать, т.к. type достаточно;&lt;/li&gt;&lt;li&gt;Эксперименты с атрибутами тега param valuetype и type не увенчались успехом;&lt;/li&gt;&lt;li&gt;Эксперименты с data="data:application/x-shockwave-flash," не увенчались успехом.&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-weight: bold;"&gt;Возможные решения&lt;/span&gt;&lt;br /&gt;Видно, что всё вертится вокруг борьбы с атрибутом data:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Можно не бороться, а одновременно использовать и атрибут data, и параметр movie.&lt;span style="font-style: italic;"&gt;&lt;br /&gt;&amp;lt;object width="400" height="300" type="application/x-shockwave-flash"&lt;/span&gt;&lt;span style="font-style: italic;"&gt; data="http://example.org/flash.swf"&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-style: italic;"&gt;&amp;nbsp; &amp;lt;param name="movie" value="http://example.org/flash.swf"&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-style: italic;"&gt;&amp;lt;/object&amp;gt;&lt;br /&gt;&lt;/span&gt;Работать будет везде, но в IE работать будет уродливо.&lt;/li&gt;&lt;li&gt;Можно бороться только с Firefox присвоением data через JS&lt;span style="font-style: italic;"&gt;&lt;br /&gt;&amp;lt;object id="swf1" width="400" height="300" type="application/x-shockwave-flash"&amp;gt;&lt;/span&gt;&lt;span style="font-style: italic;"&gt;&lt;br /&gt;&amp;nbsp; &amp;lt;param name="movie" value="http://example.org/flash.swf"&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-style: italic;"&gt;&amp;lt;/object&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-style: italic;"&gt;&amp;lt;js&amp;gt; document.getElementById("swf1").data = "http://example.org/flash.swf" &amp;lt;/js&amp;gt;&lt;br /&gt;&lt;/span&gt;Причем на firefox можно и не проверять - отлично работает и без этого.&lt;br /&gt;Способ в целом неплохой, но требует включенного JS под Firefox.&lt;/li&gt;&lt;li&gt;Можно бороться только с IE через условные комментарии&lt;span style="font-style: italic;"&gt;&lt;br /&gt;&amp;lt;!--[if IE]&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-style: italic;"&gt;&amp;nbsp; &amp;lt;object id="swf1" width="400" height="300" type="application/x-shockwave-flash"&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-style: italic;"&gt;&amp;lt;![endif]--&amp;gt;&lt;/span&gt;&lt;span style="font-style: italic;"&gt;&lt;br /&gt;&amp;lt;!--[if !IE]&amp;gt;&amp;lt;--&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-style: italic;"&gt;&amp;nbsp; &amp;lt;object id="swf1" width="400" height="300" type="application/x-shockwave-flash"&lt;/span&gt;&lt;span style="font-style: italic;"&gt; data="http://example.org/flash.swf"&amp;gt;&lt;/span&gt;&lt;span style="font-style: italic;"&gt;&lt;br /&gt;&amp;lt;!--&amp;gt;&amp;lt;![endif]--&amp;gt;&lt;/span&gt;&lt;span style="font-style: italic;"&gt;&lt;br /&gt;&amp;nbsp; &amp;lt;param name="movie" value="http://example.org/flash.swf"&amp;gt;&lt;/span&gt;&lt;span style="font-style: italic;"&gt;&lt;br /&gt;&amp;lt;/object&amp;gt;&lt;br /&gt;&lt;/span&gt;Это, пожалуй самое лучшее решение. Работает везде (похоже, что вообще в абсолютно всех браузерах) и работает красиво, плавно, без посторонних эффектов.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;Понятное дело, что я за последний вариант. Замечания по нему: &lt;br /&gt;&lt;ol&gt;&lt;li&gt;Небольшое дублирование кода. Настолько небольшое, что это и недостатком сложно назвать;&lt;/li&gt;&lt;li&gt;Забыли про щелчки для активации;&lt;/li&gt;&lt;li&gt;Забыли про альтернативный контент, и про инсталляцию плеера, если его нет;&lt;/li&gt;&lt;li&gt;Забыли про обновление плеера, если устарел.&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-weight: bold;"&gt;Обновление и инсталляция плеера&lt;/span&gt;&lt;br /&gt;Это тема сложная, достойная рассмотрения в следующей (ещё не написанной) части статьи, поэтому сейчас ограничусь общими соображениями:&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;ol&gt;&lt;li&gt;Вообще-то плеер умеет обновляться и сам. Он проверяет наличие обновлений при загрузке очередного ролика, но не чаще чем раз в 30 дней. Можно и помочь браузеру обновит плеер, задав атрибут codebase="http://fpdownload.adobe.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0". Это имеет смысл только для IE, т.к. codebase должен указывать только на свой домен, что в данном случае не соблюдается. IE на это плюет, а остальные блюдут. Причем, можно не повторять codebase у каждого тега object, а ограничиться однократным упоминанием. &lt;/li&gt;&lt;li&gt;Если плеера нет, или он недоступен, то будет отображен так называемый альтернативный контент. Соответственно, нужно этим контентом сказать пользователю, что ему нужно установить плеер.&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&amp;lt;a href="http://www.adobe.com/go/getflashplayer"&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-style: italic;"&gt;Для корректной работы сайта вам необходимо установить проигрыватель Adobe Flash&amp;lt;br /&amp;gt;&lt;/span&gt;&lt;span style="font-style: italic;"&gt;&lt;br /&gt;&amp;lt;img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Установить" /&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;&lt;/span&gt;А если используется IE, то теоретически можно и ничего не говорить, т.к. вначале отработает предложение установить плагин по codebase, а после этого пользователь должен пенять на себя.&lt;br /&gt;&lt;font size="2"&gt;Кстати, заметили, что все ссылки уже давно переехали с macromedia.com на adobe.com?&lt;/font&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-weight: bold;"&gt;Щелчок для активации&lt;/span&gt;&lt;br /&gt;Это, пожалуй, самая большая проблема, также достойная рассмотрения в следующей (ещё не написанной) части статьи. На данный момент щелчка требуют IE6 и IE7 без последних обновлений и Opera9. Т.е. проблема вроде как изживает сама себя, но всё-таки хотелось бы решить красиво. Жаль, что программно узнать необходимость фикса невозможно.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Заключение&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;Вот ссылки на пример:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.ad.by/flash-test/flash.html"&gt;HTML&lt;/a&gt; (Content-Type: text/html); &lt;/li&gt;&lt;li&gt;&lt;a href="http://www.ad.by/flash-test/flash.xhtml"&gt;XHTML&lt;/a&gt; (Content-Type: application/xhtml+xml) - напоминаю, xhtml в IE не работает.&lt;/li&gt;&lt;/ul&gt;Предложено достаточно элементарное, но весьма даже рабочее решение. Работа над недоработками ведется. Исследована применимость тега embed, который также небезынтересен. &lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Я специально оговорюсь: я знаю, что я не открыл Америку. Как минимум один человек из Чехии уже публиковал &lt;a href="http://latrine.dgx.cz/how-to-correctly-insert-a-flash-into-xhtml"&gt;аналогичное решение&lt;/a&gt;, но проблема в том, что очень часто чтобы задать вопрос нужно знать ответ. Этой заметкой я описываю не только найденное решение, но и кучу сопутствующей информации. Надеюсь, кому-нибудь это поможет. Кроме того, работа не окончена, я ещё буду возвращаться к этой теме. Я был бы очень благодарен за любые отзывы, критику и сообщения об ошибках.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4226383850373882540-5155591617441324607?l=blog.ad.by' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ad.by/feeds/5155591617441324607/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4226383850373882540&amp;postID=5155591617441324607" title="Комментарии: 4" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/5155591617441324607?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/5155591617441324607?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/adby/~3/uZce3tMZKuY/best-way-to-embed-flash-9-into-xhtml.html" title="The Best Way to Embed Flash 9 into XHTML without JavaScript, part I" /><author><name>Павел</name><uri>http://www.blogger.com/profile/15160195043765368557</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08937323532063115147" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total><feedburner:origLink>http://blog.ad.by/2008/08/best-way-to-embed-flash-9-into-xhtml.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0UBR3cyfyp7ImA9WxdVFko.&quot;"><id>tag:blogger.com,1999:blog-4226383850373882540.post-7106570703733620051</id><published>2008-07-22T00:27:00.001+02:00</published><updated>2008-07-22T00:27:36.997+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-07-22T00:27:36.997+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ie" /><category scheme="http://www.blogger.com/atom/ns#" term="памятка" /><category scheme="http://www.blogger.com/atom/ns#" term="html" /><title>Advanced Conditional Comments in IE</title><content type="html">Я тут задумал кое о чем вам рассказать, но в процессе экспериментов натолкнулся на несколько интересных и не очень известных мелочей, о коих, собственно, расcкажу в первую очередь. Заодно мне памятка будет. Этот пост посвящен первой такой мелочи — условным комментариям в Internet Explorer.&lt;br /&gt;&lt;br /&gt;Каждый может открыть MSDN и прочитать &lt;a href="http://msdn.microsoft.com/en-us/library/ms537512.aspx"&gt;об условных комменттариях&lt;/a&gt;. Если коротко, то там их приведено аж целых два типа:&lt;br /&gt;&lt;table class="clsStd"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;downlevel-hidden&lt;/td&gt;&lt;td&gt;&amp;lt;!--[if &lt;i&gt;expression&lt;/i&gt;]&amp;gt; &lt;i&gt;HTML&lt;/i&gt; &amp;lt;![endif]--&amp;gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;downlevel-revealed&lt;/td&gt;&lt;td&gt;&amp;lt;![if &lt;i&gt;expression&lt;/i&gt;]&amp;gt; &lt;i&gt;HTML&lt;/i&gt; &amp;lt;![endif]&amp;gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;Первый валиден, пригоден только для IE, т.к. остальные браузеры воспринимают эту строку как комментарий. Второй невалиден и, поэтому не очень интересен. &lt;br /&gt;&lt;br /&gt;И вот возникает у верстальщика желание сделать так, чтобы кусок  html был виден всем, кроме IE. И чтоб валидно. Дочитать указанную страницу до конца многие не осиливают (а там есть решение) и начинают искать. Погуглив, многие натыкаются на конструкцию вида &amp;lt;!--[if !IE]&amp;gt;--&amp;gt; &lt;i&gt;HTML&lt;/i&gt; &amp;lt;!--&amp;lt;![endif]--&amp;gt;&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;описанную много где. Ну и гордо её применяют. Типа и валидатор сыт, и верстальщик цел. А потом, как-нибудь появляется необходимость заверстать кусочек так, чтоб видели все, кроме младших версий IE. И если сочинить условие &amp;lt;!--[if gte IE 7]&amp;gt;--&amp;gt; &lt;i&gt;HTML&lt;/i&gt; &amp;lt;!--&amp;lt;![endif]--&amp;gt;, то моментально выясняется, что кусочек --&amp;gt; отлично отображается как текст. Так вот, правильный комментарий без посторонних эффектов это (смотрите внимательно, разница в два символа) —&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&amp;lt;!--[if gte IE 7]&amp;gt;&amp;lt;!--&amp;gt; &lt;/span&gt;&lt;i style="font-weight: bold;"&gt;HTML&lt;/i&gt;&lt;span style="font-weight: bold;"&gt;  &amp;lt;!--&amp;lt;![endif]--&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;Этот HTML увидят все версии IE &amp;gt;= 7, все немайкрософтовые браузеры, и валидатор W3C тоже увидит.&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;На закуску. Кстати, майкрософт забыл описать ещё одно условие — [if VML]. Это означает поддержку VML в IE. Подразумевалось, что IE5 поставлялся без VML и потом докачивал, при необходимости, подержку VML с сайта майкрософта.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4226383850373882540-7106570703733620051?l=blog.ad.by' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ad.by/feeds/7106570703733620051/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4226383850373882540&amp;postID=7106570703733620051" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/7106570703733620051?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/7106570703733620051?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/adby/~3/CZvajOr5T2k/advanced-conditional-comments-in-ie.html" title="Advanced Conditional Comments in IE" /><author><name>Павел</name><uri>http://www.blogger.com/profile/15160195043765368557</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08937323532063115147" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.ad.by/2008/07/advanced-conditional-comments-in-ie.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkIFSHk9fip7ImA9WxNXGEw.&quot;"><id>tag:blogger.com,1999:blog-4226383850373882540.post-1451205092000045464</id><published>2008-05-09T11:50:00.009+02:00</published><updated>2009-10-06T09:35:19.766+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-06T09:35:19.766+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="AS3" /><category scheme="http://www.blogger.com/atom/ns#" term="Flex" /><category scheme="http://www.blogger.com/atom/ns#" term="effect" /><title>Nice effect (Flash AS2 to Flex AS3 port)</title><content type="html">В&lt;a href="http://0xffffff.ru/"&gt; белом и пушистом блоге&lt;/a&gt; нашел &lt;a href="http://0xffffff.ru/temp/archives/20"&gt;интересный эффект&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Поводите мышкой...&lt;br /&gt;&lt;embed src="http://www.ad.by/as3-test/MagicDots.swf" width="640" height="480" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"&gt;&lt;/embed&gt;&lt;br /&gt;&lt;br /&gt;Не удержался и &lt;a href="http://www.ad.by/as3-test/MagicDots.as"&gt;портировал его&lt;/a&gt; на чистый AS3 Flex. Имена переменных ужасны, но оставил как было, не в этом соль.&lt;br /&gt;&lt;pre&gt;package&lt;br /&gt;{&lt;br /&gt;  import flash.events.*;&lt;br /&gt;  import flash.display.*;&lt;br /&gt;  import flash.filters.*;&lt;br /&gt;  import flash.geom.*;&lt;br /&gt;&lt;br /&gt;  [SWF(backgroundColor = '0x000000', frameRate = '30', width = '640', height = '480')]&lt;br /&gt;&lt;br /&gt;  public class MagicDots extends MovieClip&lt;br /&gt;  {&lt;br /&gt;    private var dots: Array = new Array();&lt;br /&gt;    private var bm: MovieClip = new MovieClip();&lt;br /&gt;    private var myBitmap: BitmapData = new BitmapData(640, 480, false, 0x000000);&lt;br /&gt;    private var blur: BlurFilter = new BlurFilter(2, 2, 3);&lt;br /&gt;    private var cmF: ColorMatrixFilter = new ColorMatrixFilter([&lt;br /&gt;      1,    0, 0, 0, -4,&lt;br /&gt;      0.05, 1, 0, 0, -3,&lt;br /&gt;      0.05, 0, 1, 0, -0.08,&lt;br /&gt;      0,    0, 0, 1, 0]);&lt;br /&gt;&lt;br /&gt;    ///////////////////////////////////////////////////////////////////////////&lt;br /&gt;    // конструктор&lt;br /&gt;    public function MagicDots()&lt;br /&gt;    {&lt;br /&gt;      addChild(new Bitmap(myBitmap));&lt;br /&gt;&lt;br /&gt;      for (var i: int = 0; i &amp;lt;= 100; i++) {&lt;br /&gt;        const mc: DisplayObject = bm.addChild(new Dot());&lt;br /&gt;        mc.x = (i - 1) * 5 + 80;&lt;br /&gt;        mc.y = 420;&lt;br /&gt;        dots[i] = mc;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      // запустим анимацию&lt;br /&gt;      addEventListener(Event.ENTER_FRAME, doAnimation, false, 0, true);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    ///////////////////////////////////////////////////////////////////////////&lt;br /&gt;    // анимация&lt;br /&gt;    private function doAnimation(aEvent: Event): void&lt;br /&gt;    {&lt;br /&gt;      // ускорение&lt;br /&gt;      const a: Number = 0.4;&lt;br /&gt;&lt;br /&gt;      dots[0].x = mouseX;&lt;br /&gt;      dots[0].y = mouseY;&lt;br /&gt;      for (var k: int = 0; k &amp;lt; 100; k++) {&lt;br /&gt;        dots[k + 1].y -= (dots[k + 1].y - dots[k].y) * a;&lt;br /&gt;        dots[k + 1].x -= (dots[k + 1].x - dots[k].x) * a;&lt;br /&gt;      };&lt;br /&gt;&lt;br /&gt;      myBitmap.draw(bm);&lt;br /&gt;      myBitmap.applyFilter(myBitmap, myBitmap.rect, new Point(0, 0), blur);&lt;br /&gt;      myBitmap.applyFilter(myBitmap, myBitmap.rect, new Point(0, 0), cmF);&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;import flash.display.MovieClip;&lt;br /&gt;&lt;br /&gt;class Dot extends MovieClip&lt;br /&gt;{&lt;br /&gt;  ///////////////////////////////////////////////////////////////////////////&lt;br /&gt;  // конструктор&lt;br /&gt;  public function Dot()&lt;br /&gt;  {&lt;br /&gt;    graphics.lineStyle(1, 0xFFFFFF);&lt;br /&gt;    graphics.beginFill(0xFFFFFF);&lt;br /&gt;    graphics.drawCircle(0, 0, 2.5);&lt;br /&gt;    graphics.endFill();&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;В процессе портирования также получилось обойтись без флеша — необходимый мувиклип был просто нарисован прямо в коде. Т.е. для компиляции нужен только Flex 3 SDK и ничего более.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4226383850373882540-1451205092000045464?l=blog.ad.by' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ad.by/feeds/1451205092000045464/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4226383850373882540&amp;postID=1451205092000045464" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/1451205092000045464?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/1451205092000045464?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/adby/~3/VGyzTN7W344/nice-effect-flash-as2-to-flex-as3-port.html" title="Nice effect (Flash AS2 to Flex AS3 port)" /><author><name>Павел</name><uri>http://www.blogger.com/profile/15160195043765368557</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08937323532063115147" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.ad.by/2008/05/nice-effect-flash-as2-to-flex-as3-port.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0ACRXw-eip7ImA9WxZWF0U.&quot;"><id>tag:blogger.com,1999:blog-4226383850373882540.post-5008134212365120327</id><published>2008-03-17T22:20:00.003+02:00</published><updated>2008-03-17T22:29:24.252+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-03-17T22:29:24.252+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="AS3" /><category scheme="http://www.blogger.com/atom/ns#" term="Flex" /><category scheme="http://www.blogger.com/atom/ns#" term="Flash" /><title>Flash/Flex CS3 fast loops</title><content type="html">Протестировал скорость работы циклов и массивов во флексе.&lt;br /&gt;Результаты интересные:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;        Тип переменной цикла int или uint не играет роли для скорости самого цикла    (точнее цикл по int быстрее цикла по uint на 0,9%);&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Обращения к массиву по индексу uint быстрее индекса int на 3%;&lt;/li&gt;&lt;li&gt;Скорость цикла по int с преобразованием к индексу массива uint такая же, как    если сразу завести цикл по uint и обращаться к массиву по индексу uint.    (т.е. выиграть за счет п.1 не удается);&lt;li&gt;При работе с массивом, циклы работающие с конца (i--), тормознее циклов    работающих с начала (i++) на 3,7%;&lt;li&gt;Попытки типизировать массив [ArrayElementType("Number")] ничего не дают.    Эта фича не работает вообще вне Flex Builder;&lt;li&gt;Объявление длины обрабатываемого массива как var то же, что и const;&lt;li&gt;Переменную цикла можно объявить как const! Но никакой разницы с var нет;&lt;li&gt;Локальность/глобальность обрабатываемого массива безразлична;&lt;li&gt;Выносить вычисление размера массива из цикла действительно необходимо. Очень большие потери в скорости, например в 40%;&lt;li&gt;Циклы while и for по скорости друг от друга не отличаются.&lt;br /&gt;&lt;/ol&gt;       Итого, самый быстрый (и безопасный) цикл по массиву выглядит так:&lt;br /&gt;       const len: uint = Arr.length;&lt;br /&gt;       for (var i: uint = 0; i &lt; len; i++) {&lt;br /&gt;           Arr[i] = ...&lt;br /&gt;       }&lt;br /&gt;     ...или так...&lt;br /&gt;       const len: uint = Arr.length;&lt;br /&gt;       var i: uint = 0;&lt;br /&gt;       while (uint(i++) &lt; len) {&lt;br /&gt;           a[i] = ...&lt;br /&gt;       }&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4226383850373882540-5008134212365120327?l=blog.ad.by' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ad.by/feeds/5008134212365120327/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4226383850373882540&amp;postID=5008134212365120327" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/5008134212365120327?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/5008134212365120327?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/adby/~3/7R0IqdN913k/flashflex-cs3-fast-loops.html" title="Flash/Flex CS3 fast loops" /><author><name>Павел</name><uri>http://www.blogger.com/profile/15160195043765368557</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08937323532063115147" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.ad.by/2008/03/flashflex-cs3-fast-loops.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkIDR3w8cSp7ImA9WxNXGEw.&quot;"><id>tag:blogger.com,1999:blog-4226383850373882540.post-3491210582401161277</id><published>2008-03-04T18:50:00.010+02:00</published><updated>2009-10-06T09:36:16.279+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-06T09:36:16.279+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="VML" /><category scheme="http://www.blogger.com/atom/ns#" term="rounded corners" /><title>Nice Rounded Corners for IE, Safari, Firefox</title><content type="html">&lt;span class="Apple-style-span"&gt;Некоторое время я посвятил теме скругления углов у блочных элементов. Вот что получилось.&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;Цель&lt;/span&gt;&lt;/div&gt;&lt;div&gt;Разработать самый лучший (простой и надежный) метод для скругления углов у блочных элементов.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;Требования&lt;/span&gt;&lt;/div&gt;&lt;div&gt;Необходимо достигнуть баланса со следующим списком требований:&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;Никаких изображений. В крайнем случае — одно.&lt;/li&gt;&lt;li&gt;Никакого яваскрипта. Должно работать без него. В крайнем случае — только expressions для IE. Т.е. случай с отключенным яваскриптом в IE принимаем за маргинальный.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Работать должно во всех более-менее заметных браузерах и мобильных устройствах: IE 7, 6, 5.5; Firefox 2, 1.5; Safari 3, 2; Opera 9.5, 9, 8. В крайнем случае — только на наиболее популярных — IE 7,6; Firefox 2; Safari 3&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Визуальная привлекательность. Максимально быстрая отрисовка прямо со старта — именно поэтому никаких изображений и скриптов. Уж больно эти загружающиеся изображения и прочие тормоза раздражают.&lt;/li&gt;&lt;li&gt;Валидность XHTML Strict 1.0 по нормам валидатора W3C и работа с content-type. "application/xhtml+xml" для всех кроме IE и c "text/html" для IE&lt;/li&gt;&lt;li&gt;Расширяемость на будущее. Чтобы при появлениии новых версий браузеров это не сломалось.&lt;/li&gt;&lt;li&gt;Валидность CSS 2 и отсутствие хаков в CSS. Это, пожалуй, недостижимо, но к этому нужно стремиться.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Семантичность верстки. Никаких лишних сущностей в html-коде быть не должно. В крайнем случае — должен быть семантичный DOM.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Оптимизация производительности. Главное — минимизация числа запросов к серверу. На следующем месте — минимизация трафика.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Гибкая верстка. При изменении размера блока, масштаба страницы, размера шрифта, ничего разъезжаться не должно.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;Анализ существующих методов&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;Картинки в углы. Тормоза, лишние запросы. Несемантичный код или семантичный, но требуется включенный JS в IE.&lt;/li&gt;&lt;li&gt;Буллеты в углы. Проблемы с масштабированием. Проблемы с читалками экрана.&lt;/li&gt;&lt;li&gt;Эмуляция пикселов в углах через сетку html-тегов. Несемантичный код. Раздувание кода и стилей.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Встроенные средства браузеров. Хорошо, но неуниверсально. CSS3 еще никто не поддерживает.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;SVG как фоновое изображение. Это безусловно будет хит. Но поддерживается пока только оперой 9.5 beta.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;Процесс&lt;/span&gt;&lt;/div&gt;&lt;div&gt;В общем, как можно заметить, хороших способов нет. Точнее, их будет аж два: SVG как фоновое изображение и средства предлагаемые CSS3. Но это для культурных браузеров. А вот для IE ничего нет и не предвидится. И тут меня осенило: У IE начиная с версии 5.5 есть полный аналог SVG. Это VML!&lt;/div&gt;&lt;div&gt;Итак, после некоторых раздумий было решено: использовать VML для IE, а в остальных случаях использовать аналоги из CSS3.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;Результат&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Вот &lt;a href="http://www.ad.by/vml-test/test.html"&gt;демонстрация скругления углов через VML и CSS3&lt;/a&gt;. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Для работы с VML нужно вначале включить namespace для VML. Например так: &lt;xml:namespace ns="urn:schemas-microsoft-com:vml" prefix="v"&gt; Потом нужно включить сам VML (в стилях). Например так: v\: * { behavior: url(#default#VML); } После чего можно использовать команды VML прямо в тексте.&lt;div div=""&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Разные замечания:&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;Можно ещё улучшить — подключить SVG, тогда заработает и в опере 9.5 и в других будущих продвинутых браузерах.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Обратите внимание на условные комментарии для IE. Оказывается многие не знают как сделать "else".&lt;/li&gt;&lt;li&gt;Комментарии можно вообще убрать. И использовать тег "v:roundrect" как блочный элемент (заодно и код будет семантичен). Я проверял — работает во всех браузерах. Можно даже content-type выставить в application/xhtml+xml. Но возмущается валидатор W3C. Можно дополнить DTD. Но это не понимает IE. Можно создать свой DTD. Но валидатор от W3C не понимает custom DTD. В общем, решайте сами, что вам валидней. Как по мне, так в данном конкретном случае валидатор от W3C конкретно не прав. Ну да ладно.&lt;/li&gt;&lt;li&gt;Насчет оперы. Я &lt;span class="Apple-style-span"&gt;очень&lt;/span&gt; люблю этот браузер. В том числе это означает и то, что я прощаю ему то, чего он не умеет. Он очень быстро развивается. Так что это не проблема.&lt;/li&gt;&lt;li&gt;Я не в восторге от смешивания HTML и VML, но другого способа подсоединить VML нет.&lt;/li&gt;&lt;li&gt;Те атрибуты VML-тегов, которые относятся только к VML нельзя переместить в стили. Увы.&lt;/li&gt;&lt;li&gt;Если использовать VML-теги как блочные элементы, то они не понимают margin. Padding понимают. Есть и ещё мелкие странности. Типа отступов в 1px в некоторых случаях.&lt;/li&gt;&lt;li&gt;Кривые в VML сглаживаются! Это выглядит просто отлично.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Что делать с градиентами? VML и SVG их поддерживают. Можно и реализовать.&lt;/li&gt;&lt;li&gt;Интересный случай — код &lt;span class="Apple-style-span"&gt;в примере&lt;/span&gt; не семантичен, но построенный по нему DOM — &lt;span class="Apple-style-span"&gt;да&lt;/span&gt;.&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div&gt;Итак, решение работает во всем чем только можно, исключая оперу. Лишних запросов нет вообще. Почти семантично. Отображается моментально. Красота. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Цель достигнута. Интересно только почему никто ранее не додумался до этого?&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4226383850373882540-3491210582401161277?l=blog.ad.by' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ad.by/feeds/3491210582401161277/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4226383850373882540&amp;postID=3491210582401161277" title="Комментарии: 9" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/3491210582401161277?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/3491210582401161277?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/adby/~3/hYVrY3njmhU/nice-rounded-corners-for-ie-safari.html" title="Nice Rounded Corners for IE, Safari, Firefox" /><author><name>Павел</name><uri>http://www.blogger.com/profile/15160195043765368557</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08937323532063115147" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">9</thr:total><feedburner:origLink>http://blog.ad.by/2008/03/nice-rounded-corners-for-ie-safari.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUADRHc5fCp7ImA9WB9RFkw.&quot;"><id>tag:blogger.com,1999:blog-4226383850373882540.post-6748070298683537211</id><published>2007-10-17T12:42:00.001+02:00</published><updated>2007-10-17T12:42:55.924+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-10-17T12:42:55.924+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="xhtml" /><category scheme="http://www.blogger.com/atom/ns#" term="markaby" /><category scheme="http://www.blogger.com/atom/ns#" term="camping" /><title>Markaby — окончательный итог</title><content type="html">&lt;p&gt;Итак, окочательный код по работе с Markaby revision 107 в составе Camping revision 238:&lt;/p&gt; &lt;font size="1"&gt;&lt;font face="Comic Sans MS" color="#007f00" size="2"&gt;&lt;font size="2"&gt;       &lt;p&gt;&lt;font color="#000000"&gt;require &lt;/font&gt;&lt;font face="Courier New" color="#7f007f" size="2"&gt;'camping'            &lt;br /&gt;&lt;/font&gt;# уберем xml заголовок страницы, т.к. его наличие переключает IE в режим совместимости, да и по стандарту он не нужен, если кодировка utf-8           &lt;br /&gt;&lt;font size="2"&gt;&lt;font color="#000000"&gt;Camping&lt;b&gt;::&lt;/b&gt;Mab&lt;b&gt;.&lt;/b&gt;set&lt;/font&gt; &lt;font color="#c0a030"&gt;:output_xml_instruction&lt;/font&gt;&lt;b&gt;,&lt;/b&gt;&lt;font color="#808080"&gt; &lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;b&gt;&lt;font color="#00007f"&gt;false                &lt;br /&gt;&lt;/font&gt;&lt;/b&gt;&lt;font face="Comic Sans MS" color="#007f00"&gt;# язык xhtml-документа по умолчанию переключим на русский&lt;/font&gt;             &lt;br /&gt;&lt;font color="#000000"&gt;Camping&lt;b&gt;::&lt;/b&gt;Mab&lt;b&gt;.&lt;/b&gt;set&lt;/font&gt; &lt;font color="#c0a030"&gt;:root_attributes&lt;/font&gt;&lt;b&gt;,&lt;/b&gt;&lt;font color="#808080"&gt; &lt;/font&gt;&lt;b&gt;{&lt;/b&gt;&lt;font color="#808080"&gt; &lt;/font&gt;&lt;font color="#c0a030"&gt;:xmlns&lt;/font&gt;&lt;font color="#808080"&gt; &lt;/font&gt;&lt;b&gt;=&amp;gt;&lt;/b&gt;&lt;font color="#808080"&gt; &lt;/font&gt;&lt;font face="Courier New" color="#7f007f"&gt;'http://www.w3.org/1999/xhtml'&lt;/font&gt;&lt;b&gt;,&lt;/b&gt;&lt;font color="#808080"&gt; &lt;/font&gt;&lt;b&gt;:&lt;/b&gt;&lt;font face="Courier New" color="#7f007f"&gt;'xml:lang'&lt;/font&gt;&lt;font color="#808080"&gt; &lt;/font&gt;&lt;b&gt;=&amp;gt;&lt;/b&gt;&lt;font color="#808080"&gt; &lt;/font&gt;&lt;font face="Courier New" color="#7f007f"&gt;'ru'&lt;/font&gt;&lt;b&gt;,&lt;/b&gt;&lt;font color="#808080"&gt; &lt;/font&gt;&lt;font color="#c0a030"&gt;:lang&lt;/font&gt;&lt;font color="#808080"&gt; &lt;/font&gt;&lt;b&gt;=&amp;gt;&lt;/b&gt;&lt;font color="#808080"&gt; &lt;/font&gt;&lt;font face="Courier New" color="#7f007f"&gt;'ru'&lt;/font&gt;&lt;font color="#808080"&gt; &lt;/font&gt;&lt;/font&gt;&lt;b&gt;&lt;font size="2"&gt;}              &lt;br /&gt;&lt;/font&gt;&lt;/b&gt;&lt;font face="Comic Sans MS" color="#007f00" size="2"&gt;# вывод символов в Builder/Markaby переключим на обычный utf-8            &lt;br /&gt;&lt;/font&gt;&lt;font color="#00007f"&gt;&lt;font size="2"&gt;&lt;strong&gt;class &lt;font color="#0000ff"&gt;String&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;font color="#808080"&gt; &lt;/font&gt;&lt;font color="#00007f"&gt;def&lt;/font&gt;&lt;font color="#808080"&gt; &lt;/font&gt;&lt;font color="#007f7f"&gt;to_xs&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;font color="#808080"&gt; &lt;/font&gt;&lt;font color="#000000"&gt;to_s;&lt;/font&gt;&lt;font color="#808080"&gt; &lt;/font&gt;&lt;font color="#00007f"&gt;end&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;font color="#808080"&gt; &lt;/font&gt;&lt;font color="#00007f"&gt;end&lt;/font&gt;&lt;/strong&gt;&lt;/font&gt;&lt;/font&gt; &lt;/p&gt;     &lt;/font&gt;&lt;/font&gt;    &lt;p&gt;&lt;font color="#000000"&gt;&lt;font size="2"&gt;Коротко и элегантно. Даже &lt;em&gt;require 'markaby'&lt;/em&gt; не требуется.&lt;/font&gt;&lt;/font&gt;&lt;/p&gt; &lt;/font&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4226383850373882540-6748070298683537211?l=blog.ad.by' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ad.by/feeds/6748070298683537211/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4226383850373882540&amp;postID=6748070298683537211" title="Комментарии: 4" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/6748070298683537211?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/6748070298683537211?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/adby/~3/-Ff877cqjjU/markaby.html" title="Markaby — окончательный итог" /><author><name>Павел</name><uri>http://www.blogger.com/profile/15160195043765368557</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08937323532063115147" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total><feedburner:origLink>http://blog.ad.by/2007/10/markaby.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkcHRX84fSp7ImA9WB5aFU4.&quot;"><id>tag:blogger.com,1999:blog-4226383850373882540.post-4334091505758354491</id><published>2007-09-11T20:54:00.000+02:00</published><updated>2007-09-11T21:13:54.135+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-09-11T21:13:54.135+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="tar" /><category scheme="http://www.blogger.com/atom/ns#" term="gem" /><title>tar и win32</title><content type="html">Не ожиданно натолкнулся на проблему с архиватором &lt;i&gt;tar&lt;/i&gt;. Оказалось, что версия для win32 не поддерживает сжатие архива gzip-ом! Как натолкнулся - захотел собрать gem  из trunk-версии camping. Захожу в каталог, запускаю &lt;i&gt;rake&lt;/i&gt;, получаю отлуп. Естественно, возник вопрос - где взять нормальный tar. Оказалось, что нормальной версии tar для win32 просто нет. Тем не менее решение нашлось - &lt;a href="http://gnuwin32.sourceforge.net/packages/libarchive.htm"&gt;bsdtar&lt;/a&gt;. Оказалось достаточно переименовать исполнимый модуль в &lt;i&gt;tar&lt;/i&gt; и всё заработало.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4226383850373882540-4334091505758354491?l=blog.ad.by' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ad.by/feeds/4334091505758354491/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4226383850373882540&amp;postID=4334091505758354491" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/4334091505758354491?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/4334091505758354491?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/adby/~3/9Oy5URvwROg/tar-win32.html" title="tar и win32" /><author><name>Павел</name><uri>http://www.blogger.com/profile/15160195043765368557</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08937323532063115147" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.ad.by/2007/09/tar-win32.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkEASX85cCp7ImA9WB5aFEg.&quot;"><id>tag:blogger.com,1999:blog-4226383850373882540.post-7676954740111392364</id><published>2007-09-10T20:29:00.000+02:00</published><updated>2007-09-10T20:57:28.128+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-09-10T20:57:28.128+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="markaby" /><title>Markaby fix</title><content type="html">Набрался наглости и напрямую залил исправление в &lt;a href="http://code.whytheluckystiff.net/svn/markaby/"&gt;markaby svn&lt;/a&gt;. Исправил путь к DTD. Посмотрим, как на это отреагирует _why.&lt;br /&gt;На текущий момент получается, что trunk-версия не содержит ошибок мешающих жизни. Единственное, что необходимо для русскоязычного сайта, так это поправить Builder::XChar и переопредилить @@default на нужный манер.&lt;br /&gt;&lt;br /&gt;Примерно так:&lt;br /&gt;&lt;br /&gt;class Fixnum #:nodoc:&lt;br /&gt;  XChar = Builder::XChar if ! defined?(XChar)&lt;br /&gt;&lt;br /&gt;  # XML escaped version of chr (inlines cyrillic unicode range)&lt;br /&gt;  def xchr&lt;br /&gt;   case self when *XChar::VALID&lt;br /&gt;     n = self&lt;br /&gt;     XChar::PREDEFINED[n] or [n].pack 'U'&lt;br /&gt;   else&lt;br /&gt;     '*'&lt;br /&gt;   end&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;module Markaby&lt;br /&gt;  class Builder&lt;br /&gt;   @@default = {&lt;br /&gt;     :indent =&gt; 0,&lt;br /&gt;     :output_helpers =&gt; true,&lt;br /&gt;     :output_xml_instruction =&gt; false, # !&lt;br /&gt;     :output_meta_tag =&gt; true,&lt;br /&gt;     :auto_validation =&gt; true,&lt;br /&gt;     :tagset =&gt; Markaby::XHTMLStrict,&lt;br /&gt;     :root_attributes =&gt; { # !&lt;br /&gt;       :xmlns =&gt; 'http://www.w3.org/1999/xhtml', :'xml:lang' =&gt; 'ru', :lang =&gt; 'ru'&lt;br /&gt;     }&lt;br /&gt;   }&lt;br /&gt;  end&lt;br /&gt;end&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4226383850373882540-7676954740111392364?l=blog.ad.by' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ad.by/feeds/7676954740111392364/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4226383850373882540&amp;postID=7676954740111392364" title="Комментарии: 1" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/7676954740111392364?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/7676954740111392364?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/adby/~3/o-xozQVx0Q4/markaby-fix.html" title="Markaby fix" /><author><name>Павел</name><uri>http://www.blogger.com/profile/15160195043765368557</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08937323532063115147" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://blog.ad.by/2007/09/markaby-fix.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkENQX4-eCp7ImA9WxNXGEw.&quot;"><id>tag:blogger.com,1999:blog-4226383850373882540.post-5869066128653210633</id><published>2007-09-09T11:03:00.001+02:00</published><updated>2009-10-06T09:38:10.050+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-06T09:38:10.050+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ruby on rails" /><category scheme="http://www.blogger.com/atom/ns#" term="markaby" /><category scheme="http://www.blogger.com/atom/ns#" term="erb" /><category scheme="http://www.blogger.com/atom/ns#" term="rhtml" /><title>rhtml2mab - markaby for Ruby On Rails</title><content type="html">Я, помнится, &lt;a href="http://blog.ad.by/2007/08/markaby-vs-haml.html"&gt;сожалел об отсутствии утилиты html2markaby&lt;/a&gt;. Ну, именно такой утилиты до сих пор нет, но нашлась утилита способная облечить труд по переводу rhtml на markaby. Называется &lt;a href="http://balloon.hobix.com/mablate"&gt;mablate&lt;/a&gt;. Если на неё накатить &lt;a href="http://code.whytheluckystiff.net/markaby/ticket/25"&gt;исправления описанные у _why&lt;/a&gt;, то результатом даже слегка можно пользоваться. Общее впечатление — глюконат кальция. Но лучше чем ничего.&lt;br /&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4226383850373882540-5869066128653210633?l=blog.ad.by' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ad.by/feeds/5869066128653210633/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4226383850373882540&amp;postID=5869066128653210633" title="Комментарии: 1" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/5869066128653210633?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/5869066128653210633?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/adby/~3/WI5NCyVbBmM/rhtml2mab-markaby-for-ruby-on-rails.html" title="rhtml2mab - markaby for Ruby On Rails" /><author><name>Павел</name><uri>http://www.blogger.com/profile/15160195043765368557</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08937323532063115147" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://blog.ad.by/2007/09/rhtml2mab-markaby-for-ruby-on-rails.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A08DQ3k-fyp7ImA9WB5bF08.&quot;"><id>tag:blogger.com,1999:blog-4226383850373882540.post-2545093168792745024</id><published>2007-09-02T11:48:00.000+02:00</published><updated>2007-09-02T12:44:32.757+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-09-02T12:44:32.757+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="cmd" /><category scheme="http://www.blogger.com/atom/ns#" term="windows" /><title>command line и environment</title><content type="html">Обнаружил две странные вещи в своей WinXP:&lt;br /&gt;&lt;ol id=""&gt;&lt;li&gt;Оказывается, в окружении отсутствует переменная &lt;span class="Apple-style-span" style="font-style: italic;"&gt;HOME&lt;/span&gt;. Ранее как-то не обращал на это внимания, а тут смотрю - в ruby не отрабатывает конструкция &lt;span class="Apple-style-span" style="font-style: italic;"&gt;File.expand_path('~/.camping.db'). &lt;/span&gt;Ругается на невозможность обнаружить эту переменную. Лечится через &lt;span class="Apple-style-span" style="font-style: italic;"&gt;set home=%homedrive%%homepath%&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;При работе с командной строкой оказалось, что командный интерпретатор стал понимать ассоциации между ruby-файлами и ruby-интерпретатором. Внезапно ощутил себя в Linux. 8-) Т.е. берешь, например, набираешь в командной строке &lt;span class="Apple-style-span" style="font-style: italic;"&gt;rv,&lt;/span&gt; нажимаешь &lt;span class="Apple-style-span" style="font-style: italic;"&gt;Tab&lt;/span&gt;, имя дополняется до &lt;span class="Apple-style-span" style="font-style: italic;"&gt;rv_harness.rb&lt;/span&gt;, нажимаешь &lt;span class="Apple-style-span" style="font-style: italic;"&gt;Enter&lt;/span&gt; и командный интерпретатор запускает его на выполнение, как будто было набрано &lt;span class="Apple-style-span" style="font-style: italic;"&gt;ruby rv_harness.rb&lt;/span&gt;! В чем дело, непонятно. Ранее такого точно не было. Поизучал список подгружаемых в процесс &lt;span class="Apple-style-span" style="font-style: italic;"&gt;cmd.exe&lt;/span&gt; модулей - ясности не прибавилось.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4226383850373882540-2545093168792745024?l=blog.ad.by' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ad.by/feeds/2545093168792745024/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4226383850373882540&amp;postID=2545093168792745024" title="Комментарии: 1" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/2545093168792745024?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4226383850373882540/posts/default/2545093168792745024?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/adby/~3/D1llvOeOpKY/command-line-environment.html" title="command line и environment" /><author><name>Павел</name><uri>http://www.blogger.com/profile/15160195043765368557</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08937323532063115147" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://blog.ad.by/2007/09/command-line-environment.html</feedburner:origLink></entry></feed>
