forked from ElectionGuard/ElectionGuard-SDK-C-Documentation
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
321 lines (317 loc) · 24.4 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ElectionGuard SDK Mock Implementation — ElectionGuard SDK documentation</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto+Mono"><link rel="stylesheet" href="_static/typlog.css?v=0.7.3" type="text/css" />
<link rel="stylesheet" href="_static/theme.css?v=0.7.3" type="text/css" />
<link rel="index" title="Index" href="genindex.html"/>
<link rel="search" title="Search" href="search.html"/>
<link rel="top" title="ElectionGuard SDK documentation" href="#"/>
<link rel="next" title="Key Ceremony" href="keyceremony.html"/>
<script>(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');ga('create', '');ga('send', 'pageview');</script>
<script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/language_data.js"></script>
<script async="async" type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
<meta property="og:type" content="website">
<meta property="og:site_name" content="ElectionGuard SDK">
<meta property="og:title" content="ElectionGuard SDK Mock Implementation">
<meta property="og:description" content="Building E2E verifiable elections.">
<meta name="twitter:card" content="summary">
</head>
<body role="document" data-page="index">
<header class="t-head">
<div class="t-head_menu"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M64 384h384v-42.666H64V384zm0-106.666h384v-42.667H64v42.667zM64 128v42.665h384V128H64z"/></svg></div>
<a class="t-head_logo" href="#">ElectionGuard SDK
</a>
</header>
<aside class="t-sidebar">
<div class="t-sidebar_close">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M405 136.798L375.202 107 256 226.202 136.798 107 107 136.798 226.202 256 107 375.202 136.798 405 256 285.798 375.202 405 405 375.202 285.798 256z"/></svg>
</div>
<div class="inner">
<a class="logo" href="#">
ElectionGuard SDK
</a><div class="logo_desc">Building E2E verifiable elections.</div>
<div class="github_wrap">
<a class="github" href="https://github.com/microsoft/ElectionGuard-SDK" target="_blank">
<span class="github_icon"></span>
<span class="github_stars">
<strong>-</strong>stars
</span>
<span class="github_forks">
<strong>-</strong>forks
</span>
</a>
</div><div class="globaltoc">
<ul>
<li class="toctree-l1"><a class="reference internal" href="keyceremony.html">Key Ceremony</a></li>
<li class="toctree-l1"><a class="reference internal" href="voting.html">Voting</a></li>
<li class="toctree-l1"><a class="reference internal" href="decryption.html">Decryption</a></li>
<li class="toctree-l1"><a class="reference internal" href="api/index.html">API Reference</a></li>
<li class="toctree-l1"><a class="reference internal" href="examples.html">Example Clients</a></li>
</ul>
</div>
<h3>Table of Contents</h3>
<ul>
<li><a class="reference internal" href="#">ElectionGuard SDK C Implementation</a><ul>
<li><a class="reference internal" href="#building">Building</a><ul>
<li><a class="reference internal" href="#id2">Visual Studio</a></li>
<li><a class="reference internal" href="#unix-like-systems">Unix-like Systems</a></li>
</ul>
</li>
<li><a class="reference internal" href="#testing">Testing</a><ul>
<li><a class="reference internal" href="#id3">Visual Studio</a></li>
<li><a class="reference internal" href="#id4">Unix-like Systems</a></li>
</ul>
</li>
<li><a class="reference internal" href="#debugging">Debugging</a></li>
<li><a class="reference internal" href="#developing">Developing</a></li>
<li><a class="reference internal" href="#documentation">Documentation</a></li>
<li><a class="reference internal" href="#memory-management-ownership-who-frees-what">Memory Management/Ownership: Who frees what?</a></li>
<li><a class="reference internal" href="#naming-conventions">Naming Conventions</a><ul>
<li><a class="reference internal" href="#abstract-type">Abstract Type</a></li>
<li><a class="reference internal" href="#status-enum">Status Enum</a></li>
<li><a class="reference internal" href="#return-struct">Return Struct</a></li>
<li><a class="reference internal" href="#internal-struct">Internal Struct</a></li>
</ul>
</li>
<li><a class="reference internal" href="#indices-and-tables">Indices and tables</a></li>
</ul>
</li>
</ul>
<div id="searchbox">
<form class="search" action="search.html" method="get">
<div class="input-group">
<input type="text" name="q" placeholder="Search" />
<button type="submit">Go</button>
</div>
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
</aside>
<div class="t-content">
<div class="t-body yue">
<div class="section" id="electionguard-sdk-mock-implementation">
<h1>ElectionGuard SDK C Implementation<a class="headerlink" href="#electionguard-sdk-mock-implementation" title="Permalink to this headline">¶</a></h1>
<p>This implementation of the ElectionGuard SDK serves to showcase the
API provided by the SDK. For more details about that API, see the
<a class="reference internal" href="api/index.html#include"><span class="std std-ref">API Reference</span></a>.</p>
<div class="section" id="building">
<span id="id1"></span><h2>Building<a class="headerlink" href="#building" title="Permalink to this headline">¶</a></h2>
<p>To enable cross-platform building, we use <a class="reference external" href="https://cmake.org/">cmake</a>. Any generator should work, but we describe
here how build using <a class="reference external" href="https://visualstudio.microsoft.com/">Visual Studio</a> and using a Unix-like shell.</p>
<div class="section" id="id2">
<h3>Visual Studio<a class="headerlink" href="#id2" title="Permalink to this headline">¶</a></h3>
<p>As long as you have the C++ CMake tools for Windows installed,
<strong class="program">cmake</strong> should automatically integrate with Visual Studio.
This means you can build the project from the IDE, for example by
selecting <code class="docutils literal notranslate"><span class="pre">Build</span> <span class="pre">></span> <span class="pre">Build</span> <span class="pre">All</span></code> in the menu.</p>
</div>
<div class="section" id="unix-like-systems">
<h3>Unix-like Systems<a class="headerlink" href="#unix-like-systems" title="Permalink to this headline">¶</a></h3>
<p>First create a build directory and configure the build.</p>
<div class="code sh highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">mkdir</span> <span class="n">build</span>
<span class="n">cmake</span> <span class="o">-</span><span class="n">S</span> <span class="o">.</span> <span class="o">-</span><span class="n">B</span> <span class="n">build</span>
</pre></div>
</div>
<p>To build the SDK static library <code class="docutils literal notranslate"><span class="pre">libelectionguard.a</span></code>, run</p>
<div class="code sh highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">cmake</span> <span class="o">--</span><span class="n">build</span> <span class="n">build</span>
</pre></div>
</div>
</div>
</div>
<div class="section" id="testing">
<h2>Testing<a class="headerlink" href="#testing" title="Permalink to this headline">¶</a></h2>
<p>Currently you can exercise the SDK by running the <a class="reference internal" href="examples/simple.html"><span class="doc">example client</span></a>. We include a cmake test to do so automatically. You can
also execute the client directly to better examine the output it produces.</p>
<div class="admonition warning">
<p class="first admonition-title">Warning</p>
<p>The current implementation allocates most things statically, leading
to a large stack. This can cause stack-overflows.</p>
<p>The size of the stack mostly depends on the value of <a class="reference internal" href="api/max_values.html#c.MAX_TRUSTEES" title="MAX_TRUSTEES"><code class="xref c c-data docutils literal notranslate"><span class="pre">MAX_TRUSTEES</span></code></a> in
<code class="file docutils literal notranslate"><span class="pre">include/max_trustees.h</span></code>, so one way to fix the problem is to reduce
that number and recompile.</p>
<p>You can also increase the stack size, for example using <strong class="command">ulimit</strong>.</p>
<p class="last">In addition, this causes issues with <strong class="program">valgrind</strong>. The error messages
are usually pretty helpful, and setting <code class="docutils literal notranslate"><span class="pre">--main-stacksize</span></code> and
<code class="docutils literal notranslate"><span class="pre">--main-stackframe</span></code> according to its reccomendations usually fixes the issue.</p>
</div>
<div class="section" id="id3">
<h3>Visual Studio<a class="headerlink" href="#id3" title="Permalink to this headline">¶</a></h3>
<p>To build and execute an example client of the SDK, run the tests,
for example by selecting <code class="docutils literal notranslate"><span class="pre">Test</span> <span class="pre">></span> <span class="pre">Run</span> <span class="pre">CTests</span> <span class="pre">for</span> <span class="pre">ElectionGuard</span> <span class="pre">SDK</span></code>.</p>
<p>The example client can also be built as a standalone project if it is
configured with the location of the SDK, but this is not covered here.</p>
</div>
<div class="section" id="id4">
<h3>Unix-like Systems<a class="headerlink" href="#id4" title="Permalink to this headline">¶</a></h3>
<p>To build and run an example client of the SDK, run the tests:</p>
<div class="code sh highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">cmake</span> <span class="o">--</span><span class="n">build</span> <span class="n">build</span> <span class="o">--</span><span class="n">target</span> <span class="n">test</span>
</pre></div>
</div>
<p>Alternatively you can build the client as a stand-alone project.
Create a separate build directory for the client, configure the build
to refer to the built library, and build the client.</p>
<div class="code sh highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">mkdir</span> <span class="n">simple_build</span>
<span class="n">ElectionGuard_DIR</span><span class="o">=</span><span class="s2">"$PWD/build/ElectionGuard"</span> <span class="n">cmake</span> <span class="o">-</span><span class="n">S</span> <span class="n">examples</span><span class="o">/</span><span class="n">simple</span> <span class="o">-</span><span class="n">B</span> <span class="n">simple_build</span>
<span class="n">cmake</span> <span class="o">--</span><span class="n">build</span> <span class="n">simple_build</span> <span class="o">--</span><span class="n">target</span> <span class="n">simple</span>
</pre></div>
</div>
<p>The built binary should be located at <code class="file docutils literal notranslate"><span class="pre">simple_build/simple</span></code>.</p>
</div>
</div>
<div class="section" id="debugging">
<h2>Debugging<a class="headerlink" href="#debugging" title="Permalink to this headline">¶</a></h2>
<p>To enable debug builds suitable for running with debuggers like
<strong class="program">lldb</strong>, set the <code class="docutils literal notranslate"><span class="pre">CMAKE_BUILD_TYPE</span></code> cmake variable to
<code class="docutils literal notranslate"><span class="pre">Debug</span></code> when configuring. From the command-line, this looks like</p>
<div class="code sh highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">cmake</span> <span class="o">-</span><span class="n">S</span> <span class="o">.</span> <span class="o">-</span><span class="n">B</span> <span class="n">build</span> <span class="o">-</span><span class="n">DCMAKE_BUILD_TYPE</span><span class="o">=</span><span class="n">Debug</span>
</pre></div>
</div>
</div>
<div class="section" id="developing">
<h2>Developing<a class="headerlink" href="#developing" title="Permalink to this headline">¶</a></h2>
<p>Some development tools like <strong class="program">ccls</strong> or <strong class="program">cquery</strong> use a
JSON file called <code class="file docutils literal notranslate"><span class="pre">compile_commands.json</span></code> to lookup which build
flags are used to build different files. To produce such a file while
compiling, set the <code class="docutils literal notranslate"><span class="pre">CMAKE_EXPORT_COMPILE_COMMANDS</span></code> cmake variable.
From the command-line, this looks like</p>
<div class="code sh highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">cmake</span> <span class="o">-</span><span class="n">S</span> <span class="o">.</span> <span class="o">-</span><span class="n">B</span> <span class="n">build</span> <span class="o">-</span><span class="n">DCMAKE_EXPORT_COMPILE_COMMANDS</span><span class="o">=</span><span class="n">ON</span>
</pre></div>
</div>
</div>
<div class="section" id="documentation">
<h2>Documentation<a class="headerlink" href="#documentation" title="Permalink to this headline">¶</a></h2>
<p>To build the HTML documentation, you will need to have
<strong class="program">doxygen</strong> installed, as well as <strong class="program">python</strong> with the
<code class="docutils literal notranslate"><span class="pre">sphinx</span></code> and <code class="docutils literal notranslate"><span class="pre">breathe</span></code> packages. Then configure your build with
the <code class="docutils literal notranslate"><span class="pre">BUILD_DOCUMENTATION</span></code> variable set and rebuild.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p>Make sure that you’ve initialized <strong class="program">git</strong> submodules
correctly. The theme used for the documentation is in a submodule.</p>
<div class="code sh last highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">git</span> <span class="n">submodule</span> <span class="n">update</span> <span class="o">--</span><span class="n">init</span> <span class="o">--</span><span class="n">recursive</span>
</pre></div>
</div>
</div>
<div class="code sh highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">cmake</span> <span class="o">-</span><span class="n">S</span> <span class="o">.</span> <span class="o">-</span><span class="n">B</span> <span class="n">build</span> <span class="o">-</span><span class="n">DBUILD_DOCUMENTATION</span><span class="o">=</span><span class="n">ON</span>
<span class="n">cmake</span> <span class="o">--</span><span class="n">build</span> <span class="n">build</span>
</pre></div>
</div>
<p>and the documentation will be built in the <code class="file docutils literal notranslate"><span class="pre">build/docs/html</span></code>
directory. You can browse it locally by opening
<code class="file docutils literal notranslate"><span class="pre">build/docs/html/index.html</span></code>, or by running a local server</p>
</div>
<div class="section" id="memory-management-ownership-who-frees-what">
<h2>Memory Management/Ownership: Who frees what?<a class="headerlink" href="#memory-management-ownership-who-frees-what" title="Permalink to this headline">¶</a></h2>
<p>Any pointers <em>returned by</em> functions in the SDK are considered to be
owned by the caller. This means that the SDK will retain no references
to them, and that the caller must free them when they are done.</p>
<p>Any pointers <em>passed to</em> functions in the SDK as arguments are
considered to be borrowed by the function, which means that they will
not be freed by that function, and it is still the responsibility of the
caller to free the pointer. This of course excludes functions whose
purpose is to free an opaque data type, like
<a class="reference internal" href="api/keyceremony/trustee.html#c.KeyCeremony_Trustee_free" title="KeyCeremony_Trustee_free"><code class="xref c c-func docutils literal notranslate"><span class="pre">KeyCeremony_Trustee_free()</span></code></a>.</p>
<p>This only applies when functions return with a successful status. If a
function returns with an error status, the client does not need to free
any memory that may have been allocated by the function; it will clean
up after itself.</p>
</div>
<div class="section" id="naming-conventions">
<h2>Naming Conventions<a class="headerlink" href="#naming-conventions" title="Permalink to this headline">¶</a></h2>
<p>All public functions are prefixed with the name of their “class” or
module, capitalized.</p>
<p>There are a few different kinds of types, and they each have their own
naming conventions. The rationale is that for types that we rely on the
fact that they are enums or structs, we should not <code class="docutils literal notranslate"><span class="pre">typedef</span></code> them so
that it is clear that they are enums and structs. If that changes, we
will have to go fix it everywhere, which is good, because now we cannot
rely on their representation anymore. Abstract types should be
<code class="docutils literal notranslate"><span class="pre">typedef</span></code>ed because we don’t rely on their implementation.</p>
<div class="section" id="abstract-type">
<h3>Abstract Type<a class="headerlink" href="#abstract-type" title="Permalink to this headline">¶</a></h3>
<p>A type whose implementation we want to be hidden from clients. This
means that it must be hidden behind a pointer so its size doesn’t need
to be known.</p>
<p><strong>Naming convention:</strong> uppercase, with their structs suffixed with
<code class="docutils literal notranslate"><span class="pre">_s</span></code>.</p>
<div class="code c highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">typedef</span> <span class="n">struct</span> <span class="n">Car_s</span> <span class="o">*</span><span class="n">Car</span><span class="p">;</span>
</pre></div>
</div>
</div>
<div class="section" id="status-enum">
<h3>Status Enum<a class="headerlink" href="#status-enum" title="Permalink to this headline">¶</a></h3>
<p>A enum whose values represent possible statuses that we want to return.</p>
<p><strong>Naming convention:</strong> prefixed by module or scope, then lowercase, and
no <code class="docutils literal notranslate"><span class="pre">typedef</span></code>.</p>
<div class="code c highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">enum</span> <span class="n">Car_status</span> <span class="p">{</span>
<span class="n">CAR_SUCCESS</span><span class="p">,</span>
<span class="n">CAR_ON_FIRE</span><span class="p">,</span>
<span class="p">};</span>
</pre></div>
</div>
</div>
<div class="section" id="return-struct">
<h3>Return Struct<a class="headerlink" href="#return-struct" title="Permalink to this headline">¶</a></h3>
<p>A struct whose sole purpose is to allow us to return multiple values,
often a status enum and a payload.</p>
<p><strong>Naming convention:</strong> prefixed by module or scope, then lowercase, then
<code class="docutils literal notranslate"><span class="pre">_r</span></code>, and no <code class="docutils literal notranslate"><span class="pre">typedef</span></code>. If only used for a single function, make the
name identical to the function name, then <code class="docutils literal notranslate"><span class="pre">_r</span></code>. You can forward
declare in the return type.</p>
<div class="code c highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">struct</span> <span class="n">Car_drive_r</span> <span class="n">Car_drive</span><span class="p">(</span><span class="n">Car</span> <span class="n">c</span><span class="p">);</span>
<span class="n">struct</span> <span class="n">Car_drive_r</span> <span class="p">{</span>
<span class="n">enum</span> <span class="n">Car_status</span> <span class="n">status</span><span class="p">;</span>
<span class="nb">int</span> <span class="n">x</span><span class="p">;</span>
<span class="nb">int</span> <span class="n">y</span><span class="p">;</span>
<span class="p">};</span>
</pre></div>
</div>
</div>
<div class="section" id="internal-struct">
<h3>Internal Struct<a class="headerlink" href="#internal-struct" title="Permalink to this headline">¶</a></h3>
<p>A type we want to name, but whose implementation need not be hidden. In
fact, we might rely on the details of its representation.</p>
<p><strong>Naming convention:</strong> all lowercase, no <code class="docutils literal notranslate"><span class="pre">typedef</span></code>.</p>
<div class="code c highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">struct</span> <span class="n">model</span> <span class="p">{</span>
<span class="nb">int</span> <span class="n">year</span><span class="p">;</span>
<span class="n">enum</span> <span class="n">color</span> <span class="n">color</span><span class="p">;</span>
<span class="p">};</span>
</pre></div>
</div>
<div class="toctree-wrapper compound">
</div>
</div>
</div>
<div class="section" id="indices-and-tables">
<h2>Indices and tables<a class="headerlink" href="#indices-and-tables" title="Permalink to this headline">¶</a></h2>
<ul class="simple">
<li><a class="reference internal" href="genindex.html"><span class="std std-ref">Index</span></a></li>
<li><a class="reference internal" href="search.html"><span class="std std-ref">Search Page</span></a></li>
</ul>
</div>
</div>
<div class="t-pagination clearfix">
<span style="float:right">
<a href="keyceremony.html" title="Key Ceremony">Key Ceremony</a> →
</span>
</div>
</div><footer class="t-foot">
© Copyright 1970, Jake Waksbaum.
<br>
A <a href="https://typlog.com/">typlog</a> <a href="https://github.com/typlog/sphinx-typlog-theme">sphinx theme</a>,
designed by <a href="https://lepture.com/">Hsiaoming Yang</a>.
</footer>
</div>
<script>$(function(){$(".t-head_menu").on("click",function(){$("body").addClass("_expand")});$(".t-body").on("click",function(){$("body").removeClass("_expand")});$(".t-sidebar_close").on("click",function(){$("body").removeClass("_expand")});$("a.footnote-reference").on("click",function(e){e.preventDefault();var id=$(this).attr("href");var html=$(id).find("td.label + td").html();var w=Math.max(document.documentElement.clientWidth,window.innerWidth||0);var style="top:"+e.pageY+"px;";if(w>560){style+="width:480px;";if(e.pageX>240&&e.pageX+240<w){style+="left:"+(e.pageX-240)+"px;"}else if(e.pageX<=240){style+="left:20px;"}else{style+="right:20px;"}}showFootnote(html,style)});function showFootnote(html,style){var CONTENT_ID="typlog-footnote-content";var content=document.getElementById(CONTENT_ID);if(!content){content=document.createElement("div");content.id=CONTENT_ID;$(".t-body").append(content)}var MASK_ID="typlog-footnote-mask";var mask=document.getElementById(MASK_ID);if(!mask){mask=document.createElement("div");mask.id=MASK_ID;document.body.appendChild(mask);mask.addEventListener("click",function(){content.className="";mask.className=""})}content.innerHTML=html;content.setAttribute("style",style);content.className="_active";mask.className="_active"}function fetchGitHubRepo(repo){var url="https://api.github.com/repos/"+repo;$.getJSON(url,function(data){var counts=[+new Date,data.stargazers_count,data.forks_count];localStorage.setItem("gh:"+repo,JSON.stringify(counts));updateGitHubStats(counts[1],counts[2])})}function updateGitHubStats(stars,forks){$(".github_stars strong").text(stars);$(".github_forks strong").text(forks)}function initGitHub(url){if(!url){return}var repo=url.replace("https://github.com/","");var cache=localStorage.getItem("gh:"+repo);if(cache){try{var counts=JSON.parse(cache);updateGitHubStats(counts[1],counts[2]);var delta=new Date-counts[0];if(delta<0||delta>9e5){fetchGitHubRepo(repo)}}catch(error){fetchGitHubRepo(repo)}}else{fetchGitHubRepo(repo)}}initGitHub($(".github").attr("href"))});</script>
</body>
</html>