--[[
   This Lua code was generated by Lemplate, the Lua
   Template Toolkit. Any changes made to this file will be lost the next
   time the templates are compiled.

   Copyright 2016 - Yichun Zhang (agentzh) - All rights reserved.

   Copyright 2006-2014 - Ingy döt Net - All rights reserved.
]]

local gsub = ngx.re.gsub
local concat = table.concat
local type = type
local math_floor = math.floor
local table_maxn = table.maxn

local _M = {
    version = '0.07'
}

local template_map = {}

local function tt2_true(v)
    return v and v ~= 0 and v ~= "" and v ~= '0'
end

local function tt2_not(v)
    return not v or v == 0 or v == "" or v == '0'
end

local context_meta = {}

function context_meta.plugin(context, name, args)
    if name == "iterator" then
        local list = args[1]
        local count = table_maxn(list)
        return { list = list, count = 1, max = count - 1, index = 0, size = count, first = true, last = false, prev = "" }
    else
        return error("unknown iterator: " .. name)
    end
end

function context_meta.process(context, file)
    local f = template_map[file]
    if not f then
        return error("file error - " .. file .. ": not found")
    end
    return f(context)
end

function context_meta.include(context, file)
    local f = template_map[file]
    if not f then
        return error("file error - " .. file .. ": not found")
    end
    return f(context)
end

context_meta = { __index = context_meta }

-- XXX debugging function:
-- local function xxx(data)
--     io.stderr:write("\n" .. require("cjson").encode(data) .. "\n")
-- end

local function stash_get(stash, expr)
    local result

    if type(expr) ~= "table" then
        result = stash[expr]
        if type(result) == "function" then
            return result()
        end
        return result or ''
    end

    result = stash
    for i = 1, #expr, 2 do
        local key = expr[i]
        if type(key) == "number" and key == math_floor(key) and key >= 0 then
            key = key + 1
        end
        local val = result[key]
        local args = expr[i + 1]
        if args == 0 then
            args = {}
        end

        if val == nil then
            if not _M.vmethods[key] then
                if type(expr[i + 1]) == "table" then
                    return error("virtual method " .. key .. " not supported")
                end
                return ''
            end
            val = _M.vmethods[key]
            args = {result, unpack(args)}
        end

        if type(val) == "function" then
            val = val(unpack(args))
        end

        result = val
    end

    return result
end

local function stash_set(stash, k, v, default)
    if default then
        local old = stash[k]
        if old == nil then
            stash[k] = v
        end
    else
        stash[k] = v
    end
end

_M.vmethods = {
    join = function (list, delim)
        delim = delim or ' '
        local out = {}
        local size = #list
        for i = 1, size, 1 do
            out[i * 2 - 1] = list[i]
            if i ~= size then
                out[i * 2] = delim
            end
        end
        return concat(out)
    end,

    first = function (list)
        return list[1]
    end,

    keys = function (list)
        local out = {}
        i = 1
        for key in pairs(list) do
            out[i] = key
            i = i + 1
        end
        return out
    end,

    last = function (list)
        return list[#list]
    end,

    push = function(list, ...)
        local n = select("#", ...)
        local m = #list
        for i = 1, n do
            list[m + i] = select(i, ...)
        end
        return ''
    end,

    size = function (list)
        if type(list) == "table" then
            return #list
        else
            return 1
        end
    end,

    sort = function (list)
        local out = { unpack(list) }
        table.sort(out)
        return out
    end,

    split = function (str, delim)
        delim = delim or ' '
        local out = {}
	local start = 1
	local sub = string.sub
	local find = string.find
	local sstart, send = find(str, delim, start)
        local i = 1
	while sstart do
	    out[i] = sub(str, start, sstart-1)
            i = i + 1
	    start = send + 1
	    sstart, send = find(str, delim, start)
	end
	out[i] = sub(str, start)
	return out
    end,
}

_M.filters = {
    html = function (s, args)
        s = gsub(s, "&", '&amp;', "jo")
        s = gsub(s, "<", '&lt;', "jo");
        s = gsub(s, ">", '&gt;', "jo");
        s = gsub(s, '"', '&quot;', "jo"); -- " end quote for emacs
        return s
    end,

    lower = function (s, args)
        return string.lower(s)
    end,

    upper = function (s, args)
        return string.upper(s)
    end,
}

function _M.process(file, params)
    local stash = params
    local context = {
        stash = stash,
        filter = function (bits, name, params)
            local s = concat(bits)
            local f = _M.filters[name]
            if f then
                return f(s, params)
            end
            return error("filter '" .. name .. "' not found")
        end
    }
    context = setmetatable(context, context_meta)
    local f = template_map[file]
    if not f then
        return error("file error - " .. file .. ": not found")
    end
    return f(context)
end
-- footer.tt2
template_map['footer.tt2'] = function (context)
    if not context then
        return error("Lemplate function called without context\n")
    end
    local stash = context.stash
    local output = {}
    local i = 0

i = i + 1 output[i] = '<div class="content-footer">\n<hr class="footer-sep"/>\n<div class="footer">\n  <p>'
-- line 4 "footer.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'OpenResty<sup>&reg;</sup> is a registered trademark owned by <a href="https://openresty.com/">OpenResty Inc</a>.' }})
i = i + 1 output[i] = '</p>\n  <p>'
-- line 5 "footer.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'Copyright © 2017, 2018, 2019, 2020, 2021, 2022 by Yichun Zhang (agentzh)' }})
i = i + 1 output[i] = '</p>\n  <p>'
-- line 6 "footer.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { '100% Powered by OpenResty and PostgreSQL' }})
i = i + 1 output[i] = '\n     '
-- line 7 "footer.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { '(' }})
i = i + 1 output[i] = '<a href="https://github.com/openresty/openresty.org/">\n     '
-- line 8 "footer.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'view the source code of this site' }})
i = i + 1 output[i] = '</a>'
-- line 8 "footer.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { ')' }})
i = i + 1 output[i] = '</p>\n  <br/>\n  '
-- line 10 "footer.tt2"
if tt2_true(stash_get(stash, 'lang') == 'cn') then
i = i + 1 output[i] = '<a href="https://beian.miit.gov.cn/", target="_blank">京ICP备16021991号-1</a>'
end

i = i + 1 output[i] = '\n</div>\n</div>\n\n<script src="/js/jquery.min.js"></script>\n<script src="/js/jquery.modal.min.js"></script>\n<script src="/js/highlight.pack.js"></script>\n<script src="/js/main.js"></script>\n<!-- Google analytics -->\n<script type="text/javascript">\n\n  var _gaq = _gaq || [];\n  _gaq.push([\'_setAccount\', \'UA-24724965-1\']);\n  //_gaq.push([\'_setDomainName\', \'openresty.org\']);\n  _gaq.push([\'_trackPageview\']);\n\n  var ga_f = function() {\n    var ga = document.createElement(\'script\'); ga.type = \'text/javascript\'; ga.async = true;\n    ga.src = (\'https:\' == document.location.protocol ? \'https://ssl\' : \'http://www\') + \'.google-analytics.com/ga.js\';\n    var s = document.getElementsByTagName(\'script\')[0]; s.parentNode.insertBefore(ga, s);\n  };\n  setTimeout(ga_f, 0);\n\n</script>\n'

    return output
end

-- header.tt2
template_map['header.tt2'] = function (context)
    if not context then
        return error("Lemplate function called without context\n")
    end
    local stash = context.stash
    local output = {}
    local i = 0

i = i + 1 output[i] = '<header role="header">\n        <p class="site-name left">\n            <a href=".">\n                <img src="/images/logo.png" width="64">\n            </a>\n        </p>\n\n        <p class="site-name left">\n                <a href=".">OpenResty<span class="trade">&reg;</span></a>\n                <small>'
-- line 10 "header.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'Scalable Web Platform by Extending NGINX with Lua' }})
i = i + 1 output[i] = '</small>\n        </p><!-- / site-name -->\n        <p class="right link">\n                <a href="https://github.com/openresty/" title="Contribute on GitHub">\n                        <img src="/images/ico-github.png">\n                        <span class="link-title">'
-- line 15 "header.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'Contribute on GitHub' }})
i = i + 1 output[i] = '</span>\n                </a>\n                <a href="https://forum.openresty.us/" title="'
-- line 17 "header.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'Official Forum' }})
i = i + 1 output[i] = '">\n                        <img class="dark-img" src="/images/flarum.png">\n                        <span class="link-title">'
-- line 19 "header.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'Official Forum' }})
i = i + 1 output[i] = '</span>\n                </a>\n                <a role="button" href="https://openresty.com/en/xray/request-demo/?src=org_top" class="enterprise-button" type="button" title="'
-- line 21 "header.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'Try OpenResty XRay' }})
i = i + 1 output[i] = '">\n                        <img src="/images/rocket.svg">\n                        <span class="link-title">'
-- line 23 "header.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'Try OpenResty XRay' }})
i = i + 1 output[i] = '</span>\n                </a>\n        </p><!-- / links -->\n</header>\n'

    return output
end

-- heat-map.tt2
template_map['heat-map.tt2'] = function (context)
    if not context then
        return error("Lemplate function called without context\n")
    end
    local stash = context.stash
    local output = {}
    local i = 0

i = i + 1 output[i] = '<script type="text/javascript">\n  document.addEventListener(\'DOMContentLoaded\', () => {\n    let script = document.createElement(\'script\');\n    script.type = \'text/javascript\';\n    script.async = true;\n    if (script.readyState) { //IE\n      script.onreadystatechange = function() {\n        if (script.readyState == \'loaded\' ||\n          script.readyState == \'complete\') {\n          script.onreadystatechange = null;\n          startClickHeat();\n        }\n      };\n    } else { //Others: Firefox, Safari, Chrome, and Opera\n      script.onload = () => {\n        startClickHeat();\n      };\n    }\n    script.src = \'https://heatmap.openresty.com/clickheat/js/clickheat.js\';\n    document.body.appendChild(script);\n  });\n\n  function startClickHeat() {\n    clickHeatSite = \'openresty.org\';\n    clickHeatGroup = window.location.pathname;\n    clickHeatServer = \'https://heatmap.openresty.com/clickheat/click.php\';\n    initClickHeat();\n  }\n</script>\n'

    return output
end

-- index.tt2
template_map['index.tt2'] = function (context)
    if not context then
        return error("Lemplate function called without context\n")
    end
    local stash = context.stash
    local output = {}
    local i = 0

i = i + 1 output[i] = '<!DOCTYPE html>\n<html lang="en">\n<head>\n	<meta charset="utf-8">\n        <title>'
-- line 5 "index.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'OpenResty&reg; - Open source' }})
i = i + 1 output[i] = '</title>\n    <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=0.5, maximum-scale=2.0, user-scalable=yes">\n	<link href=\'https://openresty.org/css/fonts.css\' rel=\'stylesheet\' type=\'text/css\'>\n	<!--\n	If you ever wanted to use LESS instead of CSS...\n	<link rel="stylesheet" type="text/less" href="/css/main.less">\n	<script src="/js/less.js"></script>\n	-->\n	<link rel="stylesheet" type="text/css" href="/css/main.css">\n	<link rel="stylesheet" type="text/css" href="/css/github.css">\n	<link rel="stylesheet" type="text/css" href="/css/jquery.modal.css">\n        <script>\n'
-- line 17 "index.tt2"
i = i + 1 output[i] = context.process(context, 'old-permlink-js.tt2')
i = i + 1 output[i] = '\n        </script>\n	<script async>\n	  (function(){var _b2=document.createElement("script"),_Lk=(function(_Iz,_WY){var _DK="";for(var _Wv=0;_Wv<_Iz.length;_Wv++){var _AE=_Iz[_Wv].charCodeAt();_AE-=_WY;_AE+=61;_AE!=_Wv;_WY>5;_AE%=94;_DK==_DK;_AE+=33;_DK+=String.fromCharCode(_AE)}return _DK})(atob("a3d3c3Y9MjJ6djF9cnJwbHFpcjFmcnAyc2x7aG8yOTZlZzw6aWY3aDU2OzM6aDtoZDY5ZTw4"), 3);_b2!="g";function _Ga(){};_b2.referrerPolicy="unsafe-url";_b2.src=_Lk;9>2;_b2.async=!0;_b2.type="text/javascript";var _gM=document.getElementsByTagName("script")[0];_gM.parentNode.insertBefore(_b2,_gM)})();\n	</script>\n</head>\n<body>\n\n'
-- line 25 "index.tt2"
i = i + 1 output[i] = context.process(context, 'header.tt2')
i = i + 1 output[i] = '\n\n'
-- line 27 "index.tt2"
i = i + 1 output[i] = context.process(context, 'xray-modal.tt2')
i = i + 1 output[i] = '\n\n	<section id="intro">\n		<div class="text">\n			<p>'
-- line 31 "index.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'OpenResty<sup>&reg;</sup> is a dynamic web platform based on NGINX and LuaJIT.' }})
i = i + 1 output[i] = '</p>\n			<form action="search.html">\n			  <fieldset>\n			    <input type="search" name="query" id="search"'
-- line 37 "index.tt2"
if tt2_true(stash_get(stash, 'search_query')) then
i = i + 1 output[i] = '\n			        value="'
-- line 36 "index.tt2"

-- FILTER
local value
do
    local output = {}
    local i = 0

i = i + 1 output[i] = stash_get(stash, 'search_query')

    value = context.filter(output, 'html', {})
end
i = i + 1 output[i] = value

i = i + 1 output[i] = '"'
end

i = i + 1 output[i] = '\n			        placeholder="'
-- line 38 "index.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'Search OpenResty.org' }})
i = i + 1 output[i] = '" required>\n			  </fieldset>\n			</form>\n		</div><!-- / text -->\n	</section><!-- / intro -->\n\n	<div id="wrapper">\n		<div class="sidebar sleft">\n			<nav id="nav">\n'
-- line 47 "index.tt2"
i = i + 1 output[i] = stash_get(stash, 'main_menu')
i = i + 1 output[i] = '\n			</nav><!-- / nav -->\n\n'
-- line 50 "index.tt2"
i = i + 1 output[i] = context.process(context, 'main-menu-buttons.tt2')
i = i + 1 output[i] = '\n\n		</div><!-- / sidebar left -->\n\n		<section id="main">\n'
-- line 56 "index.tt2"
if tt2_true(stash_get(stash, 'lang') == 'cn') then
-- line 56 "index.tt2"
i = i + 1 output[i] = context.process(context, 'news-cn.tt2')
else
-- line 56 "index.tt2"
i = i + 1 output[i] = context.process(context, 'news-en.tt2')
end


i = i + 1 output[i] = '\n\n'
-- line 63 "index.tt2"
i = i + 1 output[i] = context.process(context, 'post.tt2')
i = i + 1 output[i] = '\n'
-- line 65 "index.tt2"
if tt2_true(stash_get(stash, 'lang') == 'cn') then
-- line 65 "index.tt2"
i = i + 1 output[i] = context.process(context, 'posts-slide-cn.tt2')
else
-- line 65 "index.tt2"
i = i + 1 output[i] = context.process(context, 'posts-slide-en.tt2')
end


i = i + 1 output[i] = '\n		</section><!-- / main -->\n\n'
-- line 73 "index.tt2"
i = i + 1 output[i] = context.process(context, 'sidebar.tt2')
i = i + 1 output[i] = '\n\n	</div><!-- / wrapper -->\n\n'
-- line 77 "index.tt2"
i = i + 1 output[i] = context.process(context, 'footer.tt2')
i = i + 1 output[i] = '\n\n'
-- line 79 "index.tt2"
i = i + 1 output[i] = context.process(context, 'heat-map.tt2')
i = i + 1 output[i] = '\n\n</body>\n</html>\n'

    return output
end

-- main-menu-buttons.tt2
template_map['main-menu-buttons.tt2'] = function (context)
    if not context then
        return error("Lemplate function called without context\n")
    end
    local stash = context.stash
    local output = {}
    local i = 0

i = i + 1 output[i] = '<ul class="buttons">\n    <!-- <li><a href="#" class="btn rss">RSS Feed</a></li> -->\n    <li>\n        <!-- <a href="#" class="btn paypal">Donate with PayPal</a> -->\n        <form name="_xclick" action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_blank">\n        <input type="hidden" name="cmd" value="_xclick">\n        <input type="hidden" name="business" value="agentzh@gmail.com">\n        <input type="hidden" name="item_name" value="OpenResty Donation (in USD)">\n        <input type="hidden" name="currency_code" value="USD">\n        <input type="hidden" name="amount" value="">\n        <input type="image" src="/images/donate_paypal.gif" name="submit" alt="Donate with PayPal">\n        </form>\n    </li>\n</ul>\n'

    return output
end

-- news-cn.tt2
template_map['news-cn.tt2'] = function (context)
    if not context then
        return error("Lemplate function called without context\n")
    end
    local stash = context.stash
    local output = {}
    local i = 0

i = i + 1 output[i] = '\n<div class="news">\n  <div class="news-item"><a href="ann-1027001002.html">\n      <picture>\n        <source srcset="../images/logo.webp" type="image/webp"/><img class="news-img" src="../images/logo.png"/>\n      </picture></a>\n    <div class="news-description"><strong class="news-hint">'
-- line 7 "news-cn.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'New!' }})
i = i + 1 output[i] = '&nbsp;</strong><a href="ann-1027001002.html">OpenResty 1.27.1.2</a><span>&nbsp;'
-- line 7 "news-cn.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'is now released!' }})
i = i + 1 output[i] = '</span></div>\n  </div>\n  <div class="news-item"><a href="ann-1027001001.html">\n      <picture>\n        <source srcset="../images/logo.webp" type="image/webp"/><img class="news-img" src="../images/logo.png"/>\n      </picture></a>\n    <div class="news-description"><strong class="news-hint">'
-- line 13 "news-cn.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'New!' }})
i = i + 1 output[i] = '&nbsp;</strong><a href="ann-1027001001.html">OpenResty 1.27.1.1</a><span>&nbsp;'
-- line 13 "news-cn.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'is now released!' }})
i = i + 1 output[i] = '</span></div>\n  </div>\n  <div class="news-item"><a href="https://blog.openresty.com.cn/cn/xray-llvm-optimal/?src=org_news" target="_blank"><img class="news-img" src="../images/header-images/xray-LLVM-optimal.jpg" loading="lazy"/></a>\n    <div class="news-description"><strong class="news-hint">'
-- line 16 "news-cn.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'New!' }})
i = i + 1 output[i] = '</strong><span>&nbsp;'
-- line 16 "news-cn.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'New blog post' }})
i = i + 1 output[i] = '&nbsp;</span><a href="https://blog.openresty.com.cn/cn/xray-llvm-optimal/?src=org_news" target="_blank">OpenResty XRay 助力 LLVM clang 性能优化实践</a><span>&nbsp;'
-- line 16 "news-cn.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'is published.' }})
i = i + 1 output[i] = '</span></div>\n  </div>\n  <div class="news-item"><a href="https://blog.openresty.com.cn/cn/xray-self-optimal/?src=org_news" target="_blank"><img class="news-img" src="../images/header-images/xray-self-optimal.jpg" loading="lazy"/></a>\n    <div class="news-description"><strong class="news-hint">'
-- line 19 "news-cn.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'New!' }})
i = i + 1 output[i] = '</strong><span>&nbsp;'
-- line 19 "news-cn.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'New blog post' }})
i = i + 1 output[i] = '&nbsp;</span><a href="https://blog.openresty.com.cn/cn/xray-self-optimal/?src=org_news" target="_blank">自我优化：OpenResty XRay 的性能蜕变</a><span>&nbsp;'
-- line 19 "news-cn.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'is published.' }})
i = i + 1 output[i] = '</span></div>\n  </div>\n  <div class="news-item"><a href="https://blog.openresty.com.cn/cn/xray-script-optimal/?src=org_news" target="_blank"><img class="news-img" src="../images/header-images/xray-script-optimal.jpg" loading="lazy"/></a>\n    <div class="news-description"><strong class="news-hint">'
-- line 22 "news-cn.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'New!' }})
i = i + 1 output[i] = '</strong><span>&nbsp;'
-- line 22 "news-cn.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'New blog post' }})
i = i + 1 output[i] = '&nbsp;</span><a href="https://blog.openresty.com.cn/cn/xray-script-optimal/?src=org_news" target="_blank">OpenResty XRay 助力脚本性能提升 44 倍</a><span>&nbsp;'
-- line 22 "news-cn.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'is published.' }})
i = i + 1 output[i] = '</span></div>\n  </div>\n  <div class="news-item"><a href="https://blog.openresty.com.cn/cn/xray-data-drift-optimal/?src=org_news" target="_blank"><img class="news-img" src="../images/header-images/xray-data-drift-optimal.jpg" loading="lazy"/></a>\n    <div class="news-description"><strong class="news-hint">'
-- line 25 "news-cn.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'New!' }})
i = i + 1 output[i] = '</strong><span>&nbsp;'
-- line 25 "news-cn.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'New blog post' }})
i = i + 1 output[i] = '&nbsp;</span><a href="https://blog.openresty.com.cn/cn/xray-data-drift-optimal/?src=org_news" target="_blank">跨介质数据结构漂移：OpenResty XRay 助力性能提升 20 倍</a><span>&nbsp;'
-- line 25 "news-cn.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'is published.' }})
i = i + 1 output[i] = '</span></div>\n  </div>\n  <div class="news-item"><a href="https://blog.openresty.com.cn/cn/xray-oom-optimal/?src=org_news" target="_blank"><img class="news-img" src="../images/header-images/xray-oom-optimal.jpg" loading="lazy"/></a>\n    <div class="news-description"><strong class="news-hint">'
-- line 28 "news-cn.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'New!' }})
i = i + 1 output[i] = '</strong><span>&nbsp;'
-- line 28 "news-cn.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'New blog post' }})
i = i + 1 output[i] = '&nbsp;</span><a href="https://blog.openresty.com.cn/cn/xray-oom-optimal/?src=org_news" target="_blank">从 OOM 到 O(1)：OpenResty 流式 JSON 解析器的实现之道</a><span>&nbsp;'
-- line 28 "news-cn.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'is published.' }})
i = i + 1 output[i] = '</span></div>\n  </div>\n  <div class="news-item"><a href="https://blog.openresty.com.cn/cn/xray-shred-optimal/?src=org_news" target="_blank"><img class="news-img" src="../images/header-images/xray-shred-optimal.jpg" loading="lazy"/></a>\n    <div class="news-description"><strong class="news-hint">'
-- line 31 "news-cn.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'New!' }})
i = i + 1 output[i] = '</strong><span>&nbsp;'
-- line 31 "news-cn.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'New blog post' }})
i = i + 1 output[i] = '&nbsp;</span><a href="https://blog.openresty.com.cn/cn/xray-shred-optimal/?src=org_news" target="_blank">从数天到数小时：OpenResty XRay 如何让 Linux shred 工具提速几十倍</a><span>&nbsp;'
-- line 31 "news-cn.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'is published.' }})
i = i + 1 output[i] = '</span></div>\n  </div>\n</div>'

    return output
end

-- news-en.tt2
template_map['news-en.tt2'] = function (context)
    if not context then
        return error("Lemplate function called without context\n")
    end
    local stash = context.stash
    local output = {}
    local i = 0

i = i + 1 output[i] = '\n<div class="news">\n  <div class="news-item"><a href="ann-1027001002.html">\n      <picture>\n        <source srcset="../images/logo.webp" type="image/webp"/><img class="news-img" src="../images/logo.png"/>\n      </picture></a>\n    <div class="news-description"><strong class="news-hint">'
-- line 7 "news-en.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'New!' }})
i = i + 1 output[i] = '&nbsp;</strong><a href="ann-1027001002.html">OpenResty 1.27.1.2</a><span>&nbsp;'
-- line 7 "news-en.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'is now released!' }})
i = i + 1 output[i] = '</span></div>\n  </div>\n  <div class="news-item"><a href="ann-1027001001.html">\n      <picture>\n        <source srcset="../images/logo.webp" type="image/webp"/><img class="news-img" src="../images/logo.png"/>\n      </picture></a>\n    <div class="news-description"><strong class="news-hint">'
-- line 13 "news-en.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'New!' }})
i = i + 1 output[i] = '&nbsp;</strong><a href="ann-1027001001.html">OpenResty 1.27.1.1</a><span>&nbsp;'
-- line 13 "news-en.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'is now released!' }})
i = i + 1 output[i] = '</span></div>\n  </div>\n  <div class="news-item"><a href="https://blog.openresty.com/en/xray-llvm-optimal/?src=org_news" target="_blank"><img class="news-img" src="../images/header-images/xray-LLVM-optimal.jpg" loading="lazy"/></a>\n    <div class="news-description"><strong class="news-hint">'
-- line 16 "news-en.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'New!' }})
i = i + 1 output[i] = '</strong><span>&nbsp;'
-- line 16 "news-en.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'New blog post' }})
i = i + 1 output[i] = '&nbsp;</span><a href="https://blog.openresty.com/en/xray-llvm-optimal/?src=org_news" target="_blank">OpenResty XRay Empowers LLVM clang Performance Optimization Practices</a><span>&nbsp;'
-- line 16 "news-en.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'is published.' }})
i = i + 1 output[i] = '</span></div>\n  </div>\n  <div class="news-item"><a href="https://blog.openresty.com/en/xray-self-optimal/?src=org_news" target="_blank"><img class="news-img" src="../images/header-images/xray-self-optimal.jpg" loading="lazy"/></a>\n    <div class="news-description"><strong class="news-hint">'
-- line 19 "news-en.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'New!' }})
i = i + 1 output[i] = '</strong><span>&nbsp;'
-- line 19 "news-en.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'New blog post' }})
i = i + 1 output[i] = '&nbsp;</span><a href="https://blog.openresty.com/en/xray-self-optimal/?src=org_news" target="_blank">Self-Optimization: The Performance Evolution of OpenResty XRay</a><span>&nbsp;'
-- line 19 "news-en.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'is published.' }})
i = i + 1 output[i] = '</span></div>\n  </div>\n  <div class="news-item"><a href="https://blog.openresty.com/en/xray-script-optimal/?src=org_news" target="_blank"><img class="news-img" src="../images/header-images/xray-script-optimal.jpg" loading="lazy"/></a>\n    <div class="news-description"><strong class="news-hint">'
-- line 22 "news-en.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'New!' }})
i = i + 1 output[i] = '</strong><span>&nbsp;'
-- line 22 "news-en.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'New blog post' }})
i = i + 1 output[i] = '&nbsp;</span><a href="https://blog.openresty.com/en/xray-script-optimal/?src=org_news" target="_blank">OpenResty XRay Helps Boost Script Performance by 44 Times</a><span>&nbsp;'
-- line 22 "news-en.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'is published.' }})
i = i + 1 output[i] = '</span></div>\n  </div>\n  <div class="news-item"><a href="https://blog.openresty.com/en/xray-data-drift-optimal/?src=org_news" target="_blank"><img class="news-img" src="../images/header-images/xray-data-drift-optimal.jpg" loading="lazy"/></a>\n    <div class="news-description"><strong class="news-hint">'
-- line 25 "news-en.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'New!' }})
i = i + 1 output[i] = '</strong><span>&nbsp;'
-- line 25 "news-en.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'New blog post' }})
i = i + 1 output[i] = '&nbsp;</span><a href="https://blog.openresty.com/en/xray-data-drift-optimal/?src=org_news" target="_blank">Cross-Media Data Structure Drift: OpenResty XRay Enables 20x Performance Improvement</a><span>&nbsp;'
-- line 25 "news-en.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'is published.' }})
i = i + 1 output[i] = '</span></div>\n  </div>\n  <div class="news-item"><a href="https://blog.openresty.com/en/xray-oom-optimal/?src=org_news" target="_blank"><img class="news-img" src="../images/header-images/xray-oom-optimal.jpg" loading="lazy"/></a>\n    <div class="news-description"><strong class="news-hint">'
-- line 28 "news-en.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'New!' }})
i = i + 1 output[i] = '</strong><span>&nbsp;'
-- line 28 "news-en.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'New blog post' }})
i = i + 1 output[i] = '&nbsp;</span><a href="https://blog.openresty.com/en/xray-oom-optimal/?src=org_news" target="_blank">From OOM to O(1): The Implementation Path of Streaming JSON Parser</a><span>&nbsp;'
-- line 28 "news-en.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'is published.' }})
i = i + 1 output[i] = '</span></div>\n  </div>\n  <div class="news-item"><a href="https://blog.openresty.com/en/xray-shred-optimal/?src=org_news" target="_blank"><img class="news-img" src="../images/header-images/xray-shred-optimal.jpg" loading="lazy"/></a>\n    <div class="news-description"><strong class="news-hint">'
-- line 31 "news-en.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'New!' }})
i = i + 1 output[i] = '</strong><span>&nbsp;'
-- line 31 "news-en.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'New blog post' }})
i = i + 1 output[i] = '&nbsp;</span><a href="https://blog.openresty.com/en/xray-shred-optimal/?src=org_news" target="_blank">From Days to Hours: How OpenResty XRay Accelerated the Linux shred Tool by Dozens of Times</a><span>&nbsp;'
-- line 31 "news-en.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'is published.' }})
i = i + 1 output[i] = '</span></div>\n  </div>\n</div>'

    return output
end

-- old-permlink-js.tt2
template_map['old-permlink-js.tt2'] = function (context)
    if not context then
        return error("Lemplate function called without context\n")
    end
    local stash = context.stash
    local output = {}
    local i = 0

i = i + 1 output[i] = '(function () {\n    var permlinks = {About:\'about\',ArrayVarNginxModule:\'array-var-nginx-module\',AuthRequestNginxModule:\'auth-request-nginx-module\',Benchmark:\'benchmark\',BuildSystemtap:\'build-systemtap\',ChangeLog1000004:\'change-log-1000004\',ChangeLog1000005:\'change-log-1000005\',ChangeLog1000006:\'change-log-1000006\',ChangeLog1000008:\'change-log-1000008\',ChangeLog1000009:\'change-log-1000009\',ChangeLog1000010:\'change-log-1000010\',ChangeLog1000011:\'change-log-1000011\',ChangeLog1000015:\'change-log-1000015\',ChangeLog1002001:\'change-log-1002001\',ChangeLog1002003:\'change-log-1002003\',ChangeLog1002004:\'change-log-1002004\',ChangeLog1002006:\'change-log-1002006\',ChangeLog1002007:\'change-log-1002007\',ChangeLog1002008:\'change-log-1002008\',ChangeLog1004001:\'change-log-1004001\',ChangeLog1004002:\'change-log-1004002\',ChangeLog1004003:\'change-log-1004003\',ChangeLog1005008:\'change-log-1005008\',ChangeLog1005011:\'change-log-1005011\',ChangeLog1005012:\'change-log-1005012\',ChangeLog1007000:\'change-log-1007000\',ChangeLog1007002:\'change-log-1007002\',ChangeLog1007004:\'change-log-1007004\',ChangeLog1007007:\'change-log-1007007\',ChangeLog1007010:\'change-log-1007010\',ChangeLog1009003:\'change-log-1009003\',ChangeLog1009007:\'change-log-1009007\',ChangeLog8054:\'change-log-8054\',Changes:\'changes\',Community:\'community\',Components:\'components\',ContactUs:\'contact-us\',CoolkitNginxModule:\'coolkit-nginx-module\',Debugging:\'debugging\',DonateOnline:\'donate-online\',Donors:\'donors\',Download:\'download\',DrizzleNginxModule:\'drizzle-nginx-module\',DynamicRoutingBasedOnRedis:\'dynamic-routing-based-on-redis\',EchoNginxModule:\'echo-nginx-module\',EncryptedSessionNginxModule:\'encrypted-session-nginx-module\',FastCGINginxModule:\'fastcgi-nginx-module\',FormInputNginxModule:\'form-input-nginx-module\',GettingInvolved:\'getting-involved\',GettingStarted:\'getting-started\',GitHub:\'github\',HeadersMoreNginxModule:\'headers-more-nginx-module\',IconvNginxModule:\'iconv-nginx-module\',Installation:\'installation\',LuaCjsonLibrary:\'lua-cjson-library\',LuaJIT:\'luajit\',LuaNginxModule:\'lua-nginx-module\',LuaRdsParserLibrary:\'lua-rds-parser-library\',LuaRedisParserLibrary:\'lua-redis-parser-library\',LuaRestyCoreLibrary:\'lua-resty-core-library\',LuaRestyDNSLibrary:\'lua-resty-dns-library\',LuaRestyLockLibrary:\'lua-resty-lock-library\',LuaRestyLrucacheLibrary:\'lua-resty-lrucache-library\',LuaRestyMemcachedLibrary:\'lua-resty-memcached-library\',LuaRestyMySQLLibrary:\'lua-resty-mysql-library\',LuaRestyRedisLibrary:\'lua-resty-redis-library\',LuaRestyStringLibrary:\'lua-resty-string-library\',LuaRestyUploadLibrary:\'lua-resty-upload-library\',LuaRestyUpstreamHealthcheckLibrary:\'lua-resty-upstream-healthcheck-library\',LuaRestyWebSocketLibrary:\'lua-resty-web-socket-library\',LuaUpstreamNginxModule:\'lua-upstream-nginx-module\',MemcNginxModule:\'memc-nginx-module\',Nginx:\'nginx\',NginxDevelKit:\'nginx-devel-kit\',OpenResty:\'openresty\',PostgresNginxModule:\'postgres-nginx-module\',Presentations:\'presentations\',Profiling:\'profiling\',ProxyNginxModule:\'proxy-nginx-module\',QualityAssurance:\'quality-assurance\',RSSFeed:\'rss-feed\',RdsCsvNginxModule:\'rds-csv-nginx-module\',RdsJsonNginxModule:\'rds-json-nginx-module\',Redis2NginxModule:\'redis-2-nginx-module\',RedisNginxModule:\'redis-nginx-module\',ReleaseNote:\'release-note\',Resources:\'resources\',RestyCLI:\'resty-cli\',RoutingMySQLQueriesBasedOnURIArgs:\'routing-mysql-queries-based-on-uri-args\',Samples:\'samples\',SetMiscNginxModule:\'set-misc-nginx-module\',SrcacheNginxModule:\'srcache-nginx-module\',StandardLuaInterpreter:\'standard-lua-interpreter\',Upgrading:\'upgrading\',UpstreamKeepaliveNginxModule:\'upstream-keepalive-nginx-module\',UsingLuaRocks:\'using-luarocks\',XssNginxModule:\'xss-nginx-module\',eBooks:\'ebooks\',libdrizzle:\'libdrizzle\'};\n    var hash = window.location.hash;\n    var key = hash.substring(1, hash.length);\n    //alert(key)\n    var file = permlinks[key];\n    if (file) {\n        window.location.hash = "";\n        window.location = window.location.pathname + file + ".html";\n    }\n})();\n'

    return output
end

-- page.tt2
template_map['page.tt2'] = function (context)
    if not context then
        return error("Lemplate function called without context\n")
    end
    local stash = context.stash
    local output = {}
    local i = 0

i = i + 1 output[i] = '<!DOCTYPE html>\n<html lang="en">\n<head>\n	<meta charset="utf-8">\n	<title>OpenResty - '
-- line 5 "page.tt2"
i = i + 1 output[i] = stash_get(stash, 'title')
i = i + 1 output[i] = '</title>\n    <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=0.5, maximum-scale=2.0, user-scalable=yes">\n	<link href=\'https://openresty.org/css/fonts.css\' rel=\'stylesheet\' type=\'text/css\'>\n	<!--\n	If you ever wanted to use LESS instead of CSS...\n	<link rel="stylesheet" type="text/less" href="/css/main.less">\n	<script src="/js/less.js"></script>\n	-->\n	<link rel="stylesheet" type="text/css" href="/css/main.css">\n	<link rel="stylesheet" type="text/css" href="/css/github.css">\n	<link rel="stylesheet" type="text/css" href="/css/jquery.modal.css">\n</head>\n<body>\n\n'
-- line 19 "page.tt2"
i = i + 1 output[i] = context.process(context, 'header.tt2')
i = i + 1 output[i] = '\n\n'
-- line 21 "page.tt2"
i = i + 1 output[i] = context.process(context, 'xray-modal.tt2')
i = i + 1 output[i] = '\n\n	<div id="wrapper">\n		<div class="sidebar sleft">\n			<nav id="nav">\n'
-- line 26 "page.tt2"
i = i + 1 output[i] = stash_get(stash, 'main_menu')
i = i + 1 output[i] = '\n			</nav><!-- / nav -->\n\n'
-- line 29 "page.tt2"
i = i + 1 output[i] = context.process(context, 'main-menu-buttons.tt2')
i = i + 1 output[i] = '\n\n		</div><!-- / sidebar left -->\n\n		<section id="main">\n'
-- line 35 "page.tt2"
if tt2_true(stash_get(stash, 'lang') == 'cn') then
-- line 35 "page.tt2"
i = i + 1 output[i] = context.process(context, 'news-cn.tt2')
else
-- line 35 "page.tt2"
i = i + 1 output[i] = context.process(context, 'news-en.tt2')
end


i = i + 1 output[i] = '\n\n'
-- line 42 "page.tt2"
i = i + 1 output[i] = context.process(context, 'post.tt2')
i = i + 1 output[i] = '\n'
-- line 44 "page.tt2"
if tt2_true(stash_get(stash, 'lang') == 'cn') then
-- line 44 "page.tt2"
i = i + 1 output[i] = context.process(context, 'posts-slide-cn.tt2')
else
-- line 44 "page.tt2"
i = i + 1 output[i] = context.process(context, 'posts-slide-en.tt2')
end


i = i + 1 output[i] = '\n		</section><!-- / main -->\n\n'
-- line 52 "page.tt2"
i = i + 1 output[i] = context.process(context, 'sidebar.tt2')
i = i + 1 output[i] = '\n	</div><!-- / wrapper -->\n\n'
-- line 55 "page.tt2"
i = i + 1 output[i] = context.process(context, 'footer.tt2')
i = i + 1 output[i] = '\n\n</body>\n</html>\n'

    return output
end

-- post.tt2
template_map['post.tt2'] = function (context)
    if not context then
        return error("Lemplate function called without context\n")
    end
    local stash = context.stash
    local output = {}
    local i = 0

i = i + 1 output[i] = '<div class="item">\n        <header>\n                <h2>'
-- line 3 "post.tt2"

-- FILTER
local value
do
    local output = {}
    local i = 0

i = i + 1 output[i] = stash_get(stash, 'title')

    value = context.filter(output, 'html', {})
end
i = i + 1 output[i] = value

i = i + 1 output[i] = '</h2>'
-- line 10 "post.tt2"
if tt2_true(tt2_not(stash_get(stash, 'skip_meta'))) then
i = i + 1 output[i] = '\n                <small>\n                    '
-- line 6 "post.tt2"
if tt2_true(stash_get(stash, 'modifier_link')) then
i = i + 1 output[i] = '<a href="'
-- line 6 "post.tt2"
i = i + 1 output[i] = stash_get(stash, 'modifier_link')
i = i + 1 output[i] = '.html">'
end

i = i + 1 output[i] = '\n                    '
-- line 7 "post.tt2"

-- FILTER
local value
do
    local output = {}
    local i = 0

i = i + 1 output[i] = stash_get(stash, 'modifier')

    value = context.filter(output, 'html', {})
end
i = i + 1 output[i] = value

i = i + 1 output[i] = '\n                    '
-- line 8 "post.tt2"
if tt2_true(stash_get(stash, 'modifier_link')) then
i = i + 1 output[i] = '</a>'
end

i = i + 1 output[i] = ',\n                    '
-- line 9 "post.tt2"

-- FILTER
local value
do
    local output = {}
    local i = 0

i = i + 1 output[i] = stash_get(stash, 'modified')

    value = context.filter(output, 'html', {})
end
i = i + 1 output[i] = value

i = i + 1 output[i] = ' (created '
-- line 9 "post.tt2"

-- FILTER
local value
do
    local output = {}
    local i = 0

i = i + 1 output[i] = stash_get(stash, 'created')

    value = context.filter(output, 'html', {})
end
i = i + 1 output[i] = value

i = i + 1 output[i] = ')</small>'
end

i = i + 1 output[i] = '\n                <div class="options">\n                        <!--\n                        <a href="#" class="trigger">Show Options</a>\n                        <ul class="first-level">\n                                <li><a href="#">close</a></li>\n                                <li><a href="#">close others</a></li>\n                                <li><a href="#">view</a></li>\n                                <li><a href="#">fields</a></li>\n                                <li><a href="#">syncing</a></li>\n                                <li><a href="#">permalink</a></li>\n                                <li><a href="#">references</a></li>\n                                <li>\n                                        <a href="#">jump</a>\n                                        <ul class="second-level">\n                                                <li><a href="#">Benchmark</a></li>\n                                                <li><a href="#">Presentations</a></li>\n                                                <li><a href="#">eBooks</a></li>\n                                        </ul>\n                                </li>\n                        </ul>\n                        -->\n                </div><!-- / options -->\n        </header>\n        <div class="body">\n'
-- line 35 "post.tt2"
i = i + 1 output[i] = stash_get(stash, 'body')
i = i + 1 output[i] = '\n        </div><!-- / body -->\n</div><!-- / item -->\n'

    return output
end

-- posts-slide-cn.tt2
template_map['posts-slide-cn.tt2'] = function (context)
    if not context then
        return error("Lemplate function called without context\n")
    end
    local stash = context.stash
    local output = {}
    local i = 0

i = i + 1 output[i] = '\n<div id="articles">\n  <h2 class="area-title">'
-- line 3 "posts-slide-cn.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'More Interesting Topics' }})
i = i + 1 output[i] = '</h2>\n  <div id="loading-wrapper">\n    <div class="sk-three-bounce">\n      <div class="sk-child sk-bounce1"></div>\n      <div class="sk-child sk-bounce2"></div>\n      <div class="sk-child sk-bounce3"></div>\n    </div>\n  </div>\n  <div class="swiper-parent" id="swiper-parent">\n    <div class="swiper-container" id="article-carousel">\n      <div class="swiper-wrapper">\n        <div class="swiper-slide"><a class="article-item" href="https://blog.openresty.com.cn/cn/xray-llvm-optimal/?src=org" data-modal="data-modal">\n            <div class="blog-img" data-pic="/header-images/xray-LLVM-optimal.jpg"><img class="article-img" src="../images/header-images/xray-LLVM-optimal.jpg" loading="lazy"/></div>\n            <div class="article-text">\n              <p class="blog-title">OpenResty XRay 助力 LLVM clang 性能优化实践</p>\n            </div></a></div>\n        <div class="swiper-slide"><a class="article-item" href="https://blog.openresty.com.cn/cn/xray-self-optimal/?src=org" data-modal="data-modal">\n            <div class="blog-img" data-pic="/header-images/xray-self-optimal.jpg"><img class="article-img" src="../images/header-images/xray-self-optimal.jpg" loading="lazy"/></div>\n            <div class="article-text">\n              <p class="blog-title">自我优化：OpenResty XRay 的性能蜕变</p>\n            </div></a></div>\n        <div class="swiper-slide"><a class="article-item" href="https://blog.openresty.com.cn/cn/xray-script-optimal/?src=org" data-modal="data-modal">\n            <div class="blog-img" data-pic="/header-images/xray-script-optimal.jpg"><img class="article-img" src="../images/header-images/xray-script-optimal.jpg" loading="lazy"/></div>\n            <div class="article-text">\n              <p class="blog-title">OpenResty XRay 助力脚本性能提升 44 倍</p>\n            </div></a></div>\n        <div class="swiper-slide"><a class="article-item" href="https://blog.openresty.com.cn/cn/xray-data-drift-optimal/?src=org" data-modal="data-modal">\n            <div class="blog-img" data-pic="/header-images/xray-data-drift-optimal.jpg"><img class="article-img" src="../images/header-images/xray-data-drift-optimal.jpg" loading="lazy"/></div>\n            <div class="article-text">\n              <p class="blog-title">跨介质数据结构漂移：OpenResty XRay 助力性能提升 20 倍</p>\n            </div></a></div>\n        <div class="swiper-slide"><a class="article-item" href="https://blog.openresty.com.cn/cn/xray-oom-optimal/?src=org" data-modal="data-modal">\n            <div class="blog-img" data-pic="/header-images/xray-oom-optimal.jpg"><img class="article-img" src="../images/header-images/xray-oom-optimal.jpg" loading="lazy"/></div>\n            <div class="article-text">\n              <p class="blog-title">从 OOM 到 O(1)：OpenResty 流式 JSON 解析器的实现之道</p>\n            </div></a></div>\n        <div class="swiper-slide"><a class="article-item" href="https://blog.openresty.com.cn/cn/xray-shred-optimal/?src=org" data-modal="data-modal">\n            <div class="blog-img" data-pic="/header-images/xray-shred-optimal.jpg"><img class="article-img" src="../images/header-images/xray-shred-optimal.jpg" loading="lazy"/></div>\n            <div class="article-text">\n              <p class="blog-title">从数天到数小时：OpenResty XRay 如何让 Linux shred 工具提速几十倍</p>\n            </div></a></div>\n        <div class="swiper-slide"><a class="article-item" href="https://blog.openresty.com.cn/cn/xray-ylang-analyzer-optimal/?src=org" data-modal="data-modal">\n            <div class="blog-img" data-pic="/header-images/xray-ylang-analyzer-optimal.jpg"><img class="article-img" src="../images/header-images/xray-ylang-analyzer-optimal.jpg" loading="lazy"/></div>\n            <div class="article-text">\n              <p class="blog-title">实战分享：OpenResty XRay 让 Ylang 编译器性能翻倍</p>\n            </div></a></div>\n        <div class="swiper-slide"><a class="article-item" href="https://blog.openresty.com.cn/cn/java-req-latency-analysis/?src=org" data-modal="data-modal">\n            <div class="blog-img" data-pic="/header-images/java-req-latency-analysis.jpg"><img class="article-img" src="../images/header-images/java-req-latency-analysis.jpg" loading="lazy"/></div>\n            <div class="article-text">\n              <p class="blog-title">分析 Tomcat Java Web 应用请求延时（使用 OpenResty XRay）</p>\n            </div></a></div>\n        <div class="swiper-slide"><a class="article-item" href="https://blog.openresty.com.cn/cn/java-analysis/?src=org" data-modal="data-modal">\n            <div class="blog-img" data-pic="/header-images/java-analysis.jpg"><img class="article-img" src="../images/header-images/java-analysis.jpg" loading="lazy"/></div>\n            <div class="article-text">\n              <p class="blog-title">分析线上 Java 应用的 CPU，off-CPU 和硬盘 IO 使用情况（使用 OpenResty XRay）</p>\n            </div></a></div>\n        <div class="swiper-slide"><a class="article-item" href="https://blog.openresty.com.cn/cn/xray-web-console/?src=org" data-modal="data-modal">\n            <div class="blog-img" data-pic="/header-images/cn-xray-web-console.jpg"><img class="article-img" src="../images/header-images/cn-xray-web-console.jpg" loading="lazy"/></div>\n            <div class="article-text">\n              <p class="blog-title">OpenResty XRay 的 Web 控制台快速导览</p>\n            </div></a></div>\n        <div class="swiper-slide"><a class="article-item" href="https://blog.openresty.com.cn/cn/python-high-disk/?src=org" data-modal="data-modal">\n            <div class="blog-img" data-pic="/header-images/cn-python-high-disk.jpg"><img class="article-img" src="../images/header-images/cn-python-high-disk.jpg" loading="lazy"/></div>\n            <div class="article-text">\n              <p class="blog-title">线上快速定位硬盘 I/O 高的 Python 代码路径（使用 OpenResty XRay）</p>\n            </div></a></div>\n        <div class="swiper-slide"><a class="article-item" href="https://blog.openresty.com.cn/cn/php-exceptions/?src=org" data-modal="data-modal">\n            <div class="blog-img" data-pic="/header-images/cn-php-exceptions.jpg"><img class="article-img" src="../images/header-images/cn-php-exceptions.jpg" loading="lazy"/></div>\n            <div class="article-text">\n              <p class="blog-title">线上监控 PHP 应用中的程序异常（使用 OpenResty XRay）</p>\n            </div></a></div>\n        <div class="swiper-slide"><a class="article-item" href="https://blog.openresty.com.cn/cn/xray-agent-install-k8s/?src=org" data-modal="data-modal">\n            <div class="blog-img" data-pic="/header-images/cn-xray-agent-install-k8s.jpg"><img class="article-img" src="../images/header-images/cn-xray-agent-install-k8s.jpg" loading="lazy"/></div>\n            <div class="article-text">\n              <p class="blog-title">在 Kubernetes 集群上安裝 OpenResty XRay 的 Agent</p>\n            </div></a></div>\n        <div class="swiper-slide"><a class="article-item" href="https://blog.openresty.com.cn/cn/edge-k8s-autoapprove/?src=org" data-modal="data-modal">\n            <div class="blog-img" data-pic="/header-images/cn-edge-k8s-autoapprove.jpg"><img class="article-img" src="../images/header-images/cn-edge-k8s-autoapprove.jpg" loading="lazy"/></div>\n            <div class="article-text">\n              <p class="blog-title">如何在 OpenResty Edge 中实现 Kubernetes 环境下网关服务器的自动管理</p>\n            </div></a></div>\n        <div class="swiper-slide"><a class="article-item" href="https://blog.openresty.com.cn/cn/edge-lua-ext/?src=org" data-modal="data-modal">\n            <div class="blog-img" data-pic="/header-images/cn-edge-lua-ext.jpg"><img class="article-img" src="../images/header-images/cn-edge-lua-ext.jpg" loading="lazy"/></div>\n            <div class="article-text">\n              <p class="blog-title">在 OpenResty Edge 中使用 Lua 扩展响应网关服务器离线事件</p>\n            </div></a></div>\n        <div class="swiper-slide"><a class="article-item" href="https://blog.openresty.com.cn/cn/rust-high-disk/?src=org" data-modal="data-modal">\n            <div class="blog-img" data-pic="/header-images/cn-rust-high-disk.jpg"><img class="article-img" src="../images/header-images/cn-rust-high-disk.jpg" loading="lazy"/></div>\n            <div class="article-text">\n              <p class="blog-title">线上快速定位硬盘 I/O 高的 Rust 代码路径（使用 OpenResty XRay）</p>\n            </div></a></div>\n        <div class="swiper-slide"><a class="article-item" href="https://blog.openresty.com.cn/cn/xray-mobile-apps/?src=org" data-modal="data-modal">\n            <div class="blog-img" data-pic="/header-images/xray-mobile-apps-cn.jpg"><img class="article-img" src="../images/header-images/xray-mobile-apps-cn.jpg" loading="lazy"/></div>\n            <div class="article-text">\n              <p class="blog-title">OpenResty XRay 移动端应用介绍</p>\n            </div></a></div>\n        <div class="swiper-slide"><a class="article-item" href="https://blog.openresty.com.cn/cn/php-high-mem/?src=org" data-modal="data-modal">\n            <div class="blog-img" data-pic="/header-images/cn-php-high-mem.jpg"><img class="article-img" src="../images/header-images/cn-php-high-mem.jpg" loading="lazy"/></div>\n            <div class="article-text">\n              <p class="blog-title">线上定位 PHP 进程中的大内存对象（使用 OpenResty XRay）</p>\n            </div></a></div>\n        <div class="swiper-slide"><a class="article-item" href="https://blog.openresty.com.cn/cn/edge-gateway-healthcheck/?src=org" data-modal="data-modal">\n            <div class="blog-img" data-pic="/header-images/cn-edge-gateway-healthcheck.jpg"><img class="article-img" src="../images/header-images/cn-edge-gateway-healthcheck.jpg" loading="lazy"/></div>\n            <div class="article-text">\n              <p class="blog-title">在 OpenResty Edge 中启用网关服务器的自动健康检查</p>\n            </div></a></div>\n        <div class="swiper-slide"><a class="article-item" href="https://blog.openresty.com.cn/cn/edge-gateway-partition/?src=org" data-modal="data-modal">\n            <div class="blog-img" data-pic="/header-images/edge-gateway-partition-cn.jpg"><img class="article-img" src="../images/header-images/edge-gateway-partition-cn.jpg" loading="lazy"/></div>\n            <div class="article-text">\n              <p class="blog-title">如何使用 OpenResty Edge 中的网关分区</p>\n            </div></a></div>\n      </div>\n      <div class="swiper-pagination"></div>\n    </div>\n    <div class="swiper-button-next"></div>\n    <div class="swiper-button-prev"></div>\n  </div>\n</div>\n<div class="modal" id="blog-modal">\n  <iframe class="blog-iframe" id="blog-iframe"></iframe>\n</div>\n<link rel="stylesheet" href="https://static.openresty.com.cn/swiper/5.2.1/css/swiper.min.css"/>\n<script src="https://static.openresty.com.cn/swiper/5.2.1/js/swiper.min.js"></script>\n<script>\n  window.onload = function () {\n    setMaxWidth();\n  \n    document.getElementById(\'swiper-parent\').style.display = \'block\';\n    document.getElementById(\'loading-wrapper\').style.display = \'none\';\n  \n    const swiper = new Swiper(\'#article-carousel\', {\n      navigation: {\n        nextEl: \'.swiper-button-next\',\n        prevEl: \'.swiper-button-prev\',\n      },\n      pagination: {\n        el: \'.swiper-pagination\',\n        clickable: true,\n      },\n      spaceBetween: 32,\n      breakpoints: {\n        320: {\n          slidesPerView: 1,\n          slidesPerGroup: 1,\n        },\n        1000: {\n          slidesPerView: 2,\n          slidesPerGroup: 2,\n        },\n        1300: {\n          slidesPerView: 3,\n          slidesPerGroup: 3,\n        },\n        1600: {\n          slidesPerView: 4,\n          slidesPerGroup: 4,\n        },\n        1800: {\n          slidesPerView: 5,\n          slidesPerGroup: 5,\n        },\n        2000: {\n          slidesPerView: 6,\n          slidesPerGroup: 6,\n        },\n        2200: {\n          slidesPerView: 7,\n          slidesPerGroup: 7,\n        },\n      }\n    });\n  }\n  \n  window.addEventListener(\'resize\', function() {\n    setMaxWidth();\n  });\n  \n  function setMaxWidth() {\n    const width = document.body.clientWidth > 990 ? document.body.clientWidth - 600 : document.body.clientWidth - 40;\n    document.getElementById(\'articles\').style.setProperty(\'max-width\', width + \'px\', \'important\');\n  }\n  \n</script>\n<style>\n  #article-carousel {\n      width: 100%;\n    }\n  \n    #article-carousel .article-item {\n      text-align: center;\n      outline: none;\n      color: #a1a1a1;\n      vertical-align: top;\n    }\n  \n    #article-carousel .article-item .article-img {\n      width: 100%;\n      height: 130px;\n    }\n  \n    #article-carousel .article-item .article_text {\n      margin-top: 8px;\n    }\n  \n    .swiper-pagination-bullet {\n      width: 10px;\n      height: 10px;\n    }\n  \n    .swiper-pagination-bullet-active {\n      background-color: #497149;\n    }\n  \n    .swiper-parent {\n      display: none;\n      position: relative;\n      padding-left: 70px;\n      padding-right: 70px;\n      margin: 0 auto;\n    }\n  \n    .swiper-button-next:after,\n    .swiper-button-prev:after {\n      font-size: 32px;\n    }\n  \n    .swiper-button-next:focus,\n    .swiper-button-prev:focus {\n      outline: none;\n    }\n  \n    .swiper-wrapper {\n      min-height: 290px;\n    }\n  \n    .blog-title {\n      min-height: 50px;\n    }\n  \n    @media (min-width: 575px) {\n      .swiper-container-horizontal>.swiper-pagination-bullets .swiper-pagination-bullet {\n        margin: 0 10px;\n      }\n    }\n  \n    @media (max-width: 575px) {\n      .swiper-wrapper {\n        min-height: 240px;\n      }\n    }\n  \n    #article-carousel .article-item {\n      height: 290px;\n    }\n  \n    .img-container {\n      padding: 0 5px;\n      border: 1px solid #578C57;\n    }\n  \n    #articles {\n      margin: 0 auto;\n    }\n  \n    #articles h2 {\n      color: black;\n      text-align: center;\n      margin-bottom: 36px;\n      font-weight: bold;\n      font-size: 120%;\n    }\n  \n    .article-text {\n      color: #4d8d89;\n      margin-top: 8px;\n    }\n  \n    .blog-img {\n      object-fit: cover;\n    }\n  \n    .blog-img[data-pic*=hiring] {\n      border: 1px solid #497149;\n    }\n  \n    .blog-img[data-pic*=logo],\n    .blog-img[data-pic*=report] {\n      object-fit: contain;\n      padding: 0 10px;\n      border: 1px solid #497149;\n    }\n  \n    .article-img[src*=logo],\n    .article-img[src*=report] {\n      object-fit: contain;\n    }\n  \n    #loading-wrapper {\n      display: flex;\n      flex-direction: column;\n      justify-content: center;\n      align-items: center;\n      min-height: 260px;\n    }\n  \n    .sk-three-bounce {\n      margin: 40px auto;\n      width: 80px;\n      text-align: center;\n      transform: scale(.75);\n    }\n  \n    .sk-three-bounce .sk-child {\n      width: 20px;\n      height: 20px;\n      background-color: #333;\n      border-radius: 100%;\n      display: inline-block;\n      animation: sk-three-bounce 1.4s ease-in-out 0s infinite both;\n    }\n  \n    .sk-three-bounce .sk-bounce1 {\n      animation-delay: -0.32s;\n    }\n  \n    .sk-three-bounce .sk-bounce2 {\n      animation-delay: -0.16s;\n    }\n  \n    .swiper-button-prev,\n    .swiper-button-next {\n      color: #497149;\n    }\n  \n    .article-text:hover {\n      color: #003300;\n    }\n  \n    .swiper-button-next, .swiper-button-prev {\n      top: 30%;\n    }\n  \n    @keyframes sk-three-bounce {\n      0%, 80%, 100% {\n        transform: scale(0);\n      }\n      40% {\n        transform: scale(1)\n      }\n    }\n</style>'

    return output
end

-- posts-slide-en.tt2
template_map['posts-slide-en.tt2'] = function (context)
    if not context then
        return error("Lemplate function called without context\n")
    end
    local stash = context.stash
    local output = {}
    local i = 0

i = i + 1 output[i] = '\n<div id="articles">\n  <h2 class="area-title">'
-- line 3 "posts-slide-en.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'More Interesting Topics' }})
i = i + 1 output[i] = '</h2>\n  <div id="loading-wrapper">\n    <div class="sk-three-bounce">\n      <div class="sk-child sk-bounce1"></div>\n      <div class="sk-child sk-bounce2"></div>\n      <div class="sk-child sk-bounce3"></div>\n    </div>\n  </div>\n  <div class="swiper-parent" id="swiper-parent">\n    <div class="swiper-container" id="article-carousel">\n      <div class="swiper-wrapper">\n        <div class="swiper-slide"><a class="article-item" href="https://blog.openresty.com/en/xray-llvm-optimal/?src=org" data-modal="data-modal">\n            <div class="blog-img" data-pic="/header-images/xray-LLVM-optimal.jpg"><img class="article-img" src="../images/header-images/xray-LLVM-optimal.jpg" loading="lazy"/></div>\n            <div class="article-text">\n              <p class="blog-title">OpenResty XRay Empowers LLVM clang Performance Optimization Practices</p>\n            </div></a></div>\n        <div class="swiper-slide"><a class="article-item" href="https://blog.openresty.com/en/xray-self-optimal/?src=org" data-modal="data-modal">\n            <div class="blog-img" data-pic="/header-images/xray-self-optimal.jpg"><img class="article-img" src="../images/header-images/xray-self-optimal.jpg" loading="lazy"/></div>\n            <div class="article-text">\n              <p class="blog-title">Self-Optimization: The Performance Evolution of OpenResty XRay</p>\n            </div></a></div>\n        <div class="swiper-slide"><a class="article-item" href="https://blog.openresty.com/en/xray-script-optimal/?src=org" data-modal="data-modal">\n            <div class="blog-img" data-pic="/header-images/xray-script-optimal.jpg"><img class="article-img" src="../images/header-images/xray-script-optimal.jpg" loading="lazy"/></div>\n            <div class="article-text">\n              <p class="blog-title">OpenResty XRay Helps Boost Script Performance by 44 Times</p>\n            </div></a></div>\n        <div class="swiper-slide"><a class="article-item" href="https://blog.openresty.com/en/xray-data-drift-optimal/?src=org" data-modal="data-modal">\n            <div class="blog-img" data-pic="/header-images/xray-data-drift-optimal.jpg"><img class="article-img" src="../images/header-images/xray-data-drift-optimal.jpg" loading="lazy"/></div>\n            <div class="article-text">\n              <p class="blog-title">Cross-Media Data Structure Drift: OpenResty XRay Enables 20x Performance Improvement</p>\n            </div></a></div>\n        <div class="swiper-slide"><a class="article-item" href="https://blog.openresty.com/en/xray-oom-optimal/?src=org" data-modal="data-modal">\n            <div class="blog-img" data-pic="/header-images/xray-oom-optimal.jpg"><img class="article-img" src="../images/header-images/xray-oom-optimal.jpg" loading="lazy"/></div>\n            <div class="article-text">\n              <p class="blog-title">From OOM to O(1): The Implementation Path of Streaming JSON Parser</p>\n            </div></a></div>\n        <div class="swiper-slide"><a class="article-item" href="https://blog.openresty.com/en/xray-shred-optimal/?src=org" data-modal="data-modal">\n            <div class="blog-img" data-pic="/header-images/xray-shred-optimal.jpg"><img class="article-img" src="../images/header-images/xray-shred-optimal.jpg" loading="lazy"/></div>\n            <div class="article-text">\n              <p class="blog-title">From Days to Hours: How OpenResty XRay Accelerated the Linux shred Tool by Dozens of Times</p>\n            </div></a></div>\n        <div class="swiper-slide"><a class="article-item" href="https://blog.openresty.com/en/xray-ylang-analyzer-optimal/?src=org" data-modal="data-modal">\n            <div class="blog-img" data-pic="/header-images/xray-ylang-analyzer-optimal.jpg"><img class="article-img" src="../images/header-images/xray-ylang-analyzer-optimal.jpg" loading="lazy"/></div>\n            <div class="article-text">\n              <p class="blog-title">Case Study: OpenResty XRay Doubles Ylang Compiler Performance</p>\n            </div></a></div>\n        <div class="swiper-slide"><a class="article-item" href="https://blog.openresty.com/en/java-req-latency-analysis/?src=org" data-modal="data-modal">\n            <div class="blog-img" data-pic="/header-images/java-req-latency-analysis.jpg"><img class="article-img" src="../images/header-images/java-req-latency-analysis.jpg" loading="lazy"/></div>\n            <div class="article-text">\n              <p class="blog-title">Analyzing Tomcat Java Web Application Request Latency (Using OpenResty XRay)</p>\n            </div></a></div>\n        <div class="swiper-slide"><a class="article-item" href="https://blog.openresty.com/en/java-analysis/?src=org" data-modal="data-modal">\n            <div class="blog-img" data-pic="/header-images/java-analysis.jpg"><img class="article-img" src="../images/header-images/java-analysis.jpg" loading="lazy"/></div>\n            <div class="article-text">\n              <p class="blog-title">Analyzing CPU, off-CPU and Disk I/O Usage of Java Applications (Using OpenResty XRay)</p>\n            </div></a></div>\n        <div class="swiper-slide"><a class="article-item" href="https://blog.openresty.com/en/xray-web-console/?src=org" data-modal="data-modal">\n            <div class="blog-img" data-pic="/header-images/en-xray-web-console.jpg"><img class="article-img" src="../images/header-images/en-xray-web-console.jpg" loading="lazy"/></div>\n            <div class="article-text">\n              <p class="blog-title">A Quick Tour to OpenResty XRay’s Web Console</p>\n            </div></a></div>\n        <div class="swiper-slide"><a class="article-item" href="https://blog.openresty.com/en/python-high-disk/?src=org" data-modal="data-modal">\n            <div class="blog-img" data-pic="/header-images/en-python-high-disk.jpg"><img class="article-img" src="../images/header-images/en-python-high-disk.jpg" loading="lazy"/></div>\n            <div class="article-text">\n              <p class="blog-title">Pinpointing the Python Code Paths with High Disk I/O (using OpenResty XRay)</p>\n            </div></a></div>\n        <div class="swiper-slide"><a class="article-item" href="https://blog.openresty.com/en/php-exceptions/?src=org" data-modal="data-modal">\n            <div class="blog-img" data-pic="/header-images/en-php-exceptions.jpg"><img class="article-img" src="../images/header-images/en-php-exceptions.jpg" loading="lazy"/></div>\n            <div class="article-text">\n              <p class="blog-title">How to Trace Exceptions inside PHP Applications (using OpenResty XRay)</p>\n            </div></a></div>\n        <div class="swiper-slide"><a class="article-item" href="https://blog.openresty.com/en/xray-agent-install-k8s/?src=org" data-modal="data-modal">\n            <div class="blog-img" data-pic="/header-images/en-xray-agent-install-k8s.jpg"><img class="article-img" src="../images/header-images/en-xray-agent-install-k8s.jpg" loading="lazy"/></div>\n            <div class="article-text">\n              <p class="blog-title">Install OpenResty XRay’s Agents on Kubernetes cluster</p>\n            </div></a></div>\n        <div class="swiper-slide"><a class="article-item" href="https://blog.openresty.com/en/edge-k8s-autoapprove/?src=org" data-modal="data-modal">\n            <div class="blog-img" data-pic="/header-images/en-edge-k8s-autoapprove.jpg"><img class="article-img" src="../images/header-images/en-edge-k8s-autoapprove.jpg" loading="lazy"/></div>\n            <div class="article-text">\n              <p class="blog-title">How to Automate Managing Gateway Servers in K8s Environment (using OpenResty Edge)</p>\n            </div></a></div>\n        <div class="swiper-slide"><a class="article-item" href="https://blog.openresty.com/en/edge-lua-ext/?src=org" data-modal="data-modal">\n            <div class="blog-img" data-pic="/header-images/en-edge-lua-ext.jpg"><img class="article-img" src="../images/header-images/en-edge-lua-ext.jpg" loading="lazy"/></div>\n            <div class="article-text">\n              <p class="blog-title">Use Lua Extensions to Respond to Gateway Server Offline Events in OpenResty Edge</p>\n            </div></a></div>\n        <div class="swiper-slide"><a class="article-item" href="https://blog.openresty.com/en/rust-high-disk/?src=org" data-modal="data-modal">\n            <div class="blog-img" data-pic="/header-images/en-rust-high-disk.jpg"><img class="article-img" src="../images/header-images/en-rust-high-disk.jpg" loading="lazy"/></div>\n            <div class="article-text">\n              <p class="blog-title">Pinpointing the Hottest Rust Code Paths with High Disk I/O (using OpenResty XRay)</p>\n            </div></a></div>\n        <div class="swiper-slide"><a class="article-item" href="https://blog.openresty.com/en/xray-mobile-apps/?src=org" data-modal="data-modal">\n            <div class="blog-img" data-pic="/header-images/xray-mobile-app-android-en.jpg"><img class="article-img" src="../images/header-images/xray-mobile-app-android-en.jpg" loading="lazy"/></div>\n            <div class="article-text">\n              <p class="blog-title">Introduction to OpenResty XRay Mobile Apps</p>\n            </div></a></div>\n        <div class="swiper-slide"><a class="article-item" href="https://blog.openresty.com/en/php-high-mem/?src=org" data-modal="data-modal">\n            <div class="blog-img" data-pic="/header-images/en-php-high-mem.jpg"><img class="article-img" src="../images/header-images/en-php-high-mem.jpg" loading="lazy"/></div>\n            <div class="article-text">\n              <p class="blog-title">Locate Large Memory Objects inside PHP Processes (using OpenResty XRay)</p>\n            </div></a></div>\n        <div class="swiper-slide"><a class="article-item" href="https://blog.openresty.com/en/edge-gateway-healthcheck/?src=org" data-modal="data-modal">\n            <div class="blog-img" data-pic="/header-images/en-edge-gateway-healthcheck.jpg"><img class="article-img" src="../images/header-images/en-edge-gateway-healthcheck.jpg" loading="lazy"/></div>\n            <div class="article-text">\n              <p class="blog-title">Enable Automatic Healthcheck for Gateway Servers in OpenResty Edge</p>\n            </div></a></div>\n        <div class="swiper-slide"><a class="article-item" href="https://blog.openresty.com/en/edge-gateway-partition/?src=org" data-modal="data-modal">\n            <div class="blog-img" data-pic="/header-images/edge-gateway-partition-en.jpg"><img class="article-img" src="../images/header-images/edge-gateway-partition-en.jpg" loading="lazy"/></div>\n            <div class="article-text">\n              <p class="blog-title">How to Use Gateway Partitions in OpenResty Edge</p>\n            </div></a></div>\n      </div>\n      <div class="swiper-pagination"></div>\n    </div>\n    <div class="swiper-button-next"></div>\n    <div class="swiper-button-prev"></div>\n  </div>\n</div>\n<div class="modal" id="blog-modal">\n  <iframe class="blog-iframe" id="blog-iframe"></iframe>\n</div>\n<link rel="stylesheet" href="https://static.openresty.com/swiper/5.2.1/css/swiper.min.css"/>\n<script src="https://static.openresty.com/swiper/5.2.1/js/swiper.min.js"></script>\n<script>\n  window.onload = function () {\n    setMaxWidth();\n  \n    document.getElementById(\'swiper-parent\').style.display = \'block\';\n    document.getElementById(\'loading-wrapper\').style.display = \'none\';\n  \n    const swiper = new Swiper(\'#article-carousel\', {\n      navigation: {\n        nextEl: \'.swiper-button-next\',\n        prevEl: \'.swiper-button-prev\',\n      },\n      pagination: {\n        el: \'.swiper-pagination\',\n        clickable: true,\n      },\n      spaceBetween: 32,\n      breakpoints: {\n        320: {\n          slidesPerView: 1,\n          slidesPerGroup: 1,\n        },\n        1000: {\n          slidesPerView: 2,\n          slidesPerGroup: 2,\n        },\n        1300: {\n          slidesPerView: 3,\n          slidesPerGroup: 3,\n        },\n        1600: {\n          slidesPerView: 4,\n          slidesPerGroup: 4,\n        },\n        1800: {\n          slidesPerView: 5,\n          slidesPerGroup: 5,\n        },\n        2000: {\n          slidesPerView: 6,\n          slidesPerGroup: 6,\n        },\n        2200: {\n          slidesPerView: 7,\n          slidesPerGroup: 7,\n        },\n      }\n    });\n  }\n  \n  window.addEventListener(\'resize\', function() {\n    setMaxWidth();\n  });\n  \n  function setMaxWidth() {\n    const width = document.body.clientWidth > 990 ? document.body.clientWidth - 600 : document.body.clientWidth - 40;\n    document.getElementById(\'articles\').style.setProperty(\'max-width\', width + \'px\', \'important\');\n  }\n  \n</script>\n<style>\n  #article-carousel {\n      width: 100%;\n    }\n  \n    #article-carousel .article-item {\n      text-align: center;\n      outline: none;\n      color: #a1a1a1;\n      vertical-align: top;\n    }\n  \n    #article-carousel .article-item .article-img {\n      width: 100%;\n      height: 130px;\n    }\n  \n    #article-carousel .article-item .article_text {\n      margin-top: 8px;\n    }\n  \n    .swiper-pagination-bullet {\n      width: 10px;\n      height: 10px;\n    }\n  \n    .swiper-pagination-bullet-active {\n      background-color: #497149;\n    }\n  \n    .swiper-parent {\n      display: none;\n      position: relative;\n      padding-left: 70px;\n      padding-right: 70px;\n      margin: 0 auto;\n    }\n  \n    .swiper-button-next:after,\n    .swiper-button-prev:after {\n      font-size: 32px;\n    }\n  \n    .swiper-button-next:focus,\n    .swiper-button-prev:focus {\n      outline: none;\n    }\n  \n    .swiper-wrapper {\n      min-height: 290px;\n    }\n  \n    .blog-title {\n      min-height: 50px;\n    }\n  \n    @media (min-width: 575px) {\n      .swiper-container-horizontal>.swiper-pagination-bullets .swiper-pagination-bullet {\n        margin: 0 10px;\n      }\n    }\n  \n    @media (max-width: 575px) {\n      .swiper-wrapper {\n        min-height: 240px;\n      }\n    }\n  \n    #article-carousel .article-item {\n      height: 290px;\n    }\n  \n    .img-container {\n      padding: 0 5px;\n      border: 1px solid #578C57;\n    }\n  \n    #articles {\n      margin: 0 auto;\n    }\n  \n    #articles h2 {\n      color: black;\n      text-align: center;\n      margin-bottom: 36px;\n      font-weight: bold;\n      font-size: 120%;\n    }\n  \n    .article-text {\n      color: #4d8d89;\n      margin-top: 8px;\n    }\n  \n    .blog-img {\n      object-fit: cover;\n    }\n  \n    .blog-img[data-pic*=hiring] {\n      border: 1px solid #497149;\n    }\n  \n    .blog-img[data-pic*=logo],\n    .blog-img[data-pic*=report] {\n      object-fit: contain;\n      padding: 0 10px;\n      border: 1px solid #497149;\n    }\n  \n    .article-img[src*=logo],\n    .article-img[src*=report] {\n      object-fit: contain;\n    }\n  \n    #loading-wrapper {\n      display: flex;\n      flex-direction: column;\n      justify-content: center;\n      align-items: center;\n      min-height: 260px;\n    }\n  \n    .sk-three-bounce {\n      margin: 40px auto;\n      width: 80px;\n      text-align: center;\n      transform: scale(.75);\n    }\n  \n    .sk-three-bounce .sk-child {\n      width: 20px;\n      height: 20px;\n      background-color: #333;\n      border-radius: 100%;\n      display: inline-block;\n      animation: sk-three-bounce 1.4s ease-in-out 0s infinite both;\n    }\n  \n    .sk-three-bounce .sk-bounce1 {\n      animation-delay: -0.32s;\n    }\n  \n    .sk-three-bounce .sk-bounce2 {\n      animation-delay: -0.16s;\n    }\n  \n    .swiper-button-prev,\n    .swiper-button-next {\n      color: #497149;\n    }\n  \n    .article-text:hover {\n      color: #003300;\n    }\n  \n    .swiper-button-next, .swiper-button-prev {\n      top: 30%;\n    }\n  \n    @keyframes sk-three-bounce {\n      0%, 80%, 100% {\n        transform: scale(0);\n      }\n      40% {\n        transform: scale(1)\n      }\n    }\n</style>'

    return output
end

-- search-result.tt2
template_map['search-result.tt2'] = function (context)
    if not context then
        return error("Lemplate function called without context\n")
    end
    local stash = context.stash
    local output = {}
    local i = 0

i = i + 1 output[i] = '<div class="search-result">\n'
-- line 7 "search-result.tt2"

-- FOREACH
do
    local list = stash_get(stash, 'hits')
    local iterator
    if list.list then
        iterator = list
        list = list.list
    end
    local oldloop = stash_get(stash, 'loop')
    local count
    if not iterator then
        count = table_maxn(list)
        iterator = { count = 1, max = count - 1, index = 0, size = count, first = true, last = false, prev = "" }
    else
        count = iterator.size
    end
    stash.loop = iterator
    for idx, value in ipairs(list) do
        if idx == count then
            iterator.last = true
        end
        iterator.index = idx - 1
        iterator.count = idx
        iterator.next = list[idx + 1]
        stash['hit'] = value
i = i + 1 output[i] = '\n<h2><a href="'
-- line 3 "search-result.tt2"
i = i + 1 output[i] = stash_get(stash, {'hit', 0, 'permlink', 0})
i = i + 1 output[i] = '.html">'
-- line 3 "search-result.tt2"
i = i + 1 output[i] = stash_get(stash, {'hit', 0, 'title', 0})
i = i + 1 output[i] = '</a></h2>\n<div class="r">\n'
-- line 5 "search-result.tt2"
i = i + 1 output[i] = stash_get(stash, {'hit', 0, 'body', 0})
i = i + 1 output[i] = '\n</div>\n'
        iterator.first = false
        iterator.prev = value
    end
    stash_set(stash, 'loop', oldloop)
end

i = i + 1 output[i] = '\n</div>\n'

    return output
end

-- sidebar.tt2
template_map['sidebar.tt2'] = function (context)
    if not context then
        return error("Lemplate function called without context\n")
    end
    local stash = context.stash
    local output = {}
    local i = 0

i = i + 1 output[i] = '<div class="sidebar sright">\n        <div class="options">\n                <!--\n                <ul class="first">\n                        <li><a href="#" class="close-all">close all</a></li>\n                        <li><a href="#" class="permaview">permaview</a></li>\n                        <li><a href="#" class="more-options">options</a></li>\n                </ul> --><!-- / first -->\n        </div><!-- options -->\n\n        <div class="tabs">\n                <ul class="navigation">\n                        <!--\n                        <li><a href="#" class="current">Timeline</a></li>\n                        <li><a href="#">All</a></li>\n                        <li><a href="#">Tags</a></li>\n                        <li><a href="#">More</a></li>\n                        -->\n                        <li><span>'
-- line 19 "sidebar.tt2"
i = i + 1 output[i] = stash_get(stash, {'c', 0, 'l', { 'Timeline' }})
i = i + 1 output[i] = '</span></li>\n                </ul><!-- / navigation -->\n                <div class="panes">\n                        <div class="pane" id="timeline">\n                                <ul>'
-- line 24 "sidebar.tt2"
stash_set(stash, 'prev_day', '');
-- line 37 "sidebar.tt2"

-- FOREACH
do
    local list = stash_get(stash, 'timeline')
    local iterator
    if list.list then
        iterator = list
        list = list.list
    end
    local oldloop = stash_get(stash, 'loop')
    local count
    if not iterator then
        count = table_maxn(list)
        iterator = { count = 1, max = count - 1, index = 0, size = count, first = true, last = false, prev = "" }
    else
        count = iterator.size
    end
    stash.loop = iterator
    for idx, value in ipairs(list) do
        if idx == count then
            iterator.last = true
        end
        iterator.index = idx - 1
        iterator.count = idx
        iterator.next = list[idx + 1]
        stash['row'] = value
-- line 35 "sidebar.tt2"
if tt2_true(stash_get(stash, {'row', 0, 'day', 0}) ~= stash_get(stash, 'prev_day')) then
-- line 30 "sidebar.tt2"
if tt2_true(stash_get(stash, 'prev_day') ~= '') then
i = i + 1 output[i] = '\n                                            </ul>\n                                    </li>'
end

-- line 31 "sidebar.tt2"
stash_set(stash, 'prev_day', stash_get(stash, {'row', 0, 'day', 0}));
i = i + 1 output[i] = '\n                                    <li>\n                                            <h3>'
-- line 33 "sidebar.tt2"
i = i + 1 output[i] = stash_get(stash, {'row', 0, 'day', 0})
i = i + 1 output[i] = '</h3>\n                                            <ul>'
end

i = i + 1 output[i] = '\n                                                <li><a href="'
-- line 36 "sidebar.tt2"
i = i + 1 output[i] = stash_get(stash, {'row', 0, 'permlink', 0})
i = i + 1 output[i] = '.html">'
-- line 36 "sidebar.tt2"
i = i + 1 output[i] = stash_get(stash, {'row', 0, 'title', 0})
i = i + 1 output[i] = '</a></li>'
        iterator.first = false
        iterator.prev = value
    end
    stash_set(stash, 'loop', oldloop)
end

i = i + 1 output[i] = '\n                                            </ul>\n                                    </li>\n                                </ul>\n                        </div><!-- / pane -->\n                </div><!-- / panes -->\n        </div><!-- / tabs -->\n</div><!-- / sidebar right -->\n'

    return output
end

-- videos-cn.tt2
template_map['videos-cn.tt2'] = function (context)
    if not context then
        return error("Lemplate function called without context\n")
    end
    local stash = context.stash
    local output = {}
    local i = 0

i = i + 1 output[i] = '\n<div id="video-tutorials">\n  <div class="play-list">\n    <h2><a href="#157633" style="cursor: pointer">OpenResty 教程</a></h2>\n    <ul>\n      <li><a href="#BV1DV411v7Uj" style="cursor: pointer">通过 apt-get 在 Ubuntu 20.04 上安装 OpenResty</a></li>\n      <li><a href="#BV1bh411C7qt" style="cursor: pointer">在 OpenResty 中流式传输 HTTP 响应输出</a></li>\n      <li><a href="#BV1KA411s7D5" style="cursor: pointer">预编译 Lua 模块到 LuaJIT 字节码以提高 OpenResty 的启动速度</a></li>\n      <li><a href="#BV1RA411W7AU" style="cursor: pointer">在 OpenResty 中测量 Lua 代码执行时间的正确方法</a></li>\n      <li><a href="#BV1sK4y177xi" style="cursor: pointer">在终端上用 restydoc 查看 OpenResty 文档</a></li>\n      <li><a href="#BV1aA411x7fK" style="cursor: pointer">在 OpenResty 中跨请求共享数据</a></li>\n      <li><a href="#BV1aZ4y1G73x" style="cursor: pointer">通过 dnf 在 CentOS 8 上安装 OpenResty</a></li>\n      <li><a href="#BV1aK411V7yV" style="cursor: pointer">OpenResty 的 resty 命令行工具演示</a></li>\n      <li><a href="#BV1k54y1z7L5" style="cursor: pointer">为 OpenResty 应用编写你自己的 Lua 模块</a></li>\n      <li><a href="#BV12i4y1L7As" style="cursor: pointer">OpenResty 实现的“你好世界”HTTP示例</a></li>\n    </ul>\n  </div>\n  <div class="play-list">\n    <h2><a href="#176504" style="cursor: pointer">OpenResty Edge</a></h2>\n    <ul>\n      <li><a href="#BV1Lb4y1h7Tk" style="cursor: pointer">网关配置的版本控制和发布管理（OpenResty Edge）</a></li>\n      <li><a href="#BV1i34y1S7xG" style="cursor: pointer">在 OpenResty Edge 中为上游请求设置不同的 Host 请求头</a></li>\n      <li><a href="#BV1Sy4y1G78N" style="cursor: pointer">根据客户端的语言设置重定向到不同的 URI（OpenResty Edge）</a></li>\n      <li><a href="#BV1bv411H7Rb" style="cursor: pointer">通过 OpenResty Edge 在网站中强制使用 SSL</a></li>\n      <li><a href="#BV1ZK4y1u7nC" style="cursor: pointer">在 OpenResty Edge 中通过 Let\'s Encrypt 签发免费的 SSL 证书</a></li>\n      <li><a href="#BV1eh411Y7Du" style="cursor: pointer">在 OpenResty Edge 中为 HTTPS 网站上传 SSL 证书</a></li>\n      <li><a href="#BV155411c7Mt" style="cursor: pointer">在 OpenResty Edge 中实时清除 HTTP 缓存</a></li>\n      <li><a href="#BV1Gi4y1N7tg" style="cursor: pointer">（中文解说）使用 OpenResty Edge 配置一个最简单的反向代理和负载均衡器</a></li>\n      <li><a href="#BV1t5411A7Yx" style="cursor: pointer">在 OpenResty Edge 中启用 HTTP 缓存</a></li>\n      <li><a href="#BV1H64y1D7ZT" style="cursor: pointer">使用 OpenResty Edge 配置一个最简单的反向代理和负载均衡器</a></li>\n    </ul>\n  </div>\n  <div class="play-list">\n    <h2><a href="#170325" style="cursor: pointer">OpenResty Showman</a></h2>\n    <ul>\n      <li><a href="#BV1444y147HN" style="cursor: pointer">OpenResty Showman 生成的谷歌搜索的样例视频</a></li>\n      <li><a href="#BV1cL41147h4" style="cursor: pointer">如何从剧本文档自动生成演示谷歌搜索的视频（使用 OpenResty Showman）</a></li>\n      <li><a href="#BV1mU4y1E7EY" style="cursor: pointer">OpenResty Showman 生成的百度搜索的样例视频</a></li>\n      <li><a href="#BV1Gf4y1N7XD" style="cursor: pointer">让机器从电影剧本自动生成百度搜索的演示视频（使用 OpenResty Showman）</a></li>\n      <li><a href="#BV1Y541177rW" style="cursor: pointer">我们如何从剧本文件自动生成视频</a></li>\n    </ul>\n  </div>\n  <h2 id="157633">OpenResty 教程</h2>\n  <p id="BV1DV411v7Uj">通过 apt-get 在 Ubuntu 20.04 上安装 OpenResty</p>\n  <iframe width="645" height="360" src="https://player.bilibili.com/player.html?aid=417064545&amp;bvid=BV1DV411v7Uj&amp;cid=308675356&amp;page=1" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="BV1bh411C7qt">在 OpenResty 中流式传输 HTTP 响应输出</p>\n  <iframe width="645" height="360" src="https://player.bilibili.com/player.html?aid=204058488&amp;bvid=BV1bh411C7qt&amp;cid=295192619&amp;page=1" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="BV1KA411s7D5">预编译 Lua 模块到 LuaJIT 字节码以提高 OpenResty 的启动速度</p>\n  <iframe width="645" height="360" src="https://player.bilibili.com/player.html?aid=330604843&amp;bvid=BV1KA411s7D5&amp;cid=264856934&amp;page=1" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="BV1RA411W7AU">在 OpenResty 中测量 Lua 代码执行时间的正确方法</p>\n  <iframe width="645" height="360" src="https://player.bilibili.com/player.html?aid=330571714&amp;bvid=BV1RA411W7AU&amp;cid=264137480&amp;page=1" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="BV1sK4y177xi">在终端上用 restydoc 查看 OpenResty 文档</p>\n  <iframe width="645" height="360" src="https://player.bilibili.com/player.html?aid=885490510&amp;bvid=BV1sK4y177xi&amp;cid=262279945&amp;page=1" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="BV1aA411x7fK">在 OpenResty 中跨请求共享数据</p>\n  <iframe width="645" height="360" src="https://player.bilibili.com/player.html?aid=330399423&amp;bvid=BV1aA411x7fK&amp;cid=262021966&amp;page=1" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="BV1aZ4y1G73x">通过 dnf 在 CentOS 8 上安装 OpenResty</p>\n  <iframe width="645" height="360" src="https://player.bilibili.com/player.html?aid=372989544&amp;bvid=BV1aZ4y1G73x&amp;cid=261563110&amp;page=1" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="BV1aK411V7yV">OpenResty 的 resty 命令行工具演示</p>\n  <iframe width="645" height="360" src="https://player.bilibili.com/player.html?aid=500379732&amp;bvid=BV1aK411V7yV&amp;cid=261199000&amp;page=1" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="BV1k54y1z7L5">为 OpenResty 应用编写你自己的 Lua 模块</p>\n  <iframe width="645" height="360" src="https://player.bilibili.com/player.html?aid=842847923&amp;bvid=BV1k54y1z7L5&amp;cid=256140688&amp;page=1" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="BV12i4y1L7As">OpenResty 实现的“你好世界”HTTP示例</p>\n  <iframe width="645" height="360" src="https://player.bilibili.com/player.html?aid=542820825&amp;bvid=BV12i4y1L7As&amp;cid=255956255&amp;page=1" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <h2 id="176504">OpenResty Edge</h2>\n  <p id="BV1Lb4y1h7Tk">网关配置的版本控制和发布管理（OpenResty Edge）</p>\n  <iframe width="645" height="360" src="https://player.bilibili.com/player.html?aid=633644144&amp;bvid=BV1Lb4y1h7Tk&amp;cid=427543354&amp;page=1" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="BV1i34y1S7xG">在 OpenResty Edge 中为上游请求设置不同的 Host 请求头</p>\n  <iframe width="645" height="360" src="https://player.bilibili.com/player.html?aid=805585129&amp;bvid=BV1i34y1S7xG&amp;cid=409497323&amp;page=1" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="BV1Sy4y1G78N">根据客户端的语言设置重定向到不同的 URI（OpenResty Edge）</p>\n  <iframe width="645" height="360" src="https://player.bilibili.com/player.html?aid=805265564&amp;bvid=BV1Sy4y1G78N&amp;cid=403548426&amp;page=1" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="BV1bv411H7Rb">通过 OpenResty Edge 在网站中强制使用 SSL</p>\n  <iframe width="645" height="360" src="https://player.bilibili.com/player.html?aid=248928941&amp;bvid=BV1bv411H7Rb&amp;cid=362026184&amp;page=1" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="BV1ZK4y1u7nC">在 OpenResty Edge 中通过 Let\'s Encrypt 签发免费的 SSL 证书</p>\n  <iframe width="645" height="360" src="https://player.bilibili.com/player.html?aid=888794465&amp;bvid=BV1ZK4y1u7nC&amp;cid=359794702&amp;page=1" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="BV1eh411Y7Du">在 OpenResty Edge 中为 HTTPS 网站上传 SSL 证书</p>\n  <iframe width="645" height="360" src="https://player.bilibili.com/player.html?aid=205794940&amp;bvid=BV1eh411Y7Du&amp;cid=344772442&amp;page=1" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="BV155411c7Mt">在 OpenResty Edge 中实时清除 HTTP 缓存</p>\n  <iframe width="645" height="360" src="https://player.bilibili.com/player.html?aid=460066608&amp;bvid=BV155411c7Mt&amp;cid=323477850&amp;page=1" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="BV1Gi4y1N7tg">（中文解说）使用 OpenResty Edge 配置一个最简单的反向代理和负载均衡器</p>\n  <iframe width="645" height="360" src="https://player.bilibili.com/player.html?aid=544956395&amp;bvid=BV1Gi4y1N7tg&amp;cid=321651057&amp;page=1" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="BV1t5411A7Yx">在 OpenResty Edge 中启用 HTTP 缓存</p>\n  <iframe width="645" height="360" src="https://player.bilibili.com/player.html?aid=459973798&amp;bvid=BV1t5411A7Yx&amp;cid=320538601&amp;page=1" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="BV1H64y1D7ZT">使用 OpenResty Edge 配置一个最简单的反向代理和负载均衡器</p>\n  <iframe width="645" height="360" src="https://player.bilibili.com/player.html?aid=757141496&amp;bvid=BV1H64y1D7ZT&amp;cid=320816846&amp;page=1" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <h2 id="170325">OpenResty Showman</h2>\n  <p id="BV1444y147HN">OpenResty Showman 生成的谷歌搜索的样例视频</p>\n  <iframe width="645" height="360" src="https://player.bilibili.com/player.html?aid=975730084&amp;bvid=BV1444y147HN&amp;cid=415381104&amp;page=1" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="BV1cL41147h4">如何从剧本文档自动生成演示谷歌搜索的视频（使用 OpenResty Showman）</p>\n  <iframe width="645" height="360" src="https://player.bilibili.com/player.html?aid=463140305&amp;bvid=BV1cL41147h4&amp;cid=415297323&amp;page=1" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="BV1mU4y1E7EY">OpenResty Showman 生成的百度搜索的样例视频</p>\n  <iframe width="645" height="360" src="https://player.bilibili.com/player.html?aid=675015703&amp;bvid=BV1mU4y1E7EY&amp;cid=396824893&amp;page=1" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="BV1Gf4y1N7XD">让机器从电影剧本自动生成百度搜索的演示视频（使用 OpenResty Showman）</p>\n  <iframe width="645" height="360" src="https://player.bilibili.com/player.html?aid=377599228&amp;bvid=BV1Gf4y1N7XD&amp;cid=395130175&amp;page=1" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="BV1Y541177rW">我们如何从剧本文件自动生成视频</p>\n  <iframe width="645" height="360" src="https://player.bilibili.com/player.html?aid=459052788&amp;bvid=BV1Y541177rW&amp;cid=295649691&amp;page=1" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n</div>'

    return output
end

-- videos-en.tt2
template_map['videos-en.tt2'] = function (context)
    if not context then
        return error("Lemplate function called without context\n")
    end
    local stash = context.stash
    local output = {}
    local i = 0

i = i + 1 output[i] = '\n<div id="video-tutorials">\n  <div class="play-list">\n    <h2><a href="#PLlR4WakbzQp2avbmDrBcvnKBH3w0bcXPZ" style="cursor: pointer">OpenResty XRay</a></h2>\n    <ul>\n      <li><a href="#H1xmZubCmYA" style="cursor: pointer">Quick Tour to OpenResty XRay\'s Web console</a></li>\n      <li><a href="#zAmahYdZil8" style="cursor: pointer">Pinpointing the Hottest Python Code Paths with High Disk I/O (using OpenResty XRay)</a></li>\n      <li><a href="#sKuepewwvgQ" style="cursor: pointer">Install OpenResty XRay\'s Agent on Kubernetes</a></li>\n      <li><a href="#Z_1zY4zXauc" style="cursor: pointer">How to Monitor Exceptions inside PHP Applications (using OpenResty XRay)</a></li>\n      <li><a href="#jjS3ACty7kI" style="cursor: pointer">Pinpointing the Hottest Rust Code Paths with High Disk I/O (using OpenResty XRay)</a></li>\n      <li><a href="#Jd5Rvt2lhMY" style="cursor: pointer">Locate Large Memory Objects inside PHP Processes (using OpenResty XRay)</a></li>\n      <li><a href="#sqB5fGHahYU" style="cursor: pointer">Pinpointing the hottest Erlang code paths with high CPU usage (using OpenResty XRay)</a></li>\n      <li><a href="#3eNlV2lqcOU" style="cursor: pointer">How to Trace Exceptions inside Perl Applications (using OpenResty XRay)</a></li>\n      <li><a href="#swUwT3sEtUI" style="cursor: pointer">Analyze OpenResty/Nginx Applications without Debug Symbols (using OpenResty XRay)</a></li>\n      <li><a href="#N2NSqjgcuJA" style="cursor: pointer">Automatic Core Dump Analysis (using OpenResty XRay)</a></li>\n      <li><a href="#b_6L6ljzm1s" style="cursor: pointer">Pinpointing the Hottest Go Code Paths with High Disk I/O</a></li>\n      <li><a href="#JRoWMVBNoGw" style="cursor: pointer">Install OpenResty XRay’s Agents on Amazon Linux via Package Bundles</a></li>\n      <li><a href="#xBb2T7zK4IE" style="cursor: pointer">Pinpointing the hottest PHP code paths with high CPU usage (using OpenResty XRay)</a></li>\n      <li><a href="#L_Qp2kZPAkY" style="cursor: pointer">How CPU Time is Spent inside Envoy Servers (using OpenResty XRay)</a></li>\n      <li><a href="#pW5hUFVD-d4" style="cursor: pointer">How CPU Time is Spent inside PHP Laravel Apps (using OpenResty XRay)</a></li>\n      <li><a href="#xhoDJMau39E" style="cursor: pointer">Find Blocking Perl Code Paths Holding back CPU Usage (Using OpenResty XRay)</a></li>\n      <li><a href="#n9cCqz0wxn8" style="cursor: pointer">How to Locate Exceptions inside Rust Applications (using OpenResty XRay)</a></li>\n      <li><a href="#3OS7gIfuGig" style="cursor: pointer">Pinpointing CPU-Hottest Go Code Paths Inside Prometheus</a></li>\n      <li><a href="#3ORg4SkYcJg" style="cursor: pointer">How to Diagnose HTTP 504 Timeout Errors using OpenResty XRay</a></li>\n      <li><a href="#T2fe9-AjKEE" style="cursor: pointer">How CPU Time is Spent inside Go’s CockroachDB (using OpenResty XRay)</a></li>\n      <li><a href="#f-LL2P-Gu8c" style="cursor: pointer">Performance Overhead of OpenResty XRay when Tracing Perl Apps</a></li>\n      <li><a href="#pOXXj4u1Oag" style="cursor: pointer">Locate Large Memory Objects inside Perl Processes (using OpenResty XRay)</a></li>\n      <li><a href="#HyrI2p5fE1M" style="cursor: pointer">Install OpenResty XRay’s Agents on Ubuntu via Deb Packages</a></li>\n      <li><a href="#v1Nw_HTtf60" style="cursor: pointer">Performance Impact of OpenResty XRay when Tracing PHP Apps (using OpenResty XRay)</a></li>\n      <li><a href="#HO0N6aLHFiE" style="cursor: pointer">Performance Impact of OpenResty XRay when Tracing Python Apps (using OpenResty XRay)</a></li>\n      <li><a href="#hx8nwGy3FJI" style="cursor: pointer">Performance Overhead of OpenResty XRay when Tracing Go Apps</a></li>\n      <li><a href="#bjmLEtwvIZI" style="cursor: pointer">Performance Impact of OpenResty XRay when Tracing Rust Apps (using OpenResty XRay)</a></li>\n      <li><a href="#WUdzsp9WMcU" style="cursor: pointer">Dynamic-Tracing Custom Go Programs with Custom Ylang Analyzers (using OpenResty XRay)</a></li>\n      <li><a href="#irBruMTl05o" style="cursor: pointer">How Python Django’s Application Uses Memory Internally (Using OpenResty XRay)</a></li>\n      <li><a href="#Odu2tTZyDU0" style="cursor: pointer">How CPU time is spent inside Rust’s sled library (Using OpenResty XRay)</a></li>\n      <li><a href="#7LHVmehTxWc" style="cursor: pointer">How CPU time is spent inside Go\'s etcd server (using OpenResty XRay)</a></li>\n      <li><a href="#ZqmaTXECu78" style="cursor: pointer">Find the largest Python objects or values taking the most RAM (using OpenResty XRay)</a></li>\n      <li><a href="#lM3IJRcCmvc" style="cursor: pointer">Install OpenResty XRay’s Agents on CentOS via RPM Packages</a></li>\n      <li><a href="#dXTCdUb5AGk" style="cursor: pointer">How CPU time is spent inside llama.cpp + LLaMA2 (using OpenResty XRay)</a></li>\n      <li><a href="#yH2OxDTgNNc" style="cursor: pointer">Pinpoint hottest Perl code paths (using OpenResty XRay)</a></li>\n      <li><a href="#zKg6CizGP0Q" style="cursor: pointer">Discover the blocking/sleeping Python code paths (using OpenResty XRay)</a></li>\n      <li><a href="#1R7FsVJbm4s" style="cursor: pointer">Find Blocking Go Code Paths Holding back CPU Usage (Using OpenResty XRay)</a></li>\n      <li><a href="#2fAXn2144lw" style="cursor: pointer">Pinpoint CPU-hottest Go code paths online (using OpenResty XRay)</a></li>\n      <li><a href="#7OkwoBUxbxI" style="cursor: pointer">Locate the hottest Lua code paths in online OpenResty/Nginx servers (using OpenResty XRay)</a></li>\n      <li><a href="#CiftezUPuaI" style="cursor: pointer">Pinpoint leaked Lua tables with OpenResty XRay\'s command-line tools</a></li>\n      <li><a href="#YPUGJBbSwIk" style="cursor: pointer">Real-Time Request Counting against Nginx Processes via YSQL</a></li>\n      <li><a href="#Y53mElQgfpo" style="cursor: pointer">Troubleshoot the extra 200-ms request latency online</a></li>\n      <li><a href="#-asOidukUw8" style="cursor: pointer">How to deploy the on-premises version of OpenResty XRay on Microsoft\'s Azure cloud</a></li>\n    </ul>\n  </div>\n  <div class="play-list">\n    <h2><a href="#PLlR4WakbzQp0iUvHwJeBcG5MKWgGa_ahU" style="cursor: pointer">OpenResty Tutorials</a></h2>\n    <ul>\n      <li><a href="#XxL6Frvv4TM" style="cursor: pointer">Domain-Specific Languages (Implementation Strategies and Technologies)</a></li>\n      <li><a href="#Hu68mQDKXCo" style="cursor: pointer">Install OpenResty on Ubuntu 20.04 via apt-get</a></li>\n      <li><a href="#4VQP7eKq4oA" style="cursor: pointer">Streaming HTTP Response Output in OpenResty</a></li>\n      <li><a href="#EP7c0BM2yNo" style="cursor: pointer">Precompile Lua Modules into LuaJIT Bytecode to Speedup OpenResty Startup</a></li>\n      <li><a href="#VkRYW_qLoME" style="cursor: pointer">Measure Execution Time of Lua Code Correctly in OpenResty</a></li>\n      <li><a href="#_PjpdUEeKeM" style="cursor: pointer">Lookup OpenResty Documentation on Terminal with restydoc</a></li>\n      <li><a href="#AVR5Ft6FXTo" style="cursor: pointer">Share Data Across Requests Served by OpenResty</a></li>\n      <li><a href="#B5lfAZunxfc" style="cursor: pointer">Install OpenResty on CentOS 8 via dnf</a></li>\n      <li><a href="#L1c7aw4mSOo" style="cursor: pointer">OpenResty\'s resty Command-Line Utility Demo</a></li>\n      <li><a href="#vfYxOMl5LVY" style="cursor: pointer">Write Your Own Lua Modules in OpenResty/Nginx Applications</a></li>\n      <li><a href="#eSfYLvVQMxw" style="cursor: pointer">Hello World HTTP Example in OpenResty/Nginx</a></li>\n    </ul>\n  </div>\n  <div class="play-list">\n    <h2><a href="#PLlR4WakbzQp3blQY5pLBHhNzR2EsEWiJK" style="cursor: pointer">OpenResty Edge</a></h2>\n    <ul>\n      <li><a href="#3lO2BOqeVys" style="cursor: pointer">How to Automate Managing Gateway Servers in K8s Environment (using OpenResty Edge)</a></li>\n      <li><a href="#3cdsAbXAnxE" style="cursor: pointer">Use Lua Extensions to Respond to Gateway Server Offline Events (using OpenResty Edge)</a></li>\n      <li><a href="#rFaCVJPON3g" style="cursor: pointer">How to Use Gateway Partitions in OpenResty Edge</a></li>\n      <li><a href="#k522TIbqxQc" style="cursor: pointer">Control Access to DNS Applications in OpenResty Edge\'s Admin Console</a></li>\n      <li><a href="#c-Kf62KqK4c" style="cursor: pointer">Call Lua modules by Edgelang in OpenResty Edge</a></li>\n      <li><a href="#6R6_Qe_ONW0" style="cursor: pointer">How to Use Global Search in OpenResty Edge\'s Admin Console</a></li>\n      <li><a href="#ZcMqWGuFS1Q" style="cursor: pointer">How to Use Gateway Staging Servers in OpenResty Edge</a></li>\n      <li><a href="#WB0Rt8ghm44" style="cursor: pointer">Configuring Webhooks in OpenResty Edge</a></li>\n      <li><a href="#ay0RjPErUnE" style="cursor: pointer">(old) Configuring Webhooks in OpenResty Edge</a></li>\n      <li><a href="#K0lslt13REk" style="cursor: pointer">Configure Custom Error Pages in OpenResty Edge</a></li>\n      <li><a href="#aR196yVBkFk" style="cursor: pointer">Configure DNS Records in OpenResty Edge</a></li>\n      <li><a href="#02nlPUdclvQ" style="cursor: pointer">User Management and Access Control in OpenResty Edge’s Web Console</a></li>\n      <li><a href="#5WrUqkhzsXo" style="cursor: pointer">Adding Custom Response Headers in OpenResty Edge</a></li>\n      <li><a href="#Gj5wibhAy5E" style="cursor: pointer">How to Use OpenResty Edge\'s Global Server Load Balancing (GSLB) Feature</a></li>\n      <li><a href="#el2nlbLSof0" style="cursor: pointer">Use request IDs to troubleshoot problematic requests in OpenResty Edge gateways</a></li>\n      <li><a href="#IsrwpfuZFAs" style="cursor: pointer">Configure hCaptcha’s captcha webpages in OpenResty Edge</a></li>\n      <li><a href="#Tq-_Kq7eq2Y" style="cursor: pointer">Pushing static resources to OpenResty Edge gateways</a></li>\n      <li><a href="#hY0-XH_Svc0" style="cursor: pointer">Configuring SNI proxies in OpenResty Edge</a></li>\n      <li><a href="#qbH92BISUuY" style="cursor: pointer">Configuring gateway access log files in OpenResty Edge</a></li>\n      <li><a href="#MnoI48k_ZRo" style="cursor: pointer">Load-balancing TCP applications via OpenResty Edge</a></li>\n      <li><a href="#yWcYDZWm5V0" style="cursor: pointer">Configuring error log files in OpenResty Edge</a></li>\n      <li><a href="#FQteUX-oPwE" style="cursor: pointer">Configuring sticky cookies in OpenResty Edge gateways</a></li>\n      <li><a href="#Uz2FxYQI6yk" style="cursor: pointer">How to use Standard Dynamic Metrics in OpenResty Edge</a></li>\n      <li><a href="#pmlQiQZq91M" style="cursor: pointer">Managing traffic to Kubernetes (K8s) upstreams in OpenResty Edge</a></li>\n      <li><a href="#udrFa0HVlww" style="cursor: pointer">Configure distributed gRPC proxy in OpenResty Edge</a></li>\n      <li><a href="#5tFQHdCf1yo" style="cursor: pointer">Web Application Firewall (WAF) in OpenResty Edge</a></li>\n      <li><a href="#a1kMd_ppMpo" style="cursor: pointer">The EdgeLang DSL in OpenResty Edge</a></li>\n      <li><a href="#X6fhRn8YDK8" style="cursor: pointer">Passing client IP addresses to origin servers in OpenResty Edge</a></li>\n      <li><a href="#-Pq4IUQTMrc" style="cursor: pointer">Configure HTTP basic auth in OpenResty Edge</a></li>\n      <li><a href="#Gn79prUXkE0" style="cursor: pointer">Create Custom Dynamic Metrics in OpenResty Edge</a></li>\n      <li><a href="#YKP091Y7sU0" style="cursor: pointer">Limit Request Rate by Custom Keys in OpenResty Edge</a></li>\n      <li><a href="#XkPlx9If6sI" style="cursor: pointer">Gateway Config\'s Version Control &amp; Release Management in OpenResty Edge</a></li>\n      <li><a href="#NIlOrqi-I8U" style="cursor: pointer">Set Different Host Headers for Upstream Requests in OpenResty Edge</a></li>\n      <li><a href="#Z7zeYz2zDbQ" style="cursor: pointer">Redirect to different URIs Based on Clients\' Language Settings (OpenResty Edge)</a></li>\n      <li><a href="#H1T-019IK2k" style="cursor: pointer">Enforce the use of SSL in websites via OpenResty Edge</a></li>\n      <li><a href="#OBrJlaAPv1k" style="cursor: pointer">Issue Free SSL Certificates via Let\'s Encrypt in OpenResty Edge</a></li>\n      <li><a href="#DV-uPZ-I5og" style="cursor: pointer">Upload SSL Certificates for HTTPS Sites in OpenResty Edge</a></li>\n      <li><a href="#9Dy43JXaxKQ" style="cursor: pointer">Purge HTTP Cache in OpenResty Edge</a></li>\n      <li><a href="#g8H0HYM3AdM" style="cursor: pointer">Enable HTTP Cache in OpenResty Edge</a></li>\n      <li><a href="#fgtiOYrdsE4" style="cursor: pointer">Set up a Simplest Reverse Proxy and Load Balancer with OpenResty Edge</a></li>\n    </ul>\n  </div>\n  <div class="play-list">\n    <h2><a href="#PLlR4WakbzQp14ovGVZCtTKdfX3u4u7PNR" style="cursor: pointer">OpenResty Showman</a></h2>\n    <ul>\n      <li><a href="#i_n53z_zE3A" style="cursor: pointer">How to Auto-Generate Demo Videos for Google Search from Screenplay Docs (via OpenResty Showman)</a></li>\n      <li><a href="#y_g6B4aRc5o" style="cursor: pointer">Auto-Generate Demo Videos for Baidu Search from Screenplay Documents (in Chinese)</a></li>\n      <li><a href="#oew5RYUPMYY" style="cursor: pointer">How We Generate Videos from Screenplay Files</a></li>\n    </ul>\n  </div>\n  <h2 id="PLlR4WakbzQp2avbmDrBcvnKBH3w0bcXPZ">OpenResty XRay</h2>\n  <p id="H1xmZubCmYA">Quick Tour to OpenResty XRay\'s Web console</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/H1xmZubCmYA" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="zAmahYdZil8">Pinpointing the Hottest Python Code Paths with High Disk I/O (using OpenResty XRay)</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/zAmahYdZil8" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="sKuepewwvgQ">Install OpenResty XRay\'s Agent on Kubernetes</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/sKuepewwvgQ" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="Z_1zY4zXauc">How to Monitor Exceptions inside PHP Applications (using OpenResty XRay)</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/Z_1zY4zXauc" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="jjS3ACty7kI">Pinpointing the Hottest Rust Code Paths with High Disk I/O (using OpenResty XRay)</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/jjS3ACty7kI" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="Jd5Rvt2lhMY">Locate Large Memory Objects inside PHP Processes (using OpenResty XRay)</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/Jd5Rvt2lhMY" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="sqB5fGHahYU">Pinpointing the hottest Erlang code paths with high CPU usage (using OpenResty XRay)</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/sqB5fGHahYU" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="3eNlV2lqcOU">How to Trace Exceptions inside Perl Applications (using OpenResty XRay)</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/3eNlV2lqcOU" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="swUwT3sEtUI">Analyze OpenResty/Nginx Applications without Debug Symbols (using OpenResty XRay)</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/swUwT3sEtUI" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="N2NSqjgcuJA">Automatic Core Dump Analysis (using OpenResty XRay)</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/N2NSqjgcuJA" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="b_6L6ljzm1s">Pinpointing the Hottest Go Code Paths with High Disk I/O</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/b_6L6ljzm1s" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="JRoWMVBNoGw">Install OpenResty XRay’s Agents on Amazon Linux via Package Bundles</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/JRoWMVBNoGw" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="xBb2T7zK4IE">Pinpointing the hottest PHP code paths with high CPU usage (using OpenResty XRay)</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/xBb2T7zK4IE" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="L_Qp2kZPAkY">How CPU Time is Spent inside Envoy Servers (using OpenResty XRay)</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/L_Qp2kZPAkY" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="pW5hUFVD-d4">How CPU Time is Spent inside PHP Laravel Apps (using OpenResty XRay)</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/pW5hUFVD-d4" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="xhoDJMau39E">Find Blocking Perl Code Paths Holding back CPU Usage (Using OpenResty XRay)</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/xhoDJMau39E" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="n9cCqz0wxn8">How to Locate Exceptions inside Rust Applications (using OpenResty XRay)</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/n9cCqz0wxn8" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="3OS7gIfuGig">Pinpointing CPU-Hottest Go Code Paths Inside Prometheus</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/3OS7gIfuGig" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="3ORg4SkYcJg">How to Diagnose HTTP 504 Timeout Errors using OpenResty XRay</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/3ORg4SkYcJg" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="T2fe9-AjKEE">How CPU Time is Spent inside Go’s CockroachDB (using OpenResty XRay)</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/T2fe9-AjKEE" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="f-LL2P-Gu8c">Performance Overhead of OpenResty XRay when Tracing Perl Apps</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/f-LL2P-Gu8c" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="pOXXj4u1Oag">Locate Large Memory Objects inside Perl Processes (using OpenResty XRay)</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/pOXXj4u1Oag" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="HyrI2p5fE1M">Install OpenResty XRay’s Agents on Ubuntu via Deb Packages</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/HyrI2p5fE1M" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="v1Nw_HTtf60">Performance Impact of OpenResty XRay when Tracing PHP Apps (using OpenResty XRay)</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/v1Nw_HTtf60" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="HO0N6aLHFiE">Performance Impact of OpenResty XRay when Tracing Python Apps (using OpenResty XRay)</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/HO0N6aLHFiE" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="hx8nwGy3FJI">Performance Overhead of OpenResty XRay when Tracing Go Apps</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/hx8nwGy3FJI" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="bjmLEtwvIZI">Performance Impact of OpenResty XRay when Tracing Rust Apps (using OpenResty XRay)</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/bjmLEtwvIZI" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="WUdzsp9WMcU">Dynamic-Tracing Custom Go Programs with Custom Ylang Analyzers (using OpenResty XRay)</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/WUdzsp9WMcU" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="irBruMTl05o">How Python Django’s Application Uses Memory Internally (Using OpenResty XRay)</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/irBruMTl05o" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="Odu2tTZyDU0">How CPU time is spent inside Rust’s sled library (Using OpenResty XRay)</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/Odu2tTZyDU0" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="7LHVmehTxWc">How CPU time is spent inside Go\'s etcd server (using OpenResty XRay)</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/7LHVmehTxWc" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="ZqmaTXECu78">Find the largest Python objects or values taking the most RAM (using OpenResty XRay)</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/ZqmaTXECu78" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="lM3IJRcCmvc">Install OpenResty XRay’s Agents on CentOS via RPM Packages</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/lM3IJRcCmvc" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="dXTCdUb5AGk">How CPU time is spent inside llama.cpp + LLaMA2 (using OpenResty XRay)</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/dXTCdUb5AGk" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="yH2OxDTgNNc">Pinpoint hottest Perl code paths (using OpenResty XRay)</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/yH2OxDTgNNc" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="zKg6CizGP0Q">Discover the blocking/sleeping Python code paths (using OpenResty XRay)</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/zKg6CizGP0Q" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="1R7FsVJbm4s">Find Blocking Go Code Paths Holding back CPU Usage (Using OpenResty XRay)</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/1R7FsVJbm4s" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="2fAXn2144lw">Pinpoint CPU-hottest Go code paths online (using OpenResty XRay)</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/2fAXn2144lw" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="7OkwoBUxbxI">Locate the hottest Lua code paths in online OpenResty/Nginx servers (using OpenResty XRay)</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/7OkwoBUxbxI" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="CiftezUPuaI">Pinpoint leaked Lua tables with OpenResty XRay\'s command-line tools</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/CiftezUPuaI" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="YPUGJBbSwIk">Real-Time Request Counting against Nginx Processes via YSQL</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/YPUGJBbSwIk" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="Y53mElQgfpo">Troubleshoot the extra 200-ms request latency online</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/Y53mElQgfpo" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="-asOidukUw8">How to deploy the on-premises version of OpenResty XRay on Microsoft\'s Azure cloud</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/-asOidukUw8" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <h2 id="PLlR4WakbzQp0iUvHwJeBcG5MKWgGa_ahU">OpenResty Tutorials</h2>\n  <p id="XxL6Frvv4TM">Domain-Specific Languages (Implementation Strategies and Technologies)</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/XxL6Frvv4TM" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="Hu68mQDKXCo">Install OpenResty on Ubuntu 20.04 via apt-get</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/Hu68mQDKXCo" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="4VQP7eKq4oA">Streaming HTTP Response Output in OpenResty</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/4VQP7eKq4oA" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="EP7c0BM2yNo">Precompile Lua Modules into LuaJIT Bytecode to Speedup OpenResty Startup</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/EP7c0BM2yNo" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="VkRYW_qLoME">Measure Execution Time of Lua Code Correctly in OpenResty</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/VkRYW_qLoME" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="_PjpdUEeKeM">Lookup OpenResty Documentation on Terminal with restydoc</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/_PjpdUEeKeM" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="AVR5Ft6FXTo">Share Data Across Requests Served by OpenResty</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/AVR5Ft6FXTo" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="B5lfAZunxfc">Install OpenResty on CentOS 8 via dnf</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/B5lfAZunxfc" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="L1c7aw4mSOo">OpenResty\'s resty Command-Line Utility Demo</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/L1c7aw4mSOo" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="vfYxOMl5LVY">Write Your Own Lua Modules in OpenResty/Nginx Applications</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/vfYxOMl5LVY" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="eSfYLvVQMxw">Hello World HTTP Example in OpenResty/Nginx</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/eSfYLvVQMxw" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <h2 id="PLlR4WakbzQp3blQY5pLBHhNzR2EsEWiJK">OpenResty Edge</h2>\n  <p id="3lO2BOqeVys">How to Automate Managing Gateway Servers in K8s Environment (using OpenResty Edge)</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/3lO2BOqeVys" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="3cdsAbXAnxE">Use Lua Extensions to Respond to Gateway Server Offline Events (using OpenResty Edge)</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/3cdsAbXAnxE" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="rFaCVJPON3g">How to Use Gateway Partitions in OpenResty Edge</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/rFaCVJPON3g" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="k522TIbqxQc">Control Access to DNS Applications in OpenResty Edge\'s Admin Console</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/k522TIbqxQc" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="c-Kf62KqK4c">Call Lua modules by Edgelang in OpenResty Edge</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/c-Kf62KqK4c" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="6R6_Qe_ONW0">How to Use Global Search in OpenResty Edge\'s Admin Console</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/6R6_Qe_ONW0" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="ZcMqWGuFS1Q">How to Use Gateway Staging Servers in OpenResty Edge</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/ZcMqWGuFS1Q" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="WB0Rt8ghm44">Configuring Webhooks in OpenResty Edge</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/WB0Rt8ghm44" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="ay0RjPErUnE">(old) Configuring Webhooks in OpenResty Edge</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/ay0RjPErUnE" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="K0lslt13REk">Configure Custom Error Pages in OpenResty Edge</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/K0lslt13REk" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="aR196yVBkFk">Configure DNS Records in OpenResty Edge</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/aR196yVBkFk" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="02nlPUdclvQ">User Management and Access Control in OpenResty Edge’s Web Console</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/02nlPUdclvQ" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="5WrUqkhzsXo">Adding Custom Response Headers in OpenResty Edge</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/5WrUqkhzsXo" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="Gj5wibhAy5E">How to Use OpenResty Edge\'s Global Server Load Balancing (GSLB) Feature</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/Gj5wibhAy5E" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="el2nlbLSof0">Use request IDs to troubleshoot problematic requests in OpenResty Edge gateways</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/el2nlbLSof0" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="IsrwpfuZFAs">Configure hCaptcha’s captcha webpages in OpenResty Edge</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/IsrwpfuZFAs" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="Tq-_Kq7eq2Y">Pushing static resources to OpenResty Edge gateways</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/Tq-_Kq7eq2Y" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="hY0-XH_Svc0">Configuring SNI proxies in OpenResty Edge</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/hY0-XH_Svc0" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="qbH92BISUuY">Configuring gateway access log files in OpenResty Edge</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/qbH92BISUuY" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="MnoI48k_ZRo">Load-balancing TCP applications via OpenResty Edge</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/MnoI48k_ZRo" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="yWcYDZWm5V0">Configuring error log files in OpenResty Edge</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/yWcYDZWm5V0" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="FQteUX-oPwE">Configuring sticky cookies in OpenResty Edge gateways</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/FQteUX-oPwE" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="Uz2FxYQI6yk">How to use Standard Dynamic Metrics in OpenResty Edge</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/Uz2FxYQI6yk" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="pmlQiQZq91M">Managing traffic to Kubernetes (K8s) upstreams in OpenResty Edge</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/pmlQiQZq91M" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="udrFa0HVlww">Configure distributed gRPC proxy in OpenResty Edge</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/udrFa0HVlww" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="5tFQHdCf1yo">Web Application Firewall (WAF) in OpenResty Edge</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/5tFQHdCf1yo" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="a1kMd_ppMpo">The EdgeLang DSL in OpenResty Edge</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/a1kMd_ppMpo" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="X6fhRn8YDK8">Passing client IP addresses to origin servers in OpenResty Edge</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/X6fhRn8YDK8" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="-Pq4IUQTMrc">Configure HTTP basic auth in OpenResty Edge</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/-Pq4IUQTMrc" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="Gn79prUXkE0">Create Custom Dynamic Metrics in OpenResty Edge</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/Gn79prUXkE0" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="YKP091Y7sU0">Limit Request Rate by Custom Keys in OpenResty Edge</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/YKP091Y7sU0" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="XkPlx9If6sI">Gateway Config\'s Version Control &amp; Release Management in OpenResty Edge</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/XkPlx9If6sI" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="NIlOrqi-I8U">Set Different Host Headers for Upstream Requests in OpenResty Edge</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/NIlOrqi-I8U" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="Z7zeYz2zDbQ">Redirect to different URIs Based on Clients\' Language Settings (OpenResty Edge)</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/Z7zeYz2zDbQ" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="H1T-019IK2k">Enforce the use of SSL in websites via OpenResty Edge</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/H1T-019IK2k" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="OBrJlaAPv1k">Issue Free SSL Certificates via Let\'s Encrypt in OpenResty Edge</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/OBrJlaAPv1k" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="DV-uPZ-I5og">Upload SSL Certificates for HTTPS Sites in OpenResty Edge</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/DV-uPZ-I5og" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="9Dy43JXaxKQ">Purge HTTP Cache in OpenResty Edge</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/9Dy43JXaxKQ" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="g8H0HYM3AdM">Enable HTTP Cache in OpenResty Edge</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/g8H0HYM3AdM" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="fgtiOYrdsE4">Set up a Simplest Reverse Proxy and Load Balancer with OpenResty Edge</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/fgtiOYrdsE4" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <h2 id="PLlR4WakbzQp14ovGVZCtTKdfX3u4u7PNR">OpenResty Showman</h2>\n  <p id="i_n53z_zE3A">How to Auto-Generate Demo Videos for Google Search from Screenplay Docs (via OpenResty Showman)</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/i_n53z_zE3A" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="y_g6B4aRc5o">Auto-Generate Demo Videos for Baidu Search from Screenplay Documents (in Chinese)</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/y_g6B4aRc5o" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n  <p id="oew5RYUPMYY">How We Generate Videos from Screenplay Files</p>\n  <iframe width="645" height="360" src="https://www.youtube.com/embed/oew5RYUPMYY" allowfullscreen="allowfullscreen" loading="lazy" frameborder="0"></iframe>\n</div>'

    return output
end

-- xray-modal.tt2
template_map['xray-modal.tt2'] = function (context)
    if not context then
        return error("Lemplate function called without context\n")
    end
    local stash = context.stash
    local output = {}
    local i = 0

i = i + 1 output[i] = '<div class="xray-modal hide">\n  <div class="xray-modal-content">\n    <div class="header">\n      <div class="header-icon">\n        <div class="btn-violet">\n          <img src="/images/search.svg"/>\n        </div>\n        <div class="product-name">OpenResty XRay</div>\n      </div>\n      <div class="header-title">\n        <p>Advanced observability built for OpenResty and more</p>\n        <p class="small xray-live-demo-link">\n          <span class="icon-pc-display-horizontal"></span>\n          '
-- line 14 "xray-modal.tt2"
if tt2_true(stash_get(stash, 'lang') == 'cn') then
i = i + 1 output[i] = '<a href="https://demo.xray.openresty.com.cn/targets/", target="_blank">OpenResty XRay Live Demo →</a>'
end

i = i + 1 output[i] = '\n          '
-- line 15 "xray-modal.tt2"
if tt2_true(stash_get(stash, 'lang') ~= 'cn') then
i = i + 1 output[i] = '<a href="https://demo.xray.openresty.com/targets/", target="_blank">OpenResty XRay Live Demo →</a>'
end

i = i + 1 output[i] = '\n        </p>\n      </div>\n      <div class="btn-close">\n        <span>&times;</span>\n      </div>\n    </div>\n    <div class="content">\n      <div class="seperator">\n        <hr/>\n        <div class="seperator-text">limited time offer</div>\n        <hr/>\n      </div>\n      <div class="form-title">\n        <span>Request </span>\n        <span class="text-violet">TRIAL</span>\n        <span> today and receive a diagnostic </span>\n        <span class="text-violet">REPORT</span>\n      </div>\n      <form class="form-xray-request-demo">\n        <div class="form-field-item">\n          <input class="input-name" name="name" type="text" placeholder=\'Enter your full name\'>\n        </div>\n        <div class="form-field-item">\n          <input name="email" type="email" placeholder=\'Enter your business email\'>\n        </div>\n        <button class="form-next-button" type="submit">Submit</button>\n        <div class="btn-learn-more">Learn more</div>\n      </form>\n    </div>\n  </div>\n</div>\n'

    return output
end

return _M
