{"@attributes":{"version":"2.0"},"channel":{"title":"Welcome to My Digital Playground! \ud83c\udfae on kiennt26's home","link":"https:\/\/ntk148v.github.io\/","description":"Recent content in Welcome to My Digital Playground! \ud83c\udfae on kiennt26's home","generator":"Hugo","language":"en-us","managingEditor":"kiennt2609@gmail.com (Kien Nguyen-Tuan)","webMaster":"kiennt2609@gmail.com (Kien Nguyen-Tuan)","lastBuildDate":"Sat, 21 Feb 2026 11:10:44 +0700","item":[{"title":"Bloom Filter in Go","link":"https:\/\/ntk148v.github.io\/posts\/bloom-filter\/","pubDate":"Sat, 21 Feb 2026 10:29:11 +0700","author":"kiennt2609@gmail.com (Kien Nguyen-Tuan)","guid":"https:\/\/ntk148v.github.io\/posts\/bloom-filter\/","description":"<p>Source:<\/p>\n<ul>\n<li><a href=\"https:\/\/en.wikipedia.org\/wiki\/Bloom_filter\">https:\/\/en.wikipedia.org\/wiki\/Bloom_filter<\/a><\/li>\n<li><a href=\"https:\/\/redis.io\/docs\/latest\/develop\/data-types\/probabilistic\/bloom-filter\/\">https:\/\/redis.io\/docs\/latest\/develop\/data-types\/probabilistic\/bloom-filter\/<\/a><\/li>\n<li><a href=\"https:\/\/clickhouse.com\/docs\/en\/engines\/table-engines\/mergetree-family\/mergetree#table_engine-mergetree-data_skipping-indexes\">https:\/\/clickhouse.com\/docs\/en\/engines\/table-engines\/mergetree-family\/mergetree#table_engine-mergetree-data_skipping-indexes<\/a><\/li>\n<\/ul>\n<h2 id=\"what-is-bloom-filter\">What is Bloom filter?<\/h2>\n<p>When building high-performance systems, minimizing expensive operations like disk reads or remote database queries is critical.<\/p>\n<p>A Bloom filter is a highly space-efficient, probabilistic data structure designed to test whether an element is a member of a set. It was conceived by Burton Howard Bloom in 1970.<\/p>\n<p>Unlike standard data structures like hash tables or binary search trees that store the actual data, a Bloom filter only stores a cryptographic representation of the data. Because it does not store the raw elements, it requires a fraction of the memory.<\/p>"},{"title":"A clumsy Docker network notes","link":"https:\/\/ntk148v.github.io\/posts\/clumsy-docker-network-notes\/","pubDate":"Tue, 12 Dec 2023 14:47:26 +0700","author":"kiennt2609@gmail.com (Kien Nguyen-Tuan)","guid":"https:\/\/ntk148v.github.io\/posts\/clumsy-docker-network-notes\/","description":"<h1 id=\"a-clumsy-docker-networking-notes\">A clumsy Docker networking notes<\/h1>\n<p>Ngu\u1ed3n:<\/p>\n<ul>\n<li><a href=\"https:\/\/github.com\/ntk148v\/til\/tree\/master\/docker\/networking\">https:\/\/github.com\/ntk148v\/til\/tree\/master\/docker\/networking<\/a><\/li>\n<li><a href=\"https:\/\/argus-sec.com\/docker-networking-behind-the-scenes\/\">https:\/\/argus-sec.com\/docker-networking-behind-the-scenes\/<\/a><\/li>\n<li><a href=\"https:\/\/docs.docker.com\/network\/\">https:\/\/docs.docker.com\/network\/<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/KamranAzeem\/learn-docker\/blob\/master\/docs\/docker-networking-deep-dive.md\">https:\/\/github.com\/KamranAzeem\/learn-docker\/blob\/master\/docs\/docker-networking-deep-dive.md<\/a><\/li>\n<li><a href=\"https:\/\/docs.docker.com\/engine\/tutorials\/networkingcontainers\/\">https:\/\/docs.docker.com\/engine\/tutorials\/networkingcontainers\/<\/a><\/li>\n<li><a href=\"https:\/\/docs.docker.com\/network\/iptables\/\">https:\/\/docs.docker.com\/network\/iptables\/<\/a><\/li>\n<li><a href=\"https:\/\/dev.to\/polarbit\/how-docker-container-networking-works-mimic-it-using-linux-network-namespaces-9mj\">https:\/\/dev.to\/polarbit\/how-docker-container-networking-works-mimic-it-using-linux-network-namespaces-9mj<\/a><\/li>\n<\/ul>\n<h2 id=\"kh\u00e1i-ni\u1ec7m\">Kh\u00e1i ni\u1ec7m<\/h2>\n<ul>\n<li>\n<p>C\u00e1c kh\u00e1i ni\u1ec7m:<\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/man7.org\/linux\/man-pages\/man8\/ip-netns.8.html\">Network namespace<\/a>:<\/p>\n<ul>\n<li>Tr\u01b0\u1edbc khi \u0111i v\u00e0o network namespace, c\u1ea7n hi\u1ec3u v\u1ec1 <strong>Namespace<\/strong>. Namespace l\u00e0 m\u1ed9t t\u00ednh n\u0103ng c\u1ee7a Linux kernel \u0111\u1ec3 ph\u00e2n v\u00f9ng t\u00e0i nguy\u00ean c\u1ee7a kernel sao cho m\u1ed9t t\u1eadp h\u1ee3p c\u00e1c process ch\u1ec9 nh\u00ecn th\u1ea5y t\u1eadp h\u1ee3p c\u00e1c t\u00e0i nguy\u00ean (trong namespace \u0111\u00f3) trong khi m\u1ed9t t\u1eadp h\u1ee3p c\u00e1c process kh\u00e1c nh\u00ecn th\u1ea5y t\u1eadp c\u00e1c t\u00e0i nguy\u00ean kh\u00e1c (trong namespace kh\u00e1c). T\u00ednh n\u0103ng n\u00e0y ho\u1ea1t \u0111\u1ed9ng b\u1eb1ng c\u00e1ch \u0111\u01b0a t\u1eadp c\u00e1c t\u00e0i nguy\u00ean v\u00e0 process v\u00e0o c\u00f9ng m\u1ed9t namespace, c\u00e1c namespace kh\u00e1c nhau s\u1ebd tham chi\u1ebfu \u0111\u1ebfn c\u00e1c t\u00e0i nguy\u00ean ri\u00eang bi\u1ec7t. T\u00e0i nguy\u00ean c\u00f3 th\u1ec3 t\u1ed3n t\u1ea1i trong nhi\u1ec1u kh\u00f4ng gian. V\u00ed d\u1ee5 v\u1ec1 c\u00e1c t\u00e0i nguy\u00ean nh\u01b0 v\u1eady l\u00e0 process ID, hostname, user ID, t\u00ean file v\u00e0 m\u1ed9t s\u1ed1 t\u00ean (name) li\u00ean quan \u0111\u1ebfn quy\u1ec1n truy c\u1eadp m\u1ea1ng v\u00e0 giao ti\u1ebfp gi\u1eefa c\u00e1c process.<\/li>\n<li>Networking namespace l\u00e0 m\u1ed9t trong c\u00e1c lo\u1ea1i namespace. M\u1ed7i network namespace c\u00f3 <a href=\"https:\/\/en.wikipedia.org\/wiki\/Network_stack\">network stack<\/a> ri\u00eang: \u0111\u1ecba ch\u1ec9 IP, network interface, route table, &hellip;<\/li>\n<li>B\u1ea1n c\u00f3 th\u1ec3 xem thao t\u00e1c c\u00e1c network namespace b\u1eb1ng c\u00e2u l\u1ec7nh sau:<\/li>\n<\/ul>\n<div class=\"highlight\"><pre tabindex=\"0\" style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"><code class=\"language-shell\" data-lang=\"shell\"><span style=\"display:flex;\"><span>$ sudo ip netns &lt;sub-command&gt;\n<\/span><\/span><\/code><\/pre><\/div><\/li>\n<li>\n<p><a href=\"https:\/\/wiki.archlinux.org\/index.php\/Network_bridge\">Network bridge<\/a>: m\u1ed9t thi\u1ebft b\u1ecb m\u1ea1ng \u1ea3o chuy\u1ec3n ti\u1ebfp c\u00e1c g\u00f3i gi\u1eefa hai ho\u1eb7c nhi\u1ec1u ph\u00e2n \u0111o\u1ea1n m\u1ea1ng.<\/p>"},{"title":"Writing a Simple Shell in C Sharp","link":"https:\/\/ntk148v.github.io\/posts\/writing-a-simple-shell-in-c-sharp\/","pubDate":"Sun, 20 Aug 2023 23:15:34 +0700","author":"kiennt2609@gmail.com (Kien Nguyen-Tuan)","guid":"https:\/\/ntk148v.github.io\/posts\/writing-a-simple-shell-in-c-sharp\/","description":"<p>In this post, we will write a minimalistic shell for UNIX(-like) operating systems in C# programming language. I create this for learning C# purpose.<\/p>\n<p>Since its purpose demonstration (not feature completeness or even fitness for causual use), it has many limitations, including:<\/p>\n<ul>\n<li>Commands must be on a single line.<\/li>\n<li>Arguments must be separated by whitespace.<\/li>\n<li>No quoting arguments or escaping whitespace.<\/li>\n<li>No piping or redirection.<\/li>\n<\/ul>\n<blockquote>\n<p>Before we start, make sure you have .NET Core environment and knownledge.<\/p>"},{"title":"Golang Async","link":"https:\/\/ntk148v.github.io\/posts\/golang-async\/","pubDate":"Fri, 21 Jul 2023 16:16:31 +0700","author":"kiennt2609@gmail.com (Kien Nguyen-Tuan)","guid":"https:\/\/ntk148v.github.io\/posts\/golang-async\/","description":"<blockquote>\n<p>This article is Golang version of <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/asynchronous-programming\/\">Asynchronous programming with async and await guideline<\/a>. They did really good job to demonstrate how asynchronous programming looks like.<\/p>\n<p>You can find source code <a href=\"https:\/\/github.com\/ntk148v\/testing\/tree\/master\/golang\/breakfast\">here<\/a>.<\/p>\n<\/blockquote>\n<p>Throughout this article, we&rsquo;ll write the instructions to make a breakfast.<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"><code class=\"language-fallback\" data-lang=\"fallback\"><span style=\"display:flex;\"><span>1. Pour a cup of coffee.\n<\/span><\/span><span style=\"display:flex;\"><span>2. Heat a pan, then fry two eggs.\n<\/span><\/span><span style=\"display:flex;\"><span>3. Fry three slices of bacon.\n<\/span><\/span><span style=\"display:flex;\"><span>4. Toast two pieces of bread.\n<\/span><\/span><span style=\"display:flex;\"><span>5. Add butter and jam to the toast.\n<\/span><\/span><span style=\"display:flex;\"><span>6. Pour a glass of orange juice.\n<\/span><\/span><\/code><\/pre><\/div><p>Each step takes time to finish, for example, you have to wait X seconds to make a glass of orange juice. Let&rsquo;s write those instructions as Golang:<\/p>"},{"title":"Linux Run in the Background","link":"https:\/\/ntk148v.github.io\/posts\/linux-run-in-the-background\/","pubDate":"Fri, 03 Mar 2023 14:28:09 +0700","author":"kiennt2609@gmail.com (Kien Nguyen-Tuan)","guid":"https:\/\/ntk148v.github.io\/posts\/linux-run-in-the-background\/","description":"<blockquote>\n<p><strong>Environment:<\/strong> Ubuntu 22.04, but it should work in other Linux distributions.<\/p>\n<p><strong>Source<\/strong>: <a href=\"https:\/\/www.sobyte.net\/post\/2023-03\/linux-services-in-the-background\/\">https:\/\/www.sobyte.net\/post\/2023-03\/linux-services-in-the-background\/<\/a><\/p>\n<\/blockquote>\n<p>You run some commands, it may take a long time to execute, and you don&rsquo;t want to wait for it. So what should you do in that scenario?<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"><code class=\"language-fallback\" data-lang=\"fallback\"><span style=\"display:flex;\"><span>graph TD\n<\/span><\/span><span style=\"display:flex;\"><span>A(You don&#39;t want to wait &lt;br&gt;for a running command) --&gt; B{Do you want to see output?}\n<\/span><\/span><span style=\"display:flex;\"><span>A --&gt; C{Do you want the command to stay &lt;br&gt;running after the session ends?}\n<\/span><\/span><span style=\"display:flex;\"><span>C --&gt; |Yes| E(screen)\n<\/span><\/span><span style=\"display:flex;\"><span>B --&gt; |No| D(Ctrl-Z or &amp;)\n<\/span><\/span><span style=\"display:flex;\"><span>B --&gt; |Yes| F{Do you have requirements &lt;br&gt;for log cutting, running users?}\n<\/span><\/span><span style=\"display:flex;\"><span>F --&gt; |No| G(nohup)\n<\/span><\/span><span style=\"display:flex;\"><span>F --&gt; |Yes| H(supervisor or systemd)\n<\/span><\/span><\/code><\/pre><\/div><h2 id=\"ctrl-z-or-\">Ctrl-Z or &amp;<\/h2>\n<p>For example, you have to excute <code>ping<\/code> command:<\/p>"},{"title":"Linux Network Performance Ultimate Guide","link":"https:\/\/ntk148v.github.io\/posts\/linux-network-performance-ultimate-guide\/","pubDate":"Fri, 24 Feb 2023 17:22:02 +0700","author":"kiennt2609@gmail.com (Kien Nguyen-Tuan)","guid":"https:\/\/ntk148v.github.io\/posts\/linux-network-performance-ultimate-guide\/","description":"<blockquote>\n<p>The following content is from <a href=\"https:\/\/github.com\/ntk148v\/til\/blob\/master\/linux\/network-performance-ultimate-guide.md\">my #til github<\/a>.<\/p>\n<\/blockquote>\n<p><strong>Source:<\/strong><\/p>\n<ul>\n<li><a href=\"https:\/\/github.com\/leandromoreira\/linux-network-performance-parameters\/\">https:\/\/github.com\/leandromoreira\/linux-network-performance-parameters\/<\/a><\/li>\n<li><a href=\"https:\/\/access.redhat.com\/sites\/default\/files\/attachments\/20150325_network_performance_tuning.pdf\">https:\/\/access.redhat.com\/sites\/default\/files\/attachments\/20150325_network_performance_tuning.pdf<\/a><\/li>\n<li><a href=\"https:\/\/www.coverfire.com\/articles\/queueing-in-the-linux-network-stack\/\">https:\/\/www.coverfire.com\/articles\/queueing-in-the-linux-network-stack\/<\/a><\/li>\n<li><a href=\"https:\/\/blog.cloudflare.com\/how-to-achieve-low-latency\/\">https:\/\/blog.cloudflare.com\/how-to-achieve-low-latency\/<\/a><\/li>\n<li><a href=\"https:\/\/blog.cloudflare.com\/how-to-receive-a-million-packets\/\">https:\/\/blog.cloudflare.com\/how-to-receive-a-million-packets\/<\/a><\/li>\n<li><a href=\"https:\/\/beej.us\/guide\/bgnet\/html\/\">https:\/\/beej.us\/guide\/bgnet\/html\/<\/a><\/li>\n<li><a href=\"https:\/\/blog.csdn.net\/armlinuxww\/article\/details\/111930788\">https:\/\/blog.csdn.net\/armlinuxww\/article\/details\/111930788<\/a><\/li>\n<li><a href=\"https:\/\/www.ibm.com\/docs\/en\/linux-on-systems?topic=recommendations-network-performance-tuning\">https:\/\/www.ibm.com\/docs\/en\/linux-on-systems?topic=recommendations-network-performance-tuning<\/a><\/li>\n<\/ul>\n<h2 id=\"linux-networking-stack\">Linux Networking stack<\/h2>\n<p>Source:<\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/blog.packagecloud.io\/illustrated-guide-monitoring-tuning-linux-networking-stack-receiving-data\/\">https:\/\/blog.packagecloud.io\/illustrated-guide-monitoring-tuning-linux-networking-stack-receiving-data\/<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/blog.packagecloud.io\/monitoring-tuning-linux-networking-stack-receiving-data\/\">https:\/\/blog.packagecloud.io\/monitoring-tuning-linux-networking-stack-receiving-data\/<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/blog.packagecloud.io\/monitoring-tuning-linux-networking-stack-sending-data\/\">https:\/\/blog.packagecloud.io\/monitoring-tuning-linux-networking-stack-sending-data\/<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/www.sobyte.net\/post\/2022-10\/linux-net-snd-rcv\/\">https:\/\/www.sobyte.net\/post\/2022-10\/linux-net-snd-rcv\/<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/juejin.cn\/post\/7106345054368694280\">https:\/\/juejin.cn\/post\/7106345054368694280<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/openwrt.org\/docs\/guide-developer\/networking\/praxis\">https:\/\/openwrt.org\/docs\/guide-developer\/networking\/praxis<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/blog.51cto.com\/u_15169172\/2710604\">https:\/\/blog.51cto.com\/u_15169172\/2710604<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/sn0rt.github.io\/media\/paper\/TCPlinux.pdf\">https:\/\/sn0rt.github.io\/media\/paper\/TCPlinux.pdf<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/medium.com\/coccoc-engineering-blog\/linux-network-ring-buffers-cea7ead0b8e8\">https:\/\/medium.com\/coccoc-engineering-blog\/linux-network-ring-buffers-cea7ead0b8e8<\/a><\/p>\n<\/li>\n<li>\n<p>The complete network data flow:<\/p>\n<\/li>\n<\/ul>\n<p><figure>\n <img\n src=\"http:\/\/web.archive.org\/web\/20170905131225if_\/https:\/\/wiki.linuxfoundation.org\/images\/1\/1c\/Network_data_flow_through_kernel.png\"\n alt=\"\"\n loading=\"lazy\"\n \n \/><\/figure>\n<\/p>\n<ul>\n<li>It&rsquo;s a getting started. Before perform any tuning, let make sure that we understand how computers running Linux receive packets.<\/li>\n<li>Linux queue:<\/li>\n<\/ul>\n<p><figure>\n <img\n src=\"https:\/\/github.com\/leandromoreira\/linux-network-performance-parameters\/raw\/master\/img\/linux_network_flow.png\"\n alt=\"\"\n loading=\"lazy\"\n \n \/><\/figure>\n<\/p>\n<p><strong>NOTE<\/strong>: The follow sections will heavily use <code>sysctl<\/code>. If you don&rsquo;t familiar with this command, take a look at <a href=\"#sysctl\">HOWTO#sysctl section<\/a>.<\/p>"},{"title":"Goat Playground","link":"https:\/\/ntk148v.github.io\/posts\/goat-playground\/","pubDate":"Tue, 31 Jan 2023 14:15:12 +0700","author":"kiennt2609@gmail.com (Kien Nguyen-Tuan)","guid":"https:\/\/ntk148v.github.io\/posts\/goat-playground\/","description":"<p>Hey, this is a simple post to play with <a href=\"https:\/\/github.com\/blampe\/goat\">GoAT Diagram<\/a>.<\/p>\n\n\n\n<div class=\"goat svg-container \">\n \n <svg\n xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n font-family=\"Menlo,Lucida Console,monospace\"\n \n viewBox=\"0 0 760 841\"\n >\n <g transform='translate(8,16)'>\n<path d='M 64,32 L 128,32' fill='none' stroke='currentColor'><\/path>\n<path d='M 176,32 L 192,32' fill='none' stroke='currentColor'><\/path>\n<path d='M 192,32 L 224,32' fill='none' stroke='currentColor'><\/path>\n<path d='M 224,32 L 240,32' fill='none' stroke='currentColor'><\/path>\n<path d='M 288,32 L 304,32' fill='none' stroke='currentColor'><\/path>\n<path d='M 304,32 L 336,32' fill='none' stroke='currentColor'><\/path>\n<path d='M 336,32 L 352,32' fill='none' stroke='currentColor'><\/path>\n<path d='M 400,32 L 408,32' fill='none' stroke='currentColor'><\/path>\n<path d='M 456,32 L 464,32' fill='none' stroke='currentColor'><\/path>\n<path d='M 512,32 L 528,32' fill='none' stroke='currentColor'><\/path>\n<path d='M 560,32 L 576,32' fill='none' stroke='currentColor'><\/path>\n<path d='M 624,32 L 664,32' fill='none' stroke='currentColor'><\/path>\n<path d='M 680,32 L 688,32' fill='none' stroke='currentColor'><\/path>\n<path d='M 64,64 L 128,64' fill='none' stroke='currentColor'><\/path>\n<path d='M 176,64 L 192,64' fill='none' stroke='currentColor'><\/path>\n<path d='M 192,64 L 224,64' fill='none' stroke='currentColor'><\/path>\n<path d='M 224,64 L 240,64' fill='none' stroke='currentColor'><\/path>\n<path d='M 288,64 L 304,64' fill='none' stroke='currentColor'><\/path>\n<path d='M 304,64 L 336,64' fill='none' stroke='currentColor'><\/path>\n<path d='M 336,64 L 352,64' fill='none' stroke='currentColor'><\/path>\n<path d='M 400,64 L 408,64' fill='none' stroke='currentColor'><\/path>\n<path d='M 456,64 L 464,64' fill='none' stroke='currentColor'><\/path>\n<path d='M 512,64 L 528,64' fill='none' stroke='currentColor'><\/path>\n<path d='M 560,64 L 576,64' fill='none' stroke='currentColor'><\/path>\n<path d='M 624,64 L 632,64' fill='none' stroke='currentColor'><\/path>\n<path d='M 648,64 L 688,64' fill='none' stroke='currentColor'><\/path>\n<path d='M 552,128 L 608,128' fill='none' stroke='currentColor'><\/path>\n<path d='M 288,144 L 296,144' fill='none' stroke='currentColor'><\/path>\n<path d='M 256,160 L 272,160' fill='none' stroke='currentColor'><\/path>\n<path d='M 344,160 L 352,160' fill='none' stroke='currentColor'><\/path>\n<path d='M 552,160 L 608,160' fill='none' stroke='currentColor'><\/path>\n<path d='M 376,176 L 528,176' fill='none' stroke='currentColor'><\/path>\n<path d='M 256,192 L 352,192' fill='none' stroke='currentColor'><\/path>\n<path d='M 552,208 L 608,208' fill='none' stroke='currentColor'><\/path>\n<path d='M 80,240 L 280,240' fill='none' stroke='currentColor'><\/path>\n<path d='M 336,240 L 448,240' fill='none' stroke='currentColor'><\/path>\n<path d='M 568,272 L 624,272' fill='none' stroke='currentColor'><\/path>\n<path d='M 688,272 L 744,272' fill='none' stroke='currentColor'><\/path>\n<path d='M 40,288 L 112,288' fill='none' stroke='currentColor'><\/path>\n<path d='M 240,288 L 312,288' fill='none' stroke='currentColor'><\/path>\n<path d='M 432,288 L 464,288' fill='none' stroke='currentColor'><\/path>\n<path d='M 120,304 L 232,304' fill='none' stroke='currentColor'><\/path>\n<path d='M 320,304 L 408,304' fill='none' stroke='currentColor'><\/path>\n<path d='M 552,304 L 608,304' fill='none' stroke='currentColor'><\/path>\n<path d='M 672,304 L 728,304' fill='none' stroke='currentColor'><\/path>\n<path d='M 632,320 L 664,320' fill='none' stroke='currentColor'><\/path>\n<path d='M 40,336 L 112,336' fill='none' stroke='currentColor'><\/path>\n<path d='M 240,336 L 312,336' fill='none' stroke='currentColor'><\/path>\n<path d='M 24,368 L 128,368' fill='none' stroke='currentColor'><\/path>\n<path d='M 224,368 L 328,368' fill='none' stroke='currentColor'><\/path>\n<path d='M 432,368 L 464,368' fill='none' stroke='currentColor'><\/path>\n<path d='M 552,368 L 608,368' fill='none' stroke='currentColor'><\/path>\n<path d='M 672,368 L 728,368' fill='none' stroke='currentColor'><\/path>\n<path d='M 32,416 L 72,416' fill='none' stroke='currentColor'><\/path>\n<path d='M 144,416 L 184,416' fill='none' stroke='currentColor'><\/path>\n<path d='M 296,432 L 344,432' fill='none' stroke='currentColor'><\/path>\n<path d='M 344,432 L 392,432' fill='none' stroke='currentColor'><\/path>\n<path d='M 392,432 L 440,432' fill='none' stroke='currentColor'><\/path>\n<path d='M 88,448 L 128,448' fill='none' stroke='currentColor'><\/path>\n<path d='M 200,448 L 240,448' fill='none' stroke='currentColor'><\/path>\n<path d='M 528,448 L 576,448' fill='none' stroke='currentColor'><\/path>\n<path d='M 576,448 L 624,448' fill='none' stroke='currentColor'><\/path>\n<path d='M 624,448 L 672,448' fill='none' stroke='currentColor'><\/path>\n<path d='M 672,448 L 720,448' fill='none' stroke='currentColor'><\/path>\n<path d='M 32,480 L 72,480' fill='none' stroke='currentColor'><\/path>\n<path d='M 144,480 L 184,480' fill='none' stroke='currentColor'><\/path>\n<path d='M 296,480 L 344,480' fill='none' stroke='currentColor'><\/path>\n<path d='M 344,480 L 392,480' fill='none' stroke='currentColor'><\/path>\n<path d='M 392,480 L 440,480' fill='none' stroke='currentColor'><\/path>\n<path d='M 512,480 L 560,480' fill='none' stroke='currentColor'><\/path>\n<path d='M 560,480 L 608,480' fill='none' stroke='currentColor'><\/path>\n<path d='M 608,480 L 656,480' fill='none' stroke='currentColor'><\/path>\n<path d='M 656,480 L 704,480' fill='none' stroke='currentColor'><\/path>\n<path d='M 88,512 L 128,512' fill='none' stroke='currentColor'><\/path>\n<path d='M 200,512 L 240,512' fill='none' stroke='currentColor'><\/path>\n<path d='M 496,512 L 544,512' fill='none' stroke='currentColor'><\/path>\n<path d='M 544,512 L 592,512' fill='none' stroke='currentColor'><\/path>\n<path d='M 592,512 L 640,512' fill='none' stroke='currentColor'><\/path>\n<path d='M 640,512 L 688,512' fill='none' stroke='currentColor'><\/path>\n<path d='M 296,528 L 344,528' fill='none' stroke='currentColor'><\/path>\n<path d='M 344,528 L 392,528' fill='none' stroke='currentColor'><\/path>\n<path d='M 392,528 L 440,528' fill='none' stroke='currentColor'><\/path>\n<path d='M 32,544 L 72,544' fill='none' stroke='currentColor'><\/path>\n<path d='M 144,544 L 184,544' fill='none' stroke='currentColor'><\/path>\n<path d='M 480,544 L 528,544' fill='none' stroke='currentColor'><\/path>\n<path d='M 528,544 L 576,544' fill='none' stroke='currentColor'><\/path>\n<path d='M 576,544 L 624,544' fill='none' stroke='currentColor'><\/path>\n<path d='M 624,544 L 672,544' fill='none' stroke='currentColor'><\/path>\n<path d='M 88,576 L 128,576' fill='none' stroke='currentColor'><\/path>\n<path d='M 200,576 L 240,576' fill='none' stroke='currentColor'><\/path>\n<path d='M 296,576 L 344,576' fill='none' stroke='currentColor'><\/path>\n<path d='M 344,576 L 392,576' fill='none' stroke='currentColor'><\/path>\n<path d='M 392,576 L 440,576' fill='none' stroke='currentColor'><\/path>\n<path d='M 464,576 L 512,576' fill='none' stroke='currentColor'><\/path>\n<path d='M 512,576 L 560,576' fill='none' stroke='currentColor'><\/path>\n<path d='M 560,576 L 608,576' fill='none' stroke='currentColor'><\/path>\n<path d='M 608,576 L 656,576' fill='none' stroke='currentColor'><\/path>\n<path d='M 192,608 L 224,608' fill='none' stroke='currentColor'><\/path>\n<path d='M 224,608 L 256,608' fill='none' stroke='currentColor'><\/path>\n<path d='M 256,608 L 288,608' fill='none' stroke='currentColor'><\/path>\n<path d='M 288,608 L 320,608' fill='none' stroke='currentColor'><\/path>\n<path d='M 320,608 L 352,608' fill='none' stroke='currentColor'><\/path>\n<path d='M 400,608 L 432,608' fill='none' stroke='currentColor'><\/path>\n<path d='M 432,608 L 464,608' fill='none' stroke='currentColor'><\/path>\n<path d='M 464,608 L 496,608' fill='none' stroke='currentColor'><\/path>\n<path d='M 496,608 L 528,608' fill='none' stroke='currentColor'><\/path>\n<path d='M 552,608 L 584,608' fill='none' stroke='currentColor'><\/path>\n<path d='M 616,608 L 648,608' fill='none' stroke='currentColor'><\/path>\n<path d='M 584,624 L 616,624' fill='none' stroke='currentColor'><\/path>\n<path d='M 192,640 L 224,640' fill='none' stroke='currentColor'><\/path>\n<path d='M 224,640 L 256,640' fill='none' stroke='currentColor'><\/path>\n<path d='M 256,640 L 288,640' fill='none' stroke='currentColor'><\/path>\n<path d='M 288,640 L 320,640' fill='none' stroke='currentColor'><\/path>\n<path d='M 320,640 L 352,640' fill='none' stroke='currentColor'><\/path>\n<path d='M 384,640 L 416,640' fill='none' stroke='currentColor'><\/path>\n<path d='M 416,640 L 448,640' fill='none' stroke='currentColor'><\/path>\n<path d='M 448,640 L 480,640' fill='none' stroke='currentColor'><\/path>\n<path d='M 480,640 L 512,640' fill='none' stroke='currentColor'><\/path>\n<path d='M 552,640 L 584,640' fill='none' stroke='currentColor'><\/path>\n<path d='M 616,640 L 648,640' fill='none' stroke='currentColor'><\/path>\n<path d='M 584,656 L 616,656' fill='none' stroke='currentColor'><\/path>\n<path d='M 192,672 L 224,672' fill='none' stroke='currentColor'><\/path>\n<path d='M 224,672 L 256,672' fill='none' stroke='currentColor'><\/path>\n<path d='M 256,672 L 288,672' fill='none' stroke='currentColor'><\/path>\n<path d='M 288,672 L 320,672' fill='none' stroke='currentColor'><\/path>\n<path d='M 320,672 L 352,672' fill='none' stroke='currentColor'><\/path>\n<path d='M 400,672 L 432,672' fill='none' stroke='currentColor'><\/path>\n<path d='M 432,672 L 464,672' fill='none' stroke='currentColor'><\/path>\n<path d='M 464,672 L 496,672' fill='none' stroke='currentColor'><\/path>\n<path d='M 496,672 L 528,672' fill='none' stroke='currentColor'><\/path>\n<path d='M 552,672 L 584,672' fill='none' stroke='currentColor'><\/path>\n<path d='M 616,672 L 648,672' fill='none' stroke='currentColor'><\/path>\n<path d='M 584,688 L 616,688' fill='none' stroke='currentColor'><\/path>\n<path d='M 192,704 L 224,704' fill='none' stroke='currentColor'><\/path>\n<path d='M 224,704 L 256,704' fill='none' stroke='currentColor'><\/path>\n<path d='M 256,704 L 288,704' fill='none' stroke='currentColor'><\/path>\n<path d='M 288,704 L 320,704' fill='none' stroke='currentColor'><\/path>\n<path d='M 320,704 L 352,704' fill='none' stroke='currentColor'><\/path>\n<path d='M 384,704 L 416,704' fill='none' stroke='currentColor'><\/path>\n<path d='M 416,704 L 448,704' fill='none' stroke='currentColor'><\/path>\n<path d='M 448,704 L 480,704' fill='none' stroke='currentColor'><\/path>\n<path d='M 480,704 L 512,704' fill='none' stroke='currentColor'><\/path>\n<path d='M 552,704 L 584,704' fill='none' stroke='currentColor'><\/path>\n<path d='M 616,704 L 648,704' fill='none' stroke='currentColor'><\/path>\n<path d='M 64,360 L 88,360' fill='none' stroke='currentColor'><\/path>\n<path d='M 264,360 L 288,360' fill='none' stroke='currentColor'><\/path>\n<path d='M 52,616 L 76,616' fill='none' stroke='currentColor'><\/path>\n<path d='M 116,616 L 140,616' fill='none' stroke='currentColor'><\/path>\n<path d='M 20,632 L 44,632' fill='none' stroke='currentColor'><\/path>\n<path d='M 84,632 L 108,632' fill='none' stroke='currentColor'><\/path>\n<path d='M 52,648 L 76,648' fill='none' stroke='currentColor'><\/path>\n<path d='M 116,648 L 140,648' fill='none' stroke='currentColor'><\/path>\n<path d='M 20,664 L 44,664' fill='none' stroke='currentColor'><\/path>\n<path d='M 84,664 L 108,664' fill='none' stroke='currentColor'><\/path>\n<path d='M 52,680 L 76,680' fill='none' stroke='currentColor'><\/path>\n<path d='M 116,680 L 140,680' fill='none' stroke='currentColor'><\/path>\n<path d='M 20,696 L 44,696' fill='none' stroke='currentColor'><\/path>\n<path d='M 84,696 L 108,696' fill='none' stroke='currentColor'><\/path>\n<path d='M 52,712 L 76,712' fill='none' stroke='currentColor'><\/path>\n<path d='M 116,712 L 140,712' fill='none' stroke='currentColor'><\/path>\n<path d='M 40,288 L 40,336' fill='none' stroke='currentColor'><\/path>\n<path d='M 80,240 L 80,272' fill='none' stroke='currentColor'><\/path>\n<path d='M 112,288 L 112,336' fill='none' stroke='currentColor'><\/path>\n<path d='M 192,16 L 192,32' fill='none' stroke='currentColor'><\/path>\n<path d='M 192,64 L 192,80' fill='none' stroke='currentColor'><\/path>\n<path d='M 192,608 L 192,640' fill='none' stroke='currentColor'><\/path>\n<path d='M 192,640 L 192,672' fill='none' stroke='currentColor'><\/path>\n<path d='M 192,672 L 192,704' fill='none' stroke='currentColor'><\/path>\n<path d='M 224,16 L 224,32' fill='none' stroke='currentColor'><\/path>\n<path d='M 224,64 L 224,80' fill='none' stroke='currentColor'><\/path>\n<path d='M 224,608 L 224,640' fill='none' stroke='currentColor'><\/path>\n<path d='M 224,640 L 224,672' fill='none' stroke='currentColor'><\/path>\n<path d='M 224,672 L 224,704' fill='none' stroke='currentColor'><\/path>\n<path d='M 240,288 L 240,336' fill='none' stroke='currentColor'><\/path>\n<path d='M 256,608 L 256,640' fill='none' stroke='currentColor'><\/path>\n<path d='M 256,640 L 256,672' fill='none' stroke='currentColor'><\/path>\n<path d='M 256,672 L 256,704' fill='none' stroke='currentColor'><\/path>\n<path d='M 280,208 L 280,240' fill='none' stroke='currentColor'><\/path>\n<path d='M 288,608 L 288,640' fill='none' stroke='currentColor'><\/path>\n<path d='M 288,640 L 288,672' fill='none' stroke='currentColor'><\/path>\n<path d='M 288,672 L 288,704' fill='none' stroke='currentColor'><\/path>\n<path d='M 296,432 L 296,480' fill='none' stroke='currentColor'><\/path>\n<path d='M 296,480 L 296,528' fill='none' stroke='currentColor'><\/path>\n<path d='M 296,528 L 296,576' fill='none' stroke='currentColor'><\/path>\n<path d='M 304,16 L 304,32' fill='none' stroke='currentColor'><\/path>\n<path d='M 304,32 L 304,64' fill='none' stroke='currentColor'><\/path>\n<path d='M 304,64 L 304,80' fill='none' stroke='currentColor'><\/path>\n<path d='M 312,288 L 312,336' fill='none' stroke='currentColor'><\/path>\n<path d='M 320,608 L 320,640' fill='none' stroke='currentColor'><\/path>\n<path d='M 320,640 L 320,672' fill='none' stroke='currentColor'><\/path>\n<path d='M 320,672 L 320,704' fill='none' stroke='currentColor'><\/path>\n<path d='M 336,16 L 336,32' fill='none' stroke='currentColor'><\/path>\n<path d='M 336,32 L 336,64' fill='none' stroke='currentColor'><\/path>\n<path d='M 336,64 L 336,80' fill='none' stroke='currentColor'><\/path>\n<path d='M 336,208 L 336,240' fill='none' stroke='currentColor'><\/path>\n<path d='M 344,432 L 344,480' fill='none' stroke='currentColor'><\/path>\n<path d='M 344,480 L 344,528' fill='none' stroke='currentColor'><\/path>\n<path d='M 344,528 L 344,576' fill='none' stroke='currentColor'><\/path>\n<path d='M 352,608 L 352,640' fill='none' stroke='currentColor'><\/path>\n<path d='M 352,640 L 352,672' fill='none' stroke='currentColor'><\/path>\n<path d='M 352,672 L 352,704' fill='none' stroke='currentColor'><\/path>\n<path d='M 392,432 L 392,480' fill='none' stroke='currentColor'><\/path>\n<path d='M 392,480 L 392,528' fill='none' stroke='currentColor'><\/path>\n<path d='M 392,528 L 392,576' fill='none' stroke='currentColor'><\/path>\n<path d='M 416,16 L 416,80' fill='none' stroke='currentColor'><\/path>\n<path d='M 416,304 L 416,352' fill='none' stroke='currentColor'><\/path>\n<path d='M 440,432 L 440,480' fill='none' stroke='currentColor'><\/path>\n<path d='M 440,480 L 440,528' fill='none' stroke='currentColor'><\/path>\n<path d='M 440,528 L 440,576' fill='none' stroke='currentColor'><\/path>\n<path d='M 448,16 L 448,80' fill='none' stroke='currentColor'><\/path>\n<path d='M 448,240 L 448,272' fill='none' stroke='currentColor'><\/path>\n<path d='M 480,304 L 480,352' fill='none' stroke='currentColor'><\/path>\n<path d='M 528,16 L 528,32' fill='none' stroke='currentColor'><\/path>\n<path d='M 528,64 L 528,80' fill='none' stroke='currentColor'><\/path>\n<path d='M 536,144 L 536,192' fill='none' stroke='currentColor'><\/path>\n<path d='M 552,304 L 552,368' fill='none' stroke='currentColor'><\/path>\n<path d='M 552,608 L 552,640' fill='none' stroke='currentColor'><\/path>\n<path d='M 552,640 L 552,672' fill='none' stroke='currentColor'><\/path>\n<path d='M 552,672 L 552,704' fill='none' stroke='currentColor'><\/path>\n<path d='M 560,16 L 560,32' fill='none' stroke='currentColor'><\/path>\n<path d='M 560,64 L 560,80' fill='none' stroke='currentColor'><\/path>\n<path d='M 584,224 L 584,256' fill='none' stroke='currentColor'><\/path>\n<path d='M 584,608 L 584,624' fill='none' stroke='currentColor'><\/path>\n<path d='M 584,624 L 584,640' fill='none' stroke='currentColor'><\/path>\n<path d='M 584,640 L 584,656' fill='none' stroke='currentColor'><\/path>\n<path d='M 584,656 L 584,672' fill='none' stroke='currentColor'><\/path>\n<path d='M 584,672 L 584,688' fill='none' stroke='currentColor'><\/path>\n<path d='M 584,688 L 584,704' fill='none' stroke='currentColor'><\/path>\n<path d='M 608,304 L 608,320' fill='none' stroke='currentColor'><\/path>\n<path d='M 608,320 L 608,336' fill='none' stroke='currentColor'><\/path>\n<path d='M 608,336 L 608,352' fill='none' stroke='currentColor'><\/path>\n<path d='M 608,352 L 608,368' fill='none' stroke='currentColor'><\/path>\n<path d='M 616,608 L 616,624' fill='none' stroke='currentColor'><\/path>\n<path d='M 616,624 L 616,640' fill='none' stroke='currentColor'><\/path>\n<path d='M 616,640 L 616,656' fill='none' stroke='currentColor'><\/path>\n<path d='M 616,656 L 616,672' fill='none' stroke='currentColor'><\/path>\n<path d='M 616,672 L 616,688' fill='none' stroke='currentColor'><\/path>\n<path d='M 616,688 L 616,704' fill='none' stroke='currentColor'><\/path>\n<path d='M 624,144 L 624,192' fill='none' stroke='currentColor'><\/path>\n<path d='M 624,272 L 624,336' fill='none' stroke='currentColor'><\/path>\n<path d='M 640,48 L 640,80' fill='none' stroke='currentColor'><\/path>\n<path d='M 648,608 L 648,640' fill='none' stroke='currentColor'><\/path>\n<path d='M 648,640 L 648,672' fill='none' stroke='currentColor'><\/path>\n<path d='M 648,672 L 648,704' fill='none' stroke='currentColor'><\/path>\n<path d='M 672,16 L 672,48' fill='none' stroke='currentColor'><\/path>\n<path d='M 672,304 L 672,368' fill='none' stroke='currentColor'><\/path>\n<path d='M 728,304 L 728,320' fill='none' stroke='currentColor'><\/path>\n<path d='M 728,320 L 728,336' fill='none' stroke='currentColor'><\/path>\n<path d='M 728,336 L 728,352' fill='none' stroke='currentColor'><\/path>\n<path d='M 728,352 L 728,368' fill='none' stroke='currentColor'><\/path>\n<path d='M 744,272 L 744,336' fill='none' stroke='currentColor'><\/path>\n<path d='M 24,368 L 40,336' fill='none' stroke='currentColor'><\/path>\n<path d='M 36,360 L 44,344' fill='none' stroke='currentColor'><\/path>\n<path d='M 44,360 L 52,344' fill='none' stroke='currentColor'><\/path>\n<path d='M 16,448 L 32,416' fill='none' stroke='currentColor'><\/path>\n<path d='M 16,512 L 32,480' fill='none' stroke='currentColor'><\/path>\n<path d='M 72,480 L 88,448' fill='none' stroke='currentColor'><\/path>\n<path d='M 12,648 L 20,632' fill='none' stroke='currentColor'><\/path>\n<path d='M 72,544 L 88,512' fill='none' stroke='currentColor'><\/path>\n<path d='M 12,680 L 20,664' fill='none' stroke='currentColor'><\/path>\n<path d='M 128,448 L 144,416' fill='none' stroke='currentColor'><\/path>\n<path d='M 44,632 L 52,616' fill='none' stroke='currentColor'><\/path>\n<path d='M 44,664 L 52,648' fill='none' stroke='currentColor'><\/path>\n<path d='M 128,512 L 144,480' fill='none' stroke='currentColor'><\/path>\n<path d='M 44,696 L 52,680' fill='none' stroke='currentColor'><\/path>\n<path d='M 76,648 L 84,632' fill='none' stroke='currentColor'><\/path>\n<path d='M 224,368 L 240,336' fill='none' stroke='currentColor'><\/path>\n<path d='M 76,680 L 84,664' fill='none' stroke='currentColor'><\/path>\n<path d='M 128,576 L 144,544' fill='none' stroke='currentColor'><\/path>\n<path d='M 236,360 L 244,344' fill='none' stroke='currentColor'><\/path>\n<path d='M 108,632 L 116,616' fill='none' stroke='currentColor'><\/path>\n<path d='M 184,480 L 200,448' fill='none' stroke='currentColor'><\/path>\n<path d='M 244,360 L 252,344' fill='none' stroke='currentColor'><\/path>\n<path d='M 76,712 L 84,696' fill='none' stroke='currentColor'><\/path>\n<path d='M 108,664 L 116,648' fill='none' stroke='currentColor'><\/path>\n<path d='M 108,696 L 116,680' fill='none' stroke='currentColor'><\/path>\n<path d='M 184,544 L 200,512' fill='none' stroke='currentColor'><\/path>\n<path d='M 140,648 L 148,632' fill='none' stroke='currentColor'><\/path>\n<path d='M 140,680 L 148,664' fill='none' stroke='currentColor'><\/path>\n<path d='M 140,712 L 148,696' fill='none' stroke='currentColor'><\/path>\n<path d='M 240,512 L 256,480' fill='none' stroke='currentColor'><\/path>\n<path d='M 240,576 L 256,544' fill='none' stroke='currentColor'><\/path>\n<path d='M 384,640 L 400,608' fill='none' stroke='currentColor'><\/path>\n<path d='M 552,304 L 568,272' fill='none' stroke='currentColor'><\/path>\n<path d='M 384,704 L 400,672' fill='none' stroke='currentColor'><\/path>\n<path d='M 400,672 L 416,640' fill='none' stroke='currentColor'><\/path>\n<path d='M 416,640 L 432,608' fill='none' stroke='currentColor'><\/path>\n<path d='M 464,576 L 480,544' fill='none' stroke='currentColor'><\/path>\n<path d='M 480,544 L 496,512' fill='none' stroke='currentColor'><\/path>\n<path d='M 496,512 L 512,480' fill='none' stroke='currentColor'><\/path>\n<path d='M 512,480 L 528,448' fill='none' stroke='currentColor'><\/path>\n<path d='M 608,304 L 624,272' fill='none' stroke='currentColor'><\/path>\n<path d='M 416,704 L 432,672' fill='none' stroke='currentColor'><\/path>\n<path d='M 432,672 L 448,640' fill='none' stroke='currentColor'><\/path>\n<path d='M 448,640 L 464,608' fill='none' stroke='currentColor'><\/path>\n<path d='M 608,320 L 624,288' fill='none' stroke='currentColor'><\/path>\n<path d='M 608,336 L 624,304' fill='none' stroke='currentColor'><\/path>\n<path d='M 608,352 L 624,320' fill='none' stroke='currentColor'><\/path>\n<path d='M 608,368 L 624,336' fill='none' stroke='currentColor'><\/path>\n<path d='M 448,704 L 464,672' fill='none' stroke='currentColor'><\/path>\n<path d='M 464,672 L 480,640' fill='none' stroke='currentColor'><\/path>\n<path d='M 480,640 L 496,608' fill='none' stroke='currentColor'><\/path>\n<path d='M 512,576 L 528,544' fill='none' stroke='currentColor'><\/path>\n<path d='M 528,544 L 544,512' fill='none' stroke='currentColor'><\/path>\n<path d='M 544,512 L 560,480' fill='none' stroke='currentColor'><\/path>\n<path d='M 560,480 L 576,448' fill='none' stroke='currentColor'><\/path>\n<path d='M 672,304 L 688,272' fill='none' stroke='currentColor'><\/path>\n<path d='M 480,704 L 496,672' fill='none' stroke='currentColor'><\/path>\n<path d='M 496,672 L 512,640' fill='none' stroke='currentColor'><\/path>\n<path d='M 512,640 L 528,608' fill='none' stroke='currentColor'><\/path>\n<path d='M 560,576 L 576,544' fill='none' stroke='currentColor'><\/path>\n<path d='M 576,544 L 592,512' fill='none' stroke='currentColor'><\/path>\n<path d='M 592,512 L 608,480' fill='none' stroke='currentColor'><\/path>\n<path d='M 608,480 L 624,448' fill='none' stroke='currentColor'><\/path>\n<path d='M 512,704 L 528,672' fill='none' stroke='currentColor'><\/path>\n<path d='M 728,304 L 744,272' fill='none' stroke='currentColor'><\/path>\n<path d='M 728,320 L 744,288' fill='none' stroke='currentColor'><\/path>\n<path d='M 608,576 L 624,544' fill='none' stroke='currentColor'><\/path>\n<path d='M 624,544 L 640,512' fill='none' stroke='currentColor'><\/path>\n<path d='M 640,512 L 656,480' fill='none' stroke='currentColor'><\/path>\n<path d='M 656,480 L 672,448' fill='none' stroke='currentColor'><\/path>\n<path d='M 728,336 L 744,304' fill='none' stroke='currentColor'><\/path>\n<path d='M 728,352 L 744,320' fill='none' stroke='currentColor'><\/path>\n<path d='M 728,368 L 744,336' fill='none' stroke='currentColor'><\/path>\n<path d='M 656,576 L 672,544' fill='none' stroke='currentColor'><\/path>\n<path d='M 672,544 L 688,512' fill='none' stroke='currentColor'><\/path>\n<path d='M 688,512 L 704,480' fill='none' stroke='currentColor'><\/path>\n<path d='M 704,480 L 720,448' fill='none' stroke='currentColor'><\/path>\n<path d='M 12,680 L 20,696' fill='none' stroke='currentColor'><\/path>\n<path d='M 12,648 L 20,664' fill='none' stroke='currentColor'><\/path>\n<path d='M 44,696 L 52,712' fill='none' stroke='currentColor'><\/path>\n<path d='M 44,664 L 52,680' fill='none' stroke='currentColor'><\/path>\n<path d='M 44,632 L 52,648' fill='none' stroke='currentColor'><\/path>\n<path d='M 76,680 L 84,696' fill='none' stroke='currentColor'><\/path>\n<path d='M 76,648 L 84,664' fill='none' stroke='currentColor'><\/path>\n<path d='M 16,512 L 32,544' fill='none' stroke='currentColor'><\/path>\n<path d='M 108,696 L 116,712' fill='none' stroke='currentColor'><\/path>\n<path d='M 76,616 L 84,632' fill='none' stroke='currentColor'><\/path>\n<path d='M 108,664 L 116,680' fill='none' stroke='currentColor'><\/path>\n<path d='M 16,448 L 32,480' fill='none' stroke='currentColor'><\/path>\n<path d='M 108,632 L 116,648' fill='none' stroke='currentColor'><\/path>\n<path d='M 72,544 L 88,576' fill='none' stroke='currentColor'><\/path>\n<path d='M 140,680 L 148,696' fill='none' stroke='currentColor'><\/path>\n<path d='M 140,648 L 148,664' fill='none' stroke='currentColor'><\/path>\n<path d='M 72,480 L 88,512' fill='none' stroke='currentColor'><\/path>\n<path d='M 140,616 L 148,632' fill='none' stroke='currentColor'><\/path>\n<path d='M 72,416 L 88,448' fill='none' stroke='currentColor'><\/path>\n<path d='M 128,512 L 144,544' fill='none' stroke='currentColor'><\/path>\n<path d='M 128,448 L 144,480' fill='none' stroke='currentColor'><\/path>\n<path d='M 184,544 L 200,576' fill='none' stroke='currentColor'><\/path>\n<path d='M 100,344 L 108,360' fill='none' stroke='currentColor'><\/path>\n<path d='M 108,344 L 116,360' fill='none' stroke='currentColor'><\/path>\n<path d='M 112,336 L 128,368' fill='none' stroke='currentColor'><\/path>\n<path d='M 184,480 L 200,512' fill='none' stroke='currentColor'><\/path>\n<path d='M 184,416 L 200,448' fill='none' stroke='currentColor'><\/path>\n<path d='M 240,512 L 256,544' fill='none' stroke='currentColor'><\/path>\n<path d='M 240,448 L 256,480' fill='none' stroke='currentColor'><\/path>\n<path d='M 384,640 L 400,672' fill='none' stroke='currentColor'><\/path>\n<path d='M 400,672 L 416,704' fill='none' stroke='currentColor'><\/path>\n<path d='M 400,608 L 416,640' fill='none' stroke='currentColor'><\/path>\n<path d='M 416,640 L 432,672' fill='none' stroke='currentColor'><\/path>\n<path d='M 432,672 L 448,704' fill='none' stroke='currentColor'><\/path>\n<path d='M 300,344 L 308,360' fill='none' stroke='currentColor'><\/path>\n<path d='M 432,608 L 448,640' fill='none' stroke='currentColor'><\/path>\n<path d='M 448,640 L 464,672' fill='none' stroke='currentColor'><\/path>\n<path d='M 464,672 L 480,704' fill='none' stroke='currentColor'><\/path>\n<path d='M 308,344 L 316,360' fill='none' stroke='currentColor'><\/path>\n<path d='M 312,336 L 328,368' fill='none' stroke='currentColor'><\/path>\n<path d='M 464,608 L 480,640' fill='none' stroke='currentColor'><\/path>\n<path d='M 480,640 L 496,672' fill='none' stroke='currentColor'><\/path>\n<path d='M 496,672 L 512,704' fill='none' stroke='currentColor'><\/path>\n<path d='M 496,608 L 512,640' fill='none' stroke='currentColor'><\/path>\n<path d='M 512,640 L 528,672' fill='none' stroke='currentColor'><\/path>\n<path d='M 80,16 L 80,24' fill='none' stroke='currentColor'><\/path>\n<path d='M 80,72 L 80,80' fill='none' stroke='currentColor'><\/path>\n<path d='M 112,16 L 112,24' fill='none' stroke='currentColor'><\/path>\n<path d='M 112,72 L 112,80' fill='none' stroke='currentColor'><\/path>\n<path d='M 640,16 L 640,24' fill='none' stroke='currentColor'><\/path>\n<path d='M 640,40 L 640,48' fill='none' stroke='currentColor'><\/path>\n<path d='M 672,48 L 672,56' fill='none' stroke='currentColor'><\/path>\n<path d='M 672,72 L 672,80' fill='none' stroke='currentColor'><\/path>\n<path d='M 80,272 L 80,280' fill='none' stroke='currentColor'><\/path>\n<polygon points='96.000000,272.000000 84.000000,266.399994 84.000000,277.600006' fill='currentColor' transform='rotate(90.000000, 80.000000, 272.000000)'><\/polygon>\n<polygon points='128.000000,304.000000 116.000000,298.399994 116.000000,309.600006' fill='currentColor' transform='rotate(180.000000, 120.000000, 304.000000)'><\/polygon>\n<polygon points='240.000000,304.000000 228.000000,298.399994 228.000000,309.600006' fill='currentColor' transform='rotate(0.000000, 232.000000, 304.000000)'><\/polygon>\n<path d='M 280,200 L 280,208' fill='none' stroke='currentColor'><\/path>\n<polygon points='296.000000,208.000000 284.000000,202.399994 284.000000,213.600006' fill='currentColor' transform='rotate(270.000000, 280.000000, 208.000000)'><\/polygon>\n<polygon points='328.000000,304.000000 316.000000,298.399994 316.000000,309.600006' fill='currentColor' transform='rotate(180.000000, 320.000000, 304.000000)'><\/polygon>\n<path d='M 336,200 L 336,208' fill='none' stroke='currentColor'><\/path>\n<polygon points='352.000000,208.000000 340.000000,202.399994 340.000000,213.600006' fill='currentColor' transform='rotate(270.000000, 336.000000, 208.000000)'><\/polygon>\n<polygon points='384.000000,176.000000 372.000000,170.399994 372.000000,181.600006' fill='currentColor' transform='rotate(180.000000, 376.000000, 176.000000)'><\/polygon>\n<polygon points='416.000000,304.000000 404.000000,298.399994 404.000000,309.600006' fill='currentColor' transform='rotate(0.000000, 408.000000, 304.000000)'><\/polygon>\n<path d='M 448,272 L 448,280' fill='none' stroke='currentColor'><\/path>\n<polygon points='464.000000,272.000000 452.000000,266.399994 452.000000,277.600006' fill='currentColor' transform='rotate(90.000000, 448.000000, 272.000000)'><\/polygon>\n<polygon points='536.000000,176.000000 524.000000,170.399994 524.000000,181.600006' fill='currentColor' transform='rotate(0.000000, 528.000000, 176.000000)'><\/polygon>\n<path d='M 584,216 L 584,224' fill='none' stroke='currentColor'><\/path>\n<polygon points='600.000000,224.000000 588.000000,218.399994 588.000000,229.600006' fill='currentColor' transform='rotate(270.000000, 584.000000, 224.000000)'><\/polygon>\n<path d='M 584,256 L 584,264' fill='none' stroke='currentColor'><\/path>\n<polygon points='600.000000,256.000000 588.000000,250.399994 588.000000,261.600006' fill='currentColor' transform='rotate(90.000000, 584.000000, 256.000000)'><\/polygon>\n<polygon points='640.000000,320.000000 628.000000,314.399994 628.000000,325.600006' fill='currentColor' transform='rotate(180.000000, 632.000000, 320.000000)'><\/polygon>\n<polygon points='672.000000,320.000000 660.000000,314.399994 660.000000,325.600006' fill='currentColor' transform='rotate(0.000000, 664.000000, 320.000000)'><\/polygon>\n<path d='M 96,0 A 16,16 0 0,0 80,16' fill='none' stroke='currentColor'><\/path>\n<path d='M 96,0 A 16,16 0 0,1 112,16' fill='none' stroke='currentColor'><\/path>\n<path d='M 208,0 A 16,16 0 0,0 192,16' fill='none' stroke='currentColor'><\/path>\n<path d='M 208,0 A 16,16 0 0,1 224,16' fill='none' stroke='currentColor'><\/path>\n<path d='M 320,0 A 16,16 0 0,0 304,16' fill='none' stroke='currentColor'><\/path>\n<path d='M 320,0 A 16,16 0 0,1 336,16' fill='none' stroke='currentColor'><\/path>\n<path d='M 432,0 A 16,16 0 0,0 416,16' fill='none' stroke='currentColor'><\/path>\n<path d='M 432,0 A 16,16 0 0,1 448,16' fill='none' stroke='currentColor'><\/path>\n<path d='M 544,0 A 16,16 0 0,0 528,16' fill='none' stroke='currentColor'><\/path>\n<path d='M 544,0 A 16,16 0 0,1 560,16' fill='none' stroke='currentColor'><\/path>\n<path d='M 656,0 A 16,16 0 0,0 640,16' fill='none' stroke='currentColor'><\/path>\n<path d='M 656,0 A 16,16 0 0,1 672,16' fill='none' stroke='currentColor'><\/path>\n<path d='M 64,32 A 16,16 0 0,0 48,48' fill='none' stroke='currentColor'><\/path>\n<path d='M 128,32 A 16,16 0 0,1 144,48' fill='none' stroke='currentColor'><\/path>\n<path d='M 176,32 A 16,16 0 0,0 160,48' fill='none' stroke='currentColor'><\/path>\n<path d='M 240,32 A 16,16 0 0,1 256,48' fill='none' stroke='currentColor'><\/path>\n<path d='M 288,32 A 16,16 0 0,0 272,48' fill='none' stroke='currentColor'><\/path>\n<path d='M 352,32 A 16,16 0 0,1 368,48' fill='none' stroke='currentColor'><\/path>\n<path d='M 400,32 A 16,16 0 0,0 384,48' fill='none' stroke='currentColor'><\/path>\n<path d='M 464,32 A 16,16 0 0,1 480,48' fill='none' stroke='currentColor'><\/path>\n<path d='M 512,32 A 16,16 0 0,0 496,48' fill='none' stroke='currentColor'><\/path>\n<path d='M 576,32 A 16,16 0 0,1 592,48' fill='none' stroke='currentColor'><\/path>\n<path d='M 624,32 A 16,16 0 0,0 608,48' fill='none' stroke='currentColor'><\/path>\n<path d='M 688,32 A 16,16 0 0,1 704,48' fill='none' stroke='currentColor'><\/path>\n<path d='M 48,48 A 16,16 0 0,0 64,64' fill='none' stroke='currentColor'><\/path>\n<path d='M 144,48 A 16,16 0 0,1 128,64' fill='none' stroke='currentColor'><\/path>\n<path d='M 160,48 A 16,16 0 0,0 176,64' fill='none' stroke='currentColor'><\/path>\n<path d='M 256,48 A 16,16 0 0,1 240,64' fill='none' stroke='currentColor'><\/path>\n<path d='M 272,48 A 16,16 0 0,0 288,64' fill='none' stroke='currentColor'><\/path>\n<path d='M 368,48 A 16,16 0 0,1 352,64' fill='none' stroke='currentColor'><\/path>\n<path d='M 384,48 A 16,16 0 0,0 400,64' fill='none' stroke='currentColor'><\/path>\n<path d='M 480,48 A 16,16 0 0,1 464,64' fill='none' stroke='currentColor'><\/path>\n<path d='M 496,48 A 16,16 0 0,0 512,64' fill='none' stroke='currentColor'><\/path>\n<path d='M 592,48 A 16,16 0 0,1 576,64' fill='none' stroke='currentColor'><\/path>\n<path d='M 608,48 A 16,16 0 0,0 624,64' fill='none' stroke='currentColor'><\/path>\n<path d='M 704,48 A 16,16 0 0,1 688,64' fill='none' stroke='currentColor'><\/path>\n<path d='M 80,80 A 16,16 0 0,0 96,96' fill='none' stroke='currentColor'><\/path>\n<path d='M 112,80 A 16,16 0 0,1 96,96' fill='none' stroke='currentColor'><\/path>\n<path d='M 192,80 A 16,16 0 0,0 208,96' fill='none' stroke='currentColor'><\/path>\n<path d='M 224,80 A 16,16 0 0,1 208,96' fill='none' stroke='currentColor'><\/path>\n<path d='M 304,80 A 16,16 0 0,0 320,96' fill='none' stroke='currentColor'><\/path>\n<path d='M 336,80 A 16,16 0 0,1 320,96' fill='none' stroke='currentColor'><\/path>\n<path d='M 416,80 A 16,16 0 0,0 432,96' fill='none' stroke='currentColor'><\/path>\n<path d='M 448,80 A 16,16 0 0,1 432,96' fill='none' stroke='currentColor'><\/path>\n<path d='M 528,80 A 16,16 0 0,0 544,96' fill='none' stroke='currentColor'><\/path>\n<path d='M 560,80 A 16,16 0 0,1 544,96' fill='none' stroke='currentColor'><\/path>\n<path d='M 640,80 A 16,16 0 0,0 656,96' fill='none' stroke='currentColor'><\/path>\n<path d='M 672,80 A 16,16 0 0,1 656,96' fill='none' stroke='currentColor'><\/path>\n<path d='M 312,128 A 16,16 0 0,0 296,144' fill='none' stroke='currentColor'><\/path>\n<path d='M 312,128 A 16,16 0 0,1 328,144' fill='none' stroke='currentColor'><\/path>\n<path d='M 552,128 A 16,16 0 0,0 536,144' fill='none' stroke='currentColor'><\/path>\n<path d='M 608,128 A 16,16 0 0,1 624,144' fill='none' stroke='currentColor'><\/path>\n<path d='M 288,144 A 16,16 0 0,0 272,160' fill='none' stroke='currentColor'><\/path>\n<path d='M 256,160 A 16,16 0 0,0 240,176' fill='none' stroke='currentColor'><\/path>\n<path d='M 328,144 A 16,16 0 0,0 344,160' fill='none' stroke='currentColor'><\/path>\n<path d='M 352,160 A 16,16 0 0,1 368,176' fill='none' stroke='currentColor'><\/path>\n<path d='M 536,144 A 16,16 0 0,0 552,160' fill='none' stroke='currentColor'><\/path>\n<path d='M 624,144 A 16,16 0 0,1 608,160' fill='none' stroke='currentColor'><\/path>\n<path d='M 240,176 A 16,16 0 0,0 256,192' fill='none' stroke='currentColor'><\/path>\n<path d='M 368,176 A 16,16 0 0,1 352,192' fill='none' stroke='currentColor'><\/path>\n<path d='M 536,192 A 16,16 0 0,0 552,208' fill='none' stroke='currentColor'><\/path>\n<path d='M 624,192 A 16,16 0 0,1 608,208' fill='none' stroke='currentColor'><\/path>\n<path d='M 432,288 A 16,16 0 0,0 416,304' fill='none' stroke='currentColor'><\/path>\n<path d='M 464,288 A 16,16 0 0,1 480,304' fill='none' stroke='currentColor'><\/path>\n<path d='M 416,352 A 16,16 0 0,0 432,368' fill='none' stroke='currentColor'><\/path>\n<path d='M 480,352 A 16,16 0 0,1 464,368' fill='none' stroke='currentColor'><\/path>\n<circle cx='16' cy='752' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='16' cy='768' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='16' cy='784' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='16' cy='800' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='16' cy='816' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='32' cy='752' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='32' cy='768' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='32' cy='784' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='32' cy='800' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='32' cy='816' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='48' cy='752' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='48' cy='768' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='48' cy='784' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='48' cy='800' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='48' cy='816' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='64' cy='752' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='64' cy='768' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='64' cy='784' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='64' cy='800' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='64' cy='816' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='80' cy='752' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='80' cy='768' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='80' cy='784' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='80' cy='800' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='80' cy='816' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='104' cy='752' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='104' cy='768' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='104' cy='784' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='104' cy='800' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='104' cy='816' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='120' cy='752' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='120' cy='768' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='120' cy='784' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='120' cy='800' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='120' cy='816' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='136' cy='752' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='136' cy='768' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='136' cy='784' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='136' cy='800' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='136' cy='816' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='152' cy='752' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='152' cy='768' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='152' cy='784' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='152' cy='800' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='152' cy='816' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='168' cy='752' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='168' cy='768' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='168' cy='784' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='168' cy='800' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='168' cy='816' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='192' cy='752' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='192' cy='768' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='192' cy='784' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='192' cy='800' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='192' cy='816' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='208' cy='752' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='208' cy='768' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='208' cy='784' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='208' cy='800' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='208' cy='816' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='224' cy='752' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='224' cy='768' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='224' cy='784' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='224' cy='800' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='224' cy='816' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='240' cy='752' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='240' cy='768' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='240' cy='784' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='240' cy='800' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='240' cy='816' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='256' cy='752' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='256' cy='768' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='256' cy='784' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='256' cy='800' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='256' cy='816' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='280' cy='784' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='288' cy='768' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='288' cy='800' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='296' cy='752' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='296' cy='784' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='296' cy='816' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='304' cy='768' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='304' cy='800' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='312' cy='752' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='312' cy='784' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='312' cy='816' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='320' cy='768' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='320' cy='800' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='328' cy='752' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='328' cy='784' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='328' cy='816' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='336' cy='768' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='336' cy='800' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='344' cy='784' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='368' cy='784' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='376' cy='768' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='376' cy='800' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='384' cy='752' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='384' cy='784' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='384' cy='816' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='392' cy='768' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='392' cy='800' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='400' cy='752' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='400' cy='784' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='400' cy='816' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='408' cy='768' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='408' cy='800' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='416' cy='752' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='416' cy='784' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='416' cy='816' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='424' cy='768' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='424' cy='800' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='432' cy='784' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='448' cy='352' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='456' cy='784' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='464' cy='768' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='464' cy='800' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='472' cy='752' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='472' cy='784' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='472' cy='816' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='480' cy='768' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='480' cy='800' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='488' cy='752' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='488' cy='784' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='488' cy='816' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='496' cy='768' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='496' cy='800' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='504' cy='752' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='504' cy='784' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='504' cy='816' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='512' cy='768' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='512' cy='800' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='520' cy='784' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='568' cy='752' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='568' cy='768' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='568' cy='784' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='584' cy='768' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='616' cy='784' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='616' cy='800' r='6' stroke='currentColor' fill='#fff'><\/circle>\n<circle cx='680' cy='784' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='688' cy='800' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='696' cy='784' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<circle cx='696' cy='816' r='6' stroke='currentColor' fill='currentColor'><\/circle>\n<text text-anchor='middle' x='32' y='676' fill='currentColor' style='font-size:1em'>a<\/text>\n<text text-anchor='middle' x='48' y='324' fill='currentColor' style='font-size:1em'>W<\/text>\n<text text-anchor='middle' x='48' y='388' fill='currentColor' style='font-size:1em'>L<\/text>\n<text text-anchor='middle' x='48' y='516' fill='currentColor' style='font-size:1em'>A<\/text>\n<text text-anchor='middle' x='56' y='324' fill='currentColor' style='font-size:1em'>i<\/text>\n<text text-anchor='middle' x='56' y='388' fill='currentColor' style='font-size:1em'>a<\/text>\n<text text-anchor='middle' x='64' y='324' fill='currentColor' style='font-size:1em'>n<\/text>\n<text text-anchor='middle' x='64' y='388' fill='currentColor' style='font-size:1em'>p<\/text>\n<text text-anchor='middle' x='64' y='660' fill='currentColor' style='font-size:1em'>b<\/text>\n<text text-anchor='middle' x='72' y='324' fill='currentColor' style='font-size:1em'>d<\/text>\n<text text-anchor='middle' x='72' y='388' fill='currentColor' style='font-size:1em'>t<\/text>\n<text text-anchor='middle' x='80' y='324' fill='currentColor' style='font-size:1em'>o<\/text>\n<text text-anchor='middle' x='80' y='388' fill='currentColor' style='font-size:1em'>o<\/text>\n<text text-anchor='middle' x='88' y='324' fill='currentColor' style='font-size:1em'>w<\/text>\n<text text-anchor='middle' x='88' y='388' fill='currentColor' style='font-size:1em'>p<\/text>\n<text text-anchor='middle' x='96' y='324' fill='currentColor' style='font-size:1em'>s<\/text>\n<text text-anchor='middle' x='104' y='388' fill='currentColor' style='font-size:1em'>1<\/text>\n<text text-anchor='middle' x='104' y='484' fill='currentColor' style='font-size:1em'>B<\/text>\n<text text-anchor='middle' x='160' y='228' fill='currentColor' style='font-size:1em'>I<\/text>\n<text text-anchor='middle' x='168' y='228' fill='currentColor' style='font-size:1em'>n<\/text>\n<text text-anchor='middle' x='168' y='292' fill='currentColor' style='font-size:1em'>W<\/text>\n<text text-anchor='middle' x='176' y='228' fill='currentColor' style='font-size:1em'>t<\/text>\n<text text-anchor='middle' x='176' y='292' fill='currentColor' style='font-size:1em'>i<\/text>\n<text text-anchor='middle' x='184' y='228' fill='currentColor' style='font-size:1em'>e<\/text>\n<text text-anchor='middle' x='184' y='292' fill='currentColor' style='font-size:1em'>F<\/text>\n<text text-anchor='middle' x='192' y='228' fill='currentColor' style='font-size:1em'>r<\/text>\n<text text-anchor='middle' x='192' y='292' fill='currentColor' style='font-size:1em'>i<\/text>\n<text text-anchor='middle' x='200' y='228' fill='currentColor' style='font-size:1em'>n<\/text>\n<text text-anchor='middle' x='208' y='228' fill='currentColor' style='font-size:1em'>e<\/text>\n<text text-anchor='middle' x='216' y='228' fill='currentColor' style='font-size:1em'>t<\/text>\n<text text-anchor='middle' x='240' y='692' fill='currentColor' style='font-size:1em'>a<\/text>\n<text text-anchor='middle' x='248' y='388' fill='currentColor' style='font-size:1em'>L<\/text>\n<text text-anchor='middle' x='256' y='388' fill='currentColor' style='font-size:1em'>a<\/text>\n<text text-anchor='middle' x='264' y='180' fill='currentColor' style='font-size:1em'>S<\/text>\n<text text-anchor='middle' x='264' y='324' fill='currentColor' style='font-size:1em'>O<\/text>\n<text text-anchor='middle' x='264' y='388' fill='currentColor' style='font-size:1em'>p<\/text>\n<text text-anchor='middle' x='272' y='180' fill='currentColor' style='font-size:1em'>e<\/text>\n<text text-anchor='middle' x='272' y='324' fill='currentColor' style='font-size:1em'>S<\/text>\n<text text-anchor='middle' x='272' y='388' fill='currentColor' style='font-size:1em'>t<\/text>\n<text text-anchor='middle' x='272' y='660' fill='currentColor' style='font-size:1em'>b<\/text>\n<text text-anchor='middle' x='280' y='180' fill='currentColor' style='font-size:1em'>r<\/text>\n<text text-anchor='middle' x='280' y='388' fill='currentColor' style='font-size:1em'>o<\/text>\n<text text-anchor='middle' x='288' y='180' fill='currentColor' style='font-size:1em'>v<\/text>\n<text text-anchor='middle' x='288' y='324' fill='currentColor' style='font-size:1em'>X<\/text>\n<text text-anchor='middle' x='288' y='388' fill='currentColor' style='font-size:1em'>p<\/text>\n<text text-anchor='middle' x='296' y='180' fill='currentColor' style='font-size:1em'>e<\/text>\n<text text-anchor='middle' x='304' y='180' fill='currentColor' style='font-size:1em'>r<\/text>\n<text text-anchor='middle' x='304' y='388' fill='currentColor' style='font-size:1em'>2<\/text>\n<text text-anchor='middle' x='320' y='180' fill='currentColor' style='font-size:1em'>C<\/text>\n<text text-anchor='middle' x='320' y='564' fill='currentColor' style='font-size:1em'>A<\/text>\n<text text-anchor='middle' x='328' y='180' fill='currentColor' style='font-size:1em'>l<\/text>\n<text text-anchor='middle' x='336' y='180' fill='currentColor' style='font-size:1em'>o<\/text>\n<text text-anchor='middle' x='336' y='292' fill='currentColor' style='font-size:1em'>B<\/text>\n<text text-anchor='middle' x='344' y='180' fill='currentColor' style='font-size:1em'>u<\/text>\n<text text-anchor='middle' x='344' y='292' fill='currentColor' style='font-size:1em'>l<\/text>\n<text text-anchor='middle' x='352' y='180' fill='currentColor' style='font-size:1em'>d<\/text>\n<text text-anchor='middle' x='352' y='292' fill='currentColor' style='font-size:1em'>u<\/text>\n<text text-anchor='middle' x='360' y='292' fill='currentColor' style='font-size:1em'>e<\/text>\n<text text-anchor='middle' x='368' y='292' fill='currentColor' style='font-size:1em'>t<\/text>\n<text text-anchor='middle' x='368' y='516' fill='currentColor' style='font-size:1em'>B<\/text>\n<text text-anchor='middle' x='376' y='292' fill='currentColor' style='font-size:1em'>o<\/text>\n<text text-anchor='middle' x='384' y='292' fill='currentColor' style='font-size:1em'>o<\/text>\n<text text-anchor='middle' x='392' y='292' fill='currentColor' style='font-size:1em'>t<\/text>\n<text text-anchor='middle' x='400' y='292' fill='currentColor' style='font-size:1em'>h<\/text>\n<text text-anchor='middle' x='424' y='388' fill='currentColor' style='font-size:1em'>T<\/text>\n<text text-anchor='middle' x='432' y='388' fill='currentColor' style='font-size:1em'>a<\/text>\n<text text-anchor='middle' x='432' y='660' fill='currentColor' style='font-size:1em'>a<\/text>\n<text text-anchor='middle' x='440' y='324' fill='currentColor' style='font-size:1em'>i<\/text>\n<text text-anchor='middle' x='440' y='388' fill='currentColor' style='font-size:1em'>b<\/text>\n<text text-anchor='middle' x='448' y='324' fill='currentColor' style='font-size:1em'>O<\/text>\n<text text-anchor='middle' x='448' y='388' fill='currentColor' style='font-size:1em'>l<\/text>\n<text text-anchor='middle' x='456' y='324' fill='currentColor' style='font-size:1em'>S<\/text>\n<text text-anchor='middle' x='456' y='388' fill='currentColor' style='font-size:1em'>e<\/text>\n<text text-anchor='middle' x='464' y='388' fill='currentColor' style='font-size:1em'>t<\/text>\n<text text-anchor='middle' x='464' y='660' fill='currentColor' style='font-size:1em'>b<\/text>\n<text text-anchor='middle' x='480' y='388' fill='currentColor' style='font-size:1em'>1<\/text>\n<text text-anchor='middle' x='552' y='180' fill='currentColor' style='font-size:1em'>D<\/text>\n<text text-anchor='middle' x='552' y='756' fill='currentColor' style='font-size:1em'>\u00b7<\/text>\n<text text-anchor='middle' x='552' y='772' fill='currentColor' style='font-size:1em'>\u00b7<\/text>\n<text text-anchor='middle' x='552' y='788' fill='currentColor' style='font-size:1em'>\u00b7<\/text>\n<text text-anchor='middle' x='552' y='804' fill='currentColor' style='font-size:1em'>\u00b7<\/text>\n<text text-anchor='middle' x='552' y='820' fill='currentColor' style='font-size:1em'>\u00b7<\/text>\n<text text-anchor='middle' x='560' y='180' fill='currentColor' style='font-size:1em'>a<\/text>\n<text text-anchor='middle' x='560' y='340' fill='currentColor' style='font-size:1em'>U<\/text>\n<text text-anchor='middle' x='560' y='388' fill='currentColor' style='font-size:1em'>D<\/text>\n<text text-anchor='middle' x='560' y='532' fill='currentColor' style='font-size:1em'>A<\/text>\n<text text-anchor='middle' x='568' y='180' fill='currentColor' style='font-size:1em'>t<\/text>\n<text text-anchor='middle' x='568' y='340' fill='currentColor' style='font-size:1em'>b<\/text>\n<text text-anchor='middle' x='568' y='388' fill='currentColor' style='font-size:1em'>e<\/text>\n<text text-anchor='middle' x='568' y='692' fill='currentColor' style='font-size:1em'>a<\/text>\n<text text-anchor='middle' x='568' y='804' fill='currentColor' style='font-size:1em'>\u00b7<\/text>\n<text text-anchor='middle' x='568' y='820' fill='currentColor' style='font-size:1em'>\u00b7<\/text>\n<text text-anchor='middle' x='576' y='180' fill='currentColor' style='font-size:1em'>a<\/text>\n<text text-anchor='middle' x='576' y='292' fill='currentColor' style='font-size:1em'>#<\/text>\n<text text-anchor='middle' x='576' y='340' fill='currentColor' style='font-size:1em'>u<\/text>\n<text text-anchor='middle' x='576' y='388' fill='currentColor' style='font-size:1em'>d<\/text>\n<text text-anchor='middle' x='584' y='180' fill='currentColor' style='font-size:1em'>b<\/text>\n<text text-anchor='middle' x='584' y='340' fill='currentColor' style='font-size:1em'>n<\/text>\n<text text-anchor='middle' x='584' y='388' fill='currentColor' style='font-size:1em'>i<\/text>\n<text text-anchor='middle' x='584' y='756' fill='currentColor' style='font-size:1em'>\u00b7<\/text>\n<text text-anchor='middle' x='584' y='788' fill='currentColor' style='font-size:1em'>\u00b7<\/text>\n<text text-anchor='middle' x='584' y='804' fill='currentColor' style='font-size:1em'>\u00b7<\/text>\n<text text-anchor='middle' x='584' y='820' fill='currentColor' style='font-size:1em'>\u00b7<\/text>\n<text text-anchor='middle' x='592' y='180' fill='currentColor' style='font-size:1em'>a<\/text>\n<text text-anchor='middle' x='592' y='340' fill='currentColor' style='font-size:1em'>t<\/text>\n<text text-anchor='middle' x='592' y='388' fill='currentColor' style='font-size:1em'>c<\/text>\n<text text-anchor='middle' x='600' y='180' fill='currentColor' style='font-size:1em'>s<\/text>\n<text text-anchor='middle' x='600' y='292' fill='currentColor' style='font-size:1em'>#<\/text>\n<text text-anchor='middle' x='600' y='340' fill='currentColor' style='font-size:1em'>u<\/text>\n<text text-anchor='middle' x='600' y='388' fill='currentColor' style='font-size:1em'>a<\/text>\n<text text-anchor='middle' x='600' y='676' fill='currentColor' style='font-size:1em'>b<\/text>\n<text text-anchor='middle' x='600' y='756' fill='currentColor' style='font-size:1em'>\u00b7<\/text>\n<text text-anchor='middle' x='600' y='772' fill='currentColor' style='font-size:1em'>\u00b7<\/text>\n<text text-anchor='middle' x='600' y='788' fill='currentColor' style='font-size:1em'>\u00b7<\/text>\n<text text-anchor='middle' x='600' y='804' fill='currentColor' style='font-size:1em'>\u00b7<\/text>\n<text text-anchor='middle' x='600' y='820' fill='currentColor' style='font-size:1em'>\u00b7<\/text>\n<text text-anchor='middle' x='608' y='180' fill='currentColor' style='font-size:1em'>e<\/text>\n<text text-anchor='middle' x='608' y='388' fill='currentColor' style='font-size:1em'>t<\/text>\n<text text-anchor='middle' x='608' y='532' fill='currentColor' style='font-size:1em'>B<\/text>\n<text text-anchor='middle' x='616' y='388' fill='currentColor' style='font-size:1em'>e<\/text>\n<text text-anchor='middle' x='616' y='756' fill='currentColor' style='font-size:1em'>\u00b7<\/text>\n<text text-anchor='middle' x='616' y='772' fill='currentColor' style='font-size:1em'>\u00b7<\/text>\n<text text-anchor='middle' x='616' y='820' fill='currentColor' style='font-size:1em'>\u00b7<\/text>\n<text text-anchor='middle' x='624' y='388' fill='currentColor' style='font-size:1em'>d<\/text>\n<text text-anchor='middle' x='640' y='308' fill='currentColor' style='font-size:1em'>L<\/text>\n<text text-anchor='middle' x='640' y='388' fill='currentColor' style='font-size:1em'>S<\/text>\n<text text-anchor='middle' x='648' y='308' fill='currentColor' style='font-size:1em'>A<\/text>\n<text text-anchor='middle' x='648' y='388' fill='currentColor' style='font-size:1em'>e<\/text>\n<text text-anchor='middle' x='648' y='788' fill='currentColor' style='font-size:1em'>\u00b7<\/text>\n<text text-anchor='middle' x='656' y='308' fill='currentColor' style='font-size:1em'>N<\/text>\n<text text-anchor='middle' x='656' y='388' fill='currentColor' style='font-size:1em'>r<\/text>\n<text text-anchor='middle' x='656' y='772' fill='currentColor' style='font-size:1em'>\u00b7<\/text>\n<text text-anchor='middle' x='656' y='804' fill='currentColor' style='font-size:1em'>\u00b7<\/text>\n<text text-anchor='middle' x='664' y='388' fill='currentColor' style='font-size:1em'>v<\/text>\n<text text-anchor='middle' x='664' y='756' fill='currentColor' style='font-size:1em'>\u00b7<\/text>\n<text text-anchor='middle' x='664' y='788' fill='currentColor' style='font-size:1em'>\u00b7<\/text>\n<text text-anchor='middle' x='664' y='820' fill='currentColor' style='font-size:1em'>\u00b7<\/text>\n<text text-anchor='middle' x='672' y='388' fill='currentColor' style='font-size:1em'>e<\/text>\n<text text-anchor='middle' x='672' y='772' fill='currentColor' style='font-size:1em'>\u00b7<\/text>\n<text text-anchor='middle' x='672' y='804' fill='currentColor' style='font-size:1em'>\u00b7<\/text>\n<text text-anchor='middle' x='680' y='340' fill='currentColor' style='font-size:1em'>U<\/text>\n<text text-anchor='middle' x='680' y='388' fill='currentColor' style='font-size:1em'>r<\/text>\n<text text-anchor='middle' x='680' y='756' fill='currentColor' style='font-size:1em'>\u00b7<\/text>\n<text text-anchor='middle' x='680' y='820' fill='currentColor' style='font-size:1em'>\u00b7<\/text>\n<text text-anchor='middle' x='688' y='340' fill='currentColor' style='font-size:1em'>b<\/text>\n<text text-anchor='middle' x='688' y='772' fill='currentColor' style='font-size:1em'>\u00b7<\/text>\n<text text-anchor='middle' x='696' y='292' fill='currentColor' style='font-size:1em'>#<\/text>\n<text text-anchor='middle' x='696' y='340' fill='currentColor' style='font-size:1em'>u<\/text>\n<text text-anchor='middle' x='696' y='388' fill='currentColor' style='font-size:1em'>R<\/text>\n<text text-anchor='middle' x='696' y='756' fill='currentColor' style='font-size:1em'>\u00b7<\/text>\n<text text-anchor='middle' x='704' y='340' fill='currentColor' style='font-size:1em'>n<\/text>\n<text text-anchor='middle' x='704' y='388' fill='currentColor' style='font-size:1em'>a<\/text>\n<text text-anchor='middle' x='704' y='772' fill='currentColor' style='font-size:1em'>\u00b7<\/text>\n<text text-anchor='middle' x='704' y='804' fill='currentColor' style='font-size:1em'>\u00b7<\/text>\n<text text-anchor='middle' x='712' y='340' fill='currentColor' style='font-size:1em'>t<\/text>\n<text text-anchor='middle' x='712' y='388' fill='currentColor' style='font-size:1em'>c<\/text>\n<text text-anchor='middle' x='712' y='788' fill='currentColor' style='font-size:1em'>\u00b7<\/text>\n<text text-anchor='middle' x='720' y='292' fill='currentColor' style='font-size:1em'>#<\/text>\n<text text-anchor='middle' x='720' y='340' fill='currentColor' style='font-size:1em'>u<\/text>\n<text text-anchor='middle' x='720' y='388' fill='currentColor' style='font-size:1em'>k<\/text>\n<\/g>\n\n <\/svg>\n \n<\/div>"},{"title":"Docker and Iptables: You may do it wrong!","link":"https:\/\/ntk148v.github.io\/posts\/docker-iptables\/","pubDate":"Tue, 25 Oct 2022 10:29:11 +0700","author":"kiennt2609@gmail.com (Kien Nguyen-Tuan)","guid":"https:\/\/ntk148v.github.io\/posts\/docker-iptables\/","description":"<h2 id=\"mission\">Mission<\/h2>\n<p>If you&rsquo;re running Docker on a host that is exposed to the Internet (network bridge), you will probably want to restrict external access.<\/p>\n<h2 id=\"docker-network\">Docker network<\/h2>\n<p>Let&rsquo;s start with a fact that Docker manipulates <code>iptables<\/code> rules to provide network isolation, on Linux. Docker installs custom iptables chains named <code>DOCKER<\/code>, <code>DOCKER-USER<\/code> and <code>DOCKER-ISOLATION-STAGE-*<\/code>, and it ensures that incoming packets are always checked by these chains first.<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"><code class=\"language-shell\" data-lang=\"shell\"><span style=\"display:flex;\"><span>iptables -L -n\n<\/span><\/span><\/code><\/pre><\/div><p>Re.Docker network, I won&rsquo;t describe here because it&rsquo;s a lot of knowledge. You may want to check <a href=\"https:\/\/github.com\/ntk148v\/til\/blob\/master\/docker\/networking\/README.md\">Docker network note<\/a>. I will only show iptables packet flow: For example, we have a host with ip 10.0.10.26, then start a container that is exposed port 8000 to internet.<\/p>"},{"title":"Moving from Utterances to Giscus","link":"https:\/\/ntk148v.github.io\/posts\/moving-from-utterances-to-giscus\/","pubDate":"Tue, 30 Aug 2022 11:09:21 +0700","author":"kiennt2609@gmail.com (Kien Nguyen-Tuan)","guid":"https:\/\/ntk148v.github.io\/posts\/moving-from-utterances-to-giscus\/","description":"<p>I&rsquo;ve used <a href=\".\/lets-comment.md\">Utterances<\/a> for a while. Using Github&rsquo;s issue feature as a backend for comments is a very elegant solution IM O: no tracking, no ads, simple. But today, I decide to switch to a better alternative - <a href=\"https:\/\/github.com\/giscus\/giscus\">Giscus<\/a>. Giscus is heavily inspired by Utterances except one thing: instead of using Github issues it uses the fairly new Discussions features to store comments.<\/p>\n<p>So..<\/p>\n<h2 id=\"why-migrate\">Why migrate?<\/h2>\n<ul>\n<li><strong>Post reactions<\/strong>: utterances allows you to add reactions to comments but as an author I\u2019m also interested in the general reception of the post itself. giscus provides this feature.<\/li>\n<li><strong>Conversation view<\/strong>: utterances will simply render comments as a list in the order they have been created. Giscus groups replies to a comment instead. I mean comment is about discussion, right?<\/li>\n<\/ul>\n<h2 id=\"prepare-your-site\">Prepare your site<\/h2>\n<ul>\n<li>Migrate from utterances: <a href=\"https:\/\/docs.github.com\/en\/discussions\/managing-discussions-for-your-community\/moderating-discussions#converting-an-issue-to-a-discussion\">convert the existing issues into discussions<\/a>.<\/li>\n<li>Follow <a href=\"https:\/\/giscus.app\/\">Giscus<\/a>, it&rsquo;s quite simple.<\/li>\n<\/ul>\n<p><code>Leave a comment :point_down:<\/code><\/p>"},{"title":"Bgp Ecmp Load Balancing","link":"https:\/\/ntk148v.github.io\/posts\/bgp-ecmp-load-balancing\/","pubDate":"Mon, 07 Feb 2022 15:35:08 +0700","author":"kiennt2609@gmail.com (Kien Nguyen-Tuan)","guid":"https:\/\/ntk148v.github.io\/posts\/bgp-ecmp-load-balancing\/","description":"<h2 id=\"introduction\">Introduction<\/h2>\n<p>We will build a Load balancer with <a href=\"https:\/\/en.wikipedia.org\/wiki\/Border_Gateway_Protocol\">BGP<\/a> and <a href=\"https:\/\/en.wikipedia.org\/wiki\/Equal-cost_multi-path_routing\">Equal-Cost Multipath routing (ECMP)<\/a> using both <a href=\"https:\/\/bird.network.cz\/\">Bird<\/a> and <a href=\"https:\/\/github.com\/Exa-Networks\/exabgp\">ExaBGP<\/a>.<\/p>\n<p>References:<\/p>\n<ul>\n<li><a href=\"https:\/\/gist.github.com\/bufadu\/0c3ba661c141a2176cd048f65430ae8d\">How to build a load balancer with BGP and ECMP using VyOS<\/a><\/li>\n<li><a href=\"https:\/\/vincent.bernat.ch\/en\/blog\/2018-multi-tier-loadbalancer#first-tier-ecmp-routing\">Multi-tier load balancer<\/a><\/li>\n<li><a href=\"https:\/\/blog.cloudflare.com\/cloudflares-architecture-eliminating-single-p\/\">Load balancing without Load balancers<\/a><\/li>\n<\/ul>\n<h2 id=\"lab-overview\">Lab overview<\/h2>\n<ul>\n<li><a href=\"https:\/\/www.eve-ng.net\/\">EVE-NG<\/a> version 2.0.3-112<\/li>\n<li>QEMU version 2.4.0<\/li>\n<\/ul>\n<figure class=\"figure\"><img src=\"https:\/\/ntk148v.github.io\/photos\/bgp-ecmp-load-balancing\/ecmp-bgp.png\">\n<\/figure>\n\n<ul>\n<li><code>AS 65000<\/code>: internet service provider. In this post, we will build a BGP session between EdgeRouter and ISP router.<\/li>\n<li><code>ISPRouter<\/code> and <code>EdgeRouter<\/code> are <a href=\"https:\/\/docs.fortinet.com\/document\/fortigate\/7.0.3\">Fortinet Fortigate v7.0.3<\/a> instances. You can use other routers as well.<\/li>\n<li><code>Switch<\/code> is a Cisco switch.<\/li>\n<li><code>client<\/code>, <code>lb1<\/code>, and <code>lb2<\/code> are Ubuntu server 18.04 instances. <code>lb1<\/code> and <code>lb2<\/code> will be in the <code>10.12.12.0\/24<\/code> private LAN, we will install nginx (LB L7) on these. Both servers will announce the same public IP (10.13.13.1) to <code>EdgeRouter<\/code> using BGP. Incoming traffic from internet to this public IP will be routed to <code>lb1<\/code> or <code>lb2<\/code> depending of a hash.<\/li>\n<li>You need to download and install device virtual images. Follow <a href=\"https:\/\/www.eve-ng.net\/index.php\/documentation\/howtos\/howto-add-fortinet-images\/\">EVE-NG guide<\/a>.<\/li>\n<\/ul>\n<h2 id=\"configure\">Configure<\/h2>\n<h3 id=\"isprouter\">ISPRouter<\/h3>\n<p>Follow the <a href=\"https:\/\/docs.fortinet.com\/document\/fortigate\/7.0.3\">Fortigate document<\/a> for the basic commands.<\/p>"},{"title":"Getting Started Tiling Wm [Part 6] I3 Rounded Corners","link":"https:\/\/ntk148v.github.io\/posts\/getting-started-tiling-wm-part-6-i3-rounded-corners\/","pubDate":"Mon, 10 Jan 2022 13:45:01 +0700","author":"kiennt2609@gmail.com (Kien Nguyen-Tuan)","guid":"https:\/\/ntk148v.github.io\/posts\/getting-started-tiling-wm-part-6-i3-rounded-corners\/","description":"<p>According to <a href=\"https:\/\/www.reddit.com\/r\/unixporn\/comments\/7h0rm0\/what_would_you_want_in_a_wm\/\">Reddis post<\/a> and <a href=\"https:\/\/github.com\/Airblader\/i3\/issues\/167\">i3-gaps issue<\/a>, it seems like a lot of people would like this. But Airblade - i3-gaps maintainer <a href=\"https:\/\/github.com\/Airblader\/i3\/issues\/167#issuecomment-328562433\">doesn&rsquo;t like it<\/a>. But nevermind, we still have two ways to achieve it.<\/p>\n<h2 id=\"rounded-i3-gaps\">Rounded i3-gaps<\/h2>\n<p><a href=\"https:\/\/github.com\/resloved\">Resloved<\/a> have an awesome <a href=\"https:\/\/github.com\/resloved\/i3\">fork<\/a> to implement rounded corners. I fork it again to keep it up-to-date with the upstream i3-gaps. You can check it <a href=\"https:\/\/github.com\/ntk148v\/i3\">here<\/a>.<\/p>\n<ul>\n<li>Install i3-gaps.<\/li>\n<\/ul>\n<div class=\"highlight\"><pre tabindex=\"0\" style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"><code class=\"language-bash\" data-lang=\"bash\"><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># Dependencies<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span>sudo apt install git libxcb1-dev libxcb-keysyms1-dev libpango1.0-dev <span style=\"color:#666;font-style:italic\">\\\n<\/span><\/span><\/span><span style=\"display:flex;\"><span> libxcb-util0-dev libxcb-icccm4-dev libyajl-dev <span style=\"color:#666;font-style:italic\">\\\n<\/span><\/span><\/span><span style=\"display:flex;\"><span> libstartup-notification0-dev libxcb-randr0-dev <span style=\"color:#666;font-style:italic\">\\\n<\/span><\/span><\/span><span style=\"display:flex;\"><span> libev-dev libxcb-cursor-dev libxcb-xinerama0-dev <span style=\"color:#666;font-style:italic\">\\\n<\/span><\/span><\/span><span style=\"display:flex;\"><span> libxcb-xkb-dev libxkbcommon-dev libxkbcommon-x11-dev <span style=\"color:#666;font-style:italic\">\\\n<\/span><\/span><\/span><span style=\"display:flex;\"><span> autoconf libxcb-xrm0 libxcb-xrm-dev automake i3status <span style=\"color:#666;font-style:italic\">\\\n<\/span><\/span><\/span><span style=\"display:flex;\"><span> ninja-build meson libxcb-shape0-dev build-essential -y\n<\/span><\/span><span style=\"display:flex;\"><span>git clone https:\/\/github.com\/ntk148v\/i3.git\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"font-weight:bold;font-style:italic\">cd<\/span> i3\/\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># Compile<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span>mkdir -p build &amp;&amp; <span style=\"font-weight:bold;font-style:italic\">cd<\/span> build\n<\/span><\/span><span style=\"display:flex;\"><span>meson ..\n<\/span><\/span><span style=\"display:flex;\"><span>ninja\n<\/span><\/span><span style=\"display:flex;\"><span>sudo ninja install\n<\/span><\/span><\/code><\/pre><\/div><ul>\n<li>Configure rounded corners by adding this to your config.<\/li>\n<\/ul>\n<div class=\"highlight\"><pre tabindex=\"0\" style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"><code class=\"language-fallback\" data-lang=\"fallback\"><span style=\"display:flex;\"><span>border_radius 10\n<\/span><\/span><\/code><\/pre><\/div><ul>\n<li>Result, but you can see that these corners look so jagged (check out this <a href=\"https:\/\/github.com\/Airblader\/i3\/issues\/167#issuecomment-485263770\">comment<\/a>).<\/li>\n<\/ul>\n<figure class=\"figure\"><img src=\"https:\/\/ntk148v.github.io\/photos\/getting-started-tiling-wm-part-6\/rounded-corners-1.png\">\n<\/figure>\n\n<figure class=\"figure\"><img src=\"https:\/\/ntk148v.github.io\/photos\/getting-started-tiling-wm-part-6\/rounded-corners-4.png\">\n<\/figure>\n\n<h2 id=\"picom\">picom<\/h2>\n<ul>\n<li>You can also achieve rounded corners by using <a href=\"https:\/\/github.com\/yshui\/picom\">picom<\/a>.<\/li>\n<li>Install picom.<\/li>\n<li>Configure rounded corners by changing <code>corner_radius<\/code> value.<\/li>\n<\/ul>\n<div class=\"highlight\"><pre tabindex=\"0\" style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"><code class=\"language-fallback\" data-lang=\"fallback\"><span style=\"display:flex;\"><span># Path ~\/.config\/picom.conf\n<\/span><\/span><span style=\"display:flex;\"><span>corner_radius: 10;\n<\/span><\/span><\/code><\/pre><\/div><ul>\n<li>Result looks much smoother.<\/li>\n<\/ul>\n<figure class=\"figure\"><img src=\"https:\/\/ntk148v.github.io\/photos\/getting-started-tiling-wm-part-6\/rounded-corners-2.png\">\n<\/figure>\n\n<figure class=\"figure\"><img src=\"https:\/\/ntk148v.github.io\/photos\/getting-started-tiling-wm-part-6\/rounded-corners-3.png\">\n<\/figure>"},{"title":"Getting Started with Tiling WM [Part 1] - I3","link":"https:\/\/ntk148v.github.io\/posts\/getting-started-tiling-wm-part-1-i3\/","pubDate":"Mon, 19 Apr 2021 10:10:21 +0700","author":"kiennt2609@gmail.com (Kien Nguyen-Tuan)","guid":"https:\/\/ntk148v.github.io\/posts\/getting-started-tiling-wm-part-1-i3\/","description":"<blockquote>\n<p><strong>Disclaimer<\/strong><\/p>\n<p>I love customizing desktop. I make changes in my desktop everyday, make it look eye candy. My colleagues ask me how to make their desktop look like mine. But there are many steps and things to learn and follow, I know because I&rsquo;ve gone throught it. Therefore I decide to write this getting-started guide to give people a shortest path to Fancy world.<\/p>\n<\/blockquote>\n<h2 id=\"overview-window-manager\">Overview Window Manager<\/h2>\n<p>First of all, you have to know the basic concepts.<\/p>"},{"title":"Getting Started with Tiling WM [Part 2] - Rofi","link":"https:\/\/ntk148v.github.io\/posts\/getting-started-tiling-wm-part-2-rofi\/","pubDate":"Mon, 19 Apr 2021 10:10:21 +0700","author":"kiennt2609@gmail.com (Kien Nguyen-Tuan)","guid":"https:\/\/ntk148v.github.io\/posts\/getting-started-tiling-wm-part-2-rofi\/","description":"<blockquote>\n<p>In the <a href=\"https:\/\/ntk148v.github.io\/posts\/getting-started-tiling-wm-part-1-i3\/\">part1<\/a>, I&rsquo;ve used <code>rofi<\/code> instead of <code>dmenu<\/code>. This part will show you how to start with <code>rofi<\/code>.<\/p>\n<\/blockquote>\n<h2 id=\"introduction\">Introduction<\/h2>\n<ul>\n<li><a href=\"https:\/\/github.com\/davatorium\/rofi\">Rofi<\/a> is a window switcher, application launcher and dmenu replacement.<\/li>\n<li>Features:\n<ul>\n<li>Fully configurable keyboard navigation.<\/li>\n<li>Type to filer.<\/li>\n<li>Built-in modes:\n<ul>\n<li>Window switcher mode.<\/li>\n<li>Application laucher.<\/li>\n<li>Desktop file application launcher.<\/li>\n<li>SSH laucher mode.<\/li>\n<\/ul>\n<\/li>\n<li>History-based ordering.<\/li>\n<li>&hellip;<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h2 id=\"getting-started\">Getting started<\/h2>\n<ul>\n<li>Installing <code>rofi<\/code> is quite easy.<\/li>\n<\/ul>\n<div class=\"highlight\"><pre tabindex=\"0\" style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"><code class=\"language-bash\" data-lang=\"bash\"><span style=\"display:flex;\"><span>sudo apt install rofi -y\n<\/span><\/span><\/code><\/pre><\/div><ul>\n<li>Run it for the first time.<\/li>\n<\/ul>\n<div class=\"highlight\"><pre tabindex=\"0\" style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"><code class=\"language-bash\" data-lang=\"bash\"><span style=\"display:flex;\"><span>rofi -lines 12 -padding 18 -width 60 -location 0 -show drun -sidebar-mode -columns 3 -font <span style=\"color:#666;font-style:italic\">&#39;DejaVu Sans 8&#39;<\/span>\n<\/span><\/span><\/code><\/pre><\/div>\n<details>\n <summary>Details<\/summary>\n <div class=\"highlight\"><pre tabindex=\"0\" style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"><code class=\"language-bash\" data-lang=\"bash\"><span style=\"display:flex;\"><span> -show mode\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span> Open rofi in a certain mode. Available modes are window, run, drun, ssh, combi. The\n<\/span><\/span><span style=\"display:flex;\"><span> special argument keys can be used to open a searchable list of supported key bind\u2010\n<\/span><\/span><span style=\"display:flex;\"><span> ings (see KEY BINDINGS)\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span> To show the run-dialog:\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span> rofi -show run\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span> -lines\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span> Maximum number of lines to show before scrolling.\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span> rofi -lines 25\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span> Default: 15\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span> -location\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span> Specify where the window should be located. The numbers map to the following loca\u2010\n<\/span><\/span><span style=\"display:flex;\"><span> tions on screen:\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span> 1 2 3\n<\/span><\/span><span style=\"display:flex;\"><span> 8 0 4\n<\/span><\/span><span style=\"display:flex;\"><span> 7 6 5\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span> Default: 0\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span> -padding\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span> Define the inner margin of the window.\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span> Default: 5\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span> -sidebar-mode\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span> Open in sidebar-mode. In this mode a list of all enabled modes is shown at the bot\u2010\n<\/span><\/span><span style=\"display:flex;\"><span> tom. (See -modi option) To show sidebar, use:\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span> rofi -show run -sidebar-mode -lines 0\n<\/span><\/span><\/code><\/pre><\/div><\/details>\n\n<figure class=\"figure\"><img src=\"https:\/\/ntk148v.github.io\/photos\/getting-started-tiling-wm-part-1\/rofi-default.png\">\n<\/figure>\n\n<figure class=\"figure\"><img src=\"https:\/\/ntk148v.github.io\/photos\/getting-started-tiling-wm-part-1\/rofi-default-2.png\">\n<\/figure>\n\n<ul>\n<li>Press hot key (defined in i3 configuration file) <code>&lt;Window&gt;+d<\/code> to start rofi. Use <code>&lt;Shift&gt;+&lt;left\/right&gt;<\/code> to switch between mode.<\/li>\n<li>More details you can found in <a href=\"https:\/\/github.com\/davatorium\/rofi\">rofi github<\/a>.<\/li>\n<\/ul>\n<h2 id=\"tweaking\">Tweaking<\/h2>\n<ul>\n<li>The default setup looks quite boring. Let&rsquo;s tweak a bit!<\/li>\n<li>There are currently three methods of setting configuration options:\n<ul>\n<li><em>Local configuration. Normally, depending on XDG, in ~\/.config\/rofi\/config. This uses the Xresources format<\/em>.<\/li>\n<li>Xresources: A method of storing key values in the Xserver. See here for more information.<\/li>\n<li>Command line options: Arguments are passed to Rofi.<\/li>\n<\/ul>\n<\/li>\n<li>We will use configuration file.<\/li>\n<\/ul>\n<div class=\"highlight\"><pre tabindex=\"0\" style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"><code class=\"language-bash\" data-lang=\"bash\"><span style=\"display:flex;\"><span>mkdir -p ~\/.config\/rofi\/themes\n<\/span><\/span><span style=\"display:flex;\"><span>touch ~\/.config\/rofi\/themes\/onedark.theme\n<\/span><\/span><\/code><\/pre><\/div><ul>\n<li>Copy the follow content into <code>~\/.config\/rofi\/themes\/onedark.theme<\/code>:<\/li>\n<\/ul>\n<div class=\"highlight\"><pre tabindex=\"0\" style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"><code class=\"language-fallback\" data-lang=\"fallback\"><span style=\"display:flex;\"><span>configuration {\n<\/span><\/span><span style=\"display:flex;\"><span> show-icons: true;\n<\/span><\/span><span style=\"display:flex;\"><span> font: &#34;DejaVu Sans Mono 10&#34;;\n<\/span><\/span><span style=\"display:flex;\"><span> modi: &#34;window,run,drun&#34;;\n<\/span><\/span><span style=\"display:flex;\"><span>}\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span>* {\n<\/span><\/span><span style=\"display:flex;\"><span> background: #282c34;\n<\/span><\/span><span style=\"display:flex;\"><span> foreground: #abb2bf;\n<\/span><\/span><span style=\"display:flex;\"><span> background-color: @background;\n<\/span><\/span><span style=\"display:flex;\"><span> selected-normal-foreground: @foreground;\n<\/span><\/span><span style=\"display:flex;\"><span> selected-normal-background: #98c379;\n<\/span><\/span><span style=\"display:flex;\"><span> selected-urgent-background: #e5c07b;\n<\/span><\/span><span style=\"display:flex;\"><span> selected-urgent-foreground: @foreground;\n<\/span><\/span><span style=\"display:flex;\"><span> border: 5;\n<\/span><\/span><span style=\"display:flex;\"><span> lines: 12;\n<\/span><\/span><span style=\"display:flex;\"><span> padding: 0;\n<\/span><\/span><span style=\"display:flex;\"><span> margin: 0;\n<\/span><\/span><span style=\"display:flex;\"><span> spacing: 0;\n<\/span><\/span><span style=\"display:flex;\"><span>}\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span>window {\n<\/span><\/span><span style=\"display:flex;\"><span> width: 50%;\n<\/span><\/span><span style=\"display:flex;\"><span> transparency: &#34;real&#34;;\n<\/span><\/span><span style=\"display:flex;\"><span>}\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span>mainbox {\n<\/span><\/span><span style=\"display:flex;\"><span> children: [inputbar, listview];\n<\/span><\/span><span style=\"display:flex;\"><span>}\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span>listview {\n<\/span><\/span><span style=\"display:flex;\"><span> columns: 1;\n<\/span><\/span><span style=\"display:flex;\"><span>}\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span>element {\n<\/span><\/span><span style=\"display:flex;\"><span> padding: 12;\n<\/span><\/span><span style=\"display:flex;\"><span> orientation: vertical;\n<\/span><\/span><span style=\"display:flex;\"><span> text-color: @foreground;\n<\/span><\/span><span style=\"display:flex;\"><span>}\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span>element selected {\n<\/span><\/span><span style=\"display:flex;\"><span> background-color: @selected-normal-background;\n<\/span><\/span><span style=\"display:flex;\"><span> text-color: @background;\n<\/span><\/span><span style=\"display:flex;\"><span>}\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span>inputbar {\n<\/span><\/span><span style=\"display:flex;\"><span> background-color: @background;\n<\/span><\/span><span style=\"display:flex;\"><span> children: [prompt, entry];\n<\/span><\/span><span style=\"display:flex;\"><span>}\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span>prompt {\n<\/span><\/span><span style=\"display:flex;\"><span> enabled: true;\n<\/span><\/span><span style=\"display:flex;\"><span> font: &#34;DejaVu Sans Mono 10&#34;;\n<\/span><\/span><span style=\"display:flex;\"><span> padding: 12 0 0 12;\n<\/span><\/span><span style=\"display:flex;\"><span> text-color: @selected-urgent-background;\n<\/span><\/span><span style=\"display:flex;\"><span>}\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span>entry {\n<\/span><\/span><span style=\"display:flex;\"><span> padding: 12;\n<\/span><\/span><span style=\"display:flex;\"><span> text-color: @selected-urgent-background;\n<\/span><\/span><span style=\"display:flex;\"><span>}\n<\/span><\/span><\/code><\/pre><\/div><ul>\n<li>Run it and you can see the magic!<\/li>\n<\/ul>\n<div class=\"highlight\"><pre tabindex=\"0\" style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"><code class=\"language-bash\" data-lang=\"bash\"><span style=\"display:flex;\"><span>rofi -theme ~\/.config\/rofi\/themes\/onedark.theme -show drun\n<\/span><\/span><\/code><\/pre><\/div><figure class=\"figure\"><img src=\"https:\/\/ntk148v.github.io\/photos\/getting-started-tiling-wm-part-1\/rofi-custom.png\">\n<\/figure>\n\n<ul>\n<li>Don&rsquo;t forget to update hotkey in i3 configuration file.<\/li>\n<\/ul>\n<div class=\"highlight\"><pre tabindex=\"0\" style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"><code class=\"language-fallback\" data-lang=\"fallback\"><span style=\"display:flex;\"><span>bindsym $mod+d exec rofi -theme ~\/.config\/rofi\/themes\/onedark.theme -show drun\n<\/span><\/span><\/code><\/pre><\/div>"},{"title":"Getting Started with Tiling WM [Part 3] - Polybar","link":"https:\/\/ntk148v.github.io\/posts\/getting-started-tiling-wm-part-3-polybar\/","pubDate":"Mon, 19 Apr 2021 10:10:21 +0700","author":"kiennt2609@gmail.com (Kien Nguyen-Tuan)","guid":"https:\/\/ntk148v.github.io\/posts\/getting-started-tiling-wm-part-3-polybar\/","description":"<h2 id=\"overview\">Overview<\/h2>\n<p><a href=\"https:\/\/polybar.github.io\/\">According to Polybar frontpage<\/a>, <code>Polybar is A fast and easy to use tool for creating status bars <\/code>.<\/p>\n<blockquote>\n<p><strong>WIP<\/strong><\/p>\n<\/blockquote>"},{"title":"Getting Started with Tiling WM [Part 4] - Xresources","link":"https:\/\/ntk148v.github.io\/posts\/getting-started-tiling-wm-part-4-xresources\/","pubDate":"Mon, 19 Apr 2021 10:10:21 +0700","author":"kiennt2609@gmail.com (Kien Nguyen-Tuan)","guid":"https:\/\/ntk148v.github.io\/posts\/getting-started-tiling-wm-part-4-xresources\/","description":"<blockquote>\n<p><strong>WIP<\/strong><\/p>\n<\/blockquote>"},{"title":"Getting Started with Tiling WM [Part 5] - Compton","link":"https:\/\/ntk148v.github.io\/posts\/getting-started-tiling-wm-part-5-compton\/","pubDate":"Mon, 19 Apr 2021 10:10:21 +0700","author":"kiennt2609@gmail.com (Kien Nguyen-Tuan)","guid":"https:\/\/ntk148v.github.io\/posts\/getting-started-tiling-wm-part-5-compton\/","description":"<blockquote>\n<p><strong>WIP<\/strong><\/p>\n<\/blockquote>"},{"title":"Linux tools that you never knew you needed","link":"https:\/\/ntk148v.github.io\/posts\/linux-tools-that-you-never-knew-you-needed\/","pubDate":"Wed, 07 Apr 2021 09:45:59 +0700","author":"kiennt2609@gmail.com (Kien Nguyen-Tuan)","guid":"https:\/\/ntk148v.github.io\/posts\/linux-tools-that-you-never-knew-you-needed\/","description":"<h2 id=\"bat---cat-alternative\">bat - (cat alternative)<\/h2>\n<ul>\n<li><a href=\"https:\/\/github.com\/sharkdp\/bat\">bat<\/a>: A cat(1) clone with syntax highlighting and Git integration.<\/li>\n<li>Example:<\/li>\n<\/ul>\n<figure class=\"figure\"><img src=\"https:\/\/ntk148v.github.io\/photos\/linux-tools-that-you-never-knew-you-needed\/bat.png\">\n<\/figure>\n\n<h2 id=\"fd---find-alternative\">fd - (find alternative)<\/h2>\n<ul>\n<li><a href=\"https:\/\/github.com\/sharkdp\/fd\">fd<\/a>: a simple, fast and user-friendly alternative to <code>find<\/code>.<\/li>\n<li>Examples:<\/li>\n<\/ul>\n<figure class=\"figure\"><img src=\"https:\/\/raw.githubusercontent.com\/sharkdp\/fd\/master\/doc\/screencast.svg\">\n<\/figure>\n\n<h2 id=\"httpie---wgetcurl-alternative\">httpie - (wget\/curl alternative)<\/h2>\n<ul>\n<li><a href=\"https:\/\/httpie.io\">httpie<\/a>: a user-friendly command-line HTTP client for the API era. It comes with JSON support, syntax highlighting, persistent sessions, wget-like downloads, plugins, and more.<\/li>\n<li>Examples:<\/li>\n<\/ul>\n<div class=\"highlight\"><pre tabindex=\"0\" style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"><code class=\"language-bash\" data-lang=\"bash\"><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># Hello world<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span>$ http httpie.io\/hello\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># Custom HTTP method, HTTP headers and JSON data<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span>$ http PUT pie.dev\/put X-API-Token:123 <span style=\"color:#666;font-weight:bold;font-style:italic\">name<\/span>=John\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># Submitting forms<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span>$ http -f POST pie.dev\/post <span style=\"color:#666;font-weight:bold;font-style:italic\">hello<\/span>=World\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># Upload a file using redirect input<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span>$ http pie.dev\/post &lt; files\/data.json\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># ...<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># For more examples, check out: https:\/\/httpie.io<\/span>\n<\/span><\/span><\/code><\/pre><\/div><h2 id=\"ripgrep---grep-alternative\">ripgrep - (grep alternative)<\/h2>\n<ul>\n<li><a href=\"https:\/\/github.com\/BurntSushi\/ripgrep\">ripgrep<\/a>: a faster <code>grep<\/code>. ripgrep is a line-oriented search tool that recursively searches your current directory for a regex pattern. By default, ripgrep will respect your .gitignore and automatically skip hidden files\/directories and binary files.<\/li>\n<li><a href=\"https:\/\/github.com\/BurntSushi\/ripgrep#quick-examples-comparing-tools\">Benchmark<\/a>.<\/li>\n<li>Examples:<\/li>\n<\/ul>\n<div class=\"highlight\"><pre tabindex=\"0\" style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"><code class=\"language-bash\" data-lang=\"bash\"><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># Basic use<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span>$ rg fast README.md\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># Regular expressions<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span>$ rg <span style=\"color:#666;font-style:italic\">&#39;fast\\w+&#39;<\/span> README.md\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># Recursive search - recursively searching the directory (current directory is default)<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span>$ rg <span style=\"color:#666;font-style:italic\">&#39;fn write\\(&#39;<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># ...<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># For more examples, checkout: https:\/\/github.com\/BurntSushi\/ripgrep\/blob\/master\/GUIDE.md<\/span>\n<\/span><\/span><\/code><\/pre><\/div><h2 id=\"delta\">delta<\/h2>\n<ul>\n<li><a href=\"https:\/\/github.com\/dandavison\/delta\">delta<\/a>: Code evolves, and we all spend time studying diffs. Delta aims to make this both efficient and enjoyable: it allows you to make extensive changes to the layout and styling of diffs, as well as allowing you to stay arbitrarily close to the default git\/diff output.<\/li>\n<li>Diff\/git diff doesn&rsquo;t show you exactly what was changed.<\/li>\n<\/ul>\n<figure class=\"figure\"><img src=\"https:\/\/ntk148v.github.io\/photos\/linux-tools-that-you-never-knew-you-needed\/git-diff.png\">\n<\/figure>\n\n<ul>\n<li>Delta shows within-line highlights based on a Levenshtein edit inference algorithm.<\/li>\n<\/ul>\n<figure class=\"figure\"><img src=\"https:\/\/ntk148v.github.io\/photos\/linux-tools-that-you-never-knew-you-needed\/delta.png\">\n<\/figure>\n\n<ul>\n<li>By default, delta restructures the git output slightly to make the hunk markers human-readable:<\/li>\n<\/ul>\n<figure class=\"figure\"><img src=\"https:\/\/user-images.githubusercontent.com\/52205\/81059276-254cf980-8e9e-11ea-95c3-8b757a4c11b5.png\">\n<\/figure>\n\n<ul>\n<li>Example config:<\/li>\n<\/ul>\n<div class=\"highlight\"><pre tabindex=\"0\" style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"><code class=\"language-bash\" data-lang=\"bash\"><span style=\"display:flex;\"><span>[core]\n<\/span><\/span><span style=\"display:flex;\"><span> pager: delta\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span>[delta]\n<\/span><\/span><span style=\"display:flex;\"><span> plus-style: <span style=\"color:#666;font-style:italic\">&#34;syntax #98c379&#34;<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span> minus-style: <span style=\"color:#666;font-style:italic\">&#34;syntax #e06c75&#34;<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span> syntax-theme: OneHalfDark\n<\/span><\/span><span style=\"display:flex;\"><span> navigate: <span style=\"font-weight:bold;font-style:italic\">true<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span> features: line-numbers decorations\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span>[interactive]\n<\/span><\/span><span style=\"display:flex;\"><span> diffFilter: delta --color-only\n<\/span><\/span><\/code><\/pre><\/div><ul>\n<li>Completely replace <code>diff<\/code> with <code>delta<\/code>:<\/li>\n<\/ul>\n<div class=\"highlight\"><pre tabindex=\"0\" style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"><code class=\"language-bash\" data-lang=\"bash\"><span style=\"display:flex;\"><span><span style=\"font-weight:bold;font-style:italic\">alias<\/span> <span style=\"color:#666;font-weight:bold;font-style:italic\">diff<\/span>=<span style=\"color:#666;font-style:italic\">&#34;delta&#34;<\/span>\n<\/span><\/span><\/code><\/pre><\/div><h2 id=\"z\">z<\/h2>\n<ul>\n<li>Tired for <code>cd<\/code>ing into the same directories over and over? Save your time with <code>z<\/code> command!<\/li>\n<li><a href=\"https:\/\/github.com\/rupa\/z\">z<\/a>: jump around. Z is a shell script that makes jumping around your file directory pleasantly simple. Instead of trying to remember the exact path of where you need to go, or worse, <code>cd<\/code>ing into the next directory followed by <code>ls<\/code>ing and then cding again over and over (we\u2019ve all been there), Z allows you to \u201clazy type\u201d where you want to go and it\u2019ll handle the rest.<\/li>\n<li>Examples:<\/li>\n<\/ul>\n<div class=\"highlight\"><pre tabindex=\"0\" style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"><code class=\"language-bash\" data-lang=\"bash\"><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># Takes me to my workspace folder from anywhere.<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span>$ z workspace\n<\/span><\/span><\/code><\/pre><\/div><h2 id=\"fzf\">fzf<\/h2>\n<ul>\n<li><a href=\"https:\/\/github.com\/junegunn\/fzf\">fzf<\/a>: fzf is a general-purpose command-line fuzzy finder.<\/li>\n<li>It&rsquo;s an interactive Unix filter for command-line that can be used with any list; files, command history, processes, hostnames, bookmarks, git commits, etc.<\/li>\n<li>Examples:<\/li>\n<\/ul>\n<div class=\"highlight\"><pre tabindex=\"0\" style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"><code class=\"language-bash\" data-lang=\"bash\"><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># Read the list from STDIN and write the selected item to STDOUT<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span>$ find * -type f | fzf &gt; selected\n<\/span><\/span><span style=\"display:flex;\"><span>$ vim <span style=\"font-weight:bold\">$(<\/span>fzf<span style=\"font-weight:bold\">)<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># COMMAND **&lt;TAB&gt;<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># Files under the current directory<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># - You can select multiple items with TAB key<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span>$ vim **&lt;TAB&gt;\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># Files under parent directory<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span>$ vim ..\/**&lt;TAB&gt;\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># Files under parent directory that match `fzf`<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span>$ vim ..\/fzf**&lt;TAB&gt;\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># Files under your home directory<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span>$ vim ~\/**&lt;TAB&gt;\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># Directories under current directory (single-selection)<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span>$ <span style=\"font-weight:bold;font-style:italic\">cd<\/span> **&lt;TAB&gt;\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># Directories under ~\/github that match `fzf`<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span>$ <span style=\"font-weight:bold;font-style:italic\">cd<\/span> ~\/github\/fzf**&lt;TAB&gt;\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># Can select multiple processes with &lt;TAB&gt; or &lt;Shift-TAB&gt; keys<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span>$ <span style=\"font-weight:bold;font-style:italic\">kill<\/span> -9 &lt;TAB&gt;\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span>$ <span style=\"font-weight:bold;font-style:italic\">unset<\/span> **&lt;TAB&gt;\n<\/span><\/span><span style=\"display:flex;\"><span>$ <span style=\"font-weight:bold;font-style:italic\">export<\/span> **&lt;TAB&gt;\n<\/span><\/span><span style=\"display:flex;\"><span>$ <span style=\"font-weight:bold;font-style:italic\">unalias<\/span> **&lt;TAB&gt;\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># ...<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># For more examples, checkout: https:\/\/github.com\/junegunn\/fzf<\/span>\n<\/span><\/span><\/code><\/pre><\/div><figure class=\"figure\"><img src=\"https:\/\/ntk148v.github.io\/photos\/linux-tools-that-you-never-knew-you-needed\/fzf-vim.png\">\n<\/figure>\n\n<figure class=\"figure\"><img src=\"https:\/\/ntk148v.github.io\/photos\/linux-tools-that-you-never-knew-you-needed\/fzf-cd.png\">\n<\/figure>\n\n<h2 id=\"thefuck\">thefuck<\/h2>\n<ul>\n<li><a href=\"https:\/\/github.com\/nvbn\/thefuck\">thefuck<\/a>: Magnificent app which corrects your previous console command.<\/li>\n<\/ul>\n<figure class=\"figure\"><img src=\"https:\/\/raw.githubusercontent.com\/nvbn\/thefuck\/master\/example.gif\">\n<\/figure>\n\n<ul>\n<li>Examples:<\/li>\n<\/ul>\n<div class=\"highlight\"><pre tabindex=\"0\" style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"><code class=\"language-bash\" data-lang=\"bash\"><span style=\"display:flex;\"><span>$ apt-get install vim\n<\/span><\/span><span style=\"display:flex;\"><span>E: Could not open lock file \/var\/lib\/dpkg\/lock - open (13: Permission denied)\n<\/span><\/span><span style=\"display:flex;\"><span>E: Unable to lock the administration directory (\/var\/lib\/dpkg\/), are you root?\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span>$ fuck\n<\/span><\/span><span style=\"display:flex;\"><span>sudo apt-get install vim [enter\/\u2191\/\u2193\/ctrl+c]\n<\/span><\/span><span style=\"display:flex;\"><span>Reading package lists... Done\n<\/span><\/span><span style=\"display:flex;\"><span>...\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># ...<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># For more examples, check out: https:\/\/github.com\/nvbn\/thefuck<\/span>\n<\/span><\/span><\/code><\/pre><\/div><h2 id=\"exa---ls-alternative\">exa - (ls alternative)<\/h2>\n<ul>\n<li><a href=\"https:\/\/the.exa.website\">exa<\/a>: A modern replacement for ls. <code>exa<\/code> is an improved file lister with more features and better defaults. It uses colours to distinguish file types and metadata. It knows about symlinks, extended attributes, and Git. And it\u2019s small, fast, and just one single binary.<\/li>\n<li>Examples:<\/li>\n<\/ul>\n<figure class=\"figure\"><img src=\"https:\/\/ntk148v.github.io\/photos\/linux-tools-that-you-never-knew-you-needed\/exa.png\">\n<\/figure>\n\n<ul>\n<li>Completely replace <code>ls<\/code> with <code>exa<\/code>:<\/li>\n<\/ul>\n<div class=\"highlight\"><pre tabindex=\"0\" style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"><code class=\"language-bash\" data-lang=\"bash\"><span style=\"display:flex;\"><span><span style=\"font-weight:bold;font-style:italic\">alias<\/span> <span style=\"color:#666;font-weight:bold;font-style:italic\">ls<\/span>=<span style=\"color:#666;font-style:italic\">&#34;exa&#34;<\/span>\n<\/span><\/span><\/code><\/pre><\/div><figure class=\"figure\"><img src=\"https:\/\/ntk148v.github.io\/photos\/linux-tools-that-you-never-knew-you-needed\/exa-ls.png\">\n<\/figure>\n\n<h2 id=\"rename\">rename<\/h2>\n<ul>\n<li>Rename a single file with <code>mv<\/code>. Just a basic thing.<\/li>\n<li>Rename multiple files with <code>mv<\/code>.<\/li>\n<\/ul>\n<div class=\"highlight\"><pre tabindex=\"0\" style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"><code class=\"language-bash\" data-lang=\"bash\"><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># Rename files with suffix .yaml to yml<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"font-weight:bold\">for<\/span> f in *.yaml; <span style=\"font-weight:bold\">do<\/span> mv -- <span style=\"color:#666;font-style:italic\">&#34;<\/span><span style=\"color:#666;font-weight:bold;font-style:italic\">$f<\/span><span style=\"color:#666;font-style:italic\">&#34;<\/span> <span style=\"color:#666;font-style:italic\">&#34;<\/span><span style=\"color:#666;font-style:italic\">${<\/span><span style=\"color:#666;font-weight:bold;font-style:italic\">f<\/span>%.yaml<span style=\"color:#666;font-style:italic\">}<\/span><span style=\"color:#666;font-style:italic\">.yml&#34;<\/span> <span style=\"font-weight:bold\">done<\/span>\n<\/span><\/span><\/code><\/pre><\/div><ul>\n<li>Rename multiple files with <code>rename<\/code>.<\/li>\n<\/ul>\n<div class=\"highlight\"><pre tabindex=\"0\" style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"><code class=\"language-bash\" data-lang=\"bash\"><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># Install rename command<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># Ubuntu\/Debian-derived distros<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span>sudo apt install rename\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># RedHat-derived distros<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span>sudo yum install prename\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># The follow examples are performed in Ubuntu\/Debian-derived distros<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span>rename <span style=\"color:#666;font-style:italic\">&#39;s\/.yaml\/.yml\/&#39;<\/span> *.yaml\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># Replace all occurrences of &#34;prev_&#34; with &#34;next_&#34;<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span>rename <span style=\"color:#666;font-style:italic\">&#39;s\/prev_\/next_&#39;<\/span> *.c\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># Delete part of a filename<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span>rename <span style=\"color:#666;font-style:italic\">&#39;s\/next_\/\/&#39;<\/span> *.c\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># Limit changes to specific parts of filenames<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># Only change the files that start with &#34;paramater&#34;<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span>rename <span style=\"color:#666;font-style:italic\">&#39;s\/^param\/parameter\/&#39;<\/span> *.c\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># Search with grouping<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># Replace all occurrences of &#34;string&#34; and &#34;strong&#34;<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span>rename <span style=\"color:#666;font-style:italic\">&#39;s\/(str|stro)ng\/strength&#39;<\/span> *.c\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># Use translations with rename<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># Force filenames to uppercase<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span>rename <span style=\"color:#666;font-style:italic\">&#39;y\/a-z\/A-Z&#39;<\/span> *.py\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># More?<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span>man rename\n<\/span><\/span><\/code><\/pre><\/div>"},{"title":"Set Animated Gif as Wallpaper","link":"https:\/\/ntk148v.github.io\/posts\/set-animated-gif-as-wallpaper\/","pubDate":"Thu, 14 Jan 2021 09:36:34 +0700","author":"kiennt2609@gmail.com (Kien Nguyen-Tuan)","guid":"https:\/\/ntk148v.github.io\/posts\/set-animated-gif-as-wallpaper\/","description":"<blockquote>\n<p><strong>NOTE<\/strong>: Environment Ubuntu 20.04<\/p>\n<\/blockquote>\n<h2 id=\"dependencies\">Dependencies<\/h2>\n<ul>\n<li><a href=\"https:\/\/github.com\/ujjwal96\/xwinwrap\">Xwinwrap<\/a>:<\/li>\n<\/ul>\n<div class=\"highlight\"><pre tabindex=\"0\" style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"><code class=\"language-bash\" data-lang=\"bash\"><span style=\"display:flex;\"><span>sudo apt-get install xorg-dev build-essential libx11-dev x11proto-xext-dev libxrender-dev libxext-dev\n<\/span><\/span><span style=\"display:flex;\"><span>git clone https:\/\/github.com\/ujjwal96\/xwinwrap.git\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"font-weight:bold;font-style:italic\">cd<\/span> xwinwrap\n<\/span><\/span><span style=\"display:flex;\"><span>make\n<\/span><\/span><span style=\"display:flex;\"><span>sudo make install\n<\/span><\/span><span style=\"display:flex;\"><span>make clean\n<\/span><\/span><\/code><\/pre><\/div><ul>\n<li>Gifsicle:<\/li>\n<\/ul>\n<div class=\"highlight\"><pre tabindex=\"0\" style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"><code class=\"language-bash\" data-lang=\"bash\"><span style=\"display:flex;\"><span>sudo apt install gifsicle\n<\/span><\/span><\/code><\/pre><\/div><h2 id=\"the-helper-script\">The helper script<\/h2>\n<p>A helper script to setup animated .gif in dual monitors.<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"><code class=\"language-bash\" data-lang=\"bash\"><span style=\"display:flex;\"><span><span style=\"color:#888;font-weight:bold\">#!\/bin\/bash\n<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># Uses xwinwrap to display given animated .gif in dual monitors.<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"font-weight:bold\">if<\/span> [ <span style=\"color:#666;font-weight:bold;font-style:italic\">$#<\/span> -ne 1 ]; <span style=\"font-weight:bold\">then<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"font-weight:bold;font-style:italic\">echo<\/span> 1&gt;&amp;2 Usage: <span style=\"color:#666;font-weight:bold;font-style:italic\">$0<\/span> image.gif\n<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"font-weight:bold;font-style:italic\">exit<\/span> 1\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"font-weight:bold\">fi<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#666;font-weight:bold;font-style:italic\">gif<\/span>=<span style=\"color:#666;font-weight:bold;font-style:italic\">$1<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span>killall -9 xwinwrap\n<\/span><\/span><span style=\"display:flex;\"><span>killall -9 gifview\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># Get monitors resolution<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#666;font-weight:bold;font-style:italic\">SCR1<\/span>=<span style=\"color:#666;font-style:italic\">`<\/span>xrandr | awk <span style=\"color:#666;font-style:italic\">&#39;\/primary\/ &amp;&amp; \/connected\/ { print $4 }&#39;<\/span><span style=\"color:#666;font-style:italic\">`<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#666;font-weight:bold;font-style:italic\">SCR2<\/span>=<span style=\"color:#666;font-style:italic\">`<\/span>xrandr | awk <span style=\"color:#666;font-style:italic\">&#39;!\/primary\/ &amp;&amp; \/connected\/ { print $3 }&#39;<\/span><span style=\"color:#666;font-style:italic\">`<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span>xwinwrap -g <span style=\"color:#666;font-weight:bold;font-style:italic\">$SCR1<\/span> -ov -ni -s -nf -- gifview -w WID <span style=\"color:#666;font-weight:bold;font-style:italic\">$gif<\/span> -a &amp;\n<\/span><\/span><span style=\"display:flex;\"><span>xwinwrap -g <span style=\"color:#666;font-weight:bold;font-style:italic\">$SCR2<\/span> -ov -ni -s -nf -- gifview -w WID <span style=\"color:#666;font-weight:bold;font-style:italic\">$gif<\/span> -a &amp;\n<\/span><\/span><\/code><\/pre><\/div><p>If you want to run xwinwrap by yourself, here is the example:<\/p>"},{"title":"Swap space note","link":"https:\/\/ntk148v.github.io\/posts\/linux-swap-space-note\/","pubDate":"Wed, 20 May 2020 09:30:28 +0700","author":"kiennt2609@gmail.com (Kien Nguyen-Tuan)","guid":"https:\/\/ntk148v.github.io\/posts\/linux-swap-space-note\/","description":"<h2 id=\"what-is-swap\">What is Swap?<\/h2>\n<p>Swap file systems support virtual memory, data is written to a swap file system when there is not enough RAM to store the data your system is processing.<\/p>\n<h2 id=\"swap-partition-size\">Swap partition size<\/h2>\n<h3 id=\"old-rule-of-thumb\">Old rule of thumb<\/h3>\n<div class=\"highlight\"><pre tabindex=\"0\" style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"><code class=\"language-fallback\" data-lang=\"fallback\"><span style=\"display:flex;\"><span>swap: 2 * the-amount-of-RAM\n<\/span><\/span><\/code><\/pre><\/div><p>So if a computer had 64KB of RAM, a swap partition of 128KB would be an optimum size. This rule took into the facts that RAM sizes were typically quite small at the time. Nowadays, RAM has become a <code>cheap<\/code> &amp; <code>affordable<\/code> commondity, so the 2x rule is outdated.<\/p>"},{"title":"Ansitheus","link":"https:\/\/ntk148v.github.io\/posts\/ansitheus\/","pubDate":"Tue, 05 May 2020 13:51:59 +0700","author":"kiennt2609@gmail.com (Kien Nguyen-Tuan)","guid":"https:\/\/ntk148v.github.io\/posts\/ansitheus\/","description":"<div class=\"highlight\"><pre tabindex=\"0\" style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"><code class=\"language-bash\" data-lang=\"bash\"><span style=\"display:flex;\"><span>Ansitheus: Ansible + Prometheus\n<\/span><\/span><\/code><\/pre><\/div><h2 id=\"prometheus-overview\">Prometheus overview<\/h2>\n<blockquote>\n<p><strong>NOTE<\/strong>: Checkout the <a href=\"https:\/\/prometheus.io\/docs\/introduction\/overview\/\">Prometheus official documentation<\/a>.<\/p>\n<\/blockquote>\n<p><a href=\"https:\/\/github.com\/prometheus\">Prometheus<\/a> is an open-source systems monitoring &amp; alerting toolkit originally built at SoundCloud.<\/p>\n<h3 id=\"features\">Features<\/h3>\n<ul>\n<li>a multi-dimensional data model with time series data identified by metric name &amp; key\/value pairs<\/li>\n<li>PromQL, a flexible query language to leverage this dimensionality<\/li>\n<li>no reliance on distributed storage; single server nodes are autonomous<\/li>\n<li>time series collection happens via a pull model over HTTP<\/li>\n<li>pushing time series is supported via an intermediary gateway<\/li>\n<li>targets are discovered via service discovery or static configuration<\/li>\n<li>multiple modes of graphing &amp; dashboarding support<\/li>\n<\/ul>\n<h3 id=\"architecture--components\">Architecture &amp; components<\/h3>\n<p>Prometheus scrapes metrics from instrumented jobs, either directly or via an intermediary push gateway for short-lived jobs. It stores all scraped samples locally &amp; runs rules over this data to either aggregate &amp; record new time series from existing data or generate alerts. Grafana or other API consumers can be used to visualize the collected data.<\/p>"},{"title":"Operate Etcd cluster","link":"https:\/\/ntk148v.github.io\/posts\/operate-etcd-cluster\/","pubDate":"Tue, 28 Apr 2020 11:24:04 +0700","author":"kiennt2609@gmail.com (Kien Nguyen-Tuan)","guid":"https:\/\/ntk148v.github.io\/posts\/operate-etcd-cluster\/","description":"<blockquote>\n<p><strong>NOTE<\/strong>: This is my perspective aggregation. You can easily find these such of knowledges in <a href=\"#5-references\">the references<\/a>.<\/p>\n<\/blockquote>\n<h2 id=\"context\">Context<\/h2>\n<p>Etcd Version <code>v3.4.0<\/code>.<\/p>\n<h2 id=\"requirements\">Requirements<\/h2>\n<h3 id=\"number-of-nodes\">Number of nodes<\/h3>\n<ul>\n<li>&gt;= 3 nodes. A etcd cluster needs a majority of nodes, a quorum to agree on updates to the cluster state. For a cluster with <strong>n-members<\/strong>, quorum is <strong>(n\/2)+1<\/strong>.<\/li>\n<\/ul>\n<h3 id=\"cpus\">CPUs<\/h3>\n<ul>\n<li>Etcd doesn&rsquo;t require a lot of CPU capacity.<\/li>\n<li>Typical clusters need <strong>2-4 cores<\/strong> to run smoothly.<\/li>\n<\/ul>\n<h3 id=\"memory\">Memory<\/h3>\n<ul>\n<li>Etcd performance depends on having enough memory (cache key-value data, tracking watchers&hellip;).<\/li>\n<li>Typical <strong>8GB<\/strong> is enough.<\/li>\n<\/ul>\n<h3 id=\"disk\">Disk<\/h3>\n<ul>\n<li>An etcd cluster is very sensitive to disk latencies. Since etcd must persist proposals to its log, disk activity from other processes may cause long <code>fsync<\/code> latencies. The upshot is etcd may miss heartbeats, causing request timeouts and temporary leader loss. An etcd server can sometimes stably run alongside these processes when given a high disk priority.<\/li>\n<li>Check whether a disk is fast enough for etcd using <a href=\"https:\/\/github.com\/axboe\/fio\">fio<\/a>. If the 99th percentile of fdatasync is <strong>&lt;10ms<\/strong>, your storage is ok.<\/li>\n<\/ul>\n<div class=\"highlight\"><pre tabindex=\"0\" style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"><code class=\"language-bash\" data-lang=\"bash\"><span style=\"display:flex;\"><span>$ fio --rw=write --ioengine=sync --fdatasync=1 --directory=test-data <span style=\"color:#666;font-style:italic\">\\\n<\/span><\/span><\/span><span style=\"display:flex;\"><span> --size=22m --bs=2300 --name=mytest\n<\/span><\/span><\/code><\/pre><\/div><ul>\n<li><strong>SSD<\/strong> is recommended.<\/li>\n<\/ul>\n<h3 id=\"network\">Network<\/h3>\n<ul>\n<li>Etcd cluster should be deployed in a fast and reliable network. Low latency ensures etcd members can communicate fast. High bandwidth can reduce the time to recover a failed etcd member.<\/li>\n<li><strong>1GbE<\/strong> is sufficient for common etcd.<\/li>\n<li>Note that the network isn&rsquo;t the only source of latency. Each request and response may be impacted by slow disks on both the leader and followers.<\/li>\n<\/ul>\n<h2 id=\"tuning\">Tuning<\/h2>\n<h3 id=\"time-parameters\">Time parameters<\/h3>\n<ul>\n<li><code>Heartbeat interval<\/code>.\n<ul>\n<li>The frequency with which the leader will notify followers that it is still the leader.<\/li>\n<li>Default: <strong>100ms<\/strong>.<\/li>\n<li>Best practice: <strong>Around 0.5-1.5 x round-trip time (RTT) between members<\/strong>. Measure RTT with <code>ping<\/code>.<\/li>\n<li>Tradeoff: Too low -&gt; etcd will send unnecessary messages -&gt; increase the usage of CPU and network resources. Too high -&gt; leads to high election timeout.<\/li>\n<\/ul>\n<\/li>\n<li><code>Election timeout<\/code>.\n<ul>\n<li>How long a follower node will go without hearing a heartbeat before attempting to become leader itself.<\/li>\n<li>Default: <strong>1000ms<\/strong>.<\/li>\n<li>Best practice: <strong>&gt;= 10 x RTT and &lt; 50s<\/strong>.<\/li>\n<\/ul>\n<\/li>\n<li>The heartbeat interval and election timeout value should be <strong>the same for all members in one cluster<\/strong>.<\/li>\n<\/ul>\n<div class=\"highlight\"><pre tabindex=\"0\" style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"><code class=\"language-bash\" data-lang=\"bash\"><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># Command line arguments:<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span>$ etcd --heartbeat-interval=100 --election-timeout=500\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># Environment variables:<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span>$ <span style=\"color:#666;font-weight:bold;font-style:italic\">ETCD_HEARTBEAT_INTERVAL<\/span>=100 <span style=\"color:#666;font-weight:bold;font-style:italic\">ETCD_ELECTION_TIMEOUT<\/span>=500 etcd\n<\/span><\/span><\/code><\/pre><\/div><h3 id=\"disk-1\">Disk<\/h3>\n<ul>\n<li>An etcd server can sometimes stably run alongside these processes when given a high disk priority using <a href=\"https:\/\/linux.die.net\/man\/1\/ionice\">ionice<\/a>.<\/li>\n<\/ul>\n<div class=\"highlight\"><pre tabindex=\"0\" style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"><code class=\"language-bash\" data-lang=\"bash\"><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># best effort, highest priority<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span>$ sudo ionice -c2 -n0 -p <span style=\"color:#666;font-style:italic\">`<\/span>pgrep etcd<span style=\"color:#666;font-style:italic\">`<\/span>\n<\/span><\/span><\/code><\/pre><\/div><h3 id=\"snapshot\">Snapshot<\/h3>\n<ul>\n<li>etcd appends all key changes to a log file -&gt; huge log that grows forever :point_up:<\/li>\n<li>Solution: Make periodic snapshots (save the current and remove old logs).<\/li>\n<li>Default: make snapshots after every <strong>10 000 changes<\/strong>.<\/li>\n<li>Tuning: Just in case that etcd&rsquo;s memory and disk usage is too high, lower threshold.<\/li>\n<\/ul>\n<div class=\"highlight\"><pre tabindex=\"0\" style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"><code class=\"language-bash\" data-lang=\"bash\"><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># Command line arguments:<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span>$ etcd --snapshot-count=5000\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># Environment variables:<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span>$ <span style=\"color:#666;font-weight:bold;font-style:italic\">ETCD_SNAPSHOT_COUNT<\/span>=5000 etcd\n<\/span><\/span><\/code><\/pre><\/div><h2 id=\"maintenance\">Maintenance<\/h2>\n<h3 id=\"history-compaction\">History compaction<\/h3>\n<ul>\n<li>Etcd keeps an exact history of its keyspace, the history should be periodically compacted to avoid performance degradation and eventual storage space exhaustion.<\/li>\n<li>Etcd can be set to automatically compact the keyspace with the <code>--auto-compaction-*<\/code> option with a period of hours.<\/li>\n<\/ul>\n<div class=\"highlight\"><pre tabindex=\"0\" style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"><code class=\"language-bash\" data-lang=\"bash\"><span style=\"display:flex;\"><span><span style=\"color:#888;font-style:italic\"># keep one hour of history<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span>$ etcd --auto-compaction-retention=1 --auto-compaction-mode=periodic\n<\/span><\/span><\/code><\/pre><\/div><ul>\n<li>Compaction modes:\n<ul>\n<li>Revision-based: <code>--auto-compaction-mode=revision --auto-compaction-retention=1000<\/code> automatically Compact on &ldquo;latest revision&rdquo; - 1000 every 5-minute (when latest revision is 30000, compact on revision 29000). Use this when having a large keyspace.<\/li>\n<li>Periodic: <code>--auto-compaction-mode=periodic --auto-compaction-retention=72h<\/code> automatically Compact with 72-hour retention window every 1-hour. Use this when having a huge number of revisions for a key-value pair.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h3 id=\"defragmentation\">Defragmentation<\/h3>\n<ul>\n<li>Compacting old revisions internally fragments etcd by leaving gaps in backend database - <code>internal fragmentation<\/code>.<\/li>\n<li>Internal fragmentation space is available for use by etcd but unavailable to the host filesystem.<\/li>\n<li>Solution: Release this space back to the filesystem with defrag.<\/li>\n<\/ul>\n<div class=\"highlight\"><pre tabindex=\"0\" style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"><code class=\"language-bash\" data-lang=\"bash\"><span style=\"display:flex;\"><span>$ etcdctl defrag\n<\/span><\/span><\/code><\/pre><\/div><ul>\n<li>It should be run rather infrequently, as there is always going to be an unavoidable pause.<\/li>\n<\/ul>\n<h2 id=\"references\">References<\/h2>\n<ul>\n<li>Etcd hardware: <a href=\"https:\/\/github.com\/etcd-io\/etcd\/blob\/master\/Documentation\/op-guide\/hardware.md\">https:\/\/github.com\/etcd-io\/etcd\/blob\/master\/Documentation\/op-guide\/hardware.md<\/a><\/li>\n<li>Etcd tuning: <a href=\"https:\/\/github.com\/etcd-io\/etcd\/blob\/master\/Documentation\/tuning.md\">https:\/\/github.com\/etcd-io\/etcd\/blob\/master\/Documentation\/tuning.md<\/a><\/li>\n<li>Etcd maintainence: <a href=\"https:\/\/etcd.io\/docs\/v3.4.0\/op-guide\/maintenance\/\">https:\/\/etcd.io\/docs\/v3.4.0\/op-guide\/maintenance\/<\/a><\/li>\n<\/ul>"},{"title":"Golang: Block forever","link":"https:\/\/ntk148v.github.io\/posts\/golang-block-forever\/","pubDate":"Mon, 27 Apr 2020 15:59:21 +0700","author":"kiennt2609@gmail.com (Kien Nguyen-Tuan)","guid":"https:\/\/ntk148v.github.io\/posts\/golang-block-forever\/","description":"<p>Sometimes, you want to block the current goroutine when allowing others to continue. Here is some tricks I&rsquo;ve collected:<\/p>\n<h2 id=\"references\">References<\/h2>\n<p>Firstly give them some credits:<\/p>\n<ol>\n<li><a href=\"https:\/\/blog.sgmansfield.com\/2016\/06\/how-to-block-forever-in-go\/\">https:\/\/blog.sgmansfield.com\/2016\/06\/how-to-block-forever-in-go\/<\/a><\/li>\n<li><a href=\"https:\/\/pliutau.com\/different-ways-to-block-go-runtime-forever\/\">https:\/\/pliutau.com\/different-ways-to-block-go-runtime-forever\/<\/a><\/li>\n<\/ol>\n<blockquote>\n<p>NOTE: I run these with Golang 1.12<\/p>\n<\/blockquote>\n<h2 id=\"the-original\">The original<\/h2>\n<div class=\"highlight\"><pre tabindex=\"0\" style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"font-weight:bold\">package<\/span> main\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"font-weight:bold\">import<\/span> <span style=\"color:#666;font-style:italic\">&#34;fmt&#34;<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"font-weight:bold;font-style:italic\">func<\/span> <span style=\"color:#666;font-weight:bold;font-style:italic\">show<\/span>() {\n<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"font-weight:bold\">for<\/span> i := 1; i &lt; 9696969; i++ {\n<\/span><\/span><span style=\"display:flex;\"><span> time.<span style=\"color:#666;font-weight:bold;font-style:italic\">Sleep<\/span>(1000)\n<\/span><\/span><span style=\"display:flex;\"><span> fmt.<span style=\"color:#666;font-weight:bold;font-style:italic\">Println<\/span>(i)\n<\/span><\/span><span style=\"display:flex;\"><span> }\n<\/span><\/span><span style=\"display:flex;\"><span>}\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"font-weight:bold;font-style:italic\">func<\/span> <span style=\"color:#666;font-weight:bold;font-style:italic\">main<\/span>() {\n<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"font-weight:bold\">go<\/span> <span style=\"color:#666;font-weight:bold;font-style:italic\">show<\/span>() <span style=\"color:#888;font-style:italic\">\/\/ The main goroutine is exited before the show() be done.<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span> fmt.<span style=\"color:#666;font-weight:bold;font-style:italic\">Println<\/span>(<span style=\"color:#666;font-style:italic\">&#34;OK we&#39;re done&#34;<\/span>)\n<\/span><\/span><span style=\"display:flex;\"><span>}\n<\/span><\/span><\/code><\/pre><\/div><h2 id=\"bad---an-empty-infinite-loop\">Bad - An empty infinite loop<\/h2>\n<div class=\"highlight\"><pre tabindex=\"0\" style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"font-weight:bold\">package<\/span> main\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"font-weight:bold\">import<\/span> (\n<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#666;font-style:italic\">&#34;fmt&#34;<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#666;font-style:italic\">&#34;time&#34;<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span>)\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"font-weight:bold;font-style:italic\">func<\/span> <span style=\"color:#666;font-weight:bold;font-style:italic\">forever<\/span>() {\n<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"font-weight:bold\">for<\/span> {\n<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#888;font-style:italic\">\/\/ Empty, just do nothing<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span> }\n<\/span><\/span><span style=\"display:flex;\"><span>}\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"font-weight:bold;font-style:italic\">func<\/span> <span style=\"color:#666;font-weight:bold;font-style:italic\">show<\/span>() {\n<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"font-weight:bold\">for<\/span> i := 1; i &lt; 9696969; i++ {\n<\/span><\/span><span style=\"display:flex;\"><span> time.<span style=\"color:#666;font-weight:bold;font-style:italic\">Sleep<\/span>(5 * time.Second)\n<\/span><\/span><span style=\"display:flex;\"><span> fmt.<span style=\"color:#666;font-weight:bold;font-style:italic\">Println<\/span>(i)\n<\/span><\/span><span style=\"display:flex;\"><span> }\n<\/span><\/span><span style=\"display:flex;\"><span>}\n<\/span><\/span><span style=\"display:flex;\"><span>\n<\/span><\/span><span style=\"display:flex;\"><span><span style=\"font-weight:bold;font-style:italic\">func<\/span> <span style=\"color:#666;font-weight:bold;font-style:italic\">main<\/span>() {\n<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"font-weight:bold\">go<\/span> <span style=\"color:#666;font-weight:bold;font-style:italic\">show<\/span>()\n<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#666;font-weight:bold;font-style:italic\">forever<\/span>()\n<\/span><\/span><span style=\"display:flex;\"><span> fmt.<span style=\"color:#666;font-weight:bold;font-style:italic\">Println<\/span>(<span style=\"color:#666;font-style:italic\">&#34;OK we&#39;re done&#34;<\/span>)\n<\/span><\/span><span style=\"display:flex;\"><span>}\n<\/span><\/span><\/code><\/pre><\/div><p>An infinite loop here is a busy loop that does nothing except burn CPU time.<\/p>"},{"title":"Openstack Autoscaling New Approach","link":"https:\/\/ntk148v.github.io\/posts\/openstack-autoscaling-new-approach\/","pubDate":"Mon, 19 Aug 2019 21:19:38 +0700","author":"kiennt2609@gmail.com (Kien Nguyen-Tuan)","guid":"https:\/\/ntk148v.github.io\/posts\/openstack-autoscaling-new-approach\/","description":"<blockquote>\n<p>NOTE(kiennt): There is a <a href=\"https:\/\/github.com\/vCloud-DFTBA\/faythe\/blob\/legacy\/docs\/autoscaling.md\">legacy Faythe guideline<\/a>. The new version is coming soon, check <a href=\"https:\/\/github.com\/vCloud-DFTBA\/faythe\">its repository<\/a> for status.<\/p>\n<\/blockquote>\n<p>This guide describes how to automatically scale out your Compute instances in response to heavy system usage. By combining with Prometheus pre-defined rules that consider factors such as CPU or memory usage, you can configure OpenStack Orchestration (Heat) to add and remove additional instances automatically, when they are needed.<\/p>\n<h2 id=\"the-standard-openstack-autoscaling-approach\">The standard OpenStack Autoscaling approach<\/h2>\n<p>Let&rsquo;s talk about the standard OpenStack Autoscaling approach before goes to the new approach.<\/p>"},{"title":"Lets Comment","link":"https:\/\/ntk148v.github.io\/posts\/lets-comment\/","pubDate":"Tue, 02 Oct 2018 09:47:11 +0700","author":"kiennt2609@gmail.com (Kien Nguyen-Tuan)","guid":"https:\/\/ntk148v.github.io\/posts\/lets-comment\/","description":"<p>Hugo ships with support for Disqus, a third-party service that provides comment and community capabilities to websites via JavaScript. But Disqus generates a shit load of page requests and heavy contents&hellip; which even with the benefits that come with having Disqus in place. People just want something that can be used to post a comment, that is.<\/p>\n<p>That&rsquo;s why I choose a Disqus alternative - <a href=\"https:\/\/utteranc.es\/\">Utterances<\/a>. Utterances is a lightweight comments widget built on Github issues. Use Github issues for blog comments, wiki pages and more!<\/p>"}]}}