-
Notifications
You must be signed in to change notification settings - Fork 0
/
doc-introduction.html
429 lines (412 loc) · 23.3 KB
/
doc-introduction.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
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="icon" href="images/TotalAILogoTrans32.png" type="image/x-icon">
<link rel="preconnect" href="https://fonts.gstatic.com">
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600|Roboto Mono&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Goldman&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Goldman&display=swap" rel="stylesheet">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
<link rel="stylesheet" href="main.css">
<title>Total AI</title>
</head>
<body>
<nav class="navbar sticky-top tai-navbar">
<a class="navbar-brand" style="margin-top: -8px; margin-bottom: -8px;" href="index.html">
<img src="images/TotalAILogoTrans.png" height="40" alt="" loading="lazy">
</a>
<ul class="nav mr-auto">
<li class="nav-item">
<a class="nav-link" href="index.html">Home <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link active" href="doc-introduction.html">Guide</a>
</li>
<li class="nav-item">
<a class="nav-link" href="insp-introduction.html">Inspectors</a>
</li>
<li class="nav-item">
<a class="nav-link" href="script-introduction.html">Scripts</a>
</li>
<li class="nav-item">
<a class="nav-link" href="videos.html">Videos</a>
</li>
<li class="nav-item">
<a class="nav-link" href="contributors.html">Contributors</a>
</li>
<li class="nav-item">
<a class="nav-link" href="about.html">About</a>
</li>
<li class="nav-item" style="padding-left: 25px;">
<a class="nav-link" href="contrib-introduction.html">Contribute</a>
</li>
</ul>
<ul class="nav justify-content-end">
<li class="nav-item">
<a class="nav-link" target="_blank" href="https://discord.gg/PfKUm42Zax">
Discord
<svg width="1em" height="1em" viewBox="0 0 20 20" class="bi bi-box-arrow-up-right" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M8.636 3.5a.5.5 0 0 0-.5-.5H1.5A1.5 1.5 0 0 0 0 4.5v10A1.5 1.5 0 0 0 1.5 16h10a1.5 1.5 0 0 0 1.5-1.5V7.864a.5.5 0 0 0-1 0V14.5a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h6.636a.5.5 0 0 0 .5-.5z"/>
<path fill-rule="evenodd" d="M16 .5a.5.5 0 0 0-.5-.5h-5a.5.5 0 0 0 0 1h3.793L6.146 9.146a.5.5 0 1 0 .708.708L15 1.707V5.5a.5.5 0 0 0 1 0v-5z"/>
</svg>
</a>
</li>
<li class="nav-item">
<a class="nav-link" target="_blank" href="https://github.com/TotalAI/TotalAI">
GitHub
<svg width="1em" height="1em" viewBox="0 0 20 20" class="bi bi-box-arrow-up-right" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M8.636 3.5a.5.5 0 0 0-.5-.5H1.5A1.5 1.5 0 0 0 0 4.5v10A1.5 1.5 0 0 0 1.5 16h10a1.5 1.5 0 0 0 1.5-1.5V7.864a.5.5 0 0 0-1 0V14.5a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h6.636a.5.5 0 0 0 .5-.5z"/>
<path fill-rule="evenodd" d="M16 .5a.5.5 0 0 0-.5-.5h-5a.5.5 0 0 0 0 1h3.793L6.146 9.146a.5.5 0 1 0 .708.708L15 1.707V5.5a.5.5 0 0 0 1 0v-5z"/>
</svg>
</a>
</li>
<li class="nav-item">
<a class="nav-link" target="_blank" href="https://patreon.com/zacwarren">
Patreon
<svg width="1em" height="1em" viewBox="0 0 20 20" class="bi bi-box-arrow-up-right" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M8.636 3.5a.5.5 0 0 0-.5-.5H1.5A1.5 1.5 0 0 0 0 4.5v10A1.5 1.5 0 0 0 1.5 16h10a1.5 1.5 0 0 0 1.5-1.5V7.864a.5.5 0 0 0-1 0V14.5a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h6.636a.5.5 0 0 0 .5-.5z"/>
<path fill-rule="evenodd" d="M16 .5a.5.5 0 0 0-.5-.5h-5a.5.5 0 0 0 0 1h3.793L6.146 9.146a.5.5 0 1 0 .708.708L15 1.707V5.5a.5.5 0 0 0 1 0v-5z"/>
</svg>
</a>
</li>
</ul>
</nav>
<main style="width: 100%">
<div class="container-fluid">
<div class="row flex-xl-nowrap">
<div class="col-md-3 col-xl-2" style="position: sticky; top: 0; z-index: 1000; height: calc(100vh - 4rem); order: 0; overflow-y: auto; padding-top: 10px; padding-bottom: 40px;">
<h3 class="nav-header">Getting Started</h3>
<ul class="nav flex-column">
<li class="nav-item">
<a class="nav-link active" href="doc-introduction.html">Introduction</a>
</li>
<li class="nav-item">
<a class="nav-link" href="doc-installation.html">Install & Setup</a>
</li>
<li class="nav-item">
<a class="nav-link" href="doc-demo.html">Demo Worlds</a>
</li>
</ul>
<h3 class="nav-header">Entities</h3>
<ul class="nav flex-column navbar-light">
<li class="nav-item">
<a class="nav-link" href="doc-agent.html">Agent</a>
</li>
<li class="nav-item">
<a class="nav-link" href="doc-worldobject.html">WorldObject</a>
</li>
<li class="nav-item">
<a class="nav-link" href="doc-agentevent.html">AgentEvent</a>
</li>
</ul>
<h3 class="nav-header">Levels</h3>
<ul class="nav flex-column navbar-light">
<li class="nav-item">
<a class="nav-link" href="doc-drive.html">Drive</a>
</li>
<li class="nav-item">
<a class="nav-link" href="doc-action.html">Action</a>
</li>
<li class="nav-item">
<a class="nav-link" href="doc-attribute.html">Attribute</a>
</li>
<li class="nav-item">
<a class="nav-link" href="doc-tag.html">Tag</a>
</li>
<li class="nav-item">
<a class="nav-link" href="doc-role.html">Role</a>
</li>
<h3 class="nav-header">Agent</h3>
<ul class="nav flex-column navbar-light">
<li class="nav-item">
<a class="nav-link" href="doc-agent-main-loop.html">Main Loop</a>
</li>
<li class="nav-item">
<a class="nav-link" href="doc-movementtype.html">Movement Type</a>
</li>
<li class="nav-item">
<a class="nav-link" href="doc-animationtype.html">Animation Type</a>
</li>
<li class="nav-item">
<a class="nav-link" href="doc-sensortype.html">Sensor Type</a>
</li>
<li class="nav-item">
<a class="nav-link" href="doc-memorytype.html">Memory Type</a>
</li>
<li class="nav-item">
<a class="nav-link" href="doc-decider.html">Decider</a>
</li>
<li class="nav-item">
<a class="nav-link" href="doc-plannertype.html">Planner Type</a>
</li>
<li class="nav-item">
<a class="nav-link" href="doc-mapping.html">Plans & Mappings</a>
</li>
<li class="nav-item">
<a class="nav-link" href="doc-behavior.html">Behavior</a>
</li>
<li class="nav-item">
<a class="nav-link" href="doc-historytype.html">History Type</a>
</li>
</ul>
<h3 class="nav-header">AI Types</h3>
<ul class="nav flex-column navbar-light">
<li class="nav-item">
<a class="nav-link" href="doc-fsm.html">FSM</a>
</li>
<li class="nav-item">
<a class="nav-link" href="doc-goap.html">GOAP</a>
</li>
<li class="nav-item">
<a class="nav-link" href="doc-utility-ai.html">Utility AI</a>
</li>
<li class="nav-item">
<a class="nav-link" href="doc-deep-rl.html">Deep RL</a>
</li>
</ul>
<h3 class="nav-header">Other</h3>
<ul class="nav flex-column navbar-light">
<li class="nav-item">
<a class="nav-link" href="doc-typematching.html">Type Matching</a>
</li>
<li class="nav-item">
<a class="nav-link" href="doc-inventory.html">Inventory</a>
</li>
<li class="nav-item">
<a class="nav-link" href="doc-design-principles.html">Design Principles</a>
</li>
<li class="nav-item">
<a class="nav-link" href="doc-scriptableobjects.html">ScriptableObjects</a>
</li>
<li class="nav-item">
<a class="nav-link" href="doc-selector.html">Selector</a>
</li>
<li class="nav-item">
<a class="nav-link" href="doc-utility-curve.html">Utility Curve</a>
</li>
<li class="nav-item">
<a class="nav-link" href="doc-utility-function.html">Utility Function Type</a>
</li>
<li class="nav-item">
<a class="nav-link" href="doc-included-ui.html">UI & Placement</a>
</li>
<li class="nav-item">
<a class="nav-link" href="doc-more-resources.html">External Links</a>
</li>
</ul>
</div>
<div class="col-md-1">
</div>
<div class="col content" style="padding-top: 40px; padding-bottom: 40px; line-height: 1.6em; color: #304455; font-size: 1rem;">
<h1>Introduction</h1>
<h3>What is Total AI?</h3>
<hr>
<p>
<a target="_blank" class="text-link" href="https://www.youtube.com/watch?v=0iYzfrM0cjI">
Watch Quick Overview Video
<svg width="1em" height="1em" viewBox="0 0 20 20" class="bi bi-box-arrow-up-right" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M8.636 3.5a.5.5 0 0 0-.5-.5H1.5A1.5 1.5 0 0 0 0 4.5v10A1.5 1.5 0 0 0 1.5 16h10a1.5 1.5 0 0 0 1.5-1.5V7.864a.5.5 0 0 0-1 0V14.5a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h6.636a.5.5 0 0 0 .5-.5z"/>
<path fill-rule="evenodd" d="M16 .5a.5.5 0 0 0-.5-.5h-5a.5.5 0 0 0 0 1h3.793L6.146 9.146a.5.5 0 1 0 .708.708L15 1.707V5.5a.5.5 0 0 0 1 0v-5z"/>
</svg>
</a>
<br><br>
TAI is currently in Alpha and is available for FREE on
<nobr>
<a class="text-link" target="_blank" href="https://github.com/TotalAI/TotalAI">
GitHub
<svg width="1em" height="1em" viewBox="0 0 20 20" class="bi bi-box-arrow-up-right" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M8.636 3.5a.5.5 0 0 0-.5-.5H1.5A1.5 1.5 0 0 0 0 4.5v10A1.5 1.5 0 0 0 1.5 16h10a1.5 1.5 0 0 0 1.5-1.5V7.864a.5.5 0 0 0-1 0V14.5a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h6.636a.5.5 0 0 0 .5-.5z"/>
<path fill-rule="evenodd" d="M16 .5a.5.5 0 0 0-.5-.5h-5a.5.5 0 0 0 0 1h3.793L6.146 9.146a.5.5 0 1 0 .708.708L15 1.707V5.5a.5.5 0 0 0 1 0v-5z"/>
</svg>
</a>
</nobr>
<br><br>
Total AI (TAI) is a <b>complete open source agent AI Framework for Unity</b>.
Its goals are to provide an easy to prototype, flexible, fully customizable, and performant
framework for a broad array of AI types and for a broad array of game types. Eventually TAI
hopes to have a vast library of community created types that anyone can use to jumpstart their AI.
<br><br>
The core of TAI are Agents who can to sense the world, create memories, plans, and act in order to either reduce
their Drives or based on the action with the most utility.
This is accomplished with its Type System and Plan/Mapping System.
It is also easy to extend and customize through
<a class="text-link" href="doc-scriptableobjects.html">ScriptableObject's</a> pluggable data and logic ability.
This makes writing and plugging in your own custom AI logic easy.
</p>
<h3>General AI Framework</h3>
<hr>
<p>
Total AI is designed to be flexible to accomodate many different types and hyprids of AI Logic.
In fact each Agent in your game could be using a different type of AI. This is due to how all of the key
logic for an Agent is in Types that inherit from Scriptable Objects with the two key types being the Decider Type
and the Planner Type. Every agent gets its base configuration from its Agent Type but it can then use
Agent Type Overrides to change that setup configuration. Thus every Agent even if they are of the same Agent Type
can be using different AI Logic.
<br><br>
The following AI Types are currently implemented or are planned:
</p>
<ul>
<li><a class="text-link" href="doc-fsm.html">Finite State Machines</a></li>
<li><a class="text-link" href="doc-utility-ai.html">Utility AI</a></li>
<li><a class="text-link" href="doc-GOAP.html">Goal Oriented Action Planning</a></li>
<li><a class="text-link" href="doc-deep-rl.html">Deep Reinforcement Learning</a> (Planned)</li>
</ul>
<h3>Type System</h3>
<hr>
<p>
The Type System is at the core of TAI. Most objects and an object's levels have a type associated with them.
For example, An Agent has an Agent Type and an Agent's Attribute has an Attribute Type. These types not only
define what the object is and its starting configuration
but also inform TAI that this type can be used in certain Mapping Types (core unit of planning).
</p>
<h3>Entities</h3>
<hr>
<p>
An Entity actual exists in the World. It will be a Game Object with a subclass of Entity Component. For Example,
an Agent will always have an Agent Component. Agent inherits from Entity which inherits from MonoBehaviour.
Also every Entity has an Entity Type. Entity Type inherits from Input Output Type which inherits from Scriptable Object.
Similar to how Agent inherits from Entity, Agent Type inherits from Entity Type.
<br><br>
There are currently three types of Entities:
</p>
<ul>
<li><b><a class="text-link" href="doc-agent.html">Agent</a></b>:
Only Entity that can plan and act in the world.</li>
<li><b><a class="text-link" href="doc-worldobject.html">World Object</a></b>:
Any Entity that can't plan or act. Can be built or grow and can have states.</li>
<li><b><a class="text-link" href="doc-agentevent.html">Agent Event</a></b>:
A multi-Agent coordinated event. Can add Roles to Agents to force them to only have
certain Actions and Drives.</li>
</ul>
<h3>Levels</h3>
<hr>
<p>
Levels are <b>properties of Entities</b> and have an associated level (usually a float value) and a Level Type.
Default Level Types exist on Entity Types and Levels exist on Entities. For example,
An Agent Type defines the default Level Types and the default Level values for an Agent.
There are currently five Levels:
</p>
<ul>
<li><b><a class="text-link" href="doc-drive.html">Drive</a></b>:
Drives are motivation for an Agent. An Agent wants to reduce all of their Drive Levels to 0.</li>
<li><b><a class="text-link" href="doc-action.html">Action</a></b>:
Defines the Behavior Type used to perform this Action.</li>
<li><b><a class="text-link" href="doc-attribute.html">Attribute</a></b>:
Defines a property of an Entity along with the level.</li>
<li><b><a class="text-link" href="doc-tag.html">Tag</a></b>:
All Entities can be tagged which can then be used in planning.</li>
<li><b><a class="text-link" href="doc-role.html">Role</a></b>:
Can cause Drive Types and Action Types to be added or removed from an Agent.</li>
</ul>
<h3>Agent's Main Loop</h3>
<hr>
<p>
The Agent's Main Loop handles the core requirement of being autonomous. The diagram below shows the main loop along
with the Decider, Behavior, and interrupt logic. As can be seen in the diagram, all of the core logic is in Types
(ScriptableObjects). This allows for customization of any logic and also the ability to easily give different Agents
different logic.
</p>
<div style="overflow:hidden; padding-bottom: 15px; margin-right: -200px;">
<a target="_blank" href="images/AgentFlow.png">
<img src="images/AgentFlow.png" width="100%">
</a>
<br>
<i>Click on the diagram for full size.</i>
</div>
<h3>Plans</h3>
<hr>
<p>
A Plan is a tree structure with a Mapping representing a node with a parent and children.
It's Root Mapping (no parent) has to reduce a Drive Type. The Planner Type is responsible for generating the plans and
returns a List of Plans that reduce a certain Drive Type. The Decider Type is then responsible for selecting one of
the plans.
<br><br>
The Planner Type is attached to the Decider Type so it is up to the Decider Type on how it uses the
Planner Type(s). For example a Player Controlled Decider Type would not need a Planner Type as the
Player would be directly choosing the Mapping to run.
<br><br>
<i>A Player Controlled Decider Type is not currently implemented but is on TAI's Roadmap.</i>
</p>
<h3>Mapping</h3>
<hr>
<p>
A Mapping represents the <b>core unit of a plan</b>. Along with possibly having a parent and children Mappings,
it contains a Mapping Type, an Entity target if it needs one, and multiple inventory Entity targets if needed.
A Mapping Type consists of three main parts:
<ul>
<li><b>Input Conditions</b>: What needs to be true for an agent to perform this Mapping Type?</li>
<li><b>Output Changes</b>: What changes will occur at the start, during, at at the end of this Mapping Type?</li>
<li><b>Action Type</b>: Specifies the Behavior Type that will occur. A Behavior Type holds the logic for
running the Mapping along with hooking into movement and animation systems.</li>
</ul>
For more information on the Mappings and Mapping Types go <a class="text-link" href="doc-mapping.html">here</a>.
</p>
<h3>Drives</h3>
<hr>
<p>
Drives represent an Agent's motivation. The Agent's goal is to reduce all Drive Levels to zero.
An Agent will prioritize each Drive based on it's current utility level and then go one by one in
order of Drives looking for a completed (all the Plan's leaf Mappings' Input Conditions are met) Plan to run.
The Drive ranking/selection logic is easy to customize and lives in the subclasses of
<a class="text-link" href="doc-decider.html">Decider Type</a>. If there are multiple completed plans for a Drive
the Agent's Decider Type chooses one based on a <a class="text-link" href="doc-utility-function.html">Utility Function</a>
the generates an overall utility for each Plan.
<br><br>
It is also easy to use TAI without the Drive logic. Just add one single Drive Type to every Agent and have your root
mappings reduce that single Drive Type.
<br><br>
For more information on Drive Types go <a class="text-link" href="doc-drivetype.html">here</a>.
</p>
<h3>How Drive-Based Total AI Works</h3>
<hr>
<p>
TAI began with a series of simple questions. Why should NPCs (Agents) do anything at all? Why would
they choose one action over another action? <b>What motivates Agents?</b> This last
question led to the core of TAI. An Agent has Drives and <b>an Agent's central goal is to reduce their Drive
Levels to zero</b>. A simple example is why should an Agent eat? Because their Hunger Drive is high. After eating
it is reduced and the Agent can focus on reducing a different Drive or perhaps if there are no other drives with higher
<b>Drive Utility</b> the Agent could continue to eat more.
<br><br>
Drive Utility is similar to how Utility AI Works,
Drive levels are passed through a <a class="text-link" href="doc-utility-curve.html">Utility Curve</a> to
generate a 0-1 value for how important it is to reduce that Drive. This allows Drives effects to be much more nuanced.
For example, with an S shaped curve the drive will initially not be important, gradually rise up in importance,
then be maxed out before the level actually reaches the Level's max. This might be a suitable curve to represent
a Hunger Drive.
<br><br>
The Drive with the highest utility is choosen (or an alternate selection algorithm can be used) and the Agent's
Planner Type then generates plans and the Agent's Decider Type chooses a plan to reduce this drive.
<br><br>
Choosing a plan can use a <a class="text-link" href="doc-utility-function.html">Utility Function</a>
that takes into account the rate of decreasing the drive along
with any side-effects the plan might have. For example, if the Agent is cold and wants to make a fire they
could burn their wood house down but the side-effect cost of losing a house would reduce the utility. They
would find that the overall utility of gathering wood in the forest and burning that is much higher.
</p>
</div>
<div class="col-md-3">
</div>
</div>
</main>
<script>
$(document).ready(function() {
$(window).resize(function() {
resize();
});
function resize() {
var myheight = $(window).outerHeight(true) - 0;
$('.main').outerHeight(myheight);
}
resize();
});
</script>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
</body>
</html>