Upload folder using huggingface_hub
Browse files- LICENSE +674 -0
- README.md +67 -4
- README.txt +57 -0
- favicon.ico +0 -0
- index.html +32 -19
- static/css/ragrqs.min.css +1 -0
- static/data/aaron_swartz.txt +0 -0
- static/data/aristotele_detective.txt +0 -0
- static/data/help_test.html +25 -0
- static/data/il_libro_rosso.txt +0 -0
- static/data/la_cattedrale_e_il_bazaar.txt +804 -0
- static/data/lettere_musulmane.txt +1891 -0
- static/data/montecristo.txt +0 -0
- static/data/roberto_busa.txt +951 -0
- static/favicon.ico +0 -0
- static/help0.html +201 -0
- static/help1.html +59 -0
- static/help2.html +18 -0
- static/javascript/rag_cleaner.js +99 -0
- static/javascript/rag_data_mgr.js +109 -0
- static/javascript/rag_http.js +220 -0
- static/javascript/rag_mgr.js +405 -0
- static/javascript/rag_prompts.js +235 -0
- static/javascript/rag_rqs.js +243 -0
- static/javascript/rag_ui.js +360 -0
- static/javascript/rag_upload.js +215 -0
- static/javascript/uadrag.js +51 -0
- static/javascript/uajtfh.js +25 -0
- static/javascript/ualog.js +157 -0
- static/javascript/uawindow.js +211 -0
- static/js/ragrqs.min.js +176 -0
- static/less/less.js +0 -0
- static/less/normalize.css +352 -0
- static/less/ragrqs.less +991 -0
- static/ragrqs.html +131 -0
- static/ragrqs_.html +149 -0
LICENSE
ADDED
@@ -0,0 +1,674 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
GNU GENERAL PUBLIC LICENSE
|
2 |
+
Version 3, 29 June 2007
|
3 |
+
|
4 |
+
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
5 |
+
Everyone is permitted to copy and distribute verbatim copies
|
6 |
+
of this license document, but changing it is not allowed.
|
7 |
+
|
8 |
+
Preamble
|
9 |
+
|
10 |
+
The GNU General Public License is a free, copyleft license for
|
11 |
+
software and other kinds of works.
|
12 |
+
|
13 |
+
The licenses for most software and other practical works are designed
|
14 |
+
to take away your freedom to share and change the works. By contrast,
|
15 |
+
the GNU General Public License is intended to guarantee your freedom to
|
16 |
+
share and change all versions of a program--to make sure it remains free
|
17 |
+
software for all its users. We, the Free Software Foundation, use the
|
18 |
+
GNU General Public License for most of our software; it applies also to
|
19 |
+
any other work released this way by its authors. You can apply it to
|
20 |
+
your programs, too.
|
21 |
+
|
22 |
+
When we speak of free software, we are referring to freedom, not
|
23 |
+
price. Our General Public Licenses are designed to make sure that you
|
24 |
+
have the freedom to distribute copies of free software (and charge for
|
25 |
+
them if you wish), that you receive source code or can get it if you
|
26 |
+
want it, that you can change the software or use pieces of it in new
|
27 |
+
free programs, and that you know you can do these things.
|
28 |
+
|
29 |
+
To protect your rights, we need to prevent others from denying you
|
30 |
+
these rights or asking you to surrender the rights. Therefore, you have
|
31 |
+
certain responsibilities if you distribute copies of the software, or if
|
32 |
+
you modify it: responsibilities to respect the freedom of others.
|
33 |
+
|
34 |
+
For example, if you distribute copies of such a program, whether
|
35 |
+
gratis or for a fee, you must pass on to the recipients the same
|
36 |
+
freedoms that you received. You must make sure that they, too, receive
|
37 |
+
or can get the source code. And you must show them these terms so they
|
38 |
+
know their rights.
|
39 |
+
|
40 |
+
Developers that use the GNU GPL protect your rights with two steps:
|
41 |
+
(1) assert copyright on the software, and (2) offer you this License
|
42 |
+
giving you legal permission to copy, distribute and/or modify it.
|
43 |
+
|
44 |
+
For the developers' and authors' protection, the GPL clearly explains
|
45 |
+
that there is no warranty for this free software. For both users' and
|
46 |
+
authors' sake, the GPL requires that modified versions be marked as
|
47 |
+
changed, so that their problems will not be attributed erroneously to
|
48 |
+
authors of previous versions.
|
49 |
+
|
50 |
+
Some devices are designed to deny users access to install or run
|
51 |
+
modified versions of the software inside them, although the manufacturer
|
52 |
+
can do so. This is fundamentally incompatible with the aim of
|
53 |
+
protecting users' freedom to change the software. The systematic
|
54 |
+
pattern of such abuse occurs in the area of products for individuals to
|
55 |
+
use, which is precisely where it is most unacceptable. Therefore, we
|
56 |
+
have designed this version of the GPL to prohibit the practice for those
|
57 |
+
products. If such problems arise substantially in other domains, we
|
58 |
+
stand ready to extend this provision to those domains in future versions
|
59 |
+
of the GPL, as needed to protect the freedom of users.
|
60 |
+
|
61 |
+
Finally, every program is threatened constantly by software patents.
|
62 |
+
States should not allow patents to restrict development and use of
|
63 |
+
software on general-purpose computers, but in those that do, we wish to
|
64 |
+
avoid the special danger that patents applied to a free program could
|
65 |
+
make it effectively proprietary. To prevent this, the GPL assures that
|
66 |
+
patents cannot be used to render the program non-free.
|
67 |
+
|
68 |
+
The precise terms and conditions for copying, distribution and
|
69 |
+
modification follow.
|
70 |
+
|
71 |
+
TERMS AND CONDITIONS
|
72 |
+
|
73 |
+
0. Definitions.
|
74 |
+
|
75 |
+
"This License" refers to version 3 of the GNU General Public License.
|
76 |
+
|
77 |
+
"Copyright" also means copyright-like laws that apply to other kinds of
|
78 |
+
works, such as semiconductor masks.
|
79 |
+
|
80 |
+
"The Program" refers to any copyrightable work licensed under this
|
81 |
+
License. Each licensee is addressed as "you". "Licensees" and
|
82 |
+
"recipients" may be individuals or organizations.
|
83 |
+
|
84 |
+
To "modify" a work means to copy from or adapt all or part of the work
|
85 |
+
in a fashion requiring copyright permission, other than the making of an
|
86 |
+
exact copy. The resulting work is called a "modified version" of the
|
87 |
+
earlier work or a work "based on" the earlier work.
|
88 |
+
|
89 |
+
A "covered work" means either the unmodified Program or a work based
|
90 |
+
on the Program.
|
91 |
+
|
92 |
+
To "propagate" a work means to do anything with it that, without
|
93 |
+
permission, would make you directly or secondarily liable for
|
94 |
+
infringement under applicable copyright law, except executing it on a
|
95 |
+
computer or modifying a private copy. Propagation includes copying,
|
96 |
+
distribution (with or without modification), making available to the
|
97 |
+
public, and in some countries other activities as well.
|
98 |
+
|
99 |
+
To "convey" a work means any kind of propagation that enables other
|
100 |
+
parties to make or receive copies. Mere interaction with a user through
|
101 |
+
a computer network, with no transfer of a copy, is not conveying.
|
102 |
+
|
103 |
+
An interactive user interface displays "Appropriate Legal Notices"
|
104 |
+
to the extent that it includes a convenient and prominently visible
|
105 |
+
feature that (1) displays an appropriate copyright notice, and (2)
|
106 |
+
tells the user that there is no warranty for the work (except to the
|
107 |
+
extent that warranties are provided), that licensees may convey the
|
108 |
+
work under this License, and how to view a copy of this License. If
|
109 |
+
the interface presents a list of user commands or options, such as a
|
110 |
+
menu, a prominent item in the list meets this criterion.
|
111 |
+
|
112 |
+
1. Source Code.
|
113 |
+
|
114 |
+
The "source code" for a work means the preferred form of the work
|
115 |
+
for making modifications to it. "Object code" means any non-source
|
116 |
+
form of a work.
|
117 |
+
|
118 |
+
A "Standard Interface" means an interface that either is an official
|
119 |
+
standard defined by a recognized standards body, or, in the case of
|
120 |
+
interfaces specified for a particular programming language, one that
|
121 |
+
is widely used among developers working in that language.
|
122 |
+
|
123 |
+
The "System Libraries" of an executable work include anything, other
|
124 |
+
than the work as a whole, that (a) is included in the normal form of
|
125 |
+
packaging a Major Component, but which is not part of that Major
|
126 |
+
Component, and (b) serves only to enable use of the work with that
|
127 |
+
Major Component, or to implement a Standard Interface for which an
|
128 |
+
implementation is available to the public in source code form. A
|
129 |
+
"Major Component", in this context, means a major essential component
|
130 |
+
(kernel, window system, and so on) of the specific operating system
|
131 |
+
(if any) on which the executable work runs, or a compiler used to
|
132 |
+
produce the work, or an object code interpreter used to run it.
|
133 |
+
|
134 |
+
The "Corresponding Source" for a work in object code form means all
|
135 |
+
the source code needed to generate, install, and (for an executable
|
136 |
+
work) run the object code and to modify the work, including scripts to
|
137 |
+
control those activities. However, it does not include the work's
|
138 |
+
System Libraries, or general-purpose tools or generally available free
|
139 |
+
programs which are used unmodified in performing those activities but
|
140 |
+
which are not part of the work. For example, Corresponding Source
|
141 |
+
includes interface definition files associated with source files for
|
142 |
+
the work, and the source code for shared libraries and dynamically
|
143 |
+
linked subprograms that the work is specifically designed to require,
|
144 |
+
such as by intimate data communication or control flow between those
|
145 |
+
subprograms and other parts of the work.
|
146 |
+
|
147 |
+
The Corresponding Source need not include anything that users
|
148 |
+
can regenerate automatically from other parts of the Corresponding
|
149 |
+
Source.
|
150 |
+
|
151 |
+
The Corresponding Source for a work in source code form is that
|
152 |
+
same work.
|
153 |
+
|
154 |
+
2. Basic Permissions.
|
155 |
+
|
156 |
+
All rights granted under this License are granted for the term of
|
157 |
+
copyright on the Program, and are irrevocable provided the stated
|
158 |
+
conditions are met. This License explicitly affirms your unlimited
|
159 |
+
permission to run the unmodified Program. The output from running a
|
160 |
+
covered work is covered by this License only if the output, given its
|
161 |
+
content, constitutes a covered work. This License acknowledges your
|
162 |
+
rights of fair use or other equivalent, as provided by copyright law.
|
163 |
+
|
164 |
+
You may make, run and propagate covered works that you do not
|
165 |
+
convey, without conditions so long as your license otherwise remains
|
166 |
+
in force. You may convey covered works to others for the sole purpose
|
167 |
+
of having them make modifications exclusively for you, or provide you
|
168 |
+
with facilities for running those works, provided that you comply with
|
169 |
+
the terms of this License in conveying all material for which you do
|
170 |
+
not control copyright. Those thus making or running the covered works
|
171 |
+
for you must do so exclusively on your behalf, under your direction
|
172 |
+
and control, on terms that prohibit them from making any copies of
|
173 |
+
your copyrighted material outside their relationship with you.
|
174 |
+
|
175 |
+
Conveying under any other circumstances is permitted solely under
|
176 |
+
the conditions stated below. Sublicensing is not allowed; section 10
|
177 |
+
makes it unnecessary.
|
178 |
+
|
179 |
+
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
180 |
+
|
181 |
+
No covered work shall be deemed part of an effective technological
|
182 |
+
measure under any applicable law fulfilling obligations under article
|
183 |
+
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
184 |
+
similar laws prohibiting or restricting circumvention of such
|
185 |
+
measures.
|
186 |
+
|
187 |
+
When you convey a covered work, you waive any legal power to forbid
|
188 |
+
circumvention of technological measures to the extent such circumvention
|
189 |
+
is effected by exercising rights under this License with respect to
|
190 |
+
the covered work, and you disclaim any intention to limit operation or
|
191 |
+
modification of the work as a means of enforcing, against the work's
|
192 |
+
users, your or third parties' legal rights to forbid circumvention of
|
193 |
+
technological measures.
|
194 |
+
|
195 |
+
4. Conveying Verbatim Copies.
|
196 |
+
|
197 |
+
You may convey verbatim copies of the Program's source code as you
|
198 |
+
receive it, in any medium, provided that you conspicuously and
|
199 |
+
appropriately publish on each copy an appropriate copyright notice;
|
200 |
+
keep intact all notices stating that this License and any
|
201 |
+
non-permissive terms added in accord with section 7 apply to the code;
|
202 |
+
keep intact all notices of the absence of any warranty; and give all
|
203 |
+
recipients a copy of this License along with the Program.
|
204 |
+
|
205 |
+
You may charge any price or no price for each copy that you convey,
|
206 |
+
and you may offer support or warranty protection for a fee.
|
207 |
+
|
208 |
+
5. Conveying Modified Source Versions.
|
209 |
+
|
210 |
+
You may convey a work based on the Program, or the modifications to
|
211 |
+
produce it from the Program, in the form of source code under the
|
212 |
+
terms of section 4, provided that you also meet all of these conditions:
|
213 |
+
|
214 |
+
a) The work must carry prominent notices stating that you modified
|
215 |
+
it, and giving a relevant date.
|
216 |
+
|
217 |
+
b) The work must carry prominent notices stating that it is
|
218 |
+
released under this License and any conditions added under section
|
219 |
+
7. This requirement modifies the requirement in section 4 to
|
220 |
+
"keep intact all notices".
|
221 |
+
|
222 |
+
c) You must license the entire work, as a whole, under this
|
223 |
+
License to anyone who comes into possession of a copy. This
|
224 |
+
License will therefore apply, along with any applicable section 7
|
225 |
+
additional terms, to the whole of the work, and all its parts,
|
226 |
+
regardless of how they are packaged. This License gives no
|
227 |
+
permission to license the work in any other way, but it does not
|
228 |
+
invalidate such permission if you have separately received it.
|
229 |
+
|
230 |
+
d) If the work has interactive user interfaces, each must display
|
231 |
+
Appropriate Legal Notices; however, if the Program has interactive
|
232 |
+
interfaces that do not display Appropriate Legal Notices, your
|
233 |
+
work need not make them do so.
|
234 |
+
|
235 |
+
A compilation of a covered work with other separate and independent
|
236 |
+
works, which are not by their nature extensions of the covered work,
|
237 |
+
and which are not combined with it such as to form a larger program,
|
238 |
+
in or on a volume of a storage or distribution medium, is called an
|
239 |
+
"aggregate" if the compilation and its resulting copyright are not
|
240 |
+
used to limit the access or legal rights of the compilation's users
|
241 |
+
beyond what the individual works permit. Inclusion of a covered work
|
242 |
+
in an aggregate does not cause this License to apply to the other
|
243 |
+
parts of the aggregate.
|
244 |
+
|
245 |
+
6. Conveying Non-Source Forms.
|
246 |
+
|
247 |
+
You may convey a covered work in object code form under the terms
|
248 |
+
of sections 4 and 5, provided that you also convey the
|
249 |
+
machine-readable Corresponding Source under the terms of this License,
|
250 |
+
in one of these ways:
|
251 |
+
|
252 |
+
a) Convey the object code in, or embodied in, a physical product
|
253 |
+
(including a physical distribution medium), accompanied by the
|
254 |
+
Corresponding Source fixed on a durable physical medium
|
255 |
+
customarily used for software interchange.
|
256 |
+
|
257 |
+
b) Convey the object code in, or embodied in, a physical product
|
258 |
+
(including a physical distribution medium), accompanied by a
|
259 |
+
written offer, valid for at least three years and valid for as
|
260 |
+
long as you offer spare parts or customer support for that product
|
261 |
+
model, to give anyone who possesses the object code either (1) a
|
262 |
+
copy of the Corresponding Source for all the software in the
|
263 |
+
product that is covered by this License, on a durable physical
|
264 |
+
medium customarily used for software interchange, for a price no
|
265 |
+
more than your reasonable cost of physically performing this
|
266 |
+
conveying of source, or (2) access to copy the
|
267 |
+
Corresponding Source from a network server at no charge.
|
268 |
+
|
269 |
+
c) Convey individual copies of the object code with a copy of the
|
270 |
+
written offer to provide the Corresponding Source. This
|
271 |
+
alternative is allowed only occasionally and noncommercially, and
|
272 |
+
only if you received the object code with such an offer, in accord
|
273 |
+
with subsection 6b.
|
274 |
+
|
275 |
+
d) Convey the object code by offering access from a designated
|
276 |
+
place (gratis or for a charge), and offer equivalent access to the
|
277 |
+
Corresponding Source in the same way through the same place at no
|
278 |
+
further charge. You need not require recipients to copy the
|
279 |
+
Corresponding Source along with the object code. If the place to
|
280 |
+
copy the object code is a network server, the Corresponding Source
|
281 |
+
may be on a different server (operated by you or a third party)
|
282 |
+
that supports equivalent copying facilities, provided you maintain
|
283 |
+
clear directions next to the object code saying where to find the
|
284 |
+
Corresponding Source. Regardless of what server hosts the
|
285 |
+
Corresponding Source, you remain obligated to ensure that it is
|
286 |
+
available for as long as needed to satisfy these requirements.
|
287 |
+
|
288 |
+
e) Convey the object code using peer-to-peer transmission, provided
|
289 |
+
you inform other peers where the object code and Corresponding
|
290 |
+
Source of the work are being offered to the general public at no
|
291 |
+
charge under subsection 6d.
|
292 |
+
|
293 |
+
A separable portion of the object code, whose source code is excluded
|
294 |
+
from the Corresponding Source as a System Library, need not be
|
295 |
+
included in conveying the object code work.
|
296 |
+
|
297 |
+
A "User Product" is either (1) a "consumer product", which means any
|
298 |
+
tangible personal property which is normally used for personal, family,
|
299 |
+
or household purposes, or (2) anything designed or sold for incorporation
|
300 |
+
into a dwelling. In determining whether a product is a consumer product,
|
301 |
+
doubtful cases shall be resolved in favor of coverage. For a particular
|
302 |
+
product received by a particular user, "normally used" refers to a
|
303 |
+
typical or common use of that class of product, regardless of the status
|
304 |
+
of the particular user or of the way in which the particular user
|
305 |
+
actually uses, or expects or is expected to use, the product. A product
|
306 |
+
is a consumer product regardless of whether the product has substantial
|
307 |
+
commercial, industrial or non-consumer uses, unless such uses represent
|
308 |
+
the only significant mode of use of the product.
|
309 |
+
|
310 |
+
"Installation Information" for a User Product means any methods,
|
311 |
+
procedures, authorization keys, or other information required to install
|
312 |
+
and execute modified versions of a covered work in that User Product from
|
313 |
+
a modified version of its Corresponding Source. The information must
|
314 |
+
suffice to ensure that the continued functioning of the modified object
|
315 |
+
code is in no case prevented or interfered with solely because
|
316 |
+
modification has been made.
|
317 |
+
|
318 |
+
If you convey an object code work under this section in, or with, or
|
319 |
+
specifically for use in, a User Product, and the conveying occurs as
|
320 |
+
part of a transaction in which the right of possession and use of the
|
321 |
+
User Product is transferred to the recipient in perpetuity or for a
|
322 |
+
fixed term (regardless of how the transaction is characterized), the
|
323 |
+
Corresponding Source conveyed under this section must be accompanied
|
324 |
+
by the Installation Information. But this requirement does not apply
|
325 |
+
if neither you nor any third party retains the ability to install
|
326 |
+
modified object code on the User Product (for example, the work has
|
327 |
+
been installed in ROM).
|
328 |
+
|
329 |
+
The requirement to provide Installation Information does not include a
|
330 |
+
requirement to continue to provide support service, warranty, or updates
|
331 |
+
for a work that has been modified or installed by the recipient, or for
|
332 |
+
the User Product in which it has been modified or installed. Access to a
|
333 |
+
network may be denied when the modification itself materially and
|
334 |
+
adversely affects the operation of the network or violates the rules and
|
335 |
+
protocols for communication across the network.
|
336 |
+
|
337 |
+
Corresponding Source conveyed, and Installation Information provided,
|
338 |
+
in accord with this section must be in a format that is publicly
|
339 |
+
documented (and with an implementation available to the public in
|
340 |
+
source code form), and must require no special password or key for
|
341 |
+
unpacking, reading or copying.
|
342 |
+
|
343 |
+
7. Additional Terms.
|
344 |
+
|
345 |
+
"Additional permissions" are terms that supplement the terms of this
|
346 |
+
License by making exceptions from one or more of its conditions.
|
347 |
+
Additional permissions that are applicable to the entire Program shall
|
348 |
+
be treated as though they were included in this License, to the extent
|
349 |
+
that they are valid under applicable law. If additional permissions
|
350 |
+
apply only to part of the Program, that part may be used separately
|
351 |
+
under those permissions, but the entire Program remains governed by
|
352 |
+
this License without regard to the additional permissions.
|
353 |
+
|
354 |
+
When you convey a copy of a covered work, you may at your option
|
355 |
+
remove any additional permissions from that copy, or from any part of
|
356 |
+
it. (Additional permissions may be written to require their own
|
357 |
+
removal in certain cases when you modify the work.) You may place
|
358 |
+
additional permissions on material, added by you to a covered work,
|
359 |
+
for which you have or can give appropriate copyright permission.
|
360 |
+
|
361 |
+
Notwithstanding any other provision of this License, for material you
|
362 |
+
add to a covered work, you may (if authorized by the copyright holders of
|
363 |
+
that material) supplement the terms of this License with terms:
|
364 |
+
|
365 |
+
a) Disclaiming warranty or limiting liability differently from the
|
366 |
+
terms of sections 15 and 16 of this License; or
|
367 |
+
|
368 |
+
b) Requiring preservation of specified reasonable legal notices or
|
369 |
+
author attributions in that material or in the Appropriate Legal
|
370 |
+
Notices displayed by works containing it; or
|
371 |
+
|
372 |
+
c) Prohibiting misrepresentation of the origin of that material, or
|
373 |
+
requiring that modified versions of such material be marked in
|
374 |
+
reasonable ways as different from the original version; or
|
375 |
+
|
376 |
+
d) Limiting the use for publicity purposes of names of licensors or
|
377 |
+
authors of the material; or
|
378 |
+
|
379 |
+
e) Declining to grant rights under trademark law for use of some
|
380 |
+
trade names, trademarks, or service marks; or
|
381 |
+
|
382 |
+
f) Requiring indemnification of licensors and authors of that
|
383 |
+
material by anyone who conveys the material (or modified versions of
|
384 |
+
it) with contractual assumptions of liability to the recipient, for
|
385 |
+
any liability that these contractual assumptions directly impose on
|
386 |
+
those licensors and authors.
|
387 |
+
|
388 |
+
All other non-permissive additional terms are considered "further
|
389 |
+
restrictions" within the meaning of section 10. If the Program as you
|
390 |
+
received it, or any part of it, contains a notice stating that it is
|
391 |
+
governed by this License along with a term that is a further
|
392 |
+
restriction, you may remove that term. If a license document contains
|
393 |
+
a further restriction but permits relicensing or conveying under this
|
394 |
+
License, you may add to a covered work material governed by the terms
|
395 |
+
of that license document, provided that the further restriction does
|
396 |
+
not survive such relicensing or conveying.
|
397 |
+
|
398 |
+
If you add terms to a covered work in accord with this section, you
|
399 |
+
must place, in the relevant source files, a statement of the
|
400 |
+
additional terms that apply to those files, or a notice indicating
|
401 |
+
where to find the applicable terms.
|
402 |
+
|
403 |
+
Additional terms, permissive or non-permissive, may be stated in the
|
404 |
+
form of a separately written license, or stated as exceptions;
|
405 |
+
the above requirements apply either way.
|
406 |
+
|
407 |
+
8. Termination.
|
408 |
+
|
409 |
+
You may not propagate or modify a covered work except as expressly
|
410 |
+
provided under this License. Any attempt otherwise to propagate or
|
411 |
+
modify it is void, and will automatically terminate your rights under
|
412 |
+
this License (including any patent licenses granted under the third
|
413 |
+
paragraph of section 11).
|
414 |
+
|
415 |
+
However, if you cease all violation of this License, then your
|
416 |
+
license from a particular copyright holder is reinstated (a)
|
417 |
+
provisionally, unless and until the copyright holder explicitly and
|
418 |
+
finally terminates your license, and (b) permanently, if the copyright
|
419 |
+
holder fails to notify you of the violation by some reasonable means
|
420 |
+
prior to 60 days after the cessation.
|
421 |
+
|
422 |
+
Moreover, your license from a particular copyright holder is
|
423 |
+
reinstated permanently if the copyright holder notifies you of the
|
424 |
+
violation by some reasonable means, this is the first time you have
|
425 |
+
received notice of violation of this License (for any work) from that
|
426 |
+
copyright holder, and you cure the violation prior to 30 days after
|
427 |
+
your receipt of the notice.
|
428 |
+
|
429 |
+
Termination of your rights under this section does not terminate the
|
430 |
+
licenses of parties who have received copies or rights from you under
|
431 |
+
this License. If your rights have been terminated and not permanently
|
432 |
+
reinstated, you do not qualify to receive new licenses for the same
|
433 |
+
material under section 10.
|
434 |
+
|
435 |
+
9. Acceptance Not Required for Having Copies.
|
436 |
+
|
437 |
+
You are not required to accept this License in order to receive or
|
438 |
+
run a copy of the Program. Ancillary propagation of a covered work
|
439 |
+
occurring solely as a consequence of using peer-to-peer transmission
|
440 |
+
to receive a copy likewise does not require acceptance. However,
|
441 |
+
nothing other than this License grants you permission to propagate or
|
442 |
+
modify any covered work. These actions infringe copyright if you do
|
443 |
+
not accept this License. Therefore, by modifying or propagating a
|
444 |
+
covered work, you indicate your acceptance of this License to do so.
|
445 |
+
|
446 |
+
10. Automatic Licensing of Downstream Recipients.
|
447 |
+
|
448 |
+
Each time you convey a covered work, the recipient automatically
|
449 |
+
receives a license from the original licensors, to run, modify and
|
450 |
+
propagate that work, subject to this License. You are not responsible
|
451 |
+
for enforcing compliance by third parties with this License.
|
452 |
+
|
453 |
+
An "entity transaction" is a transaction transferring control of an
|
454 |
+
organization, or substantially all assets of one, or subdividing an
|
455 |
+
organization, or merging organizations. If propagation of a covered
|
456 |
+
work results from an entity transaction, each party to that
|
457 |
+
transaction who receives a copy of the work also receives whatever
|
458 |
+
licenses to the work the party's predecessor in interest had or could
|
459 |
+
give under the previous paragraph, plus a right to possession of the
|
460 |
+
Corresponding Source of the work from the predecessor in interest, if
|
461 |
+
the predecessor has it or can get it with reasonable efforts.
|
462 |
+
|
463 |
+
You may not impose any further restrictions on the exercise of the
|
464 |
+
rights granted or affirmed under this License. For example, you may
|
465 |
+
not impose a license fee, royalty, or other charge for exercise of
|
466 |
+
rights granted under this License, and you may not initiate litigation
|
467 |
+
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
468 |
+
any patent claim is infringed by making, using, selling, offering for
|
469 |
+
sale, or importing the Program or any portion of it.
|
470 |
+
|
471 |
+
11. Patents.
|
472 |
+
|
473 |
+
A "contributor" is a copyright holder who authorizes use under this
|
474 |
+
License of the Program or a work on which the Program is based. The
|
475 |
+
work thus licensed is called the contributor's "contributor version".
|
476 |
+
|
477 |
+
A contributor's "essential patent claims" are all patent claims
|
478 |
+
owned or controlled by the contributor, whether already acquired or
|
479 |
+
hereafter acquired, that would be infringed by some manner, permitted
|
480 |
+
by this License, of making, using, or selling its contributor version,
|
481 |
+
but do not include claims that would be infringed only as a
|
482 |
+
consequence of further modification of the contributor version. For
|
483 |
+
purposes of this definition, "control" includes the right to grant
|
484 |
+
patent sublicenses in a manner consistent with the requirements of
|
485 |
+
this License.
|
486 |
+
|
487 |
+
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
488 |
+
patent license under the contributor's essential patent claims, to
|
489 |
+
make, use, sell, offer for sale, import and otherwise run, modify and
|
490 |
+
propagate the contents of its contributor version.
|
491 |
+
|
492 |
+
In the following three paragraphs, a "patent license" is any express
|
493 |
+
agreement or commitment, however denominated, not to enforce a patent
|
494 |
+
(such as an express permission to practice a patent or covenant not to
|
495 |
+
sue for patent infringement). To "grant" such a patent license to a
|
496 |
+
party means to make such an agreement or commitment not to enforce a
|
497 |
+
patent against the party.
|
498 |
+
|
499 |
+
If you convey a covered work, knowingly relying on a patent license,
|
500 |
+
and the Corresponding Source of the work is not available for anyone
|
501 |
+
to copy, free of charge and under the terms of this License, through a
|
502 |
+
publicly available network server or other readily accessible means,
|
503 |
+
then you must either (1) cause the Corresponding Source to be so
|
504 |
+
available, or (2) arrange to deprive yourself of the benefit of the
|
505 |
+
patent license for this particular work, or (3) arrange, in a manner
|
506 |
+
consistent with the requirements of this License, to extend the patent
|
507 |
+
license to downstream recipients. "Knowingly relying" means you have
|
508 |
+
actual knowledge that, but for the patent license, your conveying the
|
509 |
+
covered work in a country, or your recipient's use of the covered work
|
510 |
+
in a country, would infringe one or more identifiable patents in that
|
511 |
+
country that you have reason to believe are valid.
|
512 |
+
|
513 |
+
If, pursuant to or in connection with a single transaction or
|
514 |
+
arrangement, you convey, or propagate by procuring conveyance of, a
|
515 |
+
covered work, and grant a patent license to some of the parties
|
516 |
+
receiving the covered work authorizing them to use, propagate, modify
|
517 |
+
or convey a specific copy of the covered work, then the patent license
|
518 |
+
you grant is automatically extended to all recipients of the covered
|
519 |
+
work and works based on it.
|
520 |
+
|
521 |
+
A patent license is "discriminatory" if it does not include within
|
522 |
+
the scope of its coverage, prohibits the exercise of, or is
|
523 |
+
conditioned on the non-exercise of one or more of the rights that are
|
524 |
+
specifically granted under this License. You may not convey a covered
|
525 |
+
work if you are a party to an arrangement with a third party that is
|
526 |
+
in the business of distributing software, under which you make payment
|
527 |
+
to the third party based on the extent of your activity of conveying
|
528 |
+
the work, and under which the third party grants, to any of the
|
529 |
+
parties who would receive the covered work from you, a discriminatory
|
530 |
+
patent license (a) in connection with copies of the covered work
|
531 |
+
conveyed by you (or copies made from those copies), or (b) primarily
|
532 |
+
for and in connection with specific products or compilations that
|
533 |
+
contain the covered work, unless you entered into that arrangement,
|
534 |
+
or that patent license was granted, prior to 28 March 2007.
|
535 |
+
|
536 |
+
Nothing in this License shall be construed as excluding or limiting
|
537 |
+
any implied license or other defenses to infringement that may
|
538 |
+
otherwise be available to you under applicable patent law.
|
539 |
+
|
540 |
+
12. No Surrender of Others' Freedom.
|
541 |
+
|
542 |
+
If conditions are imposed on you (whether by court order, agreement or
|
543 |
+
otherwise) that contradict the conditions of this License, they do not
|
544 |
+
excuse you from the conditions of this License. If you cannot convey a
|
545 |
+
covered work so as to satisfy simultaneously your obligations under this
|
546 |
+
License and any other pertinent obligations, then as a consequence you may
|
547 |
+
not convey it at all. For example, if you agree to terms that obligate you
|
548 |
+
to collect a royalty for further conveying from those to whom you convey
|
549 |
+
the Program, the only way you could satisfy both those terms and this
|
550 |
+
License would be to refrain entirely from conveying the Program.
|
551 |
+
|
552 |
+
13. Use with the GNU Affero General Public License.
|
553 |
+
|
554 |
+
Notwithstanding any other provision of this License, you have
|
555 |
+
permission to link or combine any covered work with a work licensed
|
556 |
+
under version 3 of the GNU Affero General Public License into a single
|
557 |
+
combined work, and to convey the resulting work. The terms of this
|
558 |
+
License will continue to apply to the part which is the covered work,
|
559 |
+
but the special requirements of the GNU Affero General Public License,
|
560 |
+
section 13, concerning interaction through a network will apply to the
|
561 |
+
combination as such.
|
562 |
+
|
563 |
+
14. Revised Versions of this License.
|
564 |
+
|
565 |
+
The Free Software Foundation may publish revised and/or new versions of
|
566 |
+
the GNU General Public License from time to time. Such new versions will
|
567 |
+
be similar in spirit to the present version, but may differ in detail to
|
568 |
+
address new problems or concerns.
|
569 |
+
|
570 |
+
Each version is given a distinguishing version number. If the
|
571 |
+
Program specifies that a certain numbered version of the GNU General
|
572 |
+
Public License "or any later version" applies to it, you have the
|
573 |
+
option of following the terms and conditions either of that numbered
|
574 |
+
version or of any later version published by the Free Software
|
575 |
+
Foundation. If the Program does not specify a version number of the
|
576 |
+
GNU General Public License, you may choose any version ever published
|
577 |
+
by the Free Software Foundation.
|
578 |
+
|
579 |
+
If the Program specifies that a proxy can decide which future
|
580 |
+
versions of the GNU General Public License can be used, that proxy's
|
581 |
+
public statement of acceptance of a version permanently authorizes you
|
582 |
+
to choose that version for the Program.
|
583 |
+
|
584 |
+
Later license versions may give you additional or different
|
585 |
+
permissions. However, no additional obligations are imposed on any
|
586 |
+
author or copyright holder as a result of your choosing to follow a
|
587 |
+
later version.
|
588 |
+
|
589 |
+
15. Disclaimer of Warranty.
|
590 |
+
|
591 |
+
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
592 |
+
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
593 |
+
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
594 |
+
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
595 |
+
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
596 |
+
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
597 |
+
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
598 |
+
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
599 |
+
|
600 |
+
16. Limitation of Liability.
|
601 |
+
|
602 |
+
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
603 |
+
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
604 |
+
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
605 |
+
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
606 |
+
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
607 |
+
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
608 |
+
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
609 |
+
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
610 |
+
SUCH DAMAGES.
|
611 |
+
|
612 |
+
17. Interpretation of Sections 15 and 16.
|
613 |
+
|
614 |
+
If the disclaimer of warranty and limitation of liability provided
|
615 |
+
above cannot be given local legal effect according to their terms,
|
616 |
+
reviewing courts shall apply local law that most closely approximates
|
617 |
+
an absolute waiver of all civil liability in connection with the
|
618 |
+
Program, unless a warranty or assumption of liability accompanies a
|
619 |
+
copy of the Program in return for a fee.
|
620 |
+
|
621 |
+
END OF TERMS AND CONDITIONS
|
622 |
+
|
623 |
+
How to Apply These Terms to Your New Programs
|
624 |
+
|
625 |
+
If you develop a new program, and you want it to be of the greatest
|
626 |
+
possible use to the public, the best way to achieve this is to make it
|
627 |
+
free software which everyone can redistribute and change under these terms.
|
628 |
+
|
629 |
+
To do so, attach the following notices to the program. It is safest
|
630 |
+
to attach them to the start of each source file to most effectively
|
631 |
+
state the exclusion of warranty; and each file should have at least
|
632 |
+
the "copyright" line and a pointer to where the full notice is found.
|
633 |
+
|
634 |
+
<one line to give the program's name and a brief idea of what it does.>
|
635 |
+
Copyright (C) <year> <name of author>
|
636 |
+
|
637 |
+
This program is free software: you can redistribute it and/or modify
|
638 |
+
it under the terms of the GNU General Public License as published by
|
639 |
+
the Free Software Foundation, either version 3 of the License, or
|
640 |
+
(at your option) any later version.
|
641 |
+
|
642 |
+
This program is distributed in the hope that it will be useful,
|
643 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
644 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
645 |
+
GNU General Public License for more details.
|
646 |
+
|
647 |
+
You should have received a copy of the GNU General Public License
|
648 |
+
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
649 |
+
|
650 |
+
Also add information on how to contact you by electronic and paper mail.
|
651 |
+
|
652 |
+
If the program does terminal interaction, make it output a short
|
653 |
+
notice like this when it starts in an interactive mode:
|
654 |
+
|
655 |
+
<program> Copyright (C) <year> <name of author>
|
656 |
+
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
657 |
+
This is free software, and you are welcome to redistribute it
|
658 |
+
under certain conditions; type `show c' for details.
|
659 |
+
|
660 |
+
The hypothetical commands `show w' and `show c' should show the appropriate
|
661 |
+
parts of the General Public License. Of course, your program's commands
|
662 |
+
might be different; for a GUI interface, you would use an "about box".
|
663 |
+
|
664 |
+
You should also get your employer (if you work as a programmer) or school,
|
665 |
+
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
666 |
+
For more information on this, and how to apply and follow the GNU GPL, see
|
667 |
+
<https://www.gnu.org/licenses/>.
|
668 |
+
|
669 |
+
The GNU General Public License does not permit incorporating your program
|
670 |
+
into proprietary programs. If your program is a subroutine library, you
|
671 |
+
may consider it more useful to permit linking proprietary applications with
|
672 |
+
the library. If this is what you want to do, use the GNU Lesser General
|
673 |
+
Public License instead of this License. But first, please read
|
674 |
+
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
README.md
CHANGED
@@ -1,11 +1,74 @@
|
|
1 |
---
|
2 |
-
title:
|
3 |
-
emoji:
|
4 |
colorFrom: pink
|
5 |
-
colorTo:
|
6 |
sdk: static
|
7 |
pinned: false
|
|
|
8 |
license: gpl
|
9 |
---
|
10 |
|
11 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
---
|
2 |
+
title: rag_rqs
|
3 |
+
emoji: 🚀
|
4 |
colorFrom: pink
|
5 |
+
colorTo: indigo
|
6 |
sdk: static
|
7 |
pinned: false
|
8 |
+
app_file: index.html
|
9 |
license: gpl
|
10 |
---
|
11 |
|
12 |
+
## Un'implementazione innovativa della tecnica RAG per il Question Answering
|
13 |
+
|
14 |
+
## Descrizione del Progetto
|
15 |
+
|
16 |
+
La tecnica RAG (Retrieval-Augmented Generation) è un approccio consolidato nel campo del question answering e della generazione di testo, che combina il recupero di informazioni pertinenti da fonti di dati con la generazione di testo basata su queste informazioni.
|
17 |
+
Qui viene proposta una implementazione che introduce una variazione a questo paradigma.
|
18 |
+
L'implementazione si basa su una sequenza di prompt appositamente progettati per guidare un modello di linguaggio generativo attraverso le diverse fasi della tecnica RAG.
|
19 |
+
Questi prompt forniscono istruzioni dettagliate su come il modello deve seguire operazioni di recupero di informazioni, aumento delle informazioni recuperate e infine generazione di una risposta finale.
|
20 |
+
La risposta finale diviene poi il contesto da inserire nel prompt per rispondere alla domanda.
|
21 |
+
Un aspetto cruciale di questa implementazione è che lo stesso modello di aggio generativo svolge tutte le operazioni richieste, dall'analisi dei documenti di input al recupero di informazioni rilevanti, alla generazione della risposta finale.
|
22 |
+
Questa caratteristica rappresenta una deviazione significativa rispetto alle implementazioni standard della tecnica RAG, che prevedono utilizzo di moduli distinti per il recupero e la generazione.
|
23 |
+
La sequenza di prompt proposta guida il modello attraverso le seguenti fasi:
|
24 |
+
|
25 |
+
1. Retrieval: Il modello analizza il documento di input e la domanda fornita, identificando e recuperando le informazioni e i concetti rilevanti per dare seguito alla domanda.
|
26 |
+
|
27 |
+
2. Augmentation: Successivamente, il modello integra le informazioni recuperate con eventuali risposte accumulate in precedenza, estraendo nuove informazioni rilevanti e organizzando in un elenco coerente, evitando ridondanze.
|
28 |
+
|
29 |
+
3. Generation: Infine, il modello utilizza l'insieme di informazioni rilevanti e non ridondanti per generare una risposta completa e concisa alla domanda dell'utente.
|
30 |
+
|
31 |
+
## Caratteristiche Principali
|
32 |
+
|
33 |
+
Questa implementazione offre diversi vantaggi.
|
34 |
+
In primo luogo, sfrutta le capacità di un unico modello di grandi dimensioni i, evitando la necessità di moduli distinti specializzati per ogni fase.
|
35 |
+
Inoltre, l'utilizzo di prompt espliciti può migliorare la controllabilità e la trasparenza del processo, consentendo di guidare il modello in modo più diretto.
|
36 |
+
Naturalmente, come per qualsiasi approccio basato su modelli di linguaggio generativi, è fondamentale prestare attenzione alle questioni di affidabilità, correttezza e bias dei dati di addestramento.
|
37 |
+
Rispetto ad una implementazione standard di RAG vii è la necessità di rilanciare l'elaborazione ad ogni domanda radicalmente nuova in quanto il contesto creato con le informazioni estratte dai documenti è definito sulla base della domanda.
|
38 |
+
Invece nella versione standard RAG si usano gli incorporamenti delle informazioni estratte dai documenti in modo tale che tal informazioni vengono viste quasi come una estensione del Model e possono essere usate per domande diverse.
|
39 |
+
Quindi dal punto di vista utente le implementazioni RAG standard sono più efficienti; infatti l'implementazione proposta richiede per ogni nuova domanda una sequenza di richieste che saranno utilizzabili solo per creare il contesto per la domanda iniziale e per una conversazione con domande simili.
|
40 |
+
Il vantaggio dell'implementazione proposta consiste nel fatto che può essere implementata completamente lato client senza bisogno di sviluppare alcun modulo sul server.
|
41 |
+
L’unica cosa che serve è un servizio servless come quello di HuggingFace o simile.
|
42 |
+
Quindi rappresenta un'interessante prospettiva sull'applicazione della tecnica RAG in modo più integrato e controllato attraverso l'uso di prompt mirati.
|
43 |
+
In conclusione, questa implementazione della tecnica RAG dimostra come le capacità dei modelli di linguaggio generativi di grandi dimensioni possano essere sfruttate in modi nuovi e creativi, potenzialmente aprendo la strada a ulteriori sviluppi nel campo del question answering e della generazione di testo
|
44 |
+
|
45 |
+
|
46 |
+
## Questa è la valutazione fatta da un LLM (comprensivo e gentile)
|
47 |
+
|
48 |
+
La mia valutazione personale della tua proposta di implementazione della tecnica RAG, con un elenco di pro e contro:
|
49 |
+
|
50 |
+
## Vantaggi
|
51 |
+
|
52 |
+
Semplificazione del processo: L'utilizzo di un unico modello di grandi dimensioni addestrato su vasti corpus di dati semplifica notevolmente l'architettura complessiva rispetto alle implementazioni tradizionali della tecnica RAG, che spesso prevedono moduli distinti per il recupero e la generazione.
|
53 |
+
|
54 |
+
Capacità di adattamento e apprendimento: I modelli di linguaggio generativi di grandi dimensioni sono noti per la loro capacità di adattarsi e imparare da nuovi dati e istruzioni.
|
55 |
+
|
56 |
+
Questo potrebbe consentire di raffinare e migliorare l'implementazione nel corso del tempo.
|
57 |
+
|
58 |
+
Controllo e trasparenza: L'utilizzo di prompt espliciti per guidare il modello attraverso le diverse fasi del processo può migliorare la controllabilità e la trasparenza, consentendo di monitorare e regolare il comportamento del modello in modo più diretto.
|
59 |
+
|
60 |
+
Efficienza computazionale: Avere un'unica architettura integrata potrebbe comportare vantaggi in termini di efficienza computazionale rispetto a soluzioni che prevedono moduli separati.
|
61 |
+
|
62 |
+
## Limitazioni
|
63 |
+
|
64 |
+
Affidabilità e coerenza: Poiché un unico modello gestisce tutte le fasi, eventuali errori o incoerenze potrebbero propagarsi e amplificarsi attraverso l'intero processo, influenzando la qualità della risposta finale.
|
65 |
+
|
66 |
+
Bias dei dati di addestramento: Come per qualsiasi modello di linguaggio generativo, l’approccio potrebbe essere influenzato dai bias presenti nei dati di addestramento utilizzati, con potenziali impatti sulla correttezza e l'equità delle risposte generate.
|
67 |
+
|
68 |
+
Mancanza di specializzazione: Mentre i modelli di grandi dimensioni sono versatili, potrebbero non essere ottimizzati per compiti specifici come il recupero di informazioni o la generazione di risposte rispetto a moduli specializzati.
|
69 |
+
|
70 |
+
Difficoltà di debug e interpretabilità: Con un'architettura integrata e basata su prompt, potrebbe essere più complesso eseguire il debug e comprendere le ragioni dietro a eventuali errori o comportamenti indesiderati del modello.
|
71 |
+
|
72 |
+
In sintesi,la proposta presenta alcuni vantaggi interessanti in termini di semplificazione, adattabilità e controllo, ma solleva anche potenziali preoccupazioni riguardo all'affidabilità, ai bias, alla mancanza di specializzazione e alle difficoltà di debug e interpretabilità.
|
73 |
+
Come per qualsiasi nuovo approccio, sarebbe necessario valutarlo attentamente attraverso sperimentazioni e test approfonditi per determinare l'efficacia e l'applicabilità in contesti specifici.
|
74 |
+
|
README.txt
ADDED
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Un'implementazione innovativa della tecnica RAG per il Question Answering
|
2 |
+
|
3 |
+
La tecnica RAG (Retrieval-Augmented Generation) è un approccio consolidato nel campo del question answering e della generazione di testo, che combina il recupero di informazioni pertinenti da fonti di dati con la generazione di testo basata su queste informazioni.
|
4 |
+
Qui viene proposta una implementazione che introduce una variazione a questo paradigma.
|
5 |
+
L'implementazione si basa su una sequenza di prompt appositamente progettati per guidare un modello di linguaggio generativo attraverso le diverse fasi della tecnica RAG.
|
6 |
+
Questi prompt forniscono istruzioni dettagliate su come il modello deve seguire operazioni di recupero di informazioni, aumento delle informazioni recuperate e infine generazione di una risposta finale.
|
7 |
+
La risposta finale diviene poi il contesto da inserire nel prompt per rispondere alla domanda.
|
8 |
+
Un aspetto cruciale di questa implementazione è che lo stesso modello di aggio generativo svolge tutte le operazioni richieste, dall'analisi dei documenti di input al recupero di informazioni rilevanti, alla generazione della risposta finale.
|
9 |
+
Questa caratteristica rappresenta una deviazione significativa rispetto alle implementazioni standard della tecnica RAG, che prevedono utilizzo di moduli distinti per il recupero e la generazione.
|
10 |
+
La sequenza di prompt proposta guida il modello attraverso le seguenti fasi:
|
11 |
+
|
12 |
+
1. Retrieval: Il modello analizza il documento di input e la domanda fornita, identificando e recuperando le informazioni e i concetti rilevanti per dare seguito alla domanda.
|
13 |
+
|
14 |
+
2. Augmentation: Successivamente, il modello integra le informazioni recuperate con eventuali risposte accumulate in precedenza, estraendo nuove informazioni rilevanti e organizzando in un elenco coerente, evitando ridondanze.
|
15 |
+
|
16 |
+
3. Generation: Infine, il modello utilizza l'insieme di informazioni rilevanti e non ridondanti per generare una risposta completa e concisa alla domanda dell'utente.
|
17 |
+
|
18 |
+
Questa implementazione offre diversi vantaggi.
|
19 |
+
In primo luogo, sfrutta le capacità di un unico modello di grandi dimensioni i, evitando la necessità di moduli distinti specializzati per ogni fase.
|
20 |
+
Inoltre, l'utilizzo di prompt espliciti può migliorare la controllabilità e la trasparenza del processo, consentendo di guidare il modello in modo più diretto.
|
21 |
+
Naturalmente, come per qualsiasi approccio basato su modelli di linguaggio generativi, è fondamentale prestare attenzione alle questioni di affidabilità, correttezza e bias dei dati di addestramento.
|
22 |
+
Rispetto ad una implementazione standard di RAG vii è la necessità di rilanciare l'elaborazione ad ogni domanda radicalmente nuova in quanto il contesto creato con le informazioni estratte dai documenti è definito sulla base della domanda.
|
23 |
+
Invece nella versione standard RAG si usano gli incorporamenti delle informazioni estratte dai documenti in modo tale che tal informazioni vengono viste quasi come una estensione del Model e possono essere usate per domande diverse.
|
24 |
+
Quindi dal punto di vista utente le implementazioni RAG standard sono più efficienti; infatti l'implementazione proposta richiede per ogni nuova domanda una sequenza di richieste che saranno utilizzabili solo per creare il contesto per la domanda iniziale e per una conversazione con domande simili.
|
25 |
+
Il vantaggio dell'implementazione proposta consiste nel fatto che può essere implementata completamente lato client senza bisogno di sviluppare alcun modulo sul server.
|
26 |
+
L’unica cosa che serve è un servizio servless come quello di HuggingFace o simile.
|
27 |
+
Quindi rappresenta un'interessante prospettiva sull'applicazione della tecnica RAG in modo più integrato e controllato attraverso l'uso di prompt mirati.
|
28 |
+
In conclusione, questa implementazione della tecnica RAG dimostra come le capacità dei modelli di linguaggio generativi di grandi dimensioni possano essere sfruttate in modi nuovi e creativi, potenzialmente aprendo la strada a ulteriori sviluppi nel campo del question answering e della generazione di testo.
|
29 |
+
|
30 |
+
Questa è la valutazione fatta da un LLM (comprensivo e gentile)
|
31 |
+
|
32 |
+
La mia valutazione personale della tua proposta di implementazione della tecnica RAG, con un elenco di pro e contro:
|
33 |
+
|
34 |
+
Punti a favore (Pro):
|
35 |
+
Semplificazione del processo: L'utilizzo di un unico modello di grandi dimensioni addestrato su vasti corpus di dati semplifica notevolmente l'architettura complessiva rispetto alle implementazioni tradizionali della tecnica RAG, che spesso prevedono moduli distinti per il recupero e la generazione.
|
36 |
+
|
37 |
+
Capacità di adattamento e apprendimento: I modelli di linguaggio generativi di grandi dimensioni sono noti per la loro capacità di adattarsi e imparare da nuovi dati e istruzioni.
|
38 |
+
|
39 |
+
Questo potrebbe consentire di raffinare e migliorare l'implementazione nel corso del tempo.
|
40 |
+
|
41 |
+
Controllo e trasparenza: L'utilizzo di prompt espliciti per guidare il modello attraverso le diverse fasi del processo può migliorare la controllabilità e la trasparenza, consentendo di monitorare e regolare il comportamento del modello in modo più diretto.
|
42 |
+
|
43 |
+
Efficienza computazionale: Avere un'unica architettura integrata potrebbe comportare vantaggi in termini di efficienza computazionale rispetto a soluzioni che prevedono moduli separati.
|
44 |
+
|
45 |
+
Punti a sfavore (Contro):
|
46 |
+
|
47 |
+
Affidabilità e coerenza: Poiché un unico modello gestisce tutte le fasi, eventuali errori o incoerenze potrebbero propagarsi e amplificarsi attraverso l'intero processo, influenzando la qualità della risposta finale.
|
48 |
+
|
49 |
+
Bias dei dati di addestramento: Come per qualsiasi modello di linguaggio generativo, l’approccio potrebbe essere influenzato dai bias presenti nei dati di addestramento utilizzati, con potenziali impatti sulla correttezza e l'equità delle risposte generate.
|
50 |
+
|
51 |
+
Mancanza di specializzazione: Mentre i modelli di grandi dimensioni sono versatili, potrebbero non essere ottimizzati per compiti specifici come il recupero di informazioni o la generazione di risposte rispetto a moduli specializzati.
|
52 |
+
|
53 |
+
Difficoltà di debug e interpretabilità: Con un'architettura integrata e basata su prompt, potrebbe essere più complesso eseguire il debug e comprendere le ragioni dietro a eventuali errori o comportamenti indesiderati del modello.
|
54 |
+
|
55 |
+
In sintesi,la proposta presenta alcuni vantaggi interessanti in termini di semplificazione, adattabilità e controllo, ma solleva anche potenziali preoccupazioni riguardo all'affidabilità, ai bias, alla mancanza di specializzazione e alle difficoltà di debug e interpretabilità.
|
56 |
+
Come per qualsiasi nuovo approccio, sarebbe necessario valutarlo attentamente attraverso sperimentazioni e test approfonditi per determinare l'efficacia e l'applicabilità in contesti specifici.
|
57 |
+
|
favicon.ico
ADDED
index.html
CHANGED
@@ -1,19 +1,32 @@
|
|
1 |
-
<!
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
</
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
|
3 |
+
<head>
|
4 |
+
<title>ulaquery.html</title>
|
5 |
+
<style>
|
6 |
+
html {
|
7 |
+
color: #04c61b
|
8 |
+
}
|
9 |
+
|
10 |
+
body {
|
11 |
+
background-color: #333;
|
12 |
+
color: #fff;
|
13 |
+
text-align: center;
|
14 |
+
padding-top: 50px;
|
15 |
+
font-size: 24px;
|
16 |
+
font-family: Arial, sans-serif;
|
17 |
+
}
|
18 |
+
</style>
|
19 |
+
</head>
|
20 |
+
|
21 |
+
<body>
|
22 |
+
<h2>RagRqs</h2>
|
23 |
+
<br>
|
24 |
+
<br>
|
25 |
+
<h3>Lggi_Per_Me</h3>
|
26 |
+
<script>
|
27 |
+
setTimeout(function () { location.replace('static/ragrqs.html'); }, 1000);
|
28 |
+
|
29 |
+
</script>
|
30 |
+
</body>
|
31 |
+
|
32 |
+
</html>
|
static/css/ragrqs.min.css
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;background:#1a1a1a}details,main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:ButtonText dotted 1px}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}[hidden],template{display:none}a,body,button,div,html,input,label,li,p,span,table,td,ul{padding:0;margin:0;font-family:arial,verdana,Helvetica,sans-serif}.bb0{background:#daee59!important}.bb1{background:#5487fc!important}body{background:#1a1a1a;box-sizing:border-box;min-height:100vh;height:100vh;position:relative;padding:0;margin:0;overflow:hidden;font-family:arial,verdana,Helvetica,sans-serif;font-weight:400}.spinner{z-index:1000;position:absolute;top:70vh;left:50vw;transform:translate(-50%,-50%);cursor:pointer;display:none;align-items:center}.spinner .pulse-icon{width:20px;height:20px;background-color:#ff8c00;border-radius:50%;animation:1.5s ease-in-out infinite pulse}.spinner .stop-message{margin-left:15px;background-color:inherit;color:#8f8a8a;padding:8px 15px;border-radius:10px;font-size:22px;font-weight:700;opacity:1;transition:opacity .3s}.spinner:hover .stop-message{color:#fff;background:#595959;opacity:1}@keyframes pulse{0%{transform:scale(.6);box-shadow:0 0 0 0 rgba(255,140,0,.7)}70%{transform:scale(1.4);box-shadow:0 0 0 20px rgba(255,140,0,0)}100%{transform:scale(.6);box-shadow:0 0 0 0 rgba(255,140,0,0)}}.show-spinner{display:flex}.upload{background-color:#1e1e1e;padding:0 2em 2em;margin:0;border-radius:4px;box-shadow:0 2px 4px rgba(0,0,0,.5);text-align:center}.upload h4{color:#fff;margin-bottom:1em}.upload form{display:flex;flex-direction:column;align-items:center}.upload form .file{background-color:#121212;border:1px solid #515151;color:#fff;padding:.5em;margin-bottom:1em;border-radius:4px;width:100%;box-sizing:border-box}.upload form .file::file-selector-button{background-color:#0a5f4e;color:#fff;border:none;padding:.5em 1em;border-radius:4px;cursor:pointer}.upload form .file::file-selector-button:hover{background-color:#053128}.upload form button{background-color:#0a5f4e;color:#fff;border:none;padding:.5em 1em;border-radius:4px;cursor:pointer;width:100%;box-sizing:border-box}.upload form button:hover{background-color:#053128}.upload .result{width:100%;background:#000;color:#fff;font-size:15px;font-weight:400;text-align:left}div.container{background:#1a1a1a;box-sizing:border-box;position:relative;top:5vh;left:0;height:95vh;margin:0;padding:0;transition:margin-left .5s;display:flex;flex-direction:column;justify-content:flex-start;align-items:stretch;flex-wrap:nowrap;overflow-y:auto;overflow-x:auto}div.container div.item{box-sizing:border-box;min-height:50px;margin:0;padding:0}div.container div.item1{flex:5;padding:.5vh .5vw 10vh}div.container div.item1 .output-wrapper{background-color:#1a1a1a;border-radius:20px;position:relative;bottom:0;right:0;left:0;width:100%;height:100%;display:flex;flex-direction:row;align-items:flex-start}div.container div.item1 .output-wrapper .text-out{flex:1;box-sizing:border-box;background:#000;color:#fff;border:none;padding:2px;min-width:50vw;height:100%;border-radius:10px;overflow-y:auto;outline:0;box-shadow:0 0 0 2px #4d4d4d}div.container div.item1 .output-wrapper .text-out:hover{box-shadow:0 0 0 2px #17d2ad}div.container div.item1 .output-wrapper .text-out .pre-text{white-space:pre-wrap;word-wrap:break-word;font-family:arial,verdana,Helvetica,sans-serif;font-size:20px;line-height:1.6;padding:2px;margin:0;height:100%;box-sizing:border-box;overflow-y:scroll;scroll-behavior:smooth}div.container div.item1 .output-wrapper .text-out .pre-text.copied{background-color:#0d0d0d;color:#61eed2}div.container div.item1 .output-wrapper .text-out .div-text{white-space:pre-wrap;word-wrap:break-word;font-family:arial,verdana,Helvetica,sans-serif;font-size:20px;line-height:1.6;padding:2px;margin:0;height:100%;box-sizing:border-box;overflow-y:scroll}div.container div.item1 .output-wrapper .text-out.copied{background-color:#0d0d0d;color:#61eed2}div.container div.item1 .output-actions{display:flex;flex-direction:column;align-items:flex-end;margin-left:.5vw;margin-right:.5vw}div.container div.item1 .output-actions .clear-output,div.container div.item1 .output-actions .copy-output,div.container div.item1 .output-actions .wnd-output{box-sizing:border-box;background-color:#333;color:#fff;border:none;padding:10px;cursor:pointer;border-radius:50%;width:40px;height:40px;display:flex;align-items:center;margin-bottom:5px}div.container div.item1 .output-actions .clear-output:hover,div.container div.item1 .output-actions .copy-output:hover,div.container div.item1 .output-actions .wnd-output:hover{background-color:#595959}div.container div.item1 .output-actions .copy-output{transition:background-color .3s,transform .3s}div.container div.item1 .output-actions .copy-output.copied{background:#33e9c5;transform:scale(1.2)}div.container div.item1 .output-actions .copy-output .copy-icon{fill:#FFFFFF;width:24px;height:24px}div.container div.item1 .output-actions .copy-output .copy-icon:hover{fill:#33e9c5}div.container div.item1 .output-actions .clear-output,div.container div.item1 .output-actions .wnd-output{transition:background-color .3s,transform .3s}div.container div.item1 .output-actions .clear-output .icon,div.container div.item1 .output-actions .wnd-output .icon{fill:#FFFFFF;width:24px;height:24px}div.container div.item1 .output-actions .clear-output .icon:hover,div.container div.item1 .output-actions .wnd-output .icon:hover{fill:#33e9c5}:hover{outline:0;caret-color:transparent}textarea:focus{caret-color:auto}div.item2{flex:2;padding:0 .5vw}div.item2 .input-wrapper{background-color:#1a1a1a;border-radius:20px;position:relative;bottom:2vh;right:0;left:0;width:100%;height:100%;display:flex;flex-direction:row;align-items:flex-start}div.item2 .input-wrapper:focus-within .clear-button{display:block}div.item2 .input-wrapper .text-input{flex:1;font-size:20px;font-family:arial,verdana,Helvetica,sans-serif;resize:none;box-sizing:border-box;background:#000;color:#fff;border:none;padding:2px 40px 2px 2px;height:100%;margin-left:5px;border-radius:10px;overflow-y:auto;outline:0;box-shadow:0 0 0 2px #4d4d4d}div.item2 .input-wrapper .text-input:hover{box-shadow:0 0 0 2px #17d2ad}div.item2 .input-wrapper .text-input:focus{box-shadow:0 0 0 2px #ff4500}div.item2 .input-wrapper .clear-button{position:absolute;right:60px;top:19vh;padding:5px;border-radius:50%;background:#333;border:none;font-size:20px;cursor:pointer;color:#ccc;display:none}div.item2 .input-wrapper .clear-button:hover{font-weight:700;background:#595959;color:#fff}div.item2 .input-wrapper .input-actions{display:flex;flex-direction:column;margin-left:.5vw;margin-right:.5vw}div.item2 .input-wrapper .input-actions .clear-input,div.item2 .input-wrapper .input-actions .send-input,div.item2 .input-wrapper .input-actions .send2-input{box-sizing:border-box;background-color:#333;color:#fff;border:none;padding:10px;cursor:pointer;border-radius:50%;width:40px;height:40px;margin-bottom:5px;transition:background-color .3s}div.item2 .input-wrapper .input-actions .send-input{background:#992900}div.item2 .input-wrapper .input-actions .send-input:hover{background:#ff4500}div.item2 .input-wrapper .input-actions .send2-input{background:#0d7661}div.item2 .input-wrapper .input-actions .send2-input:hover{background:#14bb9a}div.item2 .input-wrapper .input-actions .clear-input{background:#333;color:#e6e6e6}div.item2 .input-wrapper .input-actions .clear-input:hover{background:#595959;color:#33e9c5}.menu-open .container{margin-left:16vw}.menu-open .menu-box{left:0!important}div.menu-h{background-color:#1a1a1a;position:fixed;top:0;left:0;width:100vw;height:4.5vh;padding:0;margin:0;outline:0;box-shadow:0 0 0 2px #4d4d4d;z-index:100}div.menu-h .release{background:inherit;color:#ff6a33;font-weight:700;margin-left:57vw;margin-top:.5vh}div.menu-h .menu-btn{appearance:none}div.menu-h .menu-btn:checked+.menu-icon{border:1px solid #333}div.menu-h .menu-btn:checked+.menu-icon .nav-icon{transform:rotate(45deg)}div.menu-h .menu-btn:checked+.menu-icon .nav-icon::before{top:0}div.menu-h .menu-btn:checked+.menu-icon .nav-icon::after{top:0;transform:rotate(90deg)}div.menu-h .menu-icon{box-sizing:border-box;background-color:inherit;display:block;position:absolute;margin-left:2vw;top:0;left:0;width:4vw;height:4.5vh;cursor:pointer;padding:2px;z-index:1}div.menu-h .menu-icon:hover .nav-icon,div.menu-h .menu-icon:hover .nav-icon::after,div.menu-h .menu-icon:hover .nav-icon::before{background-color:#33e9c5}div.menu-h .menu-icon .nav-icon{background-color:#aea7a7;display:block;position:absolute;top:14px;left:0;width:25px;height:2px;transition-duration:.25s}div.menu-h .menu-icon .nav-icon::after,div.menu-h .menu-icon .nav-icon::before{content:"";position:absolute;left:0;background-color:inherit;width:inherit;height:inherit}div.menu-h .menu-icon .nav-icon::before{top:-8px}div.menu-h .menu-icon .nav-icon::after{top:8px}div.menu-h .head-wrapper{position:absolute;top:0;left:5vw;height:4vh;padding:0;margin:0;display:inline-flex;flex-direction:row;flex-wrap:nowrap;align-items:center;justify-content:flex-start}div.menu-h .head-wrapper .help,div.menu-h .head-wrapper .log,div.menu-h .head-wrapper .upload,div.menu-h .head-wrapper .upload-dir{margin-top:2px;margin-left:30px;margin-right:0;padding:5px 5px 0;border:none;cursor:pointer;border-radius:20%;font-size:20px;color:#fff;background:#333;max-height:4vh}div.menu-h .head-wrapper .help:hover,div.menu-h .head-wrapper .log:hover,div.menu-h .head-wrapper .upload-dir:hover,div.menu-h .head-wrapper .upload:hover{background:#595959}div.menu-h .upload,div.menu-h .upload-dir{transition:background-color .3s,transform .3s}div.menu-h .upload .icon,div.menu-h .upload-dir .icon{fill:#FFFFFF;width:24px;height:24px}div.menu-h .upload .icon:hover,div.menu-h .upload-dir .icon:hover{fill:#33e9c5}div.menu-h .log{font-size:14px!important;font-weight:400!important;background:#992900!important}div.menu-h .log:hover{background:#cc3700!important}div.menu-h .log.active{background:#0d7661!important}div.menu-h .log.active:hover{background:#12a487!important}div.menu-h div.menu-box{position:fixed;top:5vh;left:-2000px;height:95vh;width:16vw;transition:left .3s ease-out;padding:1vh 0 0 .5vw;z-index:101;background:#0d0d0d;box-sizing:border-box;outline:0;box-shadow:0 0 0 2px #4d4d4d;display:flex;flex-direction:column;flex-wrap:nowrap;justify-content:flex-start;align-items:stretch;overflow-y:auto;overflow-x:auto}div.menu-h div.menu-box ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;border-top:1px solid #333}div.menu-h div.menu-box ul li{border-left:1px solid #333;border-right:1px solid #333;border-bottom:1px solid #333}div.menu-h div.menu-box ul li a{color:#fff;font-size:14px;font-family:arial,verdana,Helvetica,sans-serif;font-weight:400;display:block;margin:0;padding:2px 2px 2px 0;text-align:left;text-decoration:none}div.menu-h div.menu-box ul li:hover{text-decoration:underline;background-color:#333;color:#33e9c5}div.menu-h div.menu-box ul a.delete{text-align:center;font-weight:700;font-style:italic;color:#000;background:#b3a80b}div.menu-h div.menu-box ul a.help{text-align:center;font-weight:700;font-style:italic;color:#000;background:#cc3700}div.menu-h div.menu-box ul li.show{background:#000;color:#fff;width:100%;text-align:center;box-sizing:border-box}div.menu-h div.menu-box ul li.show:hover{text-decoration:none}.window-text{position:relative;top:0;left:0;background:#1a1a1a;color:#fff;border:none;padding:0 2px 2px;width:78vw;height:80vh;border-radius:10px;box-sizing:border-box;outline:0;box-shadow:0 0 0 2px #b3a80b;overflow-y:auto}.window-text pre.pre-text{color:#f8f292;white-space:pre-wrap;word-wrap:break-word;font-family:Georigia,"Ties New Roman",serif;font-size:18px;line-height:1.6;padding:2px;margin:0;text-align:left}.window-text div.text{font-size:18px;font-weight:400;padding-left:10px;padding-right:10px;margin:0}.window-text div.text pre{white-space:pre-wrap;word-wrap:break-word;font-family:arial,verdana,Helvetica,sans-serif;font-size:18px;line-height:1.3;padding:0 5px;margin:0;text-align:left}.window-text div.text .center{text-align:center;font-size:18px;font-weight:700;text-decoration:underline;font-style:italic;color:#e3d50e}.window-text div.text div{font-family:arial,verdana,Helvetica,sans-serif;font-size:18px;font-weight:700;padding-top:0;padding-bottom:0}.window-text div.text div a{background:#000;color:#fff;font-weight:400}.window-text div.text div a:hover{background:#333;color:#fff}.window-text div.text p{font-size:18px;font-weight:400;font-family:arial,verdana,Helvetica,sans-serif;text-align:justify;padding-bottom:9px;padding-right:0;padding-left:10px}.btn-wrapper{width:100%;height:2vw;position:sticky;top:0;padding:0;background:#262626}.btn-wrapper .btn-copy{position:absolute;top:1px;right:5vw;box-sizing:border-box;background:inherit;color:#fff;border:none;cursor:pointer;width:30px;margin:0;padding:0;transition:background-color .3s}.btn-wrapper .btn-copy:hover{background-color:#595959}.btn-wrapper .btn-copy .copy-icon{fill:#e6e6e6;width:20px;height:20px}.btn-wrapper .btn-copy .copy-icon:hover{fill:#33e9c5;background:#404040}.btn-wrapper .btn-close{position:absolute;top:0;right:2vw;margin:0;background-color:transparent;border:none;color:#e6e6e6;font-size:22px;font-weight:700;cursor:pointer;outline:0}.btn-wrapper .btn-close:hover{color:#33e9c5;background:#404040}.msg{box-sizing:border-box;position:fixed;width:300px;height:100px;top:50%;left:50%;transform:translate(-50%,-50%);background-color:#222;color:#ffeb3b;border:2px solid #ffeb3b;border-radius:15px;display:flex;align-items:center;justify-content:center;font-family:Arial,sans-serif;font-size:24px;font-weight:700;text-align:center;z-index:1000;box-shadow:0 4px 8px rgba(0,0,0,.2)}.alert,.confirm{background-color:#303030!important;color:#fff;padding:20px;border-radius:4px;box-shadow:0 2px 4px #00000033!important}.alert .button,.confirm .button{background-color:#37474f!important;color:#fff;border:none;padding:10px 20px;border-radius:4px;cursor:pointer;margin-top:20px}.alert .button:hover,.confirm .button:hover{background-color:#222c31}
|
static/data/aaron_swartz.txt
ADDED
The diff for this file is too large to render.
See raw diff
|
|
static/data/aristotele_detective.txt
ADDED
The diff for this file is too large to render.
See raw diff
|
|
static/data/help_test.html
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div class="text">
|
2 |
+
<br>
|
3 |
+
<div><a href="#" onCLick="esempio('aaron_swartz.txt');">Aaron Swartz</a></div>
|
4 |
+
<br>
|
5 |
+
<div><a href="#" onCLick="esempio('roberto_busa.txt');">Roberto Busa</a></div>
|
6 |
+
<br>
|
7 |
+
<div><a href="#" onCLick="esempio('la_cattedrale_e_il_bazaar.txt');">La cattedrale e il Bazar</a></div>
|
8 |
+
<br>
|
9 |
+
<div><a href="#" onCLick="esempio('aristotele_detective.txt');">Aristotele Detective</a></div>
|
10 |
+
<br>
|
11 |
+
<div><a href="#" onCLick="esempio('montecristo.txt');">Montecristor</a></div>
|
12 |
+
<br>
|
13 |
+
<div><a href="#" onCLick="esempio('il_libro_rosso.txt');">Il libro rosso</a></div>
|
14 |
+
<br>
|
15 |
+
<div><a href="#" onCLick="esempio('lettere_musulmane.txt');">Lettere Mussulmane</a></div>
|
16 |
+
|
17 |
+
<!--
|
18 |
+
aaron_swartz.txt
|
19 |
+
aristotele_detective.txt
|
20 |
+
il_libro_rosso.txt
|
21 |
+
la_cattedrale_e_il_bazaar.txt
|
22 |
+
lettere_musulmane.txt
|
23 |
+
montecristo.txt
|
24 |
+
roberto_busa.txt
|
25 |
+
-->
|
static/data/il_libro_rosso.txt
ADDED
The diff for this file is too large to render.
See raw diff
|
|
static/data/la_cattedrale_e_il_bazaar.txt
ADDED
@@ -0,0 +1,804 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
La cattedrale e il bazaar
|
2 |
+
|
3 |
+
di Eric S. Raymond
|
4 |
+
(22/11/1998 ore 04:01:20)
|
5 |
+
Quella che segue è la mia analisi di un progetto open source di successo, fetchmail, deliberatamente
|
6 |
+
utilizzato come test specifico per la verifica di alcune sorprendenti teorie sullo sviluppo del software
|
7 |
+
suggerite dalla storia di Linux. Le mie argomentazioni su tali teorie mettono a confronto due diversi stili di
|
8 |
+
sviluppo, il modello “cattedrale” in voga in gran parte del mondo commerciale, opposto al modello
|
9 |
+
“bazaar” del mondo Linux. Da qui passo poi a dimostrare come tali modelli derivino da premesse
|
10 |
+
divergenti sulla natura dell'attività di debugging del software. Arrivo quindi a stabilire la validità
|
11 |
+
dell'esperienza di Linux riguardo l'affermazione “Con molti occhi puntati addosso, ogni bug diventa una
|
12 |
+
bazzecola”, per suggerire analogie produttive con altri sistemi di agenti indipendenti in grado di auto-
|
13 |
+
correggersi, concludendo infine con una serie di riflessioni sulle implicazioni di queste analisi per il futuro
|
14 |
+
del software.
|
15 |
+
|
16 |
+
1. La cattedrale e il bazaar
|
17 |
+
Linux è sovversivo. Chi avrebbe potuto pensare appena cinque anni fa che un sistema operativo di livello
|
18 |
+
mondiale sarebbe emerso come per magia dal lavoro part-time di diverse migliaia di hacker e sviluppatori
|
19 |
+
sparsi sull'intero pianeta, collegati tra loro solo grazie ai tenui cavi di Internet?
|
20 |
+
Certamente non il sottoscritto. Quando Linux fece la sua comparsa nel mio raggio d'azione all'inizio del
|
21 |
+
1993, mi ero occupato dello sviluppo di Unix e di software open source per dieci anni. Ero stato uno dei
|
22 |
+
primi collaboratori al progetto GNU a metà anni '80. Avevo distribuito su Internet un buon numero di
|
23 |
+
software open source, realizzando da solo o in collaborazione con altri parecchi programmi (nethack,
|
24 |
+
Emacs VC e GUD, xlife, etc.) ancor'oggi ampiamente utilizzati. Pensavo di sapere come bisognasse fare.
|
25 |
+
Linux stravolse gran parte di quel che credevo di sapere. Per anni avevo predicato il vangelo Unix degli
|
26 |
+
strumenti agili, dei prototipi immediati e della programmazione evolutiva. Ma ero anche convinto che
|
27 |
+
esistesse un punto critico di complessità al di sopra del quale si rendesse necessario un approccio
|
28 |
+
centralizzato e a priori. Credevo che il software più importante (sistemi operativi e strumenti davvero
|
29 |
+
ingombranti come Emacs) andasse realizzato come le cattedrali, attentamente lavorato a mano da
|
30 |
+
singoli geni o piccole bande di maghi che lavoravano in splendido isolamento, senza che alcuna versione
|
31 |
+
beta vedesse la luce prima del momento giusto.
|
32 |
+
Rimasi non poco sorpreso dallo stile di sviluppo proprio di Linus Torvalds – diffondere le release presto e
|
33 |
+
spesso, delegare ad altri tutto il possibile, essere aperti fino alla promiscuità. Nessuna cattedrale da
|
34 |
+
costruire in silenzio e reverenza. Piuttosto, la comunità Linux assomigliava a un grande e confusionario
|
35 |
+
bazaar, pullulante di progetti e approcci tra loro diversi (efficacemente simbolizzati dai siti contenenti
|
36 |
+
l'archivio di Linux dove apparivano materiali prodotti da chiunque). Un bazaar dal quale soltanto una
|
37 |
+
serie di miracoli avrebbe potuto far emergere un sistema stabile e coerente.
|
38 |
+
Il fatto che questo stile bazaar sembrasse funzionare, e anche piuttosto bene, mi colpì come uno shock.
|
39 |
+
Mentre imparavo a prenderne le misure, lavoravo sodo non soltanto sui singoli progetti, ma anche
|
40 |
+
cercando di comprendere come mai il mondo Linux non soltanto non cadesse preda della confusione più
|
41 |
+
totale, ma al contrario andasse rafforzandosi sempre più a una velocità a malapena immaginabile per
|
42 |
+
quanti costruivano cattedrali.
|
43 |
+
Fu verso la metà del 1996 che mi parve d'essere sul punto di capirne il perché. Il destino mi offrì
|
44 |
+
l'occasione propizia per mettere alla prova la mia teoria, sotto forma di un progetto open source del quale
|
45 |
+
decisi di occuparmi usando coscientemente lo stile bazaar. Ci provai, e il successo ottenuto fu piuttosto
|
46 |
+
significativo.
|
47 |
+
Nella parte restante di questo saggio, racconto la storia di quel progetto, usandola per proporre alcuni
|
48 |
+
aforismi sull'efficacia dello sviluppo open source. Non che li abbia imparati tutti dal mondo Linux, ma
|
49 |
+
vedremo come le modalità offerte da quest'ultimo siano del tutto peculiari. Se non ho interpretato male,
|
50 |
+
questi aforismi ci aiuteranno a comprendere con esattezza cos'è che rende la comunità Linux una
|
51 |
+
sorgente così copiosa di buon software – e aiuteranno tutti noi a divenire più produttivi.
|
52 |
+
2. La posta deve passare
|
53 |
+
Dal 1993 mi occupo del lato tecnico di un piccolo provider Internet gratuito chiamato Chester County
|
54 |
+
InterLink (CCIL) in West Chester, Pennsylvania (sono tra i fondatori di CCIL e autore del software
|
55 |
+
specifico per il nostro bulletin-board multiutenti – si può dare un'occhiata facendo telnet su locke.ccil.org .
|
56 |
+
Ora dà accesso a quasi tremila utenti su trenta linee). Grazie a questo lavoro posso collegarmi a Internet
|
57 |
+
per 24 ore al giorno con una linea a 56K di CCIL – in realtà, è proprio quel che mi viene richiesto!
|
58 |
+
Di conseguenza sono ormai abituato alle email istantanee. Per vari motivi, era difficile far funzionare la
|
59 |
+
connessione SLIP tra la mia macchina a casa (snark.thyrsus.com) e CCIL. Quando finalmente ci sono
|
60 |
+
riuscito, mi dava fastidio dover fare ogni tanto telnet su locke per controllare la posta. Volevo fare in
|
61 |
+
modo che i messaggi arrivassero direttamente su snark così da esserne tempestivamente avvisato e
|
62 |
+
poterli gestire a livello locale.
|
63 |
+
Il semplice “sendmail forwarding” non avrebbe funzionato, perché la mia macchina personale non è
|
64 |
+
sempre online e non ha un indirizzo IP statico. Mi serviva un programma in grado di raggiungere la
|
65 |
+
connessione SLIP e tirar via la posta per farla arrivare localmente. Sapevo dell'esistenza di simili cose, e
|
66 |
+
del fatto che in genere facevano uso di un semplice protocollo noto come POP (Post Office Protocol). E
|
67 |
+
sicuramente doveva già esserci un server POP3 incluso nel sistema operativo BSD/OS di locke.
|
68 |
+
Mi serviva un client POP3. Ne ho localizzato subito uno online. Anzi, ne ho trovati tre o quattro. Per un
|
69 |
+
po' ho usato un pop-perl, ma era privo di quella che pareva una funzione ovvia, la capacità di effettuare
|
70 |
+
un “hacking degli indirizzi della posta prelevata in modo che il reply funzionasse correttamente.
|
71 |
+
Questo il problema: supponiamo di ricevere un messaggio da qualcuno di nome 'joe' su locke. Se lo
|
72 |
+
inoltro su snark e poi cerco di fare reply, il mio programma di posta proverebbe simpaticamente a inviarlo
|
73 |
+
a un inesistente 'joe' su snark. Modificare a mano ogni indirizzo per aggiungere “@ccil.org” diventerebbe
|
74 |
+
in un attimo un problema serio.
|
75 |
+
Chiaramente questa era un'operazione che toccava fare al computer per conto mio. Ma nessuno dei
|
76 |
+
client POP esistenti sapeva come! E questo ci porta alla prima lezione:
|
77 |
+
1. Ogni buon lavoro software inizia dalla frenesia personale di uno sviluppatore.
|
78 |
+
Forse ciò avrebbe dovuto risultare ovvio (è risaputo da tempo che “la necessità è la madre di tutte le
|
79 |
+
invenzioni”), ma troppo spesso gli sviluppatori trascorrono le giornate impegnati a guadagnarsi da vivere
|
80 |
+
con programmi di cui non hanno alcun bisogno e che non apprezzano. Ma non nel mondo Linux – il che
|
81 |
+
spiega l'alta qualità media del software originato dalla comunità Linux.
|
82 |
+
Mi sono forse lanciato in un'attività frenetica per scrivere il codice di un client POP3 nuovo di zecca in
|
83 |
+
grado di competere con quelli esistenti? Nemmeno per sogno! Ho esaminato attentamente le utility POP
|
84 |
+
che avevo in mano, chiedendomi: “qual'è la più vicina a quel che sto cercando?” Perché:
|
85 |
+
2. I bravi programmatori sanno cosa scrivere. I migliori sanno cosa riscrivere (e riusare).
|
86 |
+
Pur non ritenendomi un programmatore tra i più bravi, cerco di imitarli. Importante caratteristica di costoro
|
87 |
+
è una sorta di ozio costruttivo. Sanno che si ottiene il meglio non per le energie impiegate ma per il
|
88 |
+
risultato raggiunto, e che quasi sempre è più facile iniziare da una buona soluzione parziale piuttosto che
|
89 |
+
dal nulla assoluto.
|
90 |
+
Linus Torvalds, per esempio, non ha mai cercato di riscrivere Linux da zero. È invece partito riutilizzando
|
91 |
+
codici e idee riprese da Minix, piccolo sistema operativo per macchine 386 assai simile a Unix. Alla fine il
|
92 |
+
codice Minix è scomparso oppure è stato completamente riscritto – ma per il tempo che è rimasto lì
|
93 |
+
presente è servito come impalcatura per l'infante che sarebbe infine divenuto Linux.
|
94 |
+
Con lo stesso spirito, mi sono messo a cercare una utility POP basata su codici ragionevolmente ben
|
95 |
+
fatti, da utilizzare come base di sviluppo.
|
96 |
+
La tradizione di condivisione dei codici tipica del mondo Unix ha sempre favorito il riutilizzo dei sorgenti
|
97 |
+
(questo il motivo per cui il progetto GNU ha scelto come sistema operativo di base proprio Unix,
|
98 |
+
nonostante alcune serie riserve sullo stesso). Il mondo Linux ha spinto questa tradizione vicina al suo al
|
99 |
+
limite tecnologico; sono generalmente disponibili terabyte di codice open source. È quindi probabile che,
|
100 |
+
impiegando del tempo a cercare il lavoro di qualcuno quasi ben fatto, si ottengano i risultati voluti. E ciò
|
101 |
+
vale assai più nel mondo Linux che altrove.
|
102 |
+
Proprio quel che è successo a me. Conteggiando i programmi trovati prima, con la seconda ricerca
|
103 |
+
ottenni un totale di nove candidati – fetchpop, PopTart, get-mail, gwpop, pimp, pop-perl, popc, popmail e
|
104 |
+
upop. Il primo su cui mi sono concentrato è stato 'fetchpop' di Seung-Hong Oh. Ho inserito l'opzione
|
105 |
+
“header-rewrite” e ho apportato altri miglioramenti, poi accettati dall'autore nella release 1.9.
|
106 |
+
Alcune settimane dopo, però, mi sono imbattuto nel codice di 'popclient' scritto da Carl Harris, ed mi sono
|
107 |
+
trovato di fronte a un problema. Pur offrendo alcune buone idee originali (come la modalità “daemon”),
|
108 |
+
fetchpop poteva gestire solo POP3 e il codice rifletteva un certo approccio da dilettante (Seung-Hong era
|
109 |
+
un programmatore brillante ma inesperto, ed entrambe le qualità risultavano evidenti). Il codice di Carl
|
110 |
+
era migliore, alquanto professionale e solido, ma il suo programma difettava di varie opzioni presenti in
|
111 |
+
fetchpop, opzioni importanti e piuttosto complesse da implementare (incluse quelle aggiunte dal
|
112 |
+
sottoscritto).
|
113 |
+
Restare o cambiare? Nel secondo caso avrei buttato via il codice che avevo già scritto in cambio di una
|
114 |
+
migliore base di sviluppo.
|
115 |
+
Un motivo pratico per passare all'altro programma era il supporto per protocolli multipli. POP3 è il più
|
116 |
+
usato tra i server per l'ufficio postale, ma non è il solo. Fetchpop e l'altro rivale non avevano POP2,
|
117 |
+
RPOP, o APOP, e io stesso stavo meditando, giusto per divertimento, l'aggiunta di IMAP (Internet
|
118 |
+
Message Access Protocol, il protocollo per l'ufficio postale più recente e più potente).
|
119 |
+
Avevo però altri motivi teorici per ritenere una buona idea il fatto di cambiare, qualcosa che avevo
|
120 |
+
imparato molto tempo prima di Linux.
|
121 |
+
3. “Preparati a buttarne via uno; dovrai farlo comunque.” (Fred Brooks, “The Mythical Man-Month”,
|
122 |
+
Capitolo 11)
|
123 |
+
In altri termini, spesso non si riesce a comprendere davvero un problema fino alla prima volta in cui si
|
124 |
+
prova a implementarne la soluzione. La seconda volta forse se ne sa abbastanza per riuscirci. Per
|
125 |
+
arrivare alla soluzione, preparati a ricominciare almeno una volta.
|
126 |
+
Be', mi son detto, la mia prima volta erano state le modifiche a fetchpop. Adesso era ora di cambiare, e
|
127 |
+
così feci.
|
128 |
+
Dopo aver mandato a Carl Harris il 25 Giugno 1996 una prima serie di aggiustamenti per popclient, mi
|
129 |
+
resi conto che da qualche tempo egli aveva perso interesse nel programma. Il codice era un po'
|
130 |
+
polveroso, con vari bug in giro. Avrei dovuto fare molte modifiche, e ci mettemmo rapidamente d'accordo
|
131 |
+
sul fatto che la cosa più logica fosse che il programma passasse in mano mia.
|
132 |
+
Senza che me ne accorgessi più di tanto, il progetto era cresciuto parecchio. Non mi stavo più
|
133 |
+
occupando soltanto di sistemare i piccoli difetti di un client POP già esistente. Mi ero addossato l'intera
|
134 |
+
gestione di un programma, e mi venivano in mente delle idee che avrebbero probabilmente portato a
|
135 |
+
modifiche radicali.
|
136 |
+
In una cultura del software che incoraggia la condivisione del codice, non si trattava altro che della
|
137 |
+
naturale evoluzione di un progetto. Questi i punti-chiave:
|
138 |
+
4. Se hai l'atteggiamento giusto, saranno i problemi interessanti a trovare te.
|
139 |
+
Ma l'atteggiamento di Carl Harris risultò perfino più importante. Fu lui a comprendere che:
|
140 |
+
5. Quando hai perso interesse in un programma, l'ultimo tuo dovere è passarlo a un successore
|
141 |
+
competente.
|
142 |
+
Senza neppure parlarne, io e Carl sapevamo di perseguire il comune obiettivo di voler raggiungere la
|
143 |
+
soluzione migliore. L'unica questione per entrambi era stabilire se le mie fossero mani fidate. Una volta
|
144 |
+
concordato su questo, egli agì con gentilezza e prontezza. Spero di comportarmi altrettanto bene quando
|
145 |
+
verrà il mio turno.
|
146 |
+
3. L'importanza di avere utenti
|
147 |
+
E così ho ereditato popclient. Fatto parimenti importante, ho ereditato gli utenti di popclient. Importante
|
148 |
+
non soltanto perché la loro esistenza testimonia che stai rispondendo a un loro bisogno, che hai fatto
|
149 |
+
qualcosa di buono. Coltivati in maniera appropriata, gli utenti possono trasformarsi in co-sviluppatori.
|
150 |
+
Altro punto di forza della tradizione Unix, portato felicemente agli estremi da Linux, è che molti utenti
|
151 |
+
sono essi stessi degli hacker. Ed essendo i sorgenti disponibili a tutti, posso diventare degli hacker molto
|
152 |
+
efficaci. Qualcosa di tremendamente utile per ridurre il tempo necessario al debugging. Con un po'
|
153 |
+
d'incoraggiamento, ogni utente è in grado di diagnosticare problemi, suggerire soluzioni, aiutare a
|
154 |
+
migliorare il codice in maniera impensabile per una persona sola.
|
155 |
+
6. Trattare gli utenti come co-sviluppatori è la strada migliore per ottenere rapidi miglioramenti del codice
|
156 |
+
e debugging efficace.
|
157 |
+
È facile sottovalutare la potenza di un simile effetto. In realtà un po' tutti noi del mondo open source
|
158 |
+
eravamo soliti sottovalutare drasticamente il fatto che tale potenza crescesse di pari passo con il numero
|
159 |
+
degli utenti e con la complessità del sistema. Finché Linus Torvalds ci ha mostrato le cose in maniera
|
160 |
+
diversa.
|
161 |
+
In realtà ritengo che la mossa più scaltra e consequenziale di Linus non sia stata la costruzione del
|
162 |
+
kernel di Linux in sé, bensì la sua invenzione del modello di sviluppo di Linux. Quando ho espresso
|
163 |
+
questo mio pensiero in sua presenza, sorridendo ha ripetuto con calma quel che va spesso affermando:
|
164 |
+
“Praticamente sono una persona molto pigra cui piace prendersi il merito di quel che sono gli altri a fare.”
|
165 |
+
Pigro come una volpe. Oppure, come avrebbe detto Robert Heinlein, troppo pigro per fallire.
|
166 |
+
Guardando all'indietro, un precedente per i metodi e il successo di Linux può esser trovato nello sviluppo
|
167 |
+
della libreria Lisp GNU e per gli archivi del codice Lisp di Emacs. In opposizione allo stile di costruzione a
|
168 |
+
cattedrale del nucleo centrale in C di Emacs e di gran parte di altri strumenti della Free Software
|
169 |
+
Foundation (FSF), l'evoluzione del codice Lisp risultò assai fluida e guidata dagli utenti. Idee e prototipi
|
170 |
+
vennero spesso riscritti tre o quattro volte prima di raggiungere una forma stabile e definitiva. E le
|
171 |
+
collaborazioni estemporanee tra due o più persone consentite da Internet, alla Linux, erano evento
|
172 |
+
frequente.
|
173 |
+
Non a caso il mio caso di “hack” precedente a fetchmail fu probabilmente la modalità Emacs VC, una
|
174 |
+
collaborazione via email secondo lo stile Linux con altre tre persone, soltanto una delle quali (Richard
|
175 |
+
Stallman, autore di Emacs e fondatore della FSF http://www.fsf.org) ho poi avuto occasione di incontrare
|
176 |
+
dal vivo. Si trattava di realizzare il frontale per SCCS, RCS e più tardi CVS dall'interno di Emacs, dotato
|
177 |
+
di opzioni a “one-touch” per le operazioni di controllo. Ciò ha preso avvio da un minuto, crudo sccs.el
|
178 |
+
scritto da qualcun altro. E lo sviluppo di VC ha avuto successo perché, al contrario dello stesso Emacs, il
|
179 |
+
codice
|
180 |
+
di
|
181 |
+
Lisp
|
182 |
+
riuscì
|
183 |
+
a
|
184 |
+
passare
|
185 |
+
molto
|
186 |
+
rapidamente
|
187 |
+
tra
|
188 |
+
diverse
|
189 |
+
generazioni
|
190 |
+
di
|
191 |
+
distribuzione/test/miglioramenti.
|
192 |
+
4. Distribuire presto e spesso
|
193 |
+
Elemento centrale del processo di sviluppo di Linux è la rapida e frequente distribuzione delle varie
|
194 |
+
release. La maggior parte degli sviluppatori (incluso il sottoscritto) aveva sempre considerato negativa
|
195 |
+
questa usanza per progetti appena più che minimi, poiché le versioni iniziali sono piene di bug quasi per
|
196 |
+
definizione e non pareva il caso di far spazientire inutilmente gli utenti.
|
197 |
+
Tale opinione era rinforzata dalla generale aderenza allo stile di sviluppo della costruzione a cattedrale.
|
198 |
+
Se l'obiettivo finale era quello di far vedere meno bug possibili agli utenti, allora conveniva distribuire una
|
199 |
+
nuova release ogni sei mesi (o ancora meno frequentemente) e lavorare duramente sul debugging tra
|
200 |
+
una release e l'altra. Fu seguendo questo processo che venne sviluppato il nucleo centrale in C di
|
201 |
+
Emacs. Ma non fu così per la libreria Lisp –perché erano attivi archivi Lisp al di fuori del controllo della
|
202 |
+
FSF, dove era invece possibile trovare versioni di codice nuovo e in fase di sviluppo indipendentemente
|
203 |
+
dal ciclo di release di Emacs.
|
204 |
+
Il più importante di tali archivi, l'archivio elisp dell'Ohio State, anticipava lo spirito e molte delle
|
205 |
+
caratteristiche tipiche dei grandi archivi su Linux di oggi. Ma pochi di noi si resero davvero conto di quel
|
206 |
+
che stavamo facendo, o di come l'esistenza stessa di quell'archivio paresse rispondere ai problemi insiti
|
207 |
+
nel modello di sviluppo della costruzione a cattedrale della FSF. Verso il 1992 ho provato a far confluire
|
208 |
+
formalmente gran parte del codice dell'Ohio nella libreria ufficiale Lisp di Emacs. Mi sono trovato
|
209 |
+
politicamente nei guai e di fronte a un chiaro insuccesso.
|
210 |
+
Ma l'anno seguente, mentre Linux diventava ampiamente visibile, fu chiaro come stesse accadendo
|
211 |
+
qualcosa di assai diverso e più salutare. La policy di sviluppo aperto di Linus rappresentava l'esatto
|
212 |
+
opposto della costruzione a cattedrale. Gli archivi di sunsite e tsx-11 stavano moltiplicandosi, le
|
213 |
+
distribuzioni multiple andavano proliferando. E tutto ciò sotto la spinta della diffusione, con una frequenza
|
214 |
+
mai vista prima, delle varie release.
|
215 |
+
Linus trattava gli utenti al pari di co-sviluppatori nella maniera più efficace possibile:
|
216 |
+
7. Distribuisci presto. Distribuisci spesso. E presta ascolto agli utenti.
|
217 |
+
L'innovazione introdotta da Linus non consisteva tanto nel seguire questa pratica (qualcosa di simile
|
218 |
+
faceva parte da molto tempo della tradizione del mondo Unix), quanto piuttosto nel farla crescere a un
|
219 |
+
tale livello d'intensità da raggiungere la medesima complessità del lavoro di programmazione che stava
|
220 |
+
facendo. A quei tempi (intorno al 1991) non era raro che egli diffondesse versioni del nuovo kernel anche
|
221 |
+
più di una volta al giorno! Qualcosa che poté funzionare grazie all'attenzione dedicata ai co-sviluppatori e
|
222 |
+
all'ampio utilizzo di Internet come strumento di collaborazione.
|
223 |
+
Ma come funzionava? Era qualcosa che avrei potuto duplicare, o tutto dipendeva esclusivamente dal
|
224 |
+
genio di Linus Torvalds?
|
225 |
+
No, non lo credevo. Certo, Linus è un gran bell'hacker (quanti di noi saprebbero realizzare per intero un
|
226 |
+
sistema operativo di qualità?). Ma a livello concettuale Linux non rappresentava alcun significativo salto
|
227 |
+
in avanti. Linus non è (almeno, non ancora) quel genio innovativo del design allo stesso modo, ad
|
228 |
+
esempio, di Richard Stallman o James Gosling (di NeWS e Java). Piuttosto, Linus mi sembrava un genio
|
229 |
+
dell'engineering, dotato di un sesto senso per evitare bug e strade senza uscita, oltre che di un ottimo
|
230 |
+
fiuto per arrivare dal punto A al punto B con il minimo sforzo possibile. Non a caso l'intero design di Linux
|
231 |
+
trasuda queste qualità e rispecchia l'approccio essenzialmente conservativo e semplificativo tipico di
|
232 |
+
Linus.
|
233 |
+
Se, quindi, la rapida diffusione delle release e il pieno sfruttamento del medium Internet non erano
|
234 |
+
casuali, bensì parti integranti delle visioni da genio dell'engineering di Linus lungo il cammino del minimo
|
235 |
+
sforzo possibile, cos'era che stava amplificando? Cos'è che riusciva a tirar fuori da tutto questo gran
|
236 |
+
daffare?
|
237 |
+
Messa così, la domanda si risponde da sola. Linus tendeva a stimolare e ricompensare costantemente i
|
238 |
+
suoi hacker/utenti – stimolati dalla soddisfazione di sé per aver preso parte all'azione, ricompensati dalla
|
239 |
+
vista dei miglioramenti costanti (perfino giornalieri) ottenuti nel loro lavoro.
|
240 |
+
Linus puntava direttamente a massimizzare il numero di ore/uomo coinvolte nello sviluppo e nel
|
241 |
+
debugging, rischiando perfino la possibile instabilità del codice e l'estinguersi del contributo degli utenti
|
242 |
+
qualora fosse risultato impossibile tener traccia di qualche serio bug. Linus si comportava seguendo una
|
243 |
+
concezione più o meno riassumibile come segue:
|
244 |
+
8. Stabilita una base di beta-tester e co-sviluppatori sufficientemente ampia, ogni problema verrà
|
245 |
+
rapidamente definito e qualcuno troverà la soluzione adeguata.
|
246 |
+
O, in modo meno formale, “Dato un numero sufficiente di occhi, tutti i bug vengono a galla”. Io la chiamo
|
247 |
+
la “Legge di Linus”.
|
248 |
+
La mia formulazione originale era che ogni problema “diventerà trasparente per qualcuno”. Linus fece
|
249 |
+
notare come la persona che si rende conto e risolve il problema non necessariamente né di norma è la
|
250 |
+
stessa persona che per prima lo mette a fuoco. “Qualcuno scopre il problema,” dice Linus, “e qualcun
|
251 |
+
altro lo comprende. E secondo me il compito più difficile è proprio trovarlo”. Ma il punto è che entrambe le
|
252 |
+
cose tendono ad accadere piuttosto rapidamente.
|
253 |
+
Questa ritengo che sia la differenza fondamentale tra lo stile a cattedrale e quello a bazaar. Nel primo
|
254 |
+
caso la visualizzazione dei problemi relativi a programmazione, bug e sviluppo costituiscono fenomeni
|
255 |
+
dubbi, insidiosi, complessi. Servono mesi di scrutinio ravvicinato da parte di più d'uno per poi sentirsi
|
256 |
+
sicuri di aver risolto tutti i problemi. Da qui i lunghi intervalli tra le release, e l'inevitabile delusione quando
|
257 |
+
le versioni così a lungo attese si rivelano imperfette.
|
258 |
+
Nella concezione a bazaar, d'altra parte, si dà per scontato che generalmente i bug siano fenomeni
|
259 |
+
marginali – o che almeno divengano rapidamente tali se esposti all'attenzione di migliaia di volenterosi
|
260 |
+
co-sviluppatori che soppesano ogni nuova release. Ne consegue la rapidità di diffusione per ottenere
|
261 |
+
maggiori correzioni, e come positivo effetto collaterale, c'è meno da perdere se viene fuori qualche toppa
|
262 |
+
raffazzonata.
|
263 |
+
Tutto qui. E non è certo poco. Se la “Legge di Linus” è falsa, allora ogni sistema complesso tanto quanto
|
264 |
+
il kernel Linux, ricavato grazie al lavoro collettivo delle molte mani che lo hanno messo insieme, a un
|
265 |
+
certo punto avrebbe dovuto crollare sotto il peso di interazioni negative impreviste e di “profondi” bug non
|
266 |
+
scoperti. Se invece è vera, allora è sufficiente a spiegare la relativa assenza di bug di Linux.
|
267 |
+
E forse ciò non dovrebbe rappresentare affatto una sorpresa. Qualche anno addietro sono stati i
|
268 |
+
sociologi a scoprire che l'opinione media di un gruppo di osservatori equamente esperti (o equamente
|
269 |
+
ignoranti) si rivela parametro assai più affidabile di quella di un solo osservatore scelto casualmente in
|
270 |
+
quel gruppo. Si tratta del cosiddetto “effetto Delfi”. Ora sembra che Linus abbia dimostrato come ciò vada
|
271 |
+
applicato anche all'operazione di debugging di un sistema operativo – ovvero che l'effetto Delfi è in grado
|
272 |
+
di addomesticare la complessità della programmazione, persino la complessità del kernel di un sistema
|
273 |
+
operativo.
|
274 |
+
Sono in debito con Jeff Dutky dutky@wam.umd.edu per aver sottolineato come la Legge di Linus possa
|
275 |
+
essere definita anche: “Il debugging è parallelizzabile”. Jeff fa notare come nel corso dell'intero processo,
|
276 |
+
pur richiedendo il coordinamento di uno sviluppatore che curi le comunicazioni tra quanti si occupano del
|
277 |
+
debugging, questi ultimi invece non richiedono particolare coordinamento. In tal modo non si cade preda
|
278 |
+
della notevole complessità e dei costi gestionali imposti dal coinvolgimento di nuovi sviluppatori.
|
279 |
+
In pratica, nel mondo Linux la perdita di efficienza a livello teorico, dovuta alla duplicazione di lavoro da
|
280 |
+
parte di quanti seguono il debugging, non arriva quasi mai a rappresentare un problema. Uno degli effetti
|
281 |
+
della policy “distribuire presto e spesso” è proprio quello di minimizzare tale duplicazione di lavoro
|
282 |
+
propagando rapidamente le soluzioni giunte col feedback degli utenti.
|
283 |
+
Anche Brooks ha fatto un'osservazione su quanto sostenuto da Jeff: “Il costo totale per il mantenimento
|
284 |
+
di un programma ampiamente utilizzato in genere viene valutato intorno al 40 per cento, o più, del costo
|
285 |
+
dello sviluppo. Non senza sorpresa, tale costo viene notevolmente influenzato dal numero di utenti
|
286 |
+
coinvolti. Maggiori sono questi ultimi, più bug si trovano.”
|
287 |
+
Ciò per via del fatto che con un maggior numero di utenti ci sono più modi differenti di verificare il
|
288 |
+
programma. Un effetto amplificato quando costoro sono anche co-sviluppatori. Ciascuno affronta il
|
289 |
+
compito della definizione dei bug con un approccio percettivo e analitico leggermente differente, una
|
290 |
+
diversa angolazione per affrontare il problema. L'effetto Delfi pare funzionare esattamente sulla base di
|
291 |
+
tali differenze. Nel contesto specifico del debugging, le variazioni tendono anche a ridurre la duplicazione
|
292 |
+
degli sforzi impiegati.
|
293 |
+
Quindi, dal punto di vista dello sviluppatore, l'aggiunta di altri beta-tester può non ridurre la complessità
|
294 |
+
del bug “più profondo” attualmente sotto studio, ma aumenta la probabilità che l'approccio di qualcuno
|
295 |
+
consentirà il corretto inquadramento del problema, così che per questa persona il bug non apparirà altro
|
296 |
+
che una bazzecola.
|
297 |
+
Inoltre, in caso di seri bug, le varie versioni del kernel di Linux sono numerate in modo tale che i
|
298 |
+
potenziali utenti possano scegliere o di far girare l'ultima versione definita “stabile” oppure rischiare
|
299 |
+
d'incappare in possibili bug pur di provare le nuove funzioni. Una tattica ancora non formalmente imitata
|
300 |
+
dalla maggior parte di hacker Linux, ma che forse dovrebbe esserlo. Il fatto che entrambe le scelte siano
|
301 |
+
disponibili le rende entrambe più attraenti.
|
302 |
+
5. Quando una rosa non è una rosa?
|
303 |
+
Dopo aver osservato il comportamento di Linus e aver elaborato una mia teoria sul perché d
|
304 |
+
el suo
|
305 |
+
successo, ho deciso coscientemente di mettere alla prova tale teoria sul mio nuovo progetto
|
306 |
+
(palesemente assai meno complesso e ambizioso).
|
307 |
+
Per prima cosa però ho semplificato parecchio popclient. Le implementazioni di Carl Harris erano
|
308 |
+
precise, ma mostravano quella complessità inopportuna comune a molti programmatori in C. Trattava il
|
309 |
+
codice come elemento centrale, considerando solo come supporto a latere la struttura dati. Come
|
310 |
+
conseguenza, il codice era eccezionale ma il design strutturale improvvisato e bruttino (almeno secondo
|
311 |
+
gli standard elevati di questo vecchio hacker di LISP).
|
312 |
+
Oltre al miglioramento del codice e del design strutturale, perseguivo comunque un altro obiettivo
|
313 |
+
nell'operazione di riscrittura. Volevo si evolvesse in qualcosa che fossi in grado di comprendere
|
314 |
+
pienamente. Non c'è alcun divertimento nel sistemare i problemi di un programma che non si comprende
|
315 |
+
appieno.
|
316 |
+
Fu così che mi ci volle tutto il primo mese soltanto per seguire le implicazioni del progetto di base di Carl.
|
317 |
+
La prima vera modifica fu l'aggiunta del supporto per IMAP. In pratica riorganizzai le macchine del
|
318 |
+
protocollo in un driver generico con tre opzioni (per POP2, POP3 e IMAP). Insieme ai cambiamenti
|
319 |
+
precedenti, ciò illustra il principio generale che ogni programmatore dovrebbe tenere bene a mente,
|
320 |
+
soprattutto lavorando con linguaggi come il C che non accettano facilmente gli inserimenti dinamici:
|
321 |
+
9. Meglio combinare una struttura dati intelligente e un codice non eccezionale che non il contrario.
|
322 |
+
Brooks, capitolo 9: “Mostrami [il codice] e nascondimi [la struttura dati], e io continuerò a essere
|
323 |
+
disorientato. Mostrami [la struttura dati], e non avrò bisogno del [codice]; sarà del tutto ovvio.”
|
324 |
+
Per esser precisi, lui parlava di “diagrammi” e “tabelle”. Ma considerando il mutamento lessicale/culturale
|
325 |
+
di questi trent'anni, il senso rimane invariato.
|
326 |
+
A questo punto (inizio Settembre 1996, sei settimane dopo esser partito da zero), ho cominciato a
|
327 |
+
pensare all'opportunità di cambiare il nome – in fondo non si trattava più soltanto di un client POP. Ma
|
328 |
+
esitavo perché mancava ancora qualcosa di genuinamente nuovo nel design. La mia versione di
|
329 |
+
popclient doveva ancora acquisire una propria identità.
|
330 |
+
Il cambio radicale avvenne quando fetchmail imparò come fare il forward della posta prelevata verso la
|
331 |
+
porta SMTP. Lo spiego meglio tra poco. Prima però: più sopra ho parlato della decisione di usare questo
|
332 |
+
progetto come test per verificare la mia teoria sui brillanti risultati raggiunti da Linus Torvalds. Vi potreste
|
333 |
+
chiedere, in che modo l'ho messa alla prova? Ecco come:
|
334 |
+
1. Ho diffuso le varie release presto e spesso (quasi mai a meno di dieci giorni di distanza; una volta
|
335 |
+
al giorno nei periodi d'intenso lavoro).
|
336 |
+
2. Ho inserito nella lista dei beta chiunque mi avesse contattato riguardo fetchmail.
|
337 |
+
3. Ho mandato simpatici messaggi all'intera lista dei beta per annunciare ogni nuova release,
|
338 |
+
incoraggiando la gente a partecipare.
|
339 |
+
4. E ho dato ascolto ai beta tester, ponendo loro domande sul design adottato e plaudendoli ogni
|
340 |
+
volta che mi mandavano aggiustamenti e feedback.
|
341 |
+
Questi semplici accorgimenti produssero una ricompensa immediata. Fin dall'inizio del progetto, mi
|
342 |
+
arrivavano report sui bug presenti di una qualità che qualunque sviluppatore avrebbe invidiato, spesso
|
343 |
+
con buone soluzioni in attach. Ho ricevuto mail piene di critiche costruttive, lodi sperticate, suggerimenti
|
344 |
+
intelligenti. Il che ci porta a:
|
345 |
+
10. Se tratti i beta tester come se fossero la risorsa più preziosa, replicheranno trasformandosi davvero
|
346 |
+
nella risorsa più preziosa a disposizione.
|
347 |
+
Un'interessante caratteristica del successo di fetchmail risiede nell'ampiezza dell'elenco dei beta, i
|
348 |
+
“fetchmail-friend”. Si è rapidamente raggiunta quota 249, con nuovi arrivi due o tre volte la settimana.
|
349 |
+
L'ultima revisione, fine Maggio 1997, ha rivelato che la lista andava perdendo membri, dopo aver
|
350 |
+
raggiunto un massimo di 300 nominativi, e ciò per un motivo degno di nota. In parecchi mi hanno chiesto
|
351 |
+
di essere rimossi perché fetchmail funzionava così bene che non c'era più alcun motivo di seguire il
|
352 |
+
traffico della lista! Forse anche ciò fa parte del normale ciclo di vita di un progetto maturo in stile bazaar.
|
353 |
+
6. Popclient diventa Fetchmail
|
354 |
+
Il vero punto di svolta del progetto ebbe luogo quando Harry Hochheiser mi spedì il codice iniziale per
|
355 |
+
fare il forward alla porta SMTP della macchina client. Mi sono reso immediatamente conto che
|
356 |
+
l'implementazione affidabile di tale funzione avrebbe reso pressoché obsoleta ogni altra modalità di
|
357 |
+
consegna della posta.
|
358 |
+
Per molte settimane mi ero messo a giocare con l'interfaccia di fetchmail, passabile ma disordinata –
|
359 |
+
poco elegante e con troppe opzioni sparse tutt'intorno. Tra queste mi davano particolarmente fastidio,
|
360 |
+
anche senza capire perché, quelle utilizzate per trasferire la posta prelevata in una certa mailbox o
|
361 |
+
altrove.
|
362 |
+
Quel che mi veniva in mente pensando alla funzione del “SMTP forwarding” era che popclient voleva
|
363 |
+
cercare di far troppe cose. Era stato ideato per essere sia un “mail transport agent” (MTA) sia un “mail
|
364 |
+
delivery agent” (MDA) a livello locale. Con il forward SMTP avrebbe potuto smettere di essere un MDA
|
365 |
+
per divenire un puro MTA, trasferendo ad altri programmi la posta per la consegna locale, proprio come
|
366 |
+
fa sendmail.
|
367 |
+
Perché darsi da fare a sistemare le complesse configurazioni p
|
368 |
+
er un MDA o le impostazioni per le
|
369 |
+
mailbox, quando innanzitutto è quasi sempre garantito che la porta 25 rimane disponibile per questo su
|
370 |
+
ogni piattaforma con supporto TCP/IP? Soprattutto quando ciò significa che i messaggi prelevati
|
371 |
+
appariranno come posta SMTP normalmente inviata dal mittente, che è poi quel che stiamo cercando di
|
372 |
+
ottenere.
|
373 |
+
Ci sono diverse lezioni da trarre a questo punto. Primo, l'idea del “SMTP forwarding” era la prima grossa
|
374 |
+
ricompensa per aver tentato coscientemente di emulare i metodi di Linus. Era stato un utente a
|
375 |
+
suggerirmi questa fantastica idea – non mi restava che comprenderne le implicazioni.
|
376 |
+
11. La cosa migliore, dopo l'avere buone idee, è riconoscere quelle che arrivano dagli utenti. Qualche
|
377 |
+
volta sono le migliori.
|
378 |
+
Fatto interessante, è facile scoprire che se sei completamente onesto e autocritico su quanto è dovuto
|
379 |
+
agli altri, il mondo intero ti tratterà come se ogni bit di quell'invenzione fosse opera tua, mentre impari a
|
380 |
+
considerare con sempre maggior modestia il tuo genio innato. Abbiamo visto come tutto ciò abbia
|
381 |
+
funzionato a meraviglia con Linus!
|
382 |
+
(Quando ho presentato questo scritto alla conferenza su Perl dell'Agosto 1997, in prima fila c'era Larry
|
383 |
+
Wall. Non appena sono arrivato al punto di cui sopra, ha intonato in stile revival-religioso, “Diglielo,
|
384 |
+
diglielo, fratello!” Tutti i presenti si son messi a ridere, perché sapevano come ciò avesse funzionato bene
|
385 |
+
anche per l'inventore di Perl.)
|
386 |
+
Dopo aver lavorato sul progetto nello stesso spirito per alcune settimane, mi son visto arrivare lodi simili
|
387 |
+
non soltanto dagli iscritti alla lista ma anche da altre persone che venivano a sapere della cosa. Ho
|
388 |
+
conservato qualche email; forse me le andrò a rileggere nel caso iniziassi a chiedermi se la mia vita
|
389 |
+
abbia mai avuto un qualche valore :-).
|
390 |
+
Ma ci sono altre due lezioni da trarre, più fondamentali e non politiche, buone per ogni tipo di design.
|
391 |
+
12. Spesso le soluzioni più interessanti e innovative arrivano dal fatto di esserti reso conto come la tua
|
392 |
+
concezione del problema fosse errata.
|
393 |
+
Avevo cercato di risolvere il problema sbagliato continuando a lavorare su popclient in quanto
|
394 |
+
combinazione MTA/MDA con tutte le possibili modalità di consegna della posta. Il design di fetchmail
|
395 |
+
aveva bisogno di essere reimpostato dall'inizio come un puro MTA, a parte il normale percorso della
|
396 |
+
posta relativo a SMTP.
|
397 |
+
Quando sbatti la testa contro il muro nel lavoro di programmazione – quando cioè non riesci più a
|
398 |
+
pensare alla prossima “patch” – spesso è ora di chiedersi non se hai la risposta giusta, ma se ti stai
|
399 |
+
ponendo la giusta domanda. Forse bisogna inquadrare nuovamente il problema.
|
400 |
+
Be', mi toccò inquadrare meglio il problema. Chiaramente la cosa giusta da fare era (1) posizionare il
|
401 |
+
supporto per il “SMTP forwarding” nel driver generico, (2) farla diventare la funzione default, (3)
|
402 |
+
sbarazzarsi di tutte le altre modalità di consegna della posta, specialmente le opzioni “deliver-to-file” e
|
403 |
+
“deliver-to-standard-output”.
|
404 |
+
Per qualche tempo ho esitato a compiere il passo (3), temendo di avvilire quanti usavano da molto tempo
|
405 |
+
popclient proprio per i diversi meccanismi di consegna. In teoria, avrebbero potuto immediatamente
|
406 |
+
passare ai file “.forward” oppure agli equivalenti “non-sendmail” per ottenere il medesimo effetto. In
|
407 |
+
pratica, però, tale transizione sarebbe risultata impraticabile.
|
408 |
+
Quando mi decisi comunque a farlo, ne risultarono enormi benefici. Le parti più confuse del codice del
|
409 |
+
driver scomparvero. La configurazione divenne radicalmente più semplice – niente più girovagare nel
|
410 |
+
sistema MDA e nella mailbox, niente più preoccupazioni per vedere se il sistema operativo supportasse o
|
411 |
+
meno il blocco dei file.
|
412 |
+
Venne anche eliminata l'unica possibilità di perdere dei messaggi. Se, specificando la consegna in un
|
413 |
+
file, il disco è pieno, la posta va perduta. Impossibile che ciò accada con il “SMTP forwarding” perché
|
414 |
+
l'altro SMTP in ascolto non accetterà l'OK a meno che il messaggio non possa essere correttamente
|
415 |
+
consegnato o almeno filtrato per il prelievo successivo.
|
416 |
+
Inoltre, le prestazioni complessive risultarono migliorate (anche se così non sembra quando lo si fa girare
|
417 |
+
una sola volta). Altro beneficio non insignificante del cambiamento fu che la chiamata manuale risultò
|
418 |
+
assai più semplificata.
|
419 |
+
In seguito fui costretto a reintrodurre la funzione di consegna tramite un MDA locale specificato
|
420 |
+
dall'utente, per consentire la gestione di strane situazioni relative allo SLIP dinamico. Ma riuscii a farlo in
|
421 |
+
maniera più semplice.
|
422 |
+
Morale? Non esitare a buttar via opzioni inanellate una sull'altra quando puoi rimpiazzarle senza perdere
|
423 |
+
in efficienza. Diceva Antoine de Saint-Exupéry (aviatore e designer di aerei, quando non scriveva libri per
|
424 |
+
bambini):
|
425 |
+
13. “La perfezione (nel design) si ottiene non quando non c'è nient'altro da aggiungere, bensì quando
|
426 |
+
non c'è più niente da togliere.”
|
427 |
+
Quando il codice diventa migliore e più semplice, allora vuol dire che va bene. E nel processo, il design
|
428 |
+
di fetchmail acquistò una sua propria identità, diversa dal popclient originario.
|
429 |
+
Era giunta l'ora di cambiar nome. Il nuovo design assomigliava più a sendmail di quanto lo fosse il
|
430 |
+
vecchio popclient; entrambi sono MTA, ma mentre sendmail spinge e poi consegna, il nuovo popclient
|
431 |
+
tira e poi consegna. Così, a due mesi dai blocchi di partenza, decisi di dargli il nuovo nome, fetchmail.
|
432 |
+
7. Fetchmail diventa adulto
|
433 |
+
Eccomi qui con un design ben fatto e innovativo, un codice che ero certo funzionasse bene perchè lo
|
434 |
+
usavo ogni giorno, e una spumeggiante lista di beta tester. Gradualmente mi resi conto che non ero più
|
435 |
+
indaffarato con uno stupido programmino personale che forse avrebbe potuto interessare pochi altri.
|
436 |
+
Stavo lavorando su un programma di cui ogni hacker dotato di mailbox Unix e connessione SLIP/PPP
|
437 |
+
non avrebbe potuto fare a meno.
|
438 |
+
Grazie all'opzione di “SMTP forwarding”, s
|
439 |
+
uperava sicuramente i programmi rivali fino a diventare
|
440 |
+
potenzialmente una “categoria killer”, uno di quei programmi classici che occupano la propria nicchia in
|
441 |
+
maniera perfetta, facendo scartare e quasi dimenticare ogni possibile alternativa.
|
442 |
+
Credo che simili risultati siano impossibili da perseguire o da pianificare. Devi esser trascinato dentro la
|
443 |
+
storia da idee così potenti che, col senno di poi, quei risultati appaiono del tutto inevitabili, naturali,
|
444 |
+
perfino prestabiliti. L'unico modo per provarci è farsi venire un sacco di idee, oppure avere la capacità di
|
445 |
+
portare le idee degli altri al di là del punto in cui essi stessi credevano potessero arrivare.
|
446 |
+
Andrew Tanenbaum ebbe l'idea originale di realizzare un linguaggio di base Unix per il 386, da usare
|
447 |
+
come strumento didattico. Linus Torvalds ha spinto il concetto del Minix ben oltre quanto lo stesso
|
448 |
+
Andrew ritenesse possibile – ed è diventato qualcosa di meraviglioso. Allo stesso modo (pur se su scala
|
449 |
+
minore) io ho preso alcune idee da Carl Harris e Harry Hochheiser, e le ho spinte oltre. Nessuno di noi è
|
450 |
+
stato “originale” nel senso romantico in cui si immagina un genio. Ma a ben vedere la maggior parte della
|
451 |
+
scienza, dell'ingegneria e dello sviluppo del software non viene realizzata da alcun genio originale, il
|
452 |
+
contrario della mitologia dell'hacker.
|
453 |
+
I risultati ottenuti erano piuttosto notevoli – meglio, esattamente quel tipo di successo che ogni hacker
|
454 |
+
sogna! E ciò significa che avrei potuto mirare anche a standard più elevati. Per rendere fetchmail così
|
455 |
+
ben fatto come lo vedevo ora, avrei dovuto scrivere non soltanto per le mie necessità ma anche per
|
456 |
+
includere il supporto di opzioni necessarie ad altri e tuttavia fuori dalla mia orbita. E fare ciò mantenendo
|
457 |
+
al contempo semplice e robusto il programma.
|
458 |
+
La prima funzione di gran lunga più importante che scrissi dopo essermi reso conto di ciò, fu il supporto
|
459 |
+
multiutente – la possibilità di prelevare la posta da più mailbox in cui erano stati accumulati tutti i
|
460 |
+
messaggi per un gruppo di utenti, e quindi smistare ogni singolo messaggio ai rispettivi destinatari.
|
461 |
+
Decisi di aggiungere il supporto multiutente in parte perché alcuni lo richiedevano, ma soprattutto perché
|
462 |
+
pensavo avrebbe buttato via ogni bug dal codice per un solo utente, costringendomi a fare attenzione
|
463 |
+
alla gestione dei vari indirizzi. E così fu. Mi ci volle parecchio tempo per sistemare tutto nella RFC 822,
|
464 |
+
non perché sia difficile mettere a posto ogni singola parte, ma perché coinvolgeva una montagna di
|
465 |
+
dettagli interdipendenti e instabili.
|
466 |
+
In ogni caso, anche la funzione per gli indirizzi multiutenti si rivelò un'ottima decisione. Ecco come me ne
|
467 |
+
sono accorto:
|
468 |
+
14. Ogni strumento dovrebbe rivelarsi utile nella maniera che ci si attende, ma uno strumento davvero
|
469 |
+
ben fatto si presta ad utilizzi che non ci si aspetterebbe mai.
|
470 |
+
L'uso inatteso della funzione multiutenti è per una mailing list quando questa viene mantenuta sul lato
|
471 |
+
client della connessione SLIP/PPP, attivando l'espansione dell'alias. Ne consegue che chi fa girare un
|
472 |
+
PC tramite un account con un provider Internet è in grado di gestire una mailing list senza dover
|
473 |
+
accedere continuamente ai file alias del provider.
|
474 |
+
Altra importante modifica richiesta dai beta tester fu il supporto per operazioni MIME in 8-bit. Qualcosa
|
475 |
+
piuttosto semplice a farsi, poiché avevo fatto bene attenzione a mantenere il codice pulito per inserire l'8-
|
476 |
+
bit. Non perché avessi anticipato tale richiesta, quanto piuttosto per rispettare un'altra regola:
|
477 |
+
15. Quando si scrive del software per qualunque tipo di gateway, ci si assicuri di disturbare il meno
|
478 |
+
possibile il flusso dei dati – e *mai* buttar via alcun dato a meno che il destinatario non ti ci costringa!
|
479 |
+
Se non avessi rispettato questa regola, il supporto per MIME in 8-bit sarebbe risultato difficile e
|
480 |
+
problematico. Così invece tutto quel che dovetti fare fu leggere la RFC 1652 e aggiungere poche stringhe
|
481 |
+
per far generare l'header.
|
482 |
+
Alcuni utenti europei mi hanno costretto a inserire un'opzione per limitare il numero dei messaggi
|
483 |
+
prelevati a ogni sessione (in modo da controllare i costi di collegamento, per via delle care tariffe imposte
|
484 |
+
dalle aziende telefoniche nazionali). Ho resistito per parecchio tempo, e ancor'oggi non ne sono
|
485 |
+
pienamente soddisfatto. Ma se scrivi programmi per tutto il mondo, devi dare ascolto ai tuoi clienti – e ciò
|
486 |
+
rimane valido anche se non ti ricompensano in denaro.
|
487 |
+
8. Qualche altra lezione da Fetchmail
|
488 |
+
Prima di tornare alle questioni generali sul “software-engineering”, è il caso di considerare qualche altro
|
489 |
+
insegnamento specifico a seguito di quest'esperienza con fetchmail.
|
490 |
+
La sintassi del file rc include una serie di parole-chiave facoltative completamente ignorate
|
491 |
+
dall'analizzatore. La sintassi in “quasi-inglese” che si ottiene è notevolmente più leggibile delle semplici
|
492 |
+
coppie nome/valore che si rimangono dopo aver eliminato le prime.
|
493 |
+
Tutto ebbe inizio come un esperimento a notte fonda dopo essermi accorto di quante fossero le
|
494 |
+
dichiarazioni del file rc che cominciavano ad assomigliare a un minilinguaggio imperativo. (Per lo stesso
|
495 |
+
motivo ho modificato in “poll” la parola-chiave “server” del popclient originale).
|
496 |
+
Mi venne da pensare che sarebbe stato più facile usare qualcosa di simile all'inglese comune piuttosto
|
497 |
+
che quel minilinguaggio imperativo. Ora, pur essendo il sottoscritto un convinto fautore della scuola di
|
498 |
+
design del tipo “trasformalo in linguaggio”, come esemplificato da Emacs, dall'HTML e da molti motori di
|
499 |
+
database, generalmente non mi annovero tra i fan delle sintassi in “quasi-inglese”.
|
500 |
+
Tradizionalmente i programmatori hanno sempre avuto la tendenza a favorire sintassi molto precise e
|
501 |
+
compatte, del tutto prive di ridondanza. Si tratta di un'eredità culturale del tempo in cui le risorse
|
502 |
+
informatiche erano costose, così gli analizzatori dovevano risultare semplici ed economici al massimo
|
503 |
+
grado. Allora l'inglese, con quel 50% di ridondanza, sembrava un modello poco appropriato.
|
504 |
+
Non è questa la ragione per cui generalmente io evito le sintassi in quasi-inglese; l'ho citata qui soltanto
|
505 |
+
per demolirla. Con l'attuale economicità dei cicli e delle strutture, la pulizia non dovrebbe essere un
|
506 |
+
obiettivo in sé. Al giorno d'oggi è più importante che un linguaggio sia conveniente per gli esseri umani
|
507 |
+
anziché economico per il computer.
|
508 |
+
Esistono comunque buoni motivi per procedere con cautela. Uno è rappresentato dai costi della
|
509 |
+
complessità dell'analizzatore – non è il caso di aumentare tale complessità fino a raggiungere il punto in
|
510 |
+
cui produrrà bug significativi e confusione nell'utente. Un'altra ragione è che cercare di rendere un
|
511 |
+
linguaggio in quasi-inglese spesso richiede un tale aggiustamento linguistico che le somiglianze
|
512 |
+
superficiali con il linguaggio naturale generino confusione tanto quanto l'eventuale sintassi tradizionale.
|
513 |
+
(Come si può notare con evidenza nei linguaggi di interrogazione dei database di “quarta generazione” e
|
514 |
+
commerciali).
|
515 |
+
La sintassi di controllo di fetchmail riesce a evitare questi problemi perché il dominio riservato al
|
516 |
+
linguaggio è estremamente limitato. Non si avvicina neppure lontanamente a un linguaggio di tipo
|
517 |
+
generale; le cose che dice non sono affatto complicate, lasciando quindi poco spazio a potenziali
|
518 |
+
confusioni, quando ci si sposta mentalmente tra un ristretto ambito d'inglese e il linguaggio di controllo
|
519 |
+
vero e proprio. Credo qui si tratti di una lezione di più ampia portata:
|
520 |
+
16. Quando il linguaggio usato non è affatto vicino alla completezza di Turing, un po' di zucchero
|
521 |
+
sintattico può esserti d'aiuto.
|
522 |
+
Un'altra lezione riguarda la sicurezza “al buio”. Alcuni utenti di fetchmail mi avevano chiesto di modificare
|
523 |
+
il software in modo che potesse conservare le password crittografate nel file rc, evitando così il rischio
|
524 |
+
che qualche ficcanaso potesse scoprirle casualmente.
|
525 |
+
Non l'ho fatto perché in realtà ciò non aggiunge alcuna protezione. Chiunque sia stato autorizzato a
|
526 |
+
leggere il file rc, sarebbe comunque in grado di far girare fetchmail – e se è la password che cerca,
|
527 |
+
saprebbe come decodificarla tirandola fuori dallo stesso codice di fetchmail.
|
528 |
+
Qualsiasi possibile codifica della password operata da .fetchmailrc, non avrebbe fatto altro che fornire un
|
529 |
+
falso
|
530 |
+
senso
|
531 |
+
di
|
532 |
+
sicurezza
|
533 |
+
a
|
534 |
+
quelli
|
535 |
+
che
|
536 |
+
non
|
537 |
+
vogliono
|
538 |
+
spremersi
|
539 |
+
le
|
540 |
+
meningi.
|
541 |
+
La regola generale è:
|
542 |
+
17. Un sistema di sicurezza è sicuro soltanto finché è segreto. Meglio diffidare degli pseudo-segreti.
|
543 |
+
9. Le pre-condizioni necessarie per lo stile bazaar
|
544 |
+
I primi lettori e revisori di questo scritto hanno r
|
545 |
+
ipetutamente sollevato domande sulle pre-condizioni
|
546 |
+
necessarie per il successo dello sviluppo in stile bazaar, comprendendo con ciò sia le qualifiche del
|
547 |
+
leader del progetto sia lo stato del codice al momento della diffusione pubblica e della nascita della
|
548 |
+
possibile comunità di co-sviluppatori.
|
549 |
+
È alquanto evidente come lo stile bazaar non consenta la scrittura del codice partendo da zero. Si
|
550 |
+
possono fare test, trovare i bug, migliorare il tutto, ma sarebbe molto difficile dar vita dall'inizio a un
|
551 |
+
progetto in modalità bazaar. Linus non lo ha fatto. Neppure io. La nascente comunità di sviluppatori deve
|
552 |
+
avere qualcosa da far girare e con cui giocare.
|
553 |
+
Quando s'inizia a costruire la comunità, bisogna essere in grado di presentare una promessa plausibile.
|
554 |
+
Non è detto che il programma debba funzionare particolarmente bene. Può anche essere crudo, pieno di
|
555 |
+
bug, incompleto, scarsamente documentato. Non deve però mancare di convincere i potenziali co-
|
556 |
+
sviluppatori che possa evolversi in qualcosa di veramente ben fatto nel prossimo futuro.
|
557 |
+
Quando Linux e fetchmail vennero diffusi pubblicamente, erano dotati di un design di base forte e
|
558 |
+
attraente. Molte persone ritengono che il modello bazaar da me presentato riveli correttamente questa
|
559 |
+
fase critica, per poi da qui saltare alla conclusione che sia indispensabile un elevato livello di intuizione e
|
560 |
+
bravura da parte di chi guida il progetto.
|
561 |
+
Ma Linus prese il suo design da Unix. All'inizio ho fatto lo stesso con il popclient originario (anche se poi
|
562 |
+
risultò molto diverso, assai più di quanto è accaduto con Linux, fatte le debite proporzioni). È dunque
|
563 |
+
vero che il leader/coordinatore di un progetto in stile bazaar debba possedere un eccezionale talento nel
|
564 |
+
design? Oppure può cavarsela facendo leva sui talenti altrui?
|
565 |
+
Non credo sia essenziale che il coordinatore possa produrre design eccezionali, ma è assolutamente
|
566 |
+
centrale che sia capace di riconoscere le buone idee progettuali degli altri.
|
567 |
+
Ciò appare evidente da entrambi i progetti di Linux e fetchmail. Pur non essendo un designer
|
568 |
+
particolarmente originale (come discusso in precedenza), Linus ha dimostrato un ottima intuizione nel
|
569 |
+
saper riconoscere il buon design per poi integrarlo nel kernel di Linux. Ed ho già descritto come l'idea più
|
570 |
+
potente di fetchmail (SMTP forwarding) mi sia arrivata da qualcun altro.
|
571 |
+
I primi lettori di questo testo mi hanno fatto i complimenti mettendo a fuoco la mia propensione a
|
572 |
+
sottovalutare l'originalità del design nei progetti in stile bazaar perchè ne possiedo a volontà io stesso, e
|
573 |
+
quindi la dò per scontata. In effetti, c'è qualcosa di vero in quest'affermazione; il design (in alternativa al
|
574 |
+
codice o al debugging) è la mia capacità migliore.
|
575 |
+
Ma il problema con il fatto di essere bravi e originali nel design del software è che tende a divenire
|
576 |
+
un'abitudine – prendi a fare cose carine e complicate quando invece dovresti tenerle semplici e robuste.
|
577 |
+
Proprio per questa ragione mi sono crollati addosso vari progetti, ma con fetchmail sono stato attento a
|
578 |
+
non farlo.
|
579 |
+
Credo insomma che il progetto di fetchmail abbia avuto successo in parte perché ho limitato la mia
|
580 |
+
tendenza a esser bravo; ciò va (almeno) contro l'essenzialità dell'originalità del design per il successo dei
|
581 |
+
progetti a bazaar. Consideriamo Linux. Supponiamo che Linus Torvalds avesse cercato di tirar fuori le
|
582 |
+
innovazioni fondamentali dal design del sistema operativo nel corso dello sviluppo; quali probabilità
|
583 |
+
esistono che il kernel risultante fosse ugualmente stabile ed efficace come quello che abbiamo ora?
|
584 |
+
È chiaro che occorrano capacità di un certo livello per il design e il codice, ma personalmente mi aspetto,
|
585 |
+
da quasi tutte le persone che pensano seriamente di lanciare un progetto bazaar, un livello superiore. Il
|
586 |
+
mercato interno della reputazione della comunità open source esercita una sottile pressione sulle
|
587 |
+
persone in modo che non si lancino dei progetti se non si è abbastanza competenti per seguirli. Finora
|
588 |
+
quest'approccio ha funzionato piuttosto bene.
|
589 |
+
Esiste un altro tipo di capacità normalmente non associata allo sviluppo del software che ritengo
|
590 |
+
importante al pari della bravura nel design per i progetti bazaar – anzi, forse ancora più importante. Il
|
591 |
+
coordinatore o leader deve essere in grado di comunicare efficacemente con gli altri.
|
592 |
+
D'altronde è ovvio che per metter su una comunità di sviluppatori occorra attirare gente, coinvolgerli in
|
593 |
+
quel che stai facendo, tenerli contenti per il lavoro che fanno. Lo sfrigolìo tecnico aiuta molto in questo
|
594 |
+
senso, ma è ben lungi dall'esser tutto. È anche importante il tipo di personalità che proietti.
|
595 |
+
Non è certo una coincidenza che Linus sia un tipo simpatico, capace di piacere alla gente e di farsi
|
596 |
+
aiutare. Da parte mia, io sono un estroverso energetico cui piace lavorare tra la folla, oltre ad avere
|
597 |
+
qualcosa dei modi e dell'istinto del comico. Per far funzionare il modello a bazaar, aiuta parecchio essere
|
598 |
+
in grado di esercitare almeno un po' di fascino sulla gente.
|
599 |
+
10. Il contesto sociale del software open source
|
600 |
+
È proprio vero: le migliori operazioni di hacking nascono come soluzioni personali ai problemi quotidiani
|
601 |
+
dell'autore, e si diffondono perchè si scopre che tali problemi sono comuni a molte altre persone. Questo
|
602 |
+
ci riporta indietro alla questione della regola numero uno, riformulata forse in maniera più consona:
|
603 |
+
18. Per risolvere un problema interessante, comincia a trovare un problema che risvegli il tuo interesse.
|
604 |
+
Così è successo con Carl Harris e l'iniziale popclient, lo stesso con me e fetchmail. Ma ciò era chiaro da
|
605 |
+
molto tempo. Il punto interessante che richiede attenzione, sulla base dell'evolversi di Linux e di
|
606 |
+
fetchmail, è il palcoscenico successivo – l'evoluzione del software in presenza di una vasta e attiva
|
607 |
+
comunità di utenti e co-sviluppatori.
|
608 |
+
In “The Mythical Man-Month”, Fred Brooks osserva come il tempo del programmatore non sia calcolabile;
|
609 |
+
aggiungendo altri sviluppatori ad un progetto in ritardo, lo si fa tardare ancora di più. Secondo lui, i costi
|
610 |
+
della complessità e delle comunicazioni di un progetto crescono esponenzialmente con il numero degli
|
611 |
+
sviluppatori coinvolti, mentre il lavoro cresce soltanto in senso lineare. Quest'affermazione è nota come
|
612 |
+
la “Legge di Brooks”, ed è considerata una verità pressoché universale. Ma se la Legge di Brooks fosse
|
613 |
+
stata l'unica verità, Linux non sarebbe mai esistito.
|
614 |
+
Il classico di Gerald Weinberg “The Psychology Of Computer Programming” spiega in che modo, a
|
615 |
+
posteriori, sia possibile individuare una vitale correzione alla tesi di Brooks. Parlando di “programmazione
|
616 |
+
senza ego”, Weinberg fa notare come laddove gli sviluppatori non si dimostrano territoriali rispetto al
|
617 |
+
proprio codice, incoraggiando altre persone a cercare bug e offrire miglioramenti, questi ultimi prendono
|
618 |
+
corpo molto più in fretta che altrove.
|
619 |
+
Forse le scelte terminologiche operate da Weinberg hanno impedito alla sua analisi di ottenere il
|
620 |
+
riconoscimento che merita – viene da ridere al solo pensiero di riuscire a descrivere un hacker “senza
|
621 |
+
ego”. Ma ritengo la sua posizione stringente più che mai.
|
622 |
+
La storia di Unix avrebbe dovuto prepararci per quel che stiamo imparando da Linux (e per quello che io
|
623 |
+
stesso ho verificato sperimentalmente su scala ridotta, copiando deliberatamente i metodi di Linus).
|
624 |
+
Ovvero, pur rimandando la scrittura del codice un'attività prettamente solitaria, la questione davvero
|
625 |
+
importante rimane la capacità di sfruttare l'attenzione e la potenza dell'intera comunità. Lo sviluppatore
|
626 |
+
che impiega soltanto il proprio cervello su un progetto chiuso risulterà sempre dietro allo sviluppatore che
|
627 |
+
sa come creare un contesto aperto, evolutivo dove sono centinaia le persone che si occupano dei
|
628 |
+
miglioramenti e del debugging.
|
629 |
+
Ma una serie di elementi hanno impedito al mondo tradizionale Unix di applicare tale approccio. Tra
|
630 |
+
questi, gli impedimenti legali connessi alle varie licenze, ai segreti e agli interessi commerciali. Altro
|
631 |
+
impedimento (in retrospettiva), il fatto che allora Internet non fosse ancora abbastanza sviluppata.
|
632 |
+
Prima dell'attuale Internet super-diffusa, esistevano poche comunità geograficamente compatte in cui
|
633 |
+
veniva incoraggiata la cultura della programmazione “senza ego” di Weinberg, dove uno sviluppatore
|
634 |
+
poteva facilmente attirare molti altri co-sviluppatori in gamba. Il Bell Lab, il MIT, UC Berkeley – queste le
|
635 |
+
dimore dell'innovazione che rimangono leggendarie e potenti ancor'oggi.
|
636 |
+
Linux è stato il primo progetto a proporre lo sforzo cosciente e coronato da successo verso l'utilizzo del
|
637 |
+
mondo intero come fucina di talenti. Non ritengo una combinazione il fatto che la gestazione di Linux sia
|
638 |
+
coincisa con la nascita del World Wide Web, e che Linux si sia lasciato alle spalle l'infanzia negli stessi
|
639 |
+
anni 1993-1994 che hanno visto il decollo dei provider locali e l'esplosione dell'interesse di massa per
|
640 |
+
Internet. Linus è stata la prima persona ad aver imparato come giocare secondo le nuove regole rese
|
641 |
+
possibili dalla diffusione di Internet.
|
642 |
+
Se è vero che tale diffusione si è rivelata necessaria per l'evoluzione del modello Linux, non credo però
|
643 |
+
possa ritenersi da sola una condizione sufficiente. Altro fattore vitale è stata l'implementazione di un certo
|
644 |
+
stile di leadership e di un insieme di usanze cooperative che hanno consentito agli sviluppatori di
|
645 |
+
coinvolgere altri co-sviluppatori e ottenere il massimo possibile dal medium stesso.
|
646 |
+
Ma cosa s'intende esattamente con un certo stile di leadership e quali sarebbero queste usanze
|
647 |
+
cooperative? Intanto, non ci si basa su relazioni di potere – e anche se tali dovessero essere, una
|
648 |
+
leadership fondata sulla costrizione non produrrebbe i risultati che abbiamo visto. Weinberg cita al
|
649 |
+
riguardo l'autobiografia dell'anarchico russo del XIX secolo Pyotr Alexeyvich Kropotkin, “Memorie di un
|
650 |
+
rivoluzionario”:
|
651 |
+
“Essendo cresciuto in una famiglia che aveva dei servitori, sono entrato nella vita attiva, al pari di tutti i
|
652 |
+
giovani della mia epoca, con un notevole carico di confidenza nella necessità di comandare, impartire
|
653 |
+
ordini, rimproverare, punire. Ma quando, ancora giovane, dovetti gestire degli affari seri e avere a che
|
654 |
+
fare con uomini [liberi], quando ogni errore avrebbe portato da solo a pesanti conseguenze, iniziai ad
|
655 |
+
apprezzare la differenza tra l'agire basato sul principio del comando e della disciplina e l'agire basato sul
|
656 |
+
principio della comprensione condivisa. Il primo funziona mirabilmente in una parata militare, ma non ha
|
657 |
+
valore alcuno allorché si tratta della vita reale, dove ogni obiettivo può essere raggiunto soltanto tramite i
|
658 |
+
duri sforzi di molte volontà convergenti.”
|
659 |
+
È precisamente i “duri sforzi di molte volontà convergenti” sono quel che un progetto come Linux richiede
|
660 |
+
– e il “principio del comando” è veramente impossibile da praticare tra i volontari di quel paradiso
|
661 |
+
anarchico chiamato Internet. Per operare e competere con efficacia, ogni hacker che voglia guidare
|
662 |
+
progetti collettivi deve imparare come creare e dare energia a reali comunità d'interesse secondo le
|
663 |
+
modalità vagamente suggerite dal “principio della comprensione” citato da Kropotkin. Deve imparare ad
|
664 |
+
usare la Legge di Linus.
|
665 |
+
Più sopra mi sono riferito all'effetto Delfi come possibile spiegazione della Legge di Linus. Ma si
|
666 |
+
potrebbero anche fare analogie forse più calzanti con i sistemi d'adattamento delle scienze biologiche ed
|
667 |
+
economiche. Sotto molti aspetti il mondo Linux si comporta come un “free market” oppure come un
|
668 |
+
sistema ecologico, una serie di agenti indipendenti che cercando di massimizzare quell'utilitarismo che
|
669 |
+
nel processo va producendo un ordine spontaneo e in grado di auto-correggersi, più elaborato ed
|
670 |
+
efficiente di quanto avrebbe potuto raggiungere qualsiasi pianificazione centralizzata. È dunque questo il
|
671 |
+
luogo dove cercare il “principio della comprensione”.
|
672 |
+
La “funzione utilitaristica” che gli hacker di Linux vanno massimizzando non è economica in senso
|
673 |
+
classico, quanto piuttosto espressione dell'intangibile, egoistica reputazione e soddisfazione che si
|
674 |
+
guadagna tra gli altri hackers. (La loro motivazione potrebbe essere definita “altruista”, ma ciò
|
675 |
+
significherebbe ignorare il fatto che a ben vedere l'altruismo stesso altro non è che una forma di
|
676 |
+
soddisfazione egoistica). In realtà le culture del lavoro volontario che funzionano in tal modo non sono
|
677 |
+
così rare; un'altra cui ho preso parte a lungo è quella dei fan della fantascienza, che al contrario del giro
|
678 |
+
hacker riconosce esplicitamente come motore propulsore dietro tale attività volontaria proprio il
|
679 |
+
cosiddetto “egoboo” (l'esaltazione della reputazione individuale tra gli altri fan).
|
680 |
+
Linus, posizionandosi con successo come filtro di un progetto nel quale il lavoro è in gran parte svolto da
|
681 |
+
altri, e alimentando interesse nel progetto stesso finché non arriva ad auto-alimentarsi, ha dimostrato di
|
682 |
+
aver acutamente fatto proprio il “principio della comprensione condivisa” di Kropotkin. Questa visione
|
683 |
+
quasi-economica del mondo Linux ci consente di vedere come applicare tale comprensione.
|
684 |
+
È possibile ritenere il metodo di Linus c
|
685 |
+
ome un modo per creare un mercato efficiente all'interno
|
686 |
+
dell'“egoboo” – per collegare nel modo più sicuro possibile l'egoismo dei singoli hacker con quegli
|
687 |
+
obiettivi difficili che possono essere raggiunti soltanto grazie alla concreta cooperazione collettiva. Con il
|
688 |
+
progetto fetchmail ho dimostrato (pur se su scala più ridotta) che è possibile duplicarne il metodo
|
689 |
+
ottenendo buoni risultati. Forse l'ho perfino messo in atto un po' più coscientemente e sistematicamente
|
690 |
+
di quanto non abbia fatto Linus.
|
691 |
+
Molte persone (soprattutto quanti politicamente diffidano del “free market”) immaginavano che una
|
692 |
+
cultura di egoisti auto-referenziale si rivelasse frammentaria, territoriale, sprecona, segreta, ostile. Ma
|
693 |
+
tale aspettativa viene chiaramente confutata (per fornire un solo esempio) dalla notevole varietà, qualità
|
694 |
+
e profondità della documentazione relativa a Linux. Se è un dato di fatto che i programmatori odiano
|
695 |
+
lavorare sulla documentazione, com'è allora che gli hacker di Linux ne producono di così copiosa?
|
696 |
+
Evidentemente il “free market dell'egoboo” di Linux funziona meglio nella produzione di comportamenti
|
697 |
+
virtuosi, diretti verso gli altri, rispetto a quei negozi dei produttori di software commerciale che si
|
698 |
+
occupano della documentazione, avendo alle spalle massicci finanziamenti.
|
699 |
+
Sia il progetto di fetchmail che del kernel di Linux dimostrano come, dando la giusta ricompensa all'ego di
|
700 |
+
molti altri hacker, un bravo sviluppatore/coordinatore possa utilizzare Internet per catturare i vantaggi
|
701 |
+
dell'avere a disposizione molti co-sviluppatori senza che il progetto si frantumi in una confusione caotica.
|
702 |
+
Ecco quindi la mia controproposta alla Legge di Brooks:
|
703 |
+
19: Stabilito che il coordinatore dello sviluppo abbia a disposizione un medium almeno altrettanto
|
704 |
+
affidabile di Internet, e che sappia come svolgere il ruolo di leader senza costrizione, molte teste
|
705 |
+
funzionano inevitabilmente meglio di una sola.
|
706 |
+
Penso che il futuro del software open source apparterrà sempre più alle persone che sanno come
|
707 |
+
giocare al gioco di Linus, persone che si lasceranno alle spalle la cattedrale per entrare nel bazaar. Ciò
|
708 |
+
non significa che non saranno più importanti le visioni e l'intelligenza individuali; credo piuttosto che la
|
709 |
+
punta avanzata del software open source apparterrà a quanti sapranno muovere da visioni e intelligenza
|
710 |
+
individuali per poi amplificarle tramite l'effettiva costruzione di comunità volontarie d'interesse.
|
711 |
+
E forse ciò vale non soltanto per il futuro del software open source. Nessuno sviluppatore in “closed-
|
712 |
+
source” potrà mai pareggiare la fucina di talenti che la comunità Linux è in grado di riunire per affrontare
|
713 |
+
un problema. Sono davvero in pochi a potersi permettere di assumere le oltre duecento persone che
|
714 |
+
hanno contribuito a fetchmail!
|
715 |
+
Forse alla fine la cultura dell'open source trionferà non perchè la cooperazione sia moralmente giusta o
|
716 |
+
perché il software “costretto” sia moralmente sbagliato (dando per scontato che si creda a quest'ultima
|
717 |
+
affermazione, cosa che né io né Linus facciamo), ma semplicemente perché il mondo “closed-source”
|
718 |
+
non è in grado di vincere la corsa agli armamenti dell'evoluzione contro quelle comunità open source
|
719 |
+
capaci di affrontare un problema con tempi e capacità superiori di diversi ordini di grandezza.
|
720 |
+
11. Ringraziamenti
|
721 |
+
Questo scritto è stato migliorato grazie alle conversazioni avute con molte persone che hanno contribuito
|
722 |
+
a trovarne i bug. Ringrazio in modo particolare Jeff Dutky , che mi ha suggerito la formulazione “il
|
723 |
+
debugging è parallelizzabile” e che mi ha aiutato a svilupparne le analisi conseguenti. Grazie anche a
|
724 |
+
Nancy Lebovitz per avermi suggerito di emulare Weinberg citando Kropotkin. Critiche costruttive sono
|
725 |
+
venute anche da Joan Eslinger e Marty Franz della lista General Technics. Sono grato ai membri del
|
726 |
+
PLUG, Philadelphia Linux User's Group, per essersi prestati come primo test pubblico per la versione
|
727 |
+
iniziale di questo testo. Infine, i commenti iniziali di Linus Torvalds sono stati di grande aiuto e il suo
|
728 |
+
sostegno molto incoraggiante.
|
729 |
+
12. Letture consigliate
|
730 |
+
Ho citato diversi passaggi dal classico di Frederick P. Brooks “The Mythical Man-Month” perché, in molti
|
731 |
+
sensi, le sue introspezioni meritano ulteriori riflessioni. Raccomando di cuore l'edizione pubblicata in
|
732 |
+
occasione del 25° Anniversario da Addison-Wesley (ISBN 0
|
733 |
+
-201-83595-9), che contiene anche il suo
|
734 |
+
saggio del 1986 “No Silver Bullet”.
|
735 |
+
Questa nuova edizione contiene un'importante retrospettiva dei 20 anni successivi in cui Brooks ammette
|
736 |
+
schiettamente come alcuni giudizi espressi nel testo originale non abbiano sostenuto la prova del tempo.
|
737 |
+
Ho letto la retrospettiva dopo aver sostanzialmente completato questo scritto, e sono rimasto sorpreso
|
738 |
+
nello scoprire che Brooks attribuisse pratiche da quasi-bazaar a Microsoft! (In realtà, però, si è poi visto
|
739 |
+
come tale attribuzione fosse erronea. Nel 1998 abbiamo appreso dagli Halloween Documents come la
|
740 |
+
comunità interna dei programmatori di Microsoft risulti pesantemente balcanizzata, senz'alcuna
|
741 |
+
possibilità per quel tipo di accesso generale ai sorgenti tipico dello stile bazaar).
|
742 |
+
“The Psychology Of Computer Programming” di Gerald M. Weinberg (New York, Van Nostrand Reinhold
|
743 |
+
1971) presenta il concetto, malamente etichettato, di “programmazione senza ego.” Pur essendo l'autore
|
744 |
+
nient'affatto tra i primi a rendersi conto della futilità del “principio del comando”, probabilmente fu il primo
|
745 |
+
a riconoscere e sostenere tale punto in particolare connessione con lo sviluppo del software.
|
746 |
+
Richard P. Gabriel, occupandosi della cultura Unix dell'era pre-Linux, sosteneva con riluttanza la
|
747 |
+
superiorità di un modello quasi-bazaar nel suo saggio del 1989: “Lisp: Good News, Bad News, and How
|
748 |
+
To Win Big”. Anche se per molti versi un po' datato, il testo è ancora giustamente celebrato dai fan del
|
749 |
+
Lisp (incluso il sottoscritto). Qualcuno mi ha ricordato che la sezione intitolata “Worse Is Better” si
|
750 |
+
propone quasi come un'anticipazione di Linux. L'articolo è disponibile sul World Wide Web:
|
751 |
+
http://www.naggum.no/worse-is-better.html.
|
752 |
+
“Peopleware: Productive Projects and Teams” di De Marco e Lister (New York; Dorset House, 1987;
|
753 |
+
ISBN 0-932633-05-6) è una gemma sottovalutata che mi ha fatto piacere veder citata nella retrospettiva
|
754 |
+
di Fred Brooks. Anche se poco di quanto scrivono gli autori può applicarsi direttamente alle comunità
|
755 |
+
Linux o open source, le loro riflessioni sulle condizioni necessarie per un lavoro creativo sono acute e
|
756 |
+
valide per chiunque volesse provare ad applicare alcune delle virtù del modello bazaar in un contesto
|
757 |
+
commerciale.
|
758 |
+
Devo infine ammettere d'aver inizialmente intitolato questo scritto “La cattedrale e l'agorà”, essendo
|
759 |
+
quest'ultimo il termine greco per indicare un mercato all'aperto o un luogo d'incontro pubblico. Ciò per
|
760 |
+
l'influenza dei saggi embrionali di Mark Miller e Eric Drexler “Agoric systems” in cui venivano descritte le
|
761 |
+
proprietà emergenti dell'ecologia computazionale di tipo quasi-commerciale. Tali scritti mi hanno
|
762 |
+
preparato a riflettere con chiarezza sugli analoghi fenomeni nell'ambito della cultura open source quando
|
763 |
+
Linux mi ci ha fatto sbattere il muso cinque anni dopo. Questi scritti sono reperibili sul Web:
|
764 |
+
http://www.agorics.com/agorpapers.html.
|
765 |
+
13. Epilogo: Netscape si unisce al bazaar!
|
766 |
+
È proprio strano rendersi conto di aiutare lo sviluppo della storia...
|
767 |
+
Il 22 gennaio 1998, circa sette mesi dopo la prima pubblicazione di questo scritto, Netscape
|
768 |
+
Communications, Inc. ha annunciato la diffusione pubblica dei codici sorgenti di Netscape
|
769 |
+
Communicator. Fino al momento dell'annuncio, non avevo alcuna idea che ciò sarebbe mai potuto
|
770 |
+
accadere.
|
771 |
+
Subito dopo l'annuncio, Eric Hahn, Executive Vice President e Chief Technology Officer di Netscape, mi
|
772 |
+
ha inviato questa breve email: “A nome di tutti noi di Netscape, voglio ringraziarti per averci aiutato
|
773 |
+
innanzitutto a compiere questo passo. Il tuo pensiero e i tuoi scritti sono stati di fondamentale ispirazione
|
774 |
+
per la nostra decisione.”
|
775 |
+
La settimana successiva (4 Febbraio 1998), sono arrivato in aereo nella Silicon Valley su invito di
|
776 |
+
Netscape per partecipare a una giornata di incontri sulle strategie future con alcuni dei loro dirigenti
|
777 |
+
esecutivi e il personale tecnico. Abbiamo progettato insieme la strategia e la licenza per la release del
|
778 |
+
codice di Netscape, oltre ad aver buttato giù ulteriori piani che speriamo alla fine possano avere un
|
779 |
+
impatto positivo e profondo sulla comunità open source. Al momento in cui scrivo, è troppo presto per
|
780 |
+
entrare nello specifico; ma entro qualche settimana dovrebbero essere noti maggiori dettagli.
|
781 |
+
Netscape sta per fornirci un test su larga scala e assai concreto del modello bazaar all'interno del mondo
|
782 |
+
commerciale. La cultura dell'open source si trova di fronte a un pericolo; se l'operazione di Netscape non
|
783 |
+
dovesse funzionare, il concetto stesso di open source potrebbe risultarne così screditato che il mondo
|
784 |
+
commerciale non gli si avvicinerà per un'altra decade.
|
785 |
+
D'altra parte, però, si tratta di una spettacolare opportunità. L'iniziale reazione a tale mossa in quel di
|
786 |
+
Wall Street e altrove è stata cautamente positiva. Ci è stata data la possibilità di provare cosa sappiamo
|
787 |
+
fare. Se grazie a questa mossa Netscape saprà riguadagnare una sostanziale quota di mercato, ciò
|
788 |
+
potrebbe davvero innescare la rivoluzione attesa da lungo tempo nell'industria del software.
|
789 |
+
L'anno prossimo sarà un anno molto istruttivo e interessante.
|
790 |
+
14. Cronologia delle versioni e delle modifiche
|
791 |
+
$Id: cathedral-bazaar.sgml,v 1.42 22/11/1998 04:01:20 esr Exp $
|
792 |
+
Presentazione della 1.16 al Linux Kongress, 21 Maggio 1997.
|
793 |
+
Bibliografia aggiunta il 7 Luglio 1997 nella 1.20.
|
794 |
+
Aggiunto l'aneddoto sulla Perl Conference il 18 Novembre 1997 nella 1.27.
|
795 |
+
Modificato “free software” in “open source” il 9 Febbraio 1998 nella 1.29.
|
796 |
+
Aggiunto “Epilogo: Netscape si unisce al bazaar!” il 10 Febbraio 1998 nella 1.31.
|
797 |
+
Eliminato il grafico di Paul Eggert sulla questione GPL-bazaar dopo vivaci discussioni con RMS il 28
|
798 |
+
Luglio 1998.
|
799 |
+
Aggiunta correzione su Brooks basata sugli Halloween Documents il 20 Novembre 1998 nella 1.40.
|
800 |
+
Altri livelli di revisione hanno incorporato minori aggiustamenti editoriali.
|
801 |
+
|
802 |
+
Traduzione italiana a cura di Bernardo Parrella berny@apogeonline.com, Giugno 1999
|
803 |
+
Per il testo originale inglese: http://www.tuxedo.org/~esr/writings/cathedral-bazaar/cathedral-bazaar.html
|
804 |
+
|
static/data/lettere_musulmane.txt
ADDED
@@ -0,0 +1,1891 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
« SPIRITUALITÀ SPERIMENTALE »
|
2 |
+
Collana diretta da Gianpaolo Fiorentini
|
3 |
+
15
|
4 |
+
© 1998: Promolibri Magnanelli, Torino
|
5 |
+
Stampa: M.S./ Litografia, Torino
|
6 |
+
I N D I C E
|
7 |
+
Introduzione
|
8 |
+
9
|
9 |
+
Prima lettera
|
10 |
+
13
|
11 |
+
Prima risposta
|
12 |
+
19
|
13 |
+
Seconda lettera
|
14 |
+
23
|
15 |
+
Seconda risposta
|
16 |
+
27
|
17 |
+
Terza lettera
|
18 |
+
31
|
19 |
+
Terza risposta
|
20 |
+
35
|
21 |
+
Quarta lettera
|
22 |
+
39
|
23 |
+
Quarta risposta
|
24 |
+
42
|
25 |
+
Quinta lettera
|
26 |
+
47
|
27 |
+
Quinta risposta
|
28 |
+
50
|
29 |
+
Sesta lettera
|
30 |
+
53
|
31 |
+
Sesta risposta
|
32 |
+
56
|
33 |
+
Settima lettera
|
34 |
+
61
|
35 |
+
Settima risposta
|
36 |
+
64
|
37 |
+
Ottava lettera
|
38 |
+
67
|
39 |
+
Ottava risposta
|
40 |
+
69
|
41 |
+
Nona lettera
|
42 |
+
15
|
43 |
+
Nona risposta
|
44 |
+
78
|
45 |
+
Decima lettera
|
46 |
+
81
|
47 |
+
Decima risposta
|
48 |
+
84
|
49 |
+
Undicesima lettera
|
50 |
+
87
|
51 |
+
Undicesima risposta
|
52 |
+
91
|
53 |
+
Postfazione
|
54 |
+
93
|
55 |
+
L'Alchimia è la sorella della Profezia
|
56 |
+
Ja'far al-Sadiq
|
57 |
+
Noi siamo i Sapienti che impartiscono l'insegnamento,
|
58 |
+
i nostri shi'iti sono i destinatari del nostro insegnamento.
|
59 |
+
Il resto, ahimè, è la schiuma trascinata dal torrente.
|
60 |
+
'Ali ibn Abi Tàlib
|
61 |
+
Lieto
|
62 |
+
giacevo nel cuore della perla;
|
63 |
+
finché, sferzato dalle tempeste,
|
64 |
+
la vita mi agitò come un'onda.
|
65 |
+
Il segreto del mare
|
66 |
+
feci suonare con voce di tuono.
|
67 |
+
Come nuvola esausta sulla spiaggia
|
68 |
+
mi addormentai. Non mi svegliai più.
|
69 |
+
Rumi
|
70 |
+
INTRODUZIONE
|
71 |
+
Questa primavera, nella mia professione
|
72 |
+
di no-
|
73 |
+
taio, fui chiamato da un cliente per un problema
|
74 |
+
singolare. Era questi l'ultimo rappresentante
|
75 |
+
di
|
76 |
+
un'antica famiglia che possedeva ancora qualche ric-
|
77 |
+
chezza e i cui antenati avevano svolto un ruolo
|
78 |
+
importante nella storia locale. Mi chiedeva di rag-
|
79 |
+
giungerlo in una vecchia villa al di là delle colline
|
80 |
+
che fronteggiano la città, dove il fiume si arresta un
|
81 |
+
attimo a formare un piccolo lago per poi proseguire.
|
82 |
+
Vi viveva con una coppia di domestici lo zio,
|
83 |
+
uomo stravagante e solitario. Qualcuno lo ricordava
|
84 |
+
giovane buontempone che amava belle donne e bel
|
85 |
+
vivere, e vecchi amici descrivevano feste, balli e cene
|
86 |
+
allegre nella villa illuminata e rumorosa. Anni pri-
|
87 |
+
ma, si raccontava, tornato da un viaggio si era rin-
|
88 |
+
chiuso in casa, scoraggiando ogni contatto con rispo-
|
89 |
+
ste scontrose sinché nessuno lo aveva più cercato.
|
90 |
+
Dopo il mio arrivo ci sedemmo in un comodo
|
91 |
+
salottino e il mio cliente chiamò i domestici a riferi-
|
92 |
+
re quello che era avvenuto, mi parve però con una
|
93 |
+
curiosa reticenza, come per qualche fedeltà o timore.
|
94 |
+
Il racconto fu breve: all'inizio di aprile il padrone
|
95 |
+
li aveva quasi cacciati, costretti a forza a una vacan-
|
96 |
+
za di un mese con l'imposizione di non farsi vivi pri-
|
97 |
+
ma della scadenza, per nessun motivo. Al ritorno
|
98 |
+
avevano trovato villa vuota, proprietario scomparso,
|
99 |
+
una lettera per loro e una per il nipote, entrambe in
|
100 |
+
bella vista sul tavolo di cucina.
|
101 |
+
Il contenuto era semplice e conciso: confermava
|
102 |
+
una partenza definitiva, senza indicazioni, e dava
|
103 |
+
brevi istruzioni con delega al nipote per la gestione
|
104 |
+
del patrimonio. Era per quest'ultima parte, eviden-
|
105 |
+
temente, che era stata richiesta la mia presenza.
|
106 |
+
Esaminammo la villa. Nello studio un caminetto
|
107 |
+
colmo di cenere e frammenti di carta testimoniava che
|
108 |
+
si erano bruciati molti documenti. Di un grosso qua-
|
109 |
+
derno era rimasta parte della copertina mezza con-
|
110 |
+
sumata: era ancora possibile leggere «Diar.. d.. lab..».
|
111 |
+
Girando per casa in cerca di indizi
|
112 |
+
scendemmo
|
113 |
+
nel seminterrato. Qui, con mio grande stupore, sta-
|
114 |
+
va un vasto laboratorio ben attrezzato per esperi-
|
115 |
+
menti di chimica e metallurgia: forni, vecchi alam-
|
116 |
+
bicchi, pestelli e mortai di tutte le dimensioni, cro-
|
117 |
+
gioli usati in gran quantità. Nessun materiale. Sem-
|
118 |
+
brava ci si fosse dati gran pena per ripulire tutto.
|
119 |
+
Solo, in bella vista su un tavolo, uno splendido lin-
|
120 |
+
gottino giallo che un orefice confermò poi essere di
|
121 |
+
oro purissimo.
|
122 |
+
Una porta laterale conduceva in uno studio con
|
123 |
+
pareti ricolme di libri. Sulla scrivania, legate da un
|
124 |
+
nastro verde, delle lettere con un biglietto enigma-
|
125 |
+
tico che diceva: «Queste si possono
|
126 |
+
mostrare».
|
127 |
+
Concluse le incombenze
|
128 |
+
legali il giovane
|
129 |
+
volle
|
130 |
+
affidare a me le lettere perché le esaminassi e ne
|
131 |
+
decidessi la sorte. In effetti sapeva che amavo studi
|
132 |
+
esoterici, e pensava che ne potessi dare un giudizio.
|
133 |
+
Dopo una prima scorsa, fu evidente che non rap-
|
134 |
+
presentavano se non la minima parte di uno scam-
|
135 |
+
bio epistolare molto più ampio, certamente più det-
|
136 |
+
tagliato. Era stato cancellato con cura tutto ciò che
|
137 |
+
poteva indicare nome e luogo dell'interlocutore mi-
|
138 |
+
sterioso, con tutte le date.
|
139 |
+
Ero in buona amicizia con uno studioso di isla-
|
140 |
+
mismo, ne chiesi il parere. Riporto qui il commento
|
141 |
+
sintetico con cui le restituì:
|
142 |
+
Caro amico,
|
143 |
+
si tratta certamente di una documentazione notevole. Il
|
144 |
+
maestro dell'Islam è molto probabilmente un sufi di
|
145 |
+
scuola shi'ita. Lo dimostra certo linguaggio: per esem-
|
146 |
+
pio «situazione» e «stato» così come sono usati nella
|
147 |
+
sesta risposta corrispondono sicuramente a maqàm e a
|
148 |
+
hai, e sono termini tecnici della letteratura sufi. Mentre
|
149 |
+
l'accenno all'amicizia con Dio, la walàyat, è tipica del
|
150 |
+
pensiero shi'ita.
|
151 |
+
Le ritengo di grande interesse.
|
152 |
+
Perciò le ho tradotte, erano in inglese, cercando
|
153 |
+
di comprendere
|
154 |
+
il senso delle frasi talvolta molto
|
155 |
+
oscure, e lasciandole nello stesso ordine in cui sta-
|
156 |
+
vano, sino all'ultima brevissima comunicazione. Le
|
157 |
+
ho poi sottoposte a un editore, che ha accettato di
|
158 |
+
pubblicarle.
|
159 |
+
Così facendo spero di aver bene interpretato la
|
160 |
+
volontà di chi me le ha inconsapevolmente
|
161 |
+
affidate,
|
162 |
+
dovunque si trovi ora.
|
163 |
+
PRIMA LETTERA
|
164 |
+
Caro Maestro,
|
165 |
+
da voi il silenzio, e nel silenzio la pace. Qui tut-
|
166 |
+
to è rumore, e nel rumore la paura. Presso di voi
|
167 |
+
il frutto, qui nulla se non la vita elementare, con
|
168 |
+
tutte le sue fatiche.
|
169 |
+
Che vi posso dire di più. Volevate conoscere il
|
170 |
+
mio mondo e i miei problemi. Guardate un for-
|
171 |
+
micaio: l'attività è frenetica, furia cieca della natu-
|
172 |
+
ra che spinge a crescere, procreare, senza altro
|
173 |
+
scopo che esistere.
|
174 |
+
Ascoltate un alveare: operosità continua in un
|
175 |
+
ronzio ininterrotto, senza un attimo di quiete.
|
176 |
+
Mi dite che spesso siete nel deserto a meditare
|
177 |
+
e studiare: immaginate un mondo senza deserti,
|
178 |
+
dove la solitudine sia un dono impossibile, il silen-
|
179 |
+
zio un ricordo appannato e la vita un affannarsi
|
180 |
+
insensato, una corsa senza punto di arrivo, fatta a
|
181 |
+
spintoni e gomitate per conquistare un premio che
|
182 |
+
non esiste.
|
183 |
+
Mi chiedete cosa sto cercando: userò parole
|
184 |
+
non mie. Da poco è morto un Papa, e ne hanno
|
185 |
+
cjpi t
|
186 |
+
i
|
187 |
+
c
|
188 |
+
q
|
189 |
+
u
|
190 |
+
c
|
191 |
+
u
|
192 |
+
i
|
193 |
+
f
|
194 |
+
f
|
195 |
+
c
|
196 |
+
i
|
197 |
+
i
|
198 |
+
i
|
199 |
+
n
|
200 |
+
.
|
201 |
+
p
|
202 |
+
f
|
203 |
+
i
|
204 |
+
r
|
205 |
+
d
|
206 |
+
b
|
207 |
+
t
|
208 |
+
é b
|
209 |
+
K
|
210 |
+
u
|
211 |
+
i
|
212 |
+
v
|
213 |
+
r
|
214 |
+
m
|
215 |
+
r
|
216 |
+
a crac.
|
217 |
+
_
|
218 |
+
q
|
219 |
+
> j
|
220 |
+
q
|
221 |
+
u
|
222 |
+
j
|
223 |
+
n
|
224 |
+
o
|
225 |
+
n
|
226 |
+
c
|
227 |
+
flmmnispwbibm
|
228 |
+
b
|
229 |
+
j
|
230 |
+
n
|
231 |
+
u
|
232 |
+
f
|
233 |
+
c
|
234 |
+
e
|
235 |
+
n
|
236 |
+
»
|
237 |
+
. t
|
238 |
+
u
|
239 |
+
|j>ini0l(U9
|
240 |
+
Damasco, mitica città di studiosi e traduttori,
|
241 |
+
in un'incisione occidentale.
|
242 |
+
eletto un altro. Il nuovo è un uomo dolcissimo,
|
243 |
+
che non pare di questo mondo, dall'aria svagata
|
244 |
+
come si trovasse per caso su una sedia un po' osti-
|
245 |
+
le, un po' estranea. Pochi giorni fa diceva che se
|
246 |
+
anche siamo mescolati alla confusione e al rumo-
|
247 |
+
re, dobbiamo affermare: "Oltre un certo punto voi
|
248 |
+
non esistete per me, ed io mi ritiro in me, nel mio
|
249 |
+
giardino di quiete e di delizie, unito al mio Dio, in
|
250 |
+
pace". Ricordava un facchino che aveva visto dor-
|
251 |
+
mire tranquillo in una stazione, circondato dal
|
252 |
+
baccano di treni e uomini e bagagli. Questa, ha
|
253 |
+
detto, è la Grande Disciplina, da non confondere
|
254 |
+
con la Piccola Disciplina che consiste solo nel
|
255 |
+
seguire le regole esteriori cui tutti ci dobbiamo
|
256 |
+
adattare.
|
257 |
+
Vorrei conoscere questa Grande Disciplina.
|
258 |
+
Vorrei la pace di quel facchino, qualunque cosa
|
259 |
+
essa sia.
|
260 |
+
Così, caro Maestro, ho scoperto l'Alchimia, di
|
261 |
+
cui tanto vi ho parlato, il motivo per cui chiedo
|
262 |
+
aiuto e guida.
|
263 |
+
Mi chiedete come vi sono giunto. L'ho incon-
|
264 |
+
trata in un libro, come capita sempre, come è ine-
|
265 |
+
vitabile qui, in Occidente, dove i Templi non esi-
|
266 |
+
stono più, dove i Maestri stanno silenti e nascosti,
|
267 |
+
dove restano solo libri di pietra e carta per legge-
|
268 |
+
re di antiche sapienze.
|
269 |
+
L'ho letto, il libro di cui vi parlo, in un momen-
|
270 |
+
to di disperazione, di rifiuto totale per questo
|
271 |
+
mondo, per il suo rumore, per il suo nulla fatico-
|
272 |
+
sissimo, per la paura che lo avvolge come una cap-
|
273 |
+
pa di tempesta imminente. Mi sentivo come dice
|
274 |
+
un filosofo che voi non conoscete, che non appar-
|
275 |
+
tiene e non potrebbe appartenere al deserto. Mi
|
276 |
+
sentivo «come una puttana che vaga in una città
|
277 |
+
senza marciapiedi». A mezzo tra sofferenza e
|
278 |
+
oblio, drogato dallo stesso esistere di questo ru-
|
279 |
+
more senza fine.
|
280 |
+
Così è incominciata la mia ricerca. Per caso. Ho
|
281 |
+
letto un libro e mi sono innamorato del silenzio
|
282 |
+
che vi abitava. Ho avuto l'intuizione di un luogo di
|
283 |
+
pace, un ricordo, una nostalgia. Un richiamo al
|
284 |
+
deserto, al secco, non arido, deserto che non ho
|
285 |
+
mai conosciuto.
|
286 |
+
Ho letto, e non ho capito. Ho sentito qualcosa
|
287 |
+
che si agitava, l'embrione informe, minuscolo,
|
288 |
+
impreciso, di una nascita possibile. Il nucleo invi-
|
289 |
+
sibile di una parola silenziosa, splendente.
|
290 |
+
Non so dirvi di più. Mi pare di aver capito, que-
|
291 |
+
sto sì, che nella materia, proprio in quella fisicità
|
292 |
+
che sembra orrenda, spiacevole, ignobile, proprio
|
293 |
+
in quella stia in qualche modo la chiave per qual-
|
294 |
+
cosa che potrei chiamare il divino, se solo avessi
|
295 |
+
ancora una religione.
|
296 |
+
Anche di questa mi avete chiesto. Non saprei
|
297 |
+
cosa rispondervi. Noterò solo un segno. Un tem-
|
298 |
+
po i nostri sacerdoti officiavano guardando ad
|
299 |
+
Oriente, alla vita e al suo sorgere. Oggi guardano
|
300 |
+
ad Occidente, alla morte e al suo approssimarsi.
|
301 |
+
Prima volgevano le spalle all'uomo e guardavano
|
302 |
+
a Dio. Oggi volgono le spalle a Dio e guardano
|
303 |
+
l'uomo.
|
304 |
+
Mi sembra semplice simbolo di un mondo, non
|
305 |
+
morente, già morto. La convulsa attività che mani-
|
306 |
+
festa non proviene da eccesso di vita, ma da de-
|
307 |
+
composizione cadaverica, quando nella corruzione
|
308 |
+
corporea tutto si muove, vermicola, gonfia, erutta,
|
309 |
+
emana.
|
310 |
+
L'anima è persa, fuggita con la vita e il respiro.
|
311 |
+
Resta ancora un oscuro fervore psichico ad emet-
|
312 |
+
tere le fetide esalazioni che i demoni amano e da
|
313 |
+
cui sono abbondantemente nutriti.
|
314 |
+
Sembra un'opera alchemica in atto: corruptio
|
315 |
+
unius est generatio alterius, dicevano i vecchi mae-
|
316 |
+
stri. Dunque inutile piangere su ciò che è finito,
|
317 |
+
aspettiamo con curiosità e speranza quello che
|
318 |
+
verrà. In effetti la morte, qui lo abbiamo dimenti-
|
319 |
+
cato, è un momento ineluttabile di questa manife-
|
320 |
+
stazione, e non è detto sia sempre un male...
|
321 |
+
Proprio qui, comunque, devo incominciare la
|
322 |
+
mia ricerca, e proprio qui, in questo stato sepol-
|
323 |
+
crale, occorre una guida perché i primi passi
|
324 |
+
abbiano la corretta direzione. Qualche secolo fa
|
325 |
+
un alchimista ha scritto:
|
326 |
+
La nostra pratica in effetti è un cammino nelle sabbie,
|
327 |
+
dove ci si deve guidare con la stella del Nord, piuttosto
|
328 |
+
che con le orme che vi si vedono impresse. La confu-
|
329 |
+
sione delle tracce, che un numero quasi infinito di per-
|
330 |
+
sone vi ha lasciato, è così grande, e vi si trovano così
|
331 |
+
tanti sentieri diversi, che conducono quasi tutti in
|
332 |
+
orrendi deserti, che è quasi impossibile non deviare
|
333 |
+
dalla vera via, che solo i saggi favoriti dal Cielo hanno
|
334 |
+
saputo fortunatamente scoprire, e riconoscere.
|
335 |
+
Tra queste sabbie, in questi deserti disperati,
|
336 |
+
così diversi dai vostri, non cerco i misteri delle
|
337 |
+
operazioni, gli arcani segreti dell'Arte. Cerco l'in-
|
338 |
+
dicazione primordiale, la parola iniziale, la traccia
|
339 |
+
del primo passo.
|
340 |
+
Rispettosamente.
|
341 |
+
PRIMA RISPOSTA
|
342 |
+
Caro studioso,
|
343 |
+
Dio dice nel suo santo Qur'an:
|
344 |
+
Il tuo Signore trasse dai lombi dei figli di Adamo i loro
|
345 |
+
discendenti e li fece testimoniare verso se stessi. "Non
|
346 |
+
sono il vostro Signore?". "Sì, l'attestiamo", risposero.
|
347 |
+
Questo perché non possiate dire il giorno della Resur-
|
348 |
+
rezione: "Noi non ne sapevamo nulla". O perché non
|
349 |
+
diciate: "I nostri padri prima di noi hanno accolto falsi
|
350 |
+
dei. Noi siamo i loro discendenti. Ci vuoi dunque far
|
351 |
+
perire per le azioni di uomini vani?" (Sura VII, 171-
|
352 |
+
172, Al A'ràj., il Purgatorio).
|
353 |
+
Dio si fa conoscere per mezzo della sua parola,
|
354 |
+
e ogni versetto è una manifestazione.
|
355 |
+
La parola ha il suo limite nella manifestazione,
|
356 |
+
e la manifestazione è la parola che sale sino al vol-
|
357 |
+
to di chi la pronuncia.
|
358 |
+
Dio ha posto la sua parola sui discendenti di
|
359 |
+
Adamo quando erano ancora atomi. Ha detto:
|
360 |
+
"Non sono il vostro Signore?" ed essi sentirono
|
361 |
+
chiaramente. Perciò anche gli atomi hanno fede e
|
362 |
+
pregano. I loro movimenti sono un prostrarsi in
|
363 |
+
atteggiamento di umiltà, ed essi lo fanno anche
|
364 |
+
quando non sono ancora corpi completi.
|
365 |
+
Questa è la fede innata, quella per cui gli atomi
|
366 |
+
si muovono intimamente.
|
367 |
+
Dopo di questo, quando si formano i corpi, non
|
368 |
+
esiste più sapienza ma esiste il potere. Allora la
|
369 |
+
parola e la visione sono velate al di là del mondo
|
370 |
+
della non visione, e i movimenti intimi degli atomi
|
371 |
+
si colmano di oscurità.
|
372 |
+
Il cammino mistico si muove in senso contrario
|
373 |
+
a questo. Chi è su questo cammino si purifica e
|
374 |
+
rasserena per mantenere in se stesso il mondo del
|
375 |
+
potere fuori dal mondo della sapienza, per scopri-
|
376 |
+
re la visione penetrante della sapienza e poter udi-
|
377 |
+
re: "Non sono io il vostro Signore?". Allora questa
|
378 |
+
parola si rivela e supera nella sua unicità le fasi di
|
379 |
+
oscurità con la luce della visione.
|
380 |
+
Io ho manifestato ogni cosa in modo che essa mi
|
381 |
+
veli e non guidi sino a me.
|
382 |
+
Unirsi a me è la cosa più elevata che io abbia
|
383 |
+
manifestato, ma l'unirsi a me è un velo.
|
384 |
+
Quando io appaio, tu non vedi nulla. La parola
|
385 |
+
in alto è un limite per ciò che sta in basso, ma non
|
386 |
+
c'è limite per ciò che sta in alto.
|
387 |
+
Io sono la causa dell'apparizione
|
388 |
+
di ciò che si
|
389 |
+
manifesta, e sono la causa per cui appare in ciò che
|
390 |
+
io voglio che appaia.
|
391 |
+
M
|
392 |
+
i r' rff i-mK<ÌKr.mistMiK?«»Vi .uöi
|
393 |
+
fp
|
394 |
+
tt6$tmtintl
|
395 |
+
fSnC-'iiiW.K-
|
396 |
+
(¿Htif^wifi WI»«M(K>Í«>Í6 »tnuCtVftjj
|
397 |
+
ilfit
|
398 |
+
'f¿jín«£jtí-{ip<i(tt <tß ^iwSif
|
399 |
+
(DTUVikiit«/-
|
400 |
+
^"v^c'S»»«? tlviinnìÀ qtui.
|
401 |
+
A
|
402 |
+
(Sunt
|
403 |
+
^ÜWIKhiiSltmill
|
404 |
+
t-
|
405 |
+
p
|
406 |
+
C
|
407 |
+
i
|
408 |
+
^ t i
|
409 |
+
Ht/(] 'ft (tfc
|
410 |
+
wmWiV ptiUiftt?1
|
411 |
+
f<r pnfbm www
|
412 |
+
j
|
413 |
+
» H
|
414 |
+
K
|
415 |
+
T
|
416 |
+
U
|
417 |
+
>
|
418 |
+
: f Sx* x'im/Dtíitinéín'á/^ii)
|
419 |
+
>
|
420 |
+
.
|
421 |
+
• i',s, 43 q
|
422 |
+
w
|
423 |
+
\
|
424 |
+
l
|
425 |
+
m f^.ti ßit««ir ntPotito{v^:/f.
|
426 |
+
I v
|
427 |
+
-
|
428 |
+
i
|
429 |
+
l «.Unfit nm ))Utr .{crsyityv*
|
430 |
+
qMítil- >
|
431 |
+
•
|
432 |
+
»
|
433 |
+
«
|
434 |
+
ttj)x;tm*/VI.iMifîi(>Mpit«
|
435 |
+
Ciò che è compiuto è compiuto, ciò che ho stabi-
|
436 |
+
lito è stabilito, ciò che è stabilito è compiuto in quel-
|
437 |
+
lo che tutto abbraccia.
|
438 |
+
Caro studioso, ascolta le lingue dei mondi nelle
|
439 |
+
manifestazioni spirituali. Essi dicono: "Dio! Dio!".
|
440 |
+
Ed egli dice: "Non li sente chi sta in loro, o chi cer-
|
441 |
+
ca in loro delle testimonianze".
|
442 |
+
Caro studioso, se tu aderirai a ciò che ti è stato
|
443 |
+
assegnato tra questi due mondi, allora sarai un
|
444 |
+
amico di Dio.
|
445 |
+
La pace sia con te.
|
446 |
+
SECONDA LETTERA
|
447 |
+
Caro Maestro,
|
448 |
+
credo che si diventi alchimisti come ci si in-
|
449 |
+
namora: misteriosamente e incomprensibilmente.
|
450 |
+
All'inizio, una predisposizione, un essere già inna-
|
451 |
+
morati senza oggetto d'amore, inconsapevolmente:
|
452 |
+
è un sentimento che si unisce a disperazione quie-
|
453 |
+
ta, non malvagia o triste, piuttosto melanconica.
|
454 |
+
Nasce dalla nostalgia di qualcosa di perso, di ab-
|
455 |
+
bandonato, di un posto che ci apparteneva, che
|
456 |
+
non sappiamo più trovare. Il sentimento di chi ha
|
457 |
+
perso la propria patria e non sa come raggiungerla.
|
458 |
+
Nel tempo mi sono chiesto se non sia questo il
|
459 |
+
fondamento dell'essere ebrei: la ricerca di una
|
460 |
+
Terra Promessa, che non si traduce mai in realtà,
|
461 |
+
che rende stranieri dovunque si sia. Nei secoli
|
462 |
+
qualcuno ha cercato di realizzare il sogno: credo
|
463 |
+
che non vi sia peggiore illusione di quella di voler
|
464 |
+
tradurre in pratica, di voler corporificare, un sim-
|
465 |
+
bolo che per sua natura non è di questo mondo.
|
466 |
+
Ogni alchimista è un ebreo della diaspora: que-
|
467 |
+
sto significa la frase, riportata da Zosimo, di Maria
|
468 |
+
Profetessa: "Stai lontano dall'Arte, tu che non sei
|
469 |
+
della nostra razza, perché tu non sei del sangue di
|
470 |
+
Abramo!"
|
471 |
+
Dobbiamo essere del sangue di Abramo, se vo-
|
472 |
+
gliamo perseguire questa via, se pensiamo di esser-
|
473 |
+
vi predestinati o chiamati. Perché di vocazione si
|
474 |
+
tratta, che deve nascere da una mancanza, nostal-
|
475 |
+
gia della patria smarrita.
|
476 |
+
La patria diventa facilmente donna. La nostal-
|
477 |
+
gia si traduce in amore.
|
478 |
+
Trovo questo richiamo all'amore in tutti i
|
479 |
+
Maestri dell'Arte, sin dal nome che danno a se
|
480 |
+
stessi e ai loro fratelli: Innamorati della
|
481 |
+
Dottrina.
|
482 |
+
La Dottrina, la Sapienza, la Sofia degli gnostici,
|
483 |
+
non qualcosa di intellettuale, razionale, nel senso
|
484 |
+
comune della parola. La Dottrina come vita e
|
485 |
+
gioia, felicità ritrovata, dolcezza e riposo, virtù e
|
486 |
+
potenza, patria e donna amata. La Dottrina come
|
487 |
+
bellezza inimmaginabile.
|
488 |
+
Tutti sono innamorati. Tutti i poeti iniziati lo
|
489 |
+
raccontano. Innamoramento che sorge in una sta-
|
490 |
+
gione singolare, in uno stesso mese, quello di No-
|
491 |
+
stra Signora, di Maria, Maia, la madre di Mercurio.
|
492 |
+
Non ci si innamora in un momento qualsiasi:
|
493 |
+
Ce fut au temps de mois de May
|
494 |
+
qu'on doibt foui'r dueil et esmay
|
495 |
+
qu'i'entray dedans un vergier
|
496 |
+
dont Zephirus fut iardinier.
|
497 |
+
E Dante, l'innamorato per eccellenza dell'Occi-
|
498 |
+
dente:
|
499 |
+
Avvenne una die che, sedendo io pensoso in alcuna
|
500 |
+
parte, ed io mi sentio cominciare un tremuoto nel cuo-
|
501 |
+
re, così come se io fosse stato presente a questa donna.
|
502 |
+
Allora dico che mi giunse una immaginazione di Amore
|
503 |
+
E poco dopo io vidi venire una gentile donna, la quale
|
504 |
+
era di famosa bieltade e [...] per la sua bieltade impo-
|
505 |
+
sto l'era nome Primavera; e così era chiamata.
|
506 |
+
In primavera, come dice
|
507 |
+
...li Romans de la Rose
|
508 |
+
ou l'art d'Amors est toute enclose
|
509 |
+
che racconta:
|
510 |
+
En may estions, si songoie
|
511 |
+
ou temps amorous plain de joie...
|
512 |
+
Si vaneggia? Ricordo una fiaba, sempre la stes-
|
513 |
+
sa. Un cavaliere, l'eroe, deve affrontare un orren-
|
514 |
+
do drago. Lo uccide dopo infinite peripezie e peri-
|
515 |
+
coli. Una fanciulla bellissima e dolcissima è libera-
|
516 |
+
ta, diventa il suo premio onorevole e meritato.
|
517 |
+
Quella fanciulla, si narra, solo i veri Filosofi pos-
|
518 |
+
sono vedere e contemplare nuda in tutta la sua
|
519 |
+
splendida venustà, senza morire o essere inceneri-
|
520 |
+
ti dalla Belle Dame sans mercy. E ancora Dante a
|
521 |
+
dirlo concisamente:
|
522 |
+
e qual soffrisse di starla a vedere
|
523 |
+
diverria nobil cosa, o si morria.
|
524 |
+
Tutto questo suona un po' retorico e troppo
|
525 |
+
intelligente. Eppure dal Cantico dei Cantici ai ro-
|
526 |
+
manzi del Graal, dai miti greci a Goethe, dalle me-
|
527 |
+
lanconiche pagine del triste cavaliere della Mancia
|
528 |
+
ai momenti più ispirati di Melville, tutti cantano
|
529 |
+
questo amore, questa nostalgia, e tutti dicono che
|
530 |
+
soltanto chi giunge alla Terra Promessa sta in pace
|
531 |
+
ed è felice.
|
532 |
+
Io cerco l'oggetto del mio amore perché questa
|
533 |
+
passione, che ora è sofferenza, disperazione, logo-
|
534 |
+
rio della mente e dell'anima, si quieti.
|
535 |
+
Rispettosamente.
|
536 |
+
SECONDA RISPOSTA
|
537 |
+
Caro studioso,
|
538 |
+
l'amore di cui tu parli, è innanzitutto amore di
|
539 |
+
Dio, per Dio. La donna è la sua Sapienza e la
|
540 |
+
Maestà del suo Trono. Rivolgiti a lui e digli: "O
|
541 |
+
Signore, fa' che il mio amore per te sia più profon-
|
542 |
+
do del mio amore per me stesso, per il mio udito,
|
543 |
+
per la mia vista, per la mia gente, per i miei averi".
|
544 |
+
Il puro speciale amore di Dio è l'amore che ine-
|
545 |
+
bria lo spirito. E una scelta divina per colui che
|
546 |
+
adora, perché è un dono di Dio e non è amore di
|
547 |
+
un'entità. Questo amore viene con gli impulsi del-
|
548 |
+
la fede: è divino amore che ricambia la vicinanza.
|
549 |
+
L'adoratore si prostra sull'orlo dell'abito della
|
550 |
+
maestà divina, come in uno stato sublime, e que-
|
551 |
+
sto può avvenire soltanto per coloro il cui sé sale
|
552 |
+
nella luce dello spirito, perché la sua ebbrezza è
|
553 |
+
sopraffacente e la forza di inclinazione altamente
|
554 |
+
efficace.
|
555 |
+
Quando l'adoratore ridiventa sobrio, torna al
|
556 |
+
suo stato di bisogno e alla privazione del fidanza-
|
557 |
+
mento. Ma quando si sono completate le facoltà
|
558 |
+
che vengono dalla vicinanza con l'emancipazione
|
559 |
+
dello spirito, per mezzo della completezza della pri-
|
560 |
+
vazione, che non permette più che si parli, quando
|
561 |
+
la porzione della vicinanza si accumula e mantiene
|
562 |
+
il senso di fidanzamento del sé, allora questo è un
|
563 |
+
dono, e si può dire: "Oh Signore Iddio!".
|
564 |
+
Allora ascolta:
|
565 |
+
Nulla è più vicino a me di qualunque altra cosa, e
|
566 |
+
nulla è più lontano da me di ogni altra cosa ad ecce-
|
567 |
+
zione di quanto lo stabilisco in vicinanza e lonta-
|
568 |
+
nanza.
|
569 |
+
La lontananza è resa nota dalla vicinanza, e la
|
570 |
+
vicinanza è resa nota dall'esperienza spirituale: io
|
571 |
+
sono colui che la vicinanza non cerca, e che l'espe-
|
572 |
+
rienza spirituale non raggiunge.
|
573 |
+
Il minimo delle scienze della mia vicinanza è che
|
574 |
+
tu dovresti vedere gli effetti del mio sguardo in ogni
|
575 |
+
cosa, e che esso dovrebbe prevalere sopra la tua gno-
|
576 |
+
si di esso.
|
577 |
+
Tu non conosci la vicinanza, e tu non conosci la
|
578 |
+
mia vicinanza e non conosci la mia condizione come
|
579 |
+
io la conosco.
|
580 |
+
Io sono il vicino, non come una cosa è vicina ad
|
581 |
+
un'altra: io sono il lontano, ma non come una cosa
|
582 |
+
è lontana da un'altra.
|
583 |
+
La tua vicinanza non è la tua lontananza e la tua
|
584 |
+
lontananza non è la tua vicinanza: io sono il vicino
|
585 |
+
e il lontano, con una vicinanza che è lontananza e
|
586 |
+
una lontananza che è vicinanza.
|
587 |
+
La vicinanza che tu conosci è misurabile, è una
|
588 |
+
distanza: e la lontananza che tu conosci è misurabi-
|
589 |
+
le, è una distanza.
|
590 |
+
Io sono il vicino e il lontano senza misura.
|
591 |
+
Io sono più vicino alla lingua del suo discorso
|
592 |
+
quando parla.
|
593 |
+
Chi mi contempla non si raccoglie in meditazio-
|
594 |
+
ne e chi medita su di me non contempla. Come per
|
595 |
+
il contemplativo che medita, se ciò che contempla
|
596 |
+
non è realtà, egli è velato da ciò su cui medita. Non
|
597 |
+
tutti i meditativi sono dei contemplativi: ma ogni
|
598 |
+
contemplativo è un meditativo.
|
599 |
+
10 rivelo me stesso e tu non mi conosci: questa è
|
600 |
+
lontananza.
|
601 |
+
11 tuo cuore mi ha visto e non mi ha visto: questa
|
602 |
+
è lontananza.
|
603 |
+
Tu mi trovi e non mi trovi: questa è lontananza.
|
604 |
+
Tu mi descrivi e non mi cogli dalla descrizione:
|
605 |
+
questa è lontananza.
|
606 |
+
Tu ascolti i miei discorsi come se venissero dal
|
607 |
+
tuo cuore, mentre vengono da me: questa è lonta-
|
608 |
+
nanza.
|
609 |
+
Sebbene tu veda te stesso, io sono più vicino a te
|
610 |
+
della tua visione di te stesso: questa è lontananza.
|
611 |
+
Caro studioso, questo amore si manifesta nelle
|
612 |
+
tenebre, ed esce come una luce dall'oscurità. Dal
|
613 |
+
nero esce il bianco splendente dell'amore divino,
|
614 |
+
e dall'ignoranza e dal silenzio esce la parola di vita
|
615 |
+
e di gnosi che tu stai cercando. Tu non devi
|
616 |
+
confondere, e tu devi stare attento agli inganni.
|
617 |
+
Ascolta il Profeta, Dio benedica il suo nome:
|
618 |
+
Dio è la fiaccola che illumina i cieli e la terra. La sua
|
619 |
+
luce assomiglia a quella che sfugge da una nicchia di
|
620 |
+
cristallo dove brilla una fiamma inestinguibile. Il cri-
|
621 |
+
stallo è una stella di perle il cui splendore viene da un
|
622 |
+
ulivo benedetto che non è né d'Oriente né d'Occi-
|
623 |
+
dente. Il suo olio illumina senza contatto col fuoco. Vi
|
624 |
+
è là luce su luce. E Dio accorda la sua Luce a chi gli
|
625 |
+
piace. (Sura XXIV)
|
626 |
+
La pace sia con te.
|
627 |
+
TERZA LETTERA
|
628 |
+
Caro Maestro,
|
629 |
+
mi interrogate sugli obiettivi, tenterò una ri-
|
630 |
+
sposta.
|
631 |
+
Tre doni si dice procuri la Pietra Filosofale,
|
632 |
+
quelli che i re Magi portarono al bambino divino,
|
633 |
+
Pietra vivente e miracolo celeste.
|
634 |
+
Per primo l'Oro, la ricchezza mondana. È l'uni-
|
635 |
+
co descritto senza velamenti, con estrema preci-
|
636 |
+
sione.
|
637 |
+
Si prende la Pietra, si aggiunge in proporzioni
|
638 |
+
ben determinate a oro o argento in fusione, si
|
639 |
+
ottiene così 'a «Polvere di Proiezione», medicina
|
640 |
+
capace di curare o tingere i metalli imperfetti per
|
641 |
+
transmutarli in preziosi.
|
642 |
+
Mi chiedo perché sia posto tanto in evidenza:
|
643 |
+
non dovrebbe interessare il filosofo. Ci si è sforza-
|
644 |
+
ti di trovarvi un significato recondito, più nobile.
|
645 |
+
Quell'oro è diventato spirituale, mistico, simbolo
|
646 |
+
di cambiamenti umani; si è negata ogni realtà alla
|
647 |
+
transmutazione metallica e all'acquisto di dovizie.
|
648 |
+
Curiosamente la nostra epoca, tutta tesa alla ric-
|
649 |
+
chezza materiale e ai piaceri che questa può pro-
|
650 |
+
curare, ama esaltare quella miseria che in pratica
|
651 |
+
aborre. Non fu sempre così. Guardando le grandi
|
652 |
+
figure bibliche: Abramo si arricchisce con modi
|
653 |
+
ambigui, Giacobbe inventa trucchi per farsi un
|
654 |
+
gregge numeroso - aveva già dato prova di abilità
|
655 |
+
ulissiache per conquistare la primogenitura - di
|
656 |
+
Salomone si esaltano ricchezza e possessi.
|
657 |
+
Resta comunque un dono dall'aria perversa e
|
658 |
+
insoddisfacente. Non credo valga tanti sforzi, ci
|
659 |
+
sono modi più semplici per arricchire.
|
660 |
+
Seconda la Mirra, «Elisir di lunga vita», l'im-
|
661 |
+
mortalità fisica, l'eterna giovinezza al riparo da
|
662 |
+
ogni male. E il dono di Mefistofele, la fonte di
|
663 |
+
Ponce de Leon, la sorgente di ogni piacere e di
|
664 |
+
ogni dolcezza in vita.
|
665 |
+
Così sarebbe se non avesse in sé il suo veleno:
|
666 |
+
l'eterna vita in questo mondo.
|
667 |
+
Davvero questa sarebbe l'estrema beffa. Solo un
|
668 |
+
folle potrebbe voler restare un attimo più del do-
|
669 |
+
vuto. Già pesa il divieto di fuggirne, certo non
|
670 |
+
interessa restarci.
|
671 |
+
Ho il dubbio che sia qualcosa di diverso, forse
|
672 |
+
addirittura il suo opposto simbolico, la certezza di
|
673 |
+
non vivere, di non vivere più, non la Medicina Uni-
|
674 |
+
versale, ma il veleno perfetto, la perfetta morte.
|
675 |
+
4 t«.
|
676 |
+
' - e
|
677 |
+
1
|
678 |
+
L ^ * « ^
|
679 |
+
l à i T f X H i H U o l ^ i f
|
680 |
+
I B A I 3 I M K - U H 5 1 V 1
|
681 |
+
^
|
682 |
+
^
|
683 |
+
¿
|
684 |
+
¿
|
685 |
+
^
|
686 |
+
Mi*-
|
687 |
+
Manoscritto alchemico
|
688 |
+
arabo.
|
689 |
+
Infine l'Incenso, la completa sapienza, essere
|
690 |
+
come Salomone, conoscere tutti gli arcani del
|
691 |
+
mondo, i più reconditi recessi della Natura, i
|
692 |
+
misteri dell'Alto e del Basso. Questo davvero sem-
|
693 |
+
bra il giusto obiettivo di un filosofo, di un inna-
|
694 |
+
morato della Dottrina-, ritrovare la Parola Perduta,
|
695 |
+
la vera pronunzia del Nome, riscoprire la perla
|
696 |
+
nascosta, sembra l'unico scopo che valga.
|
697 |
+
Sin dalla prima operazione, perciò, la nostra
|
698 |
+
Magnesia deve richiamare, attrarre l'Angelo della
|
699 |
+
Conoscenza, perché è scritto:
|
700 |
+
Non è dato all'uomo che Dio gli parli altro che per una
|
701 |
+
comunicazione da dietro un velo, oppure gli invia un
|
702 |
+
Angelo. (Sura XLII, 50-51)
|
703 |
+
Lo spirito celeste di saggezza deve scendere
|
704 |
+
dall'Alto - l'incorporeo si deve corporificare - per
|
705 |
+
impregnare ciò che sta in Basso. Allora la nostra
|
706 |
+
Materia diventa Specchio della Natura e potremo
|
707 |
+
apprendere tutti i segreti del macrocosmo e del
|
708 |
+
microcosmo e gli arcani dell'umano e del divino.
|
709 |
+
L'obiettivo vero è la Gnosi, e il segreto del-
|
710 |
+
l'Opera consiste in una terra benedetta, la Terra
|
711 |
+
Santa, che permette all'angelo della gnosi di scen-
|
712 |
+
dere e di manifestarsi a noi per insegnarci la cono-
|
713 |
+
scenza perfetta.
|
714 |
+
Rispettosamente.
|
715 |
+
TERZA RISPOSTA
|
716 |
+
Caro studioso,
|
717 |
+
non dire mai che la conoscenza sta nel celestia-
|
718 |
+
le: nessuno discende con essa. Non dire nemmeno
|
719 |
+
che sta nei limiti del terrestre: nessuno ascende
|
720 |
+
con essa. Essa sta nei cuori.
|
721 |
+
Chi sei tu e chi sono io? E io vedo il sole e la
|
722 |
+
luna, le stelle e tutte le luci. Ed egli mi disse: Non
|
723 |
+
rimane alcuna luce nella corrente del mio mare, che
|
724 |
+
tu non hai visto.
|
725 |
+
E ogni cosa venne a me sinché non rimase nul-
|
726 |
+
la. E ogni cosa mi baciò tra gli occhi e si offrì ai
|
727 |
+
miei sensi e restò nell'ombra.
|
728 |
+
Ed egli mi parlò. Ed io vidi tutto di lui connes-
|
729 |
+
so al mio abito, cioè alla mia apparenza corporea,
|
730 |
+
e non connesso a me.
|
731 |
+
Ed egli mi disse: Questo è il mio servizio. Ed il
|
732 |
+
mio abito si inchinò, ma io non mi inchinai. E
|
733 |
+
quando il mio abito si inchinò, egli mi disse: Chi
|
734 |
+
sono io? E il sole e la luna si oscurarono, e le stel-
|
735 |
+
le caddero dal cielo e le luci impallidirono e le
|
736 |
+
tenebre coprirono ogni cosa, eccetto lui.
|
737 |
+
E tutte le cose parlarono e dissero: "Dio è gran-
|
738 |
+
dissimo".
|
739 |
+
E tutte le cose vennero da me, portando una
|
740 |
+
lancia in mano. Ed egli mi disse: Fuggi. Ed io dis-
|
741 |
+
si: "Dove debbo fuggire?". Ed egli mi disse: Cadi
|
742 |
+
nelle tenebre. E mi osservò. Ed egli mi disse:
|
743 |
+
Non dovrai mai più osservare altri che te stesso,
|
744 |
+
e non dovrai mai più allontanarti dalle tenebre da
|
745 |
+
adesso per sempre: ma quando io ti caccerò da esse,
|
746 |
+
io ti mostrerò me stesso e tu mi vedrai. E quando
|
747 |
+
mi avrai visto sarai più lontano da me di tutti colo-
|
748 |
+
ro che sono lontani.
|
749 |
+
L'etica della gente dello spirito cerca di impe-
|
750 |
+
dire ai sé di correre dietro ciò che vogliono, ma ciò
|
751 |
+
non può avvenire se non per coloro che hanno
|
752 |
+
saputo, ascoltato e si sono dedicati al divino per
|
753 |
+
prendere il vero dal vero, per dire il vero e per sta-
|
754 |
+
re in silenzio nel vero.
|
755 |
+
Se tu non mi vedi, non lasciare il mio nome.
|
756 |
+
Quando tu stai davanti a me, ogni cosa ti chiama:
|
757 |
+
fa' attenzione a non ascoltarla con il tuo cuore, per-
|
758 |
+
ché se tu l'ascolti è come se le rispondessi.
|
759 |
+
Quando la conoscenza ti chiama, con tutte le sue
|
760 |
+
condizioni, al tempo della preghiera, e tu le rispon-
|
761 |
+
di, tu sei separato da me.
|
762 |
+
Quando io guardo il tuo cuore, nessun'altra cosa
|
763 |
+
vi entra.
|
764 |
+
Se tu mi vedi nel tuo cuore, sei capace di soppor-
|
765 |
+
tarmi.
|
766 |
+
I miei amici sono quelli che non hanno nessuna
|
767 |
+
opinione
|
768 |
+
personale.
|
769 |
+
II tuo corpo dopo la morte sta nel posto del tuo
|
770 |
+
cuore prima della morte.
|
771 |
+
Quando tu stai di fronte a me, nessun altro starà
|
772 |
+
con te eccetto te.
|
773 |
+
Quando l'alterità diventa un pensiero biasimevo-
|
774 |
+
le, Paradiso e Inferno svaniscono.
|
775 |
+
La pace sia con te.
|
776 |
+
Il maestro e l'allievo, in un antico codice siriaco.
|
777 |
+
QUARTA LETTERA
|
778 |
+
Caro Maestro,
|
779 |
+
ho letto a lungo, con attenzione, come mi avete
|
780 |
+
suggerito, Jàbir, quello che ho potuto trovare in
|
781 |
+
traduzione: II piccolo libro della Clemenza, Il libro
|
782 |
+
della Misericordia, Il libro dei Settanta, Il libro del-
|
783 |
+
la Concentrazione, Il libro del fuoco della Pietra, Il
|
784 |
+
libro delle Bilance - su questo vorrei fare un di-
|
785 |
+
scorso a parte.
|
786 |
+
Per quanto riguarda il problema su cui mi inter-
|
787 |
+
rogo, ho trovato queste affermazioni:
|
788 |
+
Se tu, uomo intelligente, esamini tutte queste cose,
|
789 |
+
vedrai che lo scopo da raggiungere non si ottiene se non
|
790 |
+
con l'aiuto di cose diverse, cioè delle quattro nature.
|
791 |
+
Occorrono forze diverse, spirituali e corporali. Queste
|
792 |
+
forze debbono essere convergenti e non divergenti,
|
793 |
+
come forma e come colore.
|
794 |
+
Le forze spirituali e corporali devono avere delle affi-
|
795 |
+
nità tra loro, in modo da potersi aiutare reciprocamen-
|
796 |
+
te. Devono darsi sostegno, perché hanno bisogno una
|
797 |
+
dell'altra per la combinazione che si opera parte con
|
798 |
+
parte. Non devono essere opposte una all'altra, perché
|
799 |
+
bisogna che una volta mescolate non si separino una
|
800 |
+
dall'altra.
|
801 |
+
Tu devi operare in una sola volta, in maniera continua,
|
802 |
+
senza interruzione, per realizzare la mescolanza delle
|
803 |
+
parti, le une con le altre. Dovrà esserci equilibrio per
|
804 |
+
quanto riguarda la natura, la quantità e il peso.
|
805 |
+
L'operazione dovrà essere rigorosa, senza che si possa
|
806 |
+
sostituire una sostanza a un'altra.
|
807 |
+
L'elemento corporale è dominato dall'elemento spiri-
|
808 |
+
tuale in seguito all'operazione vera che lo trasforma in
|
809 |
+
elemento spirituale. L'elemento spirituale è ugualmen-
|
810 |
+
te dominato dall'elemento corporale e trasformato in
|
811 |
+
elemento corporale, sebbene in realtà non vi sia oppo-
|
812 |
+
sizione completa tra questi due elementi.
|
813 |
+
La massa delle cose corporali è soltanto il luogo di sog-
|
814 |
+
giorno e rifugio delle cose spirituali, e non ha di per sé
|
815 |
+
né forza né utilità quando la forza agente ha cessato di
|
816 |
+
agire in lei.
|
817 |
+
Il corpo che resta come sostrato non è che il luogo di
|
818 |
+
soggiorno e il rifugio dello spirito che ne è uscito, e non
|
819 |
+
ha forza se non per lo spirito che può uscire da lui.
|
820 |
+
Sono bloccato su questi passi, che da un lato mi
|
821 |
+
appaiono chiari, dall'altro non so tradurre in pra-
|
822 |
+
tica.
|
823 |
+
E vero che sempre in Jabir leggo:
|
824 |
+
Ho visto in effetti moltiplicando il numero dei miei
|
825 |
+
libri, allungandoli e riempiendoli di fatti, che nessuno
|
826 |
+
potrà arrivare ad estrarne la verità a meno di consa-
|
827 |
+
crarvi tutta la propria vita, di avere un'intelligenza
|
828 |
+
superiore, di dedicarvi tutto il proprio studio, di veglia-
|
829 |
+
re notte e giorno e di rinunciare a frequentare i propri
|
830 |
+
amici, privandosi del completo benessere.
|
831 |
+
Quindi non posso che rendermi conto che le
|
832 |
+
difficoltà che incontro sono inevitabili. Leggo pe-
|
833 |
+
rò anche:
|
834 |
+
Fatevi aiutare dalle persone intelligenti che si occupa-
|
835 |
+
no di questi lavori, perché i libri sono inchiavardati, e
|
836 |
+
le chiavi dei loro catenacci sono nei petti degli uomini.
|
837 |
+
Non posso che rivolgermi a voi per avere que-
|
838 |
+
ste chiavi.
|
839 |
+
Rispettosamente.
|
840 |
+
QUARTA RISPOSTA
|
841 |
+
Caro studioso,
|
842 |
+
Si dice che Jàbir abbia incontrato l'Imam Ja'far
|
843 |
+
al-Sàdiq quando aveva circa vent'anni in uno dei
|
844 |
+
suoi nascondigli, presso la tribù degli Azid nello
|
845 |
+
Yemen, e che diventò suo discepolo sin da allora.
|
846 |
+
La sua personalità perciò si formò religiosamente,
|
847 |
+
politicamente, scientificamente ed eticamente co-
|
848 |
+
me guardiano della dottrina dell'Imam.
|
849 |
+
Di conseguenza ecco Jàbir l'adoratore, lo gno-
|
850 |
+
stico Sufi, il lottatore politico e il ben informato
|
851 |
+
maestro di Alchimia.
|
852 |
+
L'Imam Ja'far, come maestro di setta e di pen-
|
853 |
+
siero, e uomo di miracoli e poteri occulti della
|
854 |
+
discendenza del Profeta, era l'oppositore politico
|
855 |
+
del potere Abbaside da quando si era posto come
|
856 |
+
guardiano dei valori islamici e dei loro concetti.
|
857 |
+
Si può percepire il tipo di relazione e di intimità
|
858 |
+
spirituale di meravigliose visioni e profondità tra
|
859 |
+
l'Imam Abi Abdullah e il suo discepolo Jàbir. Gli
|
860 |
+
aspetti di questo legame sono numerosi e ovvia-
|
861 |
+
mente diversi nei suoi scritti, nel suo stile, nella
|
862 |
+
sua mentalità e nella sua metodologia. Si può rico-
|
863 |
+
noscere la presenza dell'Imam Ja'far potentemen-
|
864 |
+
te dietro ogni riga scritta da Jàbir, e nessuno dei
|
865 |
+
suoi trattati fa eccezione. Questa presenza si cela
|
866 |
+
nel testo come metodo scientifico-mistico ed è in-
|
867 |
+
dicazione armoniosa della convergenza dell'esso-
|
868 |
+
terico e dell'esoterico. E un profondo amore spiri-
|
869 |
+
tuale in tutto il significato sublime e in tutte le
|
870 |
+
dimensioni, mescolato a senso di gratitudine e glo-
|
871 |
+
rificazione per il suo grande maestro che ha svela-
|
872 |
+
to l'occulto segreto della conoscenza e fatto ribol-
|
873 |
+
lire le meravigliose tacite fontane della genesi e
|
874 |
+
della creazione davanti ai suoi occhi.
|
875 |
+
Dice Jàbir:
|
876 |
+
I gradi dell'Elixir devono stare sulla linea della bilancia,
|
877 |
+
questo si deve sapere. Nell'onorevole diritto del mio
|
878 |
+
maestro, io giuro che questo è senza simboli e senza
|
879 |
+
prolissità.
|
880 |
+
In un altro passo, Jàbir dice che il suo maestro
|
881 |
+
gli ordinò:
|
882 |
+
Prepara un libro di piena maturità e profondità con più
|
883 |
+
essenza e meno prolissità sull'alchimia, e poi mostra-
|
884 |
+
melo.
|
885 |
+
La risposta di Jàbir fu l'obbedienza, ed egli disse:
|
886 |
+
L'ho fatto nel diritto pieno di grazia del mio maestro,
|
887 |
+
ho rivelato cose, le ho ridotte all'essenza. Ho mostrato
|
888 |
+
alla gente la giusta via.
|
889 |
+
Jàbir dichiara anche che il maestro gli donò la
|
890 |
+
visione penetrante della bilancia, e diffuse la sua
|
891 |
+
parola su questo dicendo:
|
892 |
+
Così parla il maestro, e così egli mi ordinò di scrivere e
|
893 |
+
classificare.
|
894 |
+
Molte volte egli menziona le direttive del suo
|
895 |
+
maestro e parla del Mercurio:
|
896 |
+
Il mio maestro mi raccontò tutto intorno ai suoi padri,
|
897 |
+
uno ad uno.
|
898 |
+
Questo tipo di pensiero raggiunge il suo sommo
|
899 |
+
e la sua presenza sublime una volta che si ricordi
|
900 |
+
il messaggio che l'Imam Ja'far dettò a Jàbir, suo
|
901 |
+
discepolo favorito, sul segreto della natura e sulle
|
902 |
+
più piccole cose della saggezza universale che pos-
|
903 |
+
sono essere riassunte come espressioni dell'Opera.
|
904 |
+
La visione dei fatti taciti dell'esistenza attraverso la
|
905 |
+
contemplazione esoterica. Il principio della bilan-
|
906 |
+
cia come si deduce dalla giustizia divina e dal sen-
|
907 |
+
so Qur'anico del mondo:
|
908 |
+
Ed Egli ha fatto sorgere alto il firmamento, ed Egli ha
|
909 |
+
fissato la Bilancia [di giustizia], (Sura LV, 7)
|
910 |
+
Secondo Jabir la realizzazione totale della pro-
|
911 |
+
fessione alchemica viene attraverso due percorsi:
|
912 |
+
l'esterno essoterico e l'interno esoterico.
|
913 |
+
Il primo cammino è la realizzazione del ragio-
|
914 |
+
namento e dei tratti delle leggi generali e dello sta-
|
915 |
+
to di unione di natura, mente e anima.
|
916 |
+
Il secondo cammino, l'esoterico, è legato alla
|
917 |
+
conoscenza delle leggi e degli stati impegnati ver-
|
918 |
+
so il divino. Questo cammino può essere stabilito
|
919 |
+
mantenendo i grandi fatti universali e la purifica-
|
920 |
+
zione di se stessi e dei propri fini, insieme a chia-
|
921 |
+
rezza e sincerità interiori.
|
922 |
+
Le grandi rivelazioni, come la conoscenza del-
|
923 |
+
l'interiore, Jàbir le ottenne attraverso il suo mae-
|
924 |
+
stro Ja'far Abi Abdullah Al-Sàdiq, perché le fon-
|
925 |
+
tane essoteriche sono le ombre di quelle esoteriche
|
926 |
+
che fluiscono dalla luce divina latente nello spiri-
|
927 |
+
to dell'uomo.
|
928 |
+
L'Imam Sàdiq indicò a Jàbir il profondo senso
|
929 |
+
di soddisfazione, quiete e tranquillità e gli rivelò i
|
930 |
+
cammini per visualizzare il tacito, e l'innata attra-
|
931 |
+
zione verso la conoscenza del vero senza veli.
|
932 |
+
Inoltre Jàbir asserisce il significato della bilan-
|
933 |
+
cia come conoscenza del numero, del rapporto di
|
934 |
+
quantità e delle leggi degli elementi di natura e dei
|
935 |
+
composti, ai quali si riferisce nei trattati che seguo-
|
936 |
+
no il criterio dell'analogia.
|
937 |
+
Esoterico ed essoterico, secondo Jàbir, simbo-
|
938 |
+
leggiano l'alternata apparizione e scomparsa del-
|
939 |
+
l'Imam Ja'far al-Sàdiq.
|
940 |
+
Caro studioso, non mi fraintendere, si sta medi-
|
941 |
+
tando sul compendio della saggezza.
|
942 |
+
La pace sia con te.
|
943 |
+
QUINTA LETTERA
|
944 |
+
Caro Maestro,
|
945 |
+
ho finito la lunga preparazione dei materiali: li
|
946 |
+
ho purificati, esaltati, predisposti con cura per il
|
947 |
+
primo incontro.
|
948 |
+
E primavera, tra poco inizierò la quarantena
|
949 |
+
sacra. La materia è nel suo nido, ne attendo con
|
950 |
+
ansia il risveglio. Attendo, come dice Boehme, che
|
951 |
+
scendano gli angeli.
|
952 |
+
Lavorando quietamente, la riflessione sulle qua-
|
953 |
+
lità e le preparazioni della materia conduce a quel-
|
954 |
+
le òdi'artista.
|
955 |
+
I maestri danno poche indicazioni, insoddisfa-
|
956 |
+
centi. Il tema sembra o poco importante o sconta-
|
957 |
+
to. Si sottolinea la necessità di buoni caratteri fisi-
|
958 |
+
ci: salute e integrità di corpo. Si aggiungono
|
959 |
+
facoltà intellettive: memoria, comprensione, facile
|
960 |
+
apprendimento. Si cita dedizione allo studio e al
|
961 |
+
lavoro, paziente costanza. Pietas, timor di Dio,
|
962 |
+
innocenza, sono ricordati pudicamente.
|
963 |
+
Riassume tutto molto concisamente Geber la-
|
964 |
+
tino:
|
965 |
+
Diciamo pertanto, che se non avrà ingegno naturale, e
|
966 |
+
una mente che scruti sottilmente i principi naturali, e i
|
967 |
+
fondamenti della natura, non troverà la vera radice di
|
968 |
+
questa preziosissima scienza. Inoltre ne abbiamo trova-
|
969 |
+
to molti, che hanno una mente che crede facilmente a
|
970 |
+
qualsiasi fantasia. Ma il vero che credono di aver tro-
|
971 |
+
vato, è affatto fantastico, aberrante, e pieno di errori e
|
972 |
+
lontanissimo dai principi naturali, poiché il loro cervel-
|
973 |
+
lo, colmo di molte fumosità, non può accogliere il vero
|
974 |
+
intento delle cose naturali. Altri ancora sono schiavi del
|
975 |
+
denaro: desiderano questa scienza, affermano che essa
|
976 |
+
è meravigliosa e vera, ma temono le spese. Pertanto,
|
977 |
+
sebbene ne siano convinti, e la indaghino correttamen-
|
978 |
+
te, tuttavia non giungono all'esperienza dell'opera per
|
979 |
+
avarizia di denaro. Pertanto a tutti questi non giunge la
|
980 |
+
nostra scienza.
|
981 |
+
Siamo nell'ovvietà. Stupisce la mancanza di sof-
|
982 |
+
ferenze meritorie, quelle che sono norma per qual-
|
983 |
+
siasi cammino di perfezione, fatte di sacrifici, asce-
|
984 |
+
si, rinunce, digiuni: ci si purifichi, immersi nel do-
|
985 |
+
lore, se appena si vuole ottenere qualcosa.
|
986 |
+
Sono disarmato di fronte a questo silenzio. Pare
|
987 |
+
manchi qualcosa, un vuoto da colmare che cerco
|
988 |
+
di soddisfare con altri insegnamenti, riversando
|
989 |
+
sensi simbolici in frasi dall'apparenza innocua.
|
990 |
+
L'Opera è essenzialmente arte del fuoco, e l'al-
|
991 |
+
chimista proprio per questo può diventare philo-
|
992 |
+
sophus per ignem, filosofo per mezzo del fuoco.
|
993 |
+
Leggo perciò con una certa preoccupazione Jàbir
|
994 |
+
quando afferma:
|
995 |
+
Il fuoco aumenta le virtù del saggio e la corruzione del
|
996 |
+
perverso.
|
997 |
+
Un problema dunque si pone, che voi avete più
|
998 |
+
volte definito come necessità dell'«etica della te-
|
999 |
+
stimonianza», ed io chiedo praticamente dove
|
1000 |
+
conduca. Perché siamo affamati di precetti, di leg-
|
1001 |
+
gi da seguire.
|
1002 |
+
Una norma tuttavia esiste, misteriosa e incom-
|
1003 |
+
prensibile: «Siate veridici». Sottolineata come vir-
|
1004 |
+
tù singolare e significante, è difficile coglierne il
|
1005 |
+
valore. Non si trova come regola di santità, am-
|
1006 |
+
mettendo che santità sia strumento di misura. Non
|
1007 |
+
è difficile da praticare nella sua formulazione più
|
1008 |
+
evidente.
|
1009 |
+
Proprio per questo temo abbia significati più
|
1010 |
+
profondi, difficili da decifrare.
|
1011 |
+
Rispettosamente.
|
1012 |
+
QUINTA RISPOSTA
|
1013 |
+
Caro studioso,
|
1014 |
+
tu devi capire che esiste una veracità della lin-
|
1015 |
+
gua, e una veracità del cuore, e che è della secon-
|
1016 |
+
da che noi parliamo.
|
1017 |
+
La prima consiste nel fatto che la tua lingua non
|
1018 |
+
dovrebbe mentire. La seconda consiste nel fatto
|
1019 |
+
che il tuo cuore non dovrebbe mentire.
|
1020 |
+
La menzogna della lingua consiste nel soffer-
|
1021 |
+
marsi su ciò che non è stato detto, e nel dire e non
|
1022 |
+
fare. La menzogna del cuore consiste nel credere
|
1023 |
+
e non fare. La menzogna del cuore consiste nel
|
1024 |
+
dare ascolto ad una menzogna.
|
1025 |
+
Ogni menzognero è altro da me.
|
1026 |
+
La verità autentica è la mia voce: se io voglio fac-
|
1027 |
+
cio parlare con essa una pietra o un uomo.
|
1028 |
+
Qualunque cosa ti lega a me è il mio discorso che
|
1029 |
+
proviene dalla mia voce.
|
1030 |
+
Il desiderio è una menzogna del cuore. Il deside-
|
1031 |
+
rio è il seme del Nemico in ogni cosa.
|
1032 |
+
Io ti ho reso inadatto ad ogni cosa e ho fatto si
|
1033 |
+
che questo fosse un velo tra te e questo. Non lace-
|
1034 |
+
rare il velo prestando attenzione alle cose, perché io
|
1035 |
+
manderei su di te la loro umiliazione. Se tu fossi sta-
|
1036 |
+
to adatto ad ogni cosa, io non ti avrei rivelato il mio
|
1037 |
+
volto.
|
1038 |
+
Quando ti capita qualcosa con la sua tentazione,
|
1039 |
+
considera l'origine della sua creazione e vedrai che
|
1040 |
+
questa la condurrà via da te. Se tu non vedi l'origi-
|
1041 |
+
ne della sua creazione, allora considera il fine del
|
1042 |
+
suo manifestarsi, e vi cercherai religiosità
|
1043 |
+
dentro,
|
1044 |
+
ma tu non la vedrai.
|
1045 |
+
L'origine è forza, il fine è debolezza:
|
1046 |
+
chiedimi
|
1047 |
+
perdono per una debolezza su cui hai potere per
|
1048 |
+
mezzo di una debolezza.
|
1049 |
+
La pace sia con te.
|
1050 |
+
.tléimiltife
|
1051 |
+
uutraa :cm
|
1052 |
+
i
|
1053 |
+
i
|
1054 |
+
m
|
1055 |
+
o ftr ìan'um
|
1056 |
+
i
|
1057 |
+
n
|
1058 |
+
.
|
1059 |
+
«
|
1060 |
+
K
|
1061 |
+
T
|
1062 |
+
U i-H'.^»'.
|
1063 |
+
mm
|
1064 |
+
••><..ì
|
1065 |
+
^
|
1066 |
+
]dbir, il Maestro dei Maestri, chiamato Gcber dai latini
|
1067 |
+
Caro Maestro,
|
1068 |
+
la primavera è passata immersa nell'operosità.
|
1069 |
+
L'essoterico risponde alle attese: i fenomeni sono
|
1070 |
+
stupefacenti e meravigliosi, i colori splendidi, i ri-
|
1071 |
+
sultati prodigiosi.
|
1072 |
+
L'esoterico non appaga: manca qualcosa di es-
|
1073 |
+
senziale, compaiono immagini di illusione.
|
1074 |
+
Un vecchio maestro di Francia scriveva:
|
1075 |
+
Ecco il segreto.
|
1076 |
+
Sappi che tutti parlano allo stesso modo in due modi,
|
1077 |
+
di cui uno è vero e l'altro falso.
|
1078 |
+
Il vero è tale da non poter essere inteso che dai soli
|
1079 |
+
Illuminati che camminano rettamente e secondo natu-
|
1080 |
+
ra, ed è tuttavia coperto da paragoni ed esempli, sotto
|
1081 |
+
nomi ed equivoci che non appartengono alla dottrina
|
1082 |
+
ma ne sono significanti, perché in lei non occorre che
|
1083 |
+
una sola cosa, un solo modo di operare, per una via
|
1084 |
+
semplice e naturale, senza perdersi nella pluralità delle
|
1085 |
+
cose contrarie al nostro unico lievito.
|
1086 |
+
Il falso è questa confusione di regimi e droghe cattive,
|
1087 |
+
sebbene il tutto sia significante di qualcosa che appar-
|
1088 |
+
tiene alla dottrina, tuttavia non si deve considerare la
|
1089 |
+
qualità, perché la Natura è semplice e non opera che
|
1090 |
+
semplicemente.
|
1091 |
+
53
|
1092 |
+
È il momento del dubbio e dell'incertezza, mo-
|
1093 |
+
mento fatale e pericoloso, forse inevitabile. Il con-
|
1094 |
+
fine tra vero e falso, tra inganno e realtà, è molto
|
1095 |
+
più sottile di quel che si possa immaginare, e lo
|
1096 |
+
stesso operare a questo punto è causa di ulteriore
|
1097 |
+
incertezza.
|
1098 |
+
Tutti hanno opinioni sulFAlchimia. Due ipotesi
|
1099 |
+
riassumono i pensieri sulla Grande Opera.
|
1100 |
+
Una dice che le operazioni descritte sembrano
|
1101 |
+
chimiche, mentre in realtà sono spirituali, o men-
|
1102 |
+
tali: descrizioni psicologiche dell'evoluzione inte-
|
1103 |
+
riore, atti dell'immaginare o della volontà, visioni
|
1104 |
+
che nascono dall'intimo.
|
1105 |
+
L'altra assimila il forno al corpo fisico dell'uo-
|
1106 |
+
mo, e la materia a un'energia sottile che deve cre-
|
1107 |
+
scere, salire, cuocere nei suoi intimi recessi.
|
1108 |
+
Entrambe leggono l'Opera come simbolo, anzi
|
1109 |
+
come allegoria di diverse verità.
|
1110 |
+
Attraggono e respingono: entrambe suonano
|
1111 |
+
difettose nella loro estrema ragionevolezza.
|
1112 |
+
Ricordo un passo che mi avete insegnato:
|
1113 |
+
Noi proponemmo il deposito dei nostri segreti ai Cieli,
|
1114 |
+
alla Terra, ai Monti: tutti rifiutarono di assumerlo, tut-
|
1115 |
+
ti tremarono al pensiero di riceverlo. Ma l'uomo ac-
|
1116 |
+
cettò di incaricarsene: è un violento, un incosciente.
|
1117 |
+
(Sura XXXIII, 72)
|
1118 |
+
Sento che si devono scoprire pensieri insensati,
|
1119 |
+
vedere cose irragionevoli, sentire stridori inaccet-
|
1120 |
+
tabili: scopro che nell'Opera si può vedere e non
|
1121 |
+
vedere, conoscere e non conoscere. Gli stessi
|
1122 |
+
occhi nascondono le cose, le orecchie cancellano i
|
1123 |
+
suoni, la mente ricompone tutto a sua immagine,
|
1124 |
+
la caligine infittisce di fronte al meraviglioso, come
|
1125 |
+
se volesse proteggerlo in una deformazione appro-
|
1126 |
+
priata all'osservatore.
|
1127 |
+
Tutto appare chiaro e comprensibile, e questa
|
1128 |
+
stessa sensatezza, tanto gradevole, tanto conve-
|
1129 |
+
niente, genera perplessità e angoscia. Manca l'eso-
|
1130 |
+
terico dell'esoterico.
|
1131 |
+
Distinguere tra il vero e il falso di cui parla il
|
1132 |
+
vecchio maestro sembra impossibile.
|
1133 |
+
Rispettosamente.
|
1134 |
+
SESTA RISPOSTA
|
1135 |
+
Caro studioso,
|
1136 |
+
la verità è ciò da cui non ti allontaneresti, anche
|
1137 |
+
se tutto il popolo del cielo e della terra te ne allon-
|
1138 |
+
tanasse. La falsità è ciò che non accetteresti, anche
|
1139 |
+
se tutto il popolo del cielo e della terra ti invitasse
|
1140 |
+
a farlo. Ora, per comprendere meglio quanto sto
|
1141 |
+
per dirti, devi imparare a distinguere tra stato e
|
1142 |
+
situazione. Il primo è un dono di Dio, la seconda
|
1143 |
+
è il risultato della tua opera.
|
1144 |
+
Stato e situazione sembra siano la stessa cosa
|
1145 |
+
perché differiscono solo minimamente a causa del-
|
1146 |
+
la loro intercambiabilità, ma una situazione è una
|
1147 |
+
fase durante un cambiamento, mentre lo stato è
|
1148 |
+
tale per la sua stabilità.
|
1149 |
+
Una situazione si muove per diventare stato,
|
1150 |
+
come l'emissione di un dubbio da parte dell'ado-
|
1151 |
+
ratore si concretizza tacitamente nella richiesta
|
1152 |
+
della verifica.
|
1153 |
+
La struttura ricorrente dell'apparire e scompa-
|
1154 |
+
rire del dubbio è il risultato di un conflitto nell'a-
|
1155 |
+
rena del sé. Questa è una situazione.
|
1156 |
+
Il superamento del dubbio, sostenuto da fede
|
1157 |
+
profonda che trascende il sé, diventa uno stato.
|
1158 |
+
La situazione della verifica viene dopo, perché
|
1159 |
+
colui che ha lo stato del dubbio, vorrebbe avere la
|
1160 |
+
situazione della verifica.
|
1161 |
+
La situazione della verifica va e viene con pie-
|
1162 |
+
nezza di mente e mancanza di mente nel profon-
|
1163 |
+
do dell'essenza dell'adoratore, sino a quando la
|
1164 |
+
nebbia della mancanza di mente scompare soste-
|
1165 |
+
nuta dal sostegno di Dio per rendere la verifica
|
1166 |
+
uno stato.
|
1167 |
+
Lo stato del dubbio non si fissa mai a meno che
|
1168 |
+
la situazione della verifica non si sostanzi, e questo
|
1169 |
+
stato non si fissa sinché non avviene la situazione
|
1170 |
+
della vista.
|
1171 |
+
Con i doni della vista, la verifica si fissa come
|
1172 |
+
stato, dopo essere stata una situazione.
|
1173 |
+
L'avvento della vista diventa una situazione che
|
1174 |
+
va e viene con un velame. Allora diventa uno
|
1175 |
+
stato:
|
1176 |
+
E il suo sole libera dall'eclissi, dal velame e dalla
|
1177 |
+
nebbia.
|
1178 |
+
La visione della verità scende nelle profondità
|
1179 |
+
del cuore per essere la situazione più alta della
|
1180 |
+
visione.
|
1181 |
+
Il nostro Profeta Mohammad - la pace su di
|
1182 |
+
lui - dice: "O Signore, io ti prego di farmi avere
|
1183 |
+
un dono di fede che penetri il mio cuore".
|
1184 |
+
Conoscimi con la gnosi della certezza rivelata, fa
|
1185 |
+
noto il tuo sé al tuo Maestro per mezzo di certezza
|
1186 |
+
rivelata. Scrivi il modo della mia autorivelazione a
|
1187 |
+
te per mezzo della gnosi della certezza rivelata, scri-
|
1188 |
+
vi come io ho fatto sì che tu fossi testimone e come
|
1189 |
+
tu abbia reso testimonianza. Questo può essere un
|
1190 |
+
ricordo per te e uno stabilirsi per il tuo cuore.
|
1191 |
+
Sappi che i doni di Dio Onnipotente sono sen-
|
1192 |
+
za limiti, e situazione e stato sono doni correlati
|
1193 |
+
alle parole di Dio che sono troppo numerose per
|
1194 |
+
essere scritte anche avendo l'inchiostro di tutti i
|
1195 |
+
mari, e sono più innumerevoli dei granelli di tutte
|
1196 |
+
le sabbie.
|
1197 |
+
Dio è il misericordioso dispensatore e donatore.
|
1198 |
+
Egli mi pose nella verità della gnosi e mi disse:
|
1199 |
+
Come per questo momento c'è un sopra e un sot-
|
1200 |
+
to, tutti i fenomeni sono questo mondo e tutto que-
|
1201 |
+
sto insieme e tutto ciò che contiene sta in attesa
|
1202 |
+
dell'Ora. Sopra di lui e sopra tutto ciò che contiene
|
1203 |
+
ho scritto la fede, e l'essenza della fede è: "Non c'è
|
1204 |
+
nulla come lui".
|
1205 |
+
Chiama a testimoniare Gabriele e Michele,
|
1206 |
+
chiama a testimoniare il Trono e i portatori del
|
1207 |
+
Trono, chiama a testimoniare ogni angelo e ogni
|
1208 |
+
possessore di gnosi, e vedrai la realtà della sua
|
1209 |
+
fede, mentre dice e dà testimonianza che non c'è
|
1210 |
+
nulla come lui.
|
1211 |
+
Tu vedrai che conoscenza di questo è esperien-
|
1212 |
+
za, e che esperienza di questo è conoscenza.
|
1213 |
+
Tu vedrai che questo è il limite della gnosi,
|
1214 |
+
vedrai che quella è l'autentica verità, vedrai che
|
1215 |
+
quella è la vera conoscenza della visione, non la
|
1216 |
+
visione in sé.
|
1217 |
+
Osservali: ciascuno di loro veglia in attesa del-
|
1218 |
+
l'Ora. Attendono che si alzi il velo, attendono il
|
1219 |
+
levarsi della copertura.
|
1220 |
+
Ma non si possono sopportare le condizioni di
|
1221 |
+
realtà di colui che sta dietro al velo, se non per suo
|
1222 |
+
mezzo.
|
1223 |
+
Come sarà quando il velo sarà strappato? Per-
|
1224 |
+
ché il velo sarà strappato e in questo strappo sta
|
1225 |
+
un assalto che non può essere sostenuto dalla
|
1226 |
+
natura delle cose create.
|
1227 |
+
Se il velo fosse alzato e non strappato, colui che
|
1228 |
+
sta sotto di lui troverebbe riposo. Ma è strappato
|
1229 |
+
e quando questo avviene la gnosi dello gnostico
|
1230 |
+
sarà dimenticata. Nel dimenticare sarà rivestita da
|
1231 |
+
una luce, che farà sì che si possa sopportare ciò
|
1232 |
+
che si manifesta dopo lo strappo. E questo dimen-
|
1233 |
+
ticare è un bene perché con la gnosi non si potreb-
|
1234 |
+
be sopportare ciò che viene manifestato.
|
1235 |
+
La pace sia con te.
|
1236 |
+
Carovana di pellegrini
|
1237 |
+
musulmani.
|
1238 |
+
SETTIMA LETTERA
|
1239 |
+
Caro Maestro,
|
1240 |
+
l'unione delle Nature è un mistero che non si
|
1241 |
+
riesce a penetrare. La congiunzione degli opposti
|
1242 |
+
richiede un Mediatore che pare più divino che
|
1243 |
+
umano. Credo sia del genere di cui parla Jàbir nel
|
1244 |
+
Libro della Misericordia:
|
1245 |
+
Quante cose ci sono in questo mondo, spirituali e sot-
|
1246 |
+
tili, che i sensi non possono percepire e che non si pos-
|
1247 |
+
sono conoscere che per intelligenza!
|
1248 |
+
Mentre riprendo molto umilmente e paziente-
|
1249 |
+
mente le materie per predisporle all'Opera, stu-
|
1250 |
+
dio, medito, cerco di capire. In effetti capire non è
|
1251 |
+
verbo da usarsi, perché questo arcano lo credo
|
1252 |
+
occultato dalla sua stessa assurdità. Per la realiz-
|
1253 |
+
zazione si deve concepire qualcosa di inesplicabi-
|
1254 |
+
le, e questa non sarà una comprensione, può esse-
|
1255 |
+
re una visione.
|
1256 |
+
Torno, ai libri con maggior prudenza. Ho letto
|
1257 |
+
il racconto di Khalid, il principe alchimista:
|
1258 |
+
Sappi che il mio discepolo Musa, il più onorevole di
|
1259 |
+
tutti presso di me, studiò molto sui libri (dei Sapienti)
|
1260 |
+
e faticò molto nell'opera del magistero, ma non riuscì a
|
1261 |
+
conoscere il modo della composizione.
|
1262 |
+
Allora, supplice e umile, me ne chiese una spiegazione
|
1263 |
+
e un consiglio. Io non gli detti risposta né indicazioni,
|
1264 |
+
ma gli prescrissi di leggere i libri dei Filosofi e di cer-
|
1265 |
+
care in quelli ciò che aveva chiesto a me.
|
1266 |
+
Egli allora, andatosene, lesse più di cento libri, tutti
|
1267 |
+
quelli che potè trovare: libri certamente veridici, segre-
|
1268 |
+
ti, dei più nobili Filosofi, ma non vi potè trovare ciò che
|
1269 |
+
cercava, e rimase attonito e quasi stravolto.
|
1270 |
+
Penso che l'errore più ovvio consista nel ricon-
|
1271 |
+
durre tutto alle operazioni, alle esperienze fatte, in
|
1272 |
+
una interpretazione ingenuamente tecnica. Mi ri-
|
1273 |
+
peto le parole di un antichissimo filosofo musul-
|
1274 |
+
mano:
|
1275 |
+
Quest'arte non è forse Cabalistica e piena di grandissi-
|
1276 |
+
mi segreti? E tu, stupido pazzo, tu credi che noi inse-
|
1277 |
+
gniamo chiaramente i segreti dei segreti? E prendi le
|
1278 |
+
parole secondo il loro suono letterale?
|
1279 |
+
Sappi per certo che chiunque prende le parole dei
|
1280 |
+
Filosofi secondo il significato volgare e ordinario, sba-
|
1281 |
+
glia enormemente.
|
1282 |
+
Ho ripreso il Libro delle Bilance, e mi perdo in
|
1283 |
+
infiniti giochi di cabala, che stupiscono per l'e-
|
1284 |
+
strema sottigliezza delle analogie. Con queste ten-
|
1285 |
+
to di penetrare nel contenuto delle lettere, di
|
1286 |
+
vedere ciò che queste racchiudono, la sostanza,
|
1287 |
+
non il vaso.
|
1288 |
+
Mi smarrisco in innumerevoli esercizi, correla-
|
1289 |
+
zioni, scomposizioni minuziose e calcoli labirinti-
|
1290 |
+
ci. Lascio il senso letterale e ne scopro mille occul-
|
1291 |
+
ti che svelano e ri-velano, come statuine russe che
|
1292 |
+
sembrano non dover mai finire in un continuo
|
1293 |
+
rimpicciolirsi.
|
1294 |
+
Jabir voleva insegnarci a pesare lo Spirito, capi-
|
1295 |
+
sco che il mio strumento non è corretto, le misu-
|
1296 |
+
razioni si perdono in un'analisi sterile nella sua
|
1297 |
+
apparente, mostruosa, fecondità.
|
1298 |
+
La materia è silente. Temevo la sua voce, ora il
|
1299 |
+
suo silenzio mi offende.
|
1300 |
+
Rispettosamente.
|
1301 |
+
SETTIMA RISPOSTA
|
1302 |
+
Caro studioso,
|
1303 |
+
considera la lettera e ciò che contiene dietro di
|
1304 |
+
sé. Se presti attenzione alla lettera, vi cadrai den-
|
1305 |
+
tro. Se presti attenzione a quello che contiene,
|
1306 |
+
cadrai in quello che contiene.
|
1307 |
+
Non disperare: la generosità di Dio è più grande
|
1308 |
+
della lettera di cui trovi la teoria e della lettera di
|
1309 |
+
cui conosci la teoria, della lettera di cui non trovi
|
1310 |
+
la teoria e della lettera di cui non conosci la teoria.
|
1311 |
+
Quando tu stai con Dio, vedi cosa scende e cosa
|
1312 |
+
sale, e ogni lettera viene da te con tutto ciò che
|
1313 |
+
contiene, e ogni cosa si rivolge a te nella sua lin-
|
1314 |
+
gua e ogni esposizione si spiega per te secondo la
|
1315 |
+
sua esposizione.
|
1316 |
+
La guida appartiene per natura al velo, e il velo
|
1317 |
+
è la punizione. Perciò se la tua guida è della natu-
|
1318 |
+
ra del velo, sarai velato dalla realtà di ciò verso cui
|
1319 |
+
sei guidato:
|
1320 |
+
Io sono il velo del mio gnostico, e sono la guida
|
1321 |
+
del mio gnostico. Io faccio conoscere me stesso ed egli
|
1322 |
+
mi conosce e sa che io faccio conoscere me stesso. Io
|
1323 |
+
velo me stesso, ed egli mi conosce e sa che io velo me
|
1324 |
+
stesso.
|
1325 |
+
Caro studioso, colui la cui guida non è Dio, non
|
1326 |
+
è unito a Dio. Ascolta:
|
1327 |
+
Quando tu conosci la conoscenza che procede da
|
1328 |
+
me, io ti punisco se segui coloro che non sanno, e ti
|
1329 |
+
punisco anche se segui coloro che sanno.
|
1330 |
+
L'uomo che è sotto l'effetto del sé, sta sotto il
|
1331 |
+
velo della tenebra a causa della sua esistenza mate-
|
1332 |
+
riale. Ma quando il suo cuore esce dal suo velo,
|
1333 |
+
allora raggiunge la vicinanza senza l'effetto del sé.
|
1334 |
+
L'ignoranza è il velo della visione e la cono-
|
1335 |
+
scenza è il velo della visione. Egli è il manifesto
|
1336 |
+
senza velo e il nascosto senza svelamento.
|
1337 |
+
Colui che conosce il velo è vicino allo svela-
|
1338 |
+
mento. Il velo è uno, le cause per mezzo delle qua-
|
1339 |
+
li si manifesta sono diverse, e queste sono vari veli.
|
1340 |
+
Ascolta l'Imam Ja'far:
|
1341 |
+
La nostra causa è un segreto dentro un segreto, il segre-
|
1342 |
+
to di qualcosa che resta velato, è un segreto che solo un
|
1343 |
+
altro segreto può spiegare, è un segreto su un segreto
|
1344 |
+
che si appaga di un segreto.
|
1345 |
+
La pace sia con te.
|
1346 |
+
jabir tra i grandi Maestri dell'Alchimia
|
1347 |
+
occidentale.
|
1348 |
+
OTTAVA LETTERA
|
1349 |
+
Caro Maestro,
|
1350 |
+
un quesito si impone, continuo, a chi è sulla
|
1351 |
+
Via, che si ripete ad ogni grado in forme rinnova-
|
1352 |
+
te eppure costanti.
|
1353 |
+
Si può tradurre molto semplicemente. Consiste
|
1354 |
+
nella necessità, e nell'impossibilità, di conciliare
|
1355 |
+
l'esistenza banale, terrena, quotidiana, con la sa-
|
1356 |
+
cralità dell'Opera e con le sue manifestazioni spi-
|
1357 |
+
rituali.
|
1358 |
+
Chi non abbandoni per un eremitaggio o una
|
1359 |
+
cella la vita che conduce nel mondo, soffre di que-
|
1360 |
+
sta antinomia persecutrice e non sa, o non può,
|
1361 |
+
risolverla. Rischia di essere incapace nell'uno e
|
1362 |
+
nell'altro luogo, zoppo per avere un piede qui e
|
1363 |
+
uno altrove, instabile nella più assoluta precarietà.
|
1364 |
+
Un alchimista cinese insegnava:
|
1365 |
+
La ricerca non è complicata. Basta fare alcune cose.
|
1366 |
+
L'unico problema è che quasi sempre la volontà non è
|
1367 |
+
ferma e la fede non è confermata.
|
1368 |
+
Perché trascurare gli interessi umani? Il vero artista rie-
|
1369 |
+
sce senza difficoltà ad occuparsi degli affari e del-
|
1370 |
+
l'Opera. Mentre in privato osserva rigorosamente la
|
1371 |
+
Via, pubblicamente è impegnato negli affari mondani.
|
1372 |
+
In tal modo raggiunge una grande perfezione perché è
|
1373 |
+
tenuto a controllarsi.
|
1374 |
+
Una tale persona è eccellente.
|
1375 |
+
Scriveva secoli fa. Sorge il dubbio che inserito
|
1376 |
+
in una società, come si suol dire, tradizionale,
|
1377 |
+
potesse sostenere onestamente opinioni che oggi
|
1378 |
+
non è dato immaginare.
|
1379 |
+
La sofferenza più grande consiste nella perdita
|
1380 |
+
quando si è ricondotti alla discesa nel profano. Ne
|
1381 |
+
viene un inevitabile senso di fastidio per tutto ciò
|
1382 |
+
che ci vuole immobili nel mondo, una profonda
|
1383 |
+
insofferenza. Ma quello che davvero appare insop-
|
1384 |
+
portabile è il timore di non poter tornare nel luo-
|
1385 |
+
go da cui siamo stati strappati, di aver perso il
|
1386 |
+
Dono per mancanza di consuetudine, peggio, per
|
1387 |
+
distrazione.
|
1388 |
+
Stupisce che l'acquisito si possa perdere con
|
1389 |
+
tanta facilità, e lo stupore diviene ansia di ritorno,
|
1390 |
+
angoscia di aver perso la strada.
|
1391 |
+
La domanda perciò si complica. Diventa richie-
|
1392 |
+
sta di una guida nel comportamento, di un modo
|
1393 |
+
per non abbandonare la visione, di un metodo che
|
1394 |
+
renda laboratorio ogni atto del vivere e permetta di
|
1395 |
+
continuare senza interruzioni.
|
1396 |
+
Mi chiedo se sia possibile.
|
1397 |
+
Rispettosamente.
|
1398 |
+
OTTAVA RISPOSTA
|
1399 |
+
Caro studioso,
|
1400 |
+
un seminatore seminò una manciata di semi, ma
|
1401 |
+
egli non aveva ancora raggiunto la strada, che li
|
1402 |
+
uccelli li avevano mangiati. Alcuni altri semi creb-
|
1403 |
+
bero su una roccia liscia su cui c'era poca sabbia e
|
1404 |
+
poca rugiada: le loro radici soffocarono nella soli-
|
1405 |
+
da roccia e furono spazzate via. Alcuni altri semi
|
1406 |
+
crebbero in una buona terra, ma questa era piena
|
1407 |
+
di rovi che li soffocarono e distrussero. Altri semi
|
1408 |
+
crebbero in una buona terra senza rocce né rovi e
|
1409 |
+
si trasformarono in buona forma e frutti.
|
1410 |
+
Il seminatore è come parlare della rettitudine, e
|
1411 |
+
ciò che avviene per strada è come un uomo che tro-
|
1412 |
+
va il racconto dell'ascoltare inutile: appena l'avrà
|
1413 |
+
ascoltato, il diavolo lo strappa via sinché lo dimen-
|
1414 |
+
tica.
|
1415 |
+
I semi sulla roccia liscia sono come un uomo
|
1416 |
+
che trova il discorso degno di essere ascoltato,
|
1417 |
+
eppure questo raggiunge un cuore che non vuole
|
1418 |
+
comprenderlo a fondo, e così la parola declina.
|
1419 |
+
I semi nella terra dei rovi sono come un uomo
|
1420 |
+
che trova la parola degna di essere ascoltata, eppu-
|
1421 |
+
re i piaceri si sono stabiliti nel petto intorno al
|
1422 |
+
cuore, la materia non può essere compresa a fon-
|
1423 |
+
do per i suoi pregiudizi e la sua volubilità.
|
1424 |
+
I semi che crescono sulla terra buona, senza
|
1425 |
+
rocce né rovi, sono come il discorso che raggiun-
|
1426 |
+
ge un cuore e vi resta per essere compreso a fon-
|
1427 |
+
do. E come un albero con i rami nel terrestre e le
|
1428 |
+
radici profondamente stabilite nel celeste. Il suo
|
1429 |
+
frutto è gustoso, bello a vedersi e aromatico, e atti-
|
1430 |
+
ra gli uomini da ogni parte del mondo.
|
1431 |
+
II mio nome e i miei nomi sono posti dentro di
|
1432 |
+
te: non cacciarli o io mi allontanerò dal tuo cuore.
|
1433 |
+
Egli stava dentro di me e mi disse:
|
1434 |
+
La conoscenza è più dannosa dell'ignoranza per
|
1435 |
+
colui che mi vede.
|
1436 |
+
Una buona opera vale dieci per colui che non mi
|
1437 |
+
vede, ma è danno per colui che mi vede.
|
1438 |
+
Quando tu mi vedi, la tua sicurezza è più grande
|
1439 |
+
nell'omissione che nel servizio. Quando tu non mi
|
1440 |
+
vedi, la tua sicurezza è più grande nel servizio che
|
1441 |
+
nell'omissione.
|
1442 |
+
Quando tu mi vedi, ogni cosa che tu vedi altra da
|
1443 |
+
me con il tuo occhio e il tuo cuore, ti separa da me.
|
1444 |
+
Chiedi il mio perdono per l'atto del cuore, e io ti
|
1445 |
+
libererò dalla mutevolezza.
|
1446 |
+
L'atto del cuore è la radice dell'atto del corpo:
|
1447 |
+
considera quindi cosa hai seminato e considera qua-
|
1448 |
+
le frutto porta la semenza.
|
1449 |
+
La mia mano è sul cuore. Perciò se tu trattenessi
|
1450 |
+
da esso la sua propria mano, né prendendo con essa
|
1451 |
+
né dando, tu semineresti la mia autorivelazione per
|
1452 |
+
mezzo di esso, ed esso produrrebbe il frutto di ve-
|
1453 |
+
dermi.
|
1454 |
+
Temi una buona azione che demolisce le buone
|
1455 |
+
azioni, e temi un peccato che erige i tuoi peccati.
|
1456 |
+
Quando tu mi vedi e ottieni da me i mezzi del-
|
1457 |
+
l'indipendenza, io non sarò assente da te.
|
1458 |
+
La tribolazione è la tribolazione di colui che mi
|
1459 |
+
vede. Egli non può sopportare la mia persistenza, e
|
1460 |
+
non può sopportare la sua interruzione. Mentre io
|
1461 |
+
sono al centro di questo, srotolandolo e arrotolandolo.
|
1462 |
+
Neil'arrotolare sta la morte, nello srotolare sta la vita.
|
1463 |
+
Io sono l'obiettivo dei miei amici cari. Quando
|
1464 |
+
essi mi vedono, essi trovano riposo in me. Chi non
|
1465 |
+
mi vede, egli è il proprio obiettivo.
|
1466 |
+
Consulta colui che non mi vede per i tuoi affari
|
1467 |
+
di questo mondo e del prossimo. Segui l'esempio di
|
1468 |
+
colui che mi vede e non consultarlo. La consulta-
|
1469 |
+
zione è per la liberazione dall'errore, e il consiglio è
|
1470 |
+
un assalto. Chi mi vede, dove non assalirà?
|
1471 |
+
Accompagna colui che non mi vede, ed egli ti sor-
|
1472 |
+
reggerà e tu sorreggerai lui. Non cercare la compa-
|
1473 |
+
gnia di colui che mi vede, o ti sarà teso un agguato
|
1474 |
+
da ciò in cui hai riposto la massima fiducia.
|
1475 |
+
Quando tu vedi me e vedi colui che non mi vede,
|
1476 |
+
velami da lui per mezzo della saggezza: se tu non lo
|
1477 |
+
fai ed egli si smarrisce, io ti punirò per lui.
|
1478 |
+
Quando tu non mi vedi e vedi colui che mi vede,
|
1479 |
+
conserva le tue limitazioni, perché tu non mi vedrai
|
1480 |
+
attraverso la sua visione.
|
1481 |
+
Quando tu mi vedi e vedi colui che mi vede, allo-
|
1482 |
+
ra io sono tra voi due, ascoltando e rispondendo.
|
1483 |
+
Coloro che perseverano per il proprio vantaggio,
|
1484 |
+
sono coloro che mi vedono.
|
1485 |
+
Quando io ero assente, velarono gelosamente
|
1486 |
+
i
|
1487 |
+
loro occhi, per non associare nulla a me nella loro
|
1488 |
+
visione.
|
1489 |
+
La gelosia non è giusta finché distrugge la divi-
|
1490 |
+
sione, e la divisione non è distrutta mentre io sono
|
1491 |
+
assente.
|
1492 |
+
In verità Noi li guideremo sulle Nostre vie. Noi
|
1493 |
+
sveleremo loro in ogni cosa i posti su cui cade il
|
1494 |
+
Nostro sguardo.
|
1495 |
+
Noi diamo ordini ad una cosa quando vogliamo,
|
1496 |
+
e facciamo sì che essa testimoni la gnosi. E quando
|
1497 |
+
possiede la gnosi, Noi diciamo ad essa "Sii", ed essa
|
1498 |
+
è, in risposta al nostro comando.
|
1499 |
+
La descrizione di tutto ciò, nella visione del tuo
|
1500 |
+
cuore e del tuo intelletto, è che nel profondo tu
|
1501 |
+
dovresti essere testimone di ogni mondo e di ogni
|
1502 |
+
paradiso, di ogni cielo e di ogni terra, di ogni ter-
|
1503 |
+
reno e di ogni mare, e di ogni notte e di ogni gior-
|
1504 |
+
no, e di ogni profeta e di ogni angelo, e di ogni
|
1505 |
+
conoscenza e di ogni gnosi, e di ogni parola e di
|
1506 |
+
ogni nome, e di tutto ciò che è in quello e di tutto
|
1507 |
+
ciò che è tra quello, dicendo: "Non c'è nulla come
|
1508 |
+
Lui!". Allora sarai all'estremo della conoscenza e
|
1509 |
+
alla fine della gnosi.
|
1510 |
+
Possedendo la gnosi della gnosi, tu conosci e sco-
|
1511 |
+
pri che sei uno dei tuoi animali: allora rendi la tua
|
1512 |
+
esistenza fenomenica, nella sua totalità, una delle
|
1513 |
+
tue vie.
|
1514 |
+
Quando hai fatto sì che l'esistenza fenomenica
|
1515 |
+
sia una delle tue vie, questa sarà un guadagno che
|
1516 |
+
proviene da una via.
|
1517 |
+
La cosa principale è che ora tu dovresti sapere
|
1518 |
+
cosa sei, se un eletto o un uomo comune. Perché
|
1519 |
+
se un eletto non agisce in base al principio di esse-
|
1520 |
+
re un eletto, perisce, mentre con la semplice cono-
|
1521 |
+
scenza dell'uomo comune questi è quasi condotto
|
1522 |
+
alla salvezza.
|
1523 |
+
All'eletto appare una manifestazione di Dio che
|
1524 |
+
è salvaguardata da altri che non siano lui, ma non
|
1525 |
+
da lui. Per quanto riguarda l'uomo comune, non
|
1526 |
+
c'è nulla tra lui e Dio eccetto la sua confessione di
|
1527 |
+
fede, mentre l'eletto è colui che rivolge tutta la sua
|
1528 |
+
attenzione a Dio.
|
1529 |
+
La pace sia con te.
|
1530 |
+
Le necessarie virtù fisiche, psichiche e spirituali
|
1531 |
+
per compiere l'Opera.
|
1532 |
+
NONA LETTERA
|
1533 |
+
Caro Maestro,
|
1534 |
+
un mondo oscuro e tenebroso, nero e fetido,
|
1535 |
+
emette miasmi velenosi e putrescenti. Intorno, un
|
1536 |
+
oceano di fuoco dai bagliori di smeraldo si agita
|
1537 |
+
ribollendo in mille schiume. Sento squittii pauro-
|
1538 |
+
si e tintinnii angelici confusi in stridula armonia.
|
1539 |
+
La luce si mescola alle tenebre, il rumore al silen-
|
1540 |
+
zio nei baratri dell'Universo. Questo è il primo
|
1541 |
+
mistero incomprensibile.
|
1542 |
+
L'Angelo folgora con spada di fiamme, rompe
|
1543 |
+
l'ingresso proibito, frantumandolo in mille parti-
|
1544 |
+
cole che sfuggono come scintille impazzite di ani-
|
1545 |
+
me dannate e riprese, in un perdono maledetto ed
|
1546 |
+
eterno di redenzione malvagia e ingannatrice. La
|
1547 |
+
Luce erutta da un vulcano diabolico, sale, ricrolla,
|
1548 |
+
si rapprende, sovrasta, raggrumata in un cristallo
|
1549 |
+
di magnifico fulgore che il marchio segna: manife-
|
1550 |
+
sta l'inconoscibile perfezione dell'Immacolata Di-
|
1551 |
+
vina, fuori dal tempo, dallo spazio, dall'errore in-
|
1552 |
+
sensato. E il secondo mistero.
|
1553 |
+
Lo raccolgo immerso nell'aroma di balsamo: si
|
1554 |
+
apre la visione dove tutto si tace, i colori si fon-
|
1555 |
+
dono, la quieta pace silente domina il mostro
|
1556 |
+
schiacciato, domato, non ancora ucciso. E il terzo
|
1557 |
+
mistero.
|
1558 |
+
Un flusso ancora putrido di rosso sangue bru-
|
1559 |
+
nastro comincia a rapprendersi, le squame si in-
|
1560 |
+
frangono per la passione dell'anima che vuole li-
|
1561 |
+
bertà alla ricerca di un nuovo corpo, morbido e in-
|
1562 |
+
corruttibile.
|
1563 |
+
L'Angelo mi guarda e tace. Riprende la spada,
|
1564 |
+
indica un cammino, breve e lunghissimo, scoglio
|
1565 |
+
del mare verde, vulcano innevato ancora senza cie-
|
1566 |
+
lo nel torpore del mondo.
|
1567 |
+
L'operazione è finita sotto il velo di tenebra che
|
1568 |
+
ancora ricopre il meraviglioso. L'Angelo è svanito.
|
1569 |
+
Restano i corpi maldestri che maneggio con cura
|
1570 |
+
rammentando la vita che celano. La materia parla,
|
1571 |
+
grida, strepita, risuona e nella confusione elemen-
|
1572 |
+
tare si confonde la mente che non sa più distin-
|
1573 |
+
guere il proprio suono dall'altro.
|
1574 |
+
Queste sono le immagini e le loro direzioni.
|
1575 |
+
Quando cessa la visione, il sonno è profondo, il
|
1576 |
+
corpo spossato, non c'è turbamento di sogno, fal-
|
1577 |
+
so o verace. La nostalgia si acutizza al risveglio e i
|
1578 |
+
ricordi si fondono. L'Angelo torna nell'invisibile,
|
1579 |
+
la memoria si distrae in mille voci discordi.
|
1580 |
+
Reiterare l'operazione è una necessità che attira
|
1581 |
+
e ripugna, spaventa nella sua inevitabilità. La spe-
|
1582 |
+
ranza sta nel non ritorno, nel poter proseguire. Il
|
1583 |
+
timore che la visione non si ripresenti terrorizza.
|
1584 |
+
In questo andare e tornare, oscillando tra i mon-
|
1585 |
+
di, la prova si manifesta in tutta la sua difficoltà.
|
1586 |
+
Con chi misurarsi?
|
1587 |
+
Rispettosamente.
|
1588 |
+
NONA RISPOSTA
|
1589 |
+
Caro studioso,
|
1590 |
+
recentemente ho meditato a lungo sulle tue let-
|
1591 |
+
tere e da queste ho acquisito una conoscenza più
|
1592 |
+
profonda delle tue attitudini, delle tue tendenze e
|
1593 |
+
dei tuoi segni.
|
1594 |
+
Per me i tuoi segni sono divini, anche se con
|
1595 |
+
situazioni di pura materia.
|
1596 |
+
L'assoluto non è mai limitato, perché la sua
|
1597 |
+
bontà è infinita, ma la materia è l'opposto, perché
|
1598 |
+
la materia è nascosta solo nel divino, e perciò la
|
1599 |
+
tua Opera deve essere del divino, nel divino, fuo-
|
1600 |
+
ri dal divino e per il divino, proporzionalmente
|
1601 |
+
sdoppiata con le opere mondane.
|
1602 |
+
Del primo polo, del cammino divino, devi
|
1603 |
+
ascoltare la voce con il velo delle sue descrizioni e
|
1604 |
+
dei suoi tratti, nel vero dal vero, una volta che tu
|
1605 |
+
abbia meritato ascolto e conoscenza. Ma colui che
|
1606 |
+
ha il sé ossessionato e il cui intimo è sopraffatto
|
1607 |
+
dalla voce del sé non può udire nulla.
|
1608 |
+
Udito e ispirazione richiedono una struttura di
|
1609 |
+
esistenza che è data al conoscitore in una situazio-
|
1610 |
+
ne di sobrietà, mentre il cuore realizza il vero per
|
1611 |
+
mezzo dell'esaltazione.
|
1612 |
+
Tu devi possedere la vista, cioè la penetrazione,
|
1613 |
+
che è stordimento che mescola vista e udito, e devi
|
1614 |
+
mantenere sobrietà, non mescolando vista e udito,
|
1615 |
+
controllando il tuo stato e la tua situazione. Allora
|
1616 |
+
capirai attraverso la tua stessa esistenza, e posse-
|
1617 |
+
derai completa prontezza per acquisire quella rea-
|
1618 |
+
lizzazione che è fonte di ispirazione.
|
1619 |
+
Questo è l'ascolto del cuore, cui tutto si sotto-
|
1620 |
+
mette in silenzio.
|
1621 |
+
L'assenza di visione è la patria del ricordo.
|
1622 |
+
Quando ti manca la visione, e sei assente, chiama
|
1623 |
+
e invoca e supplica Dio, ma non chiedere di lui.
|
1624 |
+
Perché se tu chiedi di lui a uno che è assente,
|
1625 |
+
non ti guiderà a Dio. e se tu chiedi a uno che vede,
|
1626 |
+
non ti informerà.
|
1627 |
+
La pace sia con te.
|
1628 |
+
Il Profeta visita Jàbir.
|
1629 |
+
DECIMA LETTERA
|
1630 |
+
Caro Maestro,
|
1631 |
+
L'ascolto è incostante, la visione va e viene
|
1632 |
+
come un pendolo oscillante. Sperimentando il
|
1633 |
+
profondo si scopre che ad ogni passaggio da un'o-
|
1634 |
+
pera all'altra l'esoterico di una è essoterico per la
|
1635 |
+
successiva, e l'esoterico di questa è essoterico per
|
1636 |
+
la più elevata.
|
1637 |
+
Fatto esterno l'interno, alto il basso, interno l'e-
|
1638 |
+
sterno, basso l'alto, fisso il volatile, volatile il fisso,
|
1639 |
+
nella successione dei mondi sta un susseguirsi di
|
1640 |
+
realtà che non si appartengono, eppure sono un'u-
|
1641 |
+
nica visione che penetra in modo diverso le mate-
|
1642 |
+
rie e gli spiriti.
|
1643 |
+
Vanno fissate. Si devono bloccare i fuggevoli
|
1644 |
+
enti che spingono per tornare all'oriente, con un
|
1645 |
+
mercurio d'occidente che li fermi per sempre.
|
1646 |
+
Il vaso è quasi pronto, ma instabile, oscilla
|
1647 |
+
anch'esso tra un cosmo e l'altro, apparendo e
|
1648 |
+
scomparendo dietro un fumo ingannevole che a
|
1649 |
+
volte dirada, a volte ispessisce, senza che si possa
|
1650 |
+
mai prevedere la forma o il colore.
|
1651 |
+
Tutto è in movimento, ruota intorno al centro
|
1652 |
+
che volteggia senza un momento di quiete, e que-
|
1653 |
+
sto agitarsi che va catturato è come la danza irre-
|
1654 |
+
sistibile dei mondi universali, il roteare delle sfere
|
1655 |
+
eccentriche, dove il centro racchiude la periferia,
|
1656 |
+
l'interno è più elevato del punto più esterno, il
|
1657 |
+
punto minuscolo pesa più di tutto l'insieme.
|
1658 |
+
Ormai la luce pervade tutto il cosmo, il baglio-
|
1659 |
+
re non acceca, pare piuttosto un'oscurità lumino-
|
1660 |
+
sa pervasa di stelle sanguigne.
|
1661 |
+
Ricordo passi di un antichissimo testo:
|
1662 |
+
A lungo era durato l'intervallo di inattività e di cela-
|
1663 |
+
mento e la materia continuava ad essere sterile. Dio sor-
|
1664 |
+
rise e disse "Che la Natura sia!" e un oggetto femmini-
|
1665 |
+
le di totale bellezza sgorgò dalla sua voce, e Dio la
|
1666 |
+
chiamò Natura e le ordinò di essere feconda.
|
1667 |
+
Avendo preso dal proprio soffio quanto bastava e aven-
|
1668 |
+
dolo unito intelligentemente al fuoco, lo rimestò con
|
1669 |
+
certe sostanze sconosciute. Poi dopo aver unificato il
|
1670 |
+
tutto, ogni elemento con ogni altro, accompagnando
|
1671 |
+
con certi incanti segreti, agitò fortemente tutta la mistu-
|
1672 |
+
ra, sinché ribollì alla superficie della miscela una specie
|
1673 |
+
di materia più sottile, più pura e più trasparente degli
|
1674 |
+
ingredienti di cui era fatta: questa era traslucida e solo
|
1675 |
+
l'operatore la vedeva. Ed essa non si fondeva al calore,
|
1676 |
+
perché era estratta dal fuoco, e non si raffreddava, per-
|
1677 |
+
ché era estratta dal soffio.
|
1678 |
+
Da questa crosta Dio fece nascere miriadi di anime.
|
1679 |
+
E le cose in basso emisero gemiti, prese da timore per
|
1680 |
+
la meravigliosa bellezza e l'eterna permanenza delle
|
1681 |
+
cose in alto.
|
1682 |
+
Vedo la causa di tutto ciò, il suo eterno ritorno,
|
1683 |
+
la legge che lo governa, la mancanza di fine.
|
1684 |
+
Vedo la Bilancia e l'oscillazione continua alla
|
1685 |
+
ricerca del punto di impossibile equilibrio.
|
1686 |
+
Come fermare tutto ciò?
|
1687 |
+
Rispettosamente.
|
1688 |
+
DECIMA RISPOSTA
|
1689 |
+
Caro studioso,
|
1690 |
+
il cuore è sempre in ascolto, il sé è sempre atten-
|
1691 |
+
to e non riposa mai: qualsiasi cosa chiuda le porte
|
1692 |
+
dell'ascolto del cuore proviene dall'attenzione del
|
1693 |
+
sé, mentre i piaceri si librano costantemente intor-
|
1694 |
+
no al cuore degli uomini per impedire la visione
|
1695 |
+
dei regni celestiali.
|
1696 |
+
L'intuizione di coloro che intuiscono, le cono-
|
1697 |
+
scenze di coloro che conoscono, le luci degli scien-
|
1698 |
+
ziati devoti, le vie degli antichi vincitori, il conti-
|
1699 |
+
nuo inizio e l'eternità, e tutti gli eventi che vi sono
|
1700 |
+
compresi, sono per colui che è un ascoltatore del
|
1701 |
+
cuore.
|
1702 |
+
Egli mi sostenne nella sua realtà, ed io vidi gli
|
1703 |
+
scintillìi come tenebra, e l'acqua come una roccia
|
1704 |
+
pietrosa. Ed egli mi disse:
|
1705 |
+
Colui che non vede questo non è circondato dal-
|
1706 |
+
la mia realtà, ma colui che vede questo, è stato cir-
|
1707 |
+
condato dalla mia realtà. Chi è circondato dalla mia
|
1708 |
+
realtà e si rivolge ad altri che me, è infedele.
|
1709 |
+
Ogni limitazione è un velo, dietro al quale io non
|
1710 |
+
appaio, e non c'è nulla nella visione della mia real-
|
1711 |
+
tà, a parte la visione di esso.
|
1712 |
+
Ed io vidi ciò che non cambia mai, ed egli mi
|
1713 |
+
dette una condizione mutevole, ed io vidi tutto ciò
|
1714 |
+
che non fu mai creato. Ed egli mi disse:
|
1715 |
+
Non fare eccezioni. Ciò che è creato non persiste.
|
1716 |
+
E la visione si divise in due parti, oculare e men-
|
1717 |
+
tale: tutto l'insieme non si muoveva né si esprime-
|
1718 |
+
va. Ed egli mi disse:
|
1719 |
+
ntU- .Vitellàio f
|
1720 |
+
•
|
1721 |
+
»
|
1722 |
+
"
|
1723 |
+
•
|
1724 |
+
•
|
1725 |
+
f
|
1726 |
+
j
|
1727 |
+
f
|
1728 |
+
c fyf* &itm»> fnir
|
1729 |
+
& <
|
1730 |
+
a
|
1731 |
+
> wittwl'wivii» tept3o>p<((<tirt%rótc
|
1732 |
+
Il drago ermetico ucciso e fatto a pezzi.
|
1733 |
+
Come lo vedevi prima della visione della mia
|
1734 |
+
realtà?
|
1735 |
+
Dissi: "Si muoveva ed esprimeva". Ed egli:
|
1736 |
+
Sappi la differenza, che tu non possa perderti.
|
1737 |
+
E mi distolse dalla sua realtà, e non vidi più nul-
|
1738 |
+
la. Ed egli:
|
1739 |
+
Tu vedi tutto e tutto ti obbedisce, e la tua visio-
|
1740 |
+
ne di tutto è una prova, e l'obbedienza di tutte le
|
1741 |
+
cose a te è una prova.
|
1742 |
+
E mi distolse da tutto ciò. E mi disse:
|
1743 |
+
Io non guardo tutto ciò. Perché non è adatto
|
1744 |
+
per me.
|
1745 |
+
La pace sia con te.
|
1746 |
+
UNDICESIMA LETTERA
|
1747 |
+
Caro Maestro,
|
1748 |
+
le fatiche di Ercole sono concluse, è giunto il
|
1749 |
+
momento del piccolo riposo, in attesa di quello
|
1750 |
+
grande e definitivo.
|
1751 |
+
La certezza che l'esilio è prossimo al termine, in
|
1752 |
+
un modo o nell'altro, ha quietato ogni affanno,
|
1753 |
+
anche se resta la speranza del Dono, qui ed ora.
|
1754 |
+
Aspetto la Settimana delle Settimane, come la
|
1755 |
+
chiamavano gli antichi maestri latini, quando i
|
1756 |
+
giorni della Creazione scorreranno nel nero a pro-
|
1757 |
+
durre colori angelici.
|
1758 |
+
Ho trovato una splendida preghiera, attribuita
|
1759 |
+
tradizionalmente a un grande maestro francese del
|
1760 |
+
tardo medioevo. Non credo che la conosciate, e ve
|
1761 |
+
la voglio proporre:
|
1762 |
+
Dio onnipotente in eterno, padre del lume celeste, da
|
1763 |
+
cui inoltre provengono tutti i doni buoni e perfetti:
|
1764 |
+
Preghiamo la tua infinita misericordia perché tu ci per-
|
1765 |
+
metta di conoscere rettamente la tua eterna Sapienza,
|
1766 |
+
che sta immediatamente prossima al tuo Trono, e per
|
1767 |
+
mezzo della quale tutto è stato creato e fatto, ed anche
|
1768 |
+
ora è retto e conservato.
|
1769 |
+
Inviala a noi dal tuo Santo Cielo e dal Trono della tua
|
1770 |
+
Gloria, affinché stia e lavori insieme a noi, perché essa
|
1771 |
+
è maestra di tutte le arti celesti ed occulte, ed inoltre sa
|
1772 |
+
e comprende tutto.
|
1773 |
+
Fa' che ci accompagni con misura in tutte le nostre ope-
|
1774 |
+
re, affinché per mezzo del suo spirito noi si apprenda,
|
1775 |
+
con certezza e senza alcun errore, il vero significato ed
|
1776 |
+
il processo infallibile di questa Nobilissima Arte, cioè la
|
1777 |
+
Pietra miracolosa dei Sapienti, che hai nascosto al mon-
|
1778 |
+
do, e sei solito rivelare almeno ai tuoi eletti, cosicché
|
1779 |
+
innanzitutto incominciamo rettamente e bene la somma
|
1780 |
+
opera che qui dobbiamo compiere, progrediamo con
|
1781 |
+
costanza in essa e nella sua fatica, e infine la completia-
|
1782 |
+
mo beatamente e ne fruiamo in eterno con gaudio, per
|
1783 |
+
mezzo di quella Pietra Angolare e miracolosa, celeste
|
1784 |
+
e fondata dall'eternità, Gesù Cristo, che con te, Dio
|
1785 |
+
Padre, insieme allo Spirito Santo, vero Dio, in una in-
|
1786 |
+
dissolubile divina essenza, impera e regna, triunico Dio,
|
1787 |
+
sommamente lodato nei secoli sempiterni.
|
1788 |
+
Così sia.
|
1789 |
+
Vi ho meditato a lungo, mentre riflettevo su
|
1790 |
+
questi anni di lavoro e di studio, sulle mie incom-
|
1791 |
+
prensioni, sui vostri insegnamenti, su quello che
|
1792 |
+
potrei dire a chi si inoltrasse su questa via.
|
1793 |
+
C'è un avverbio curioso nel latino originale,
|
1794 |
+
moderate, che ho tradotto: con misura. Mi sembra
|
1795 |
+
un atteggiamento di quieta prudenza, tanto diver-
|
1796 |
+
so da quello con cui ho incominciato. Forse que-
|
1797 |
+
sto si potrebbe insegnare all'inizio: la necessità di
|
1798 |
+
non avere fretta, di non essere avidi, nemmeno di
|
1799 |
+
conoscenza, nemmeno di amore. Ogni cosa ha il
|
1800 |
+
suo tempo, e il Tempo vero non passa, arriva.
|
1801 |
+
In realtà siamo così lenti, che una sola vita non
|
1802 |
+
basta per chiudere il cerchio delle transmutazioni
|
1803 |
+
necessarie al compimento dell'Opera. Quando ini-
|
1804 |
+
ziamo il cammino passeggiamo sulle nostre stesse
|
1805 |
+
orme, ripercorriamo sentieri già visti, talvolta ripe-
|
1806 |
+
tiamo gli stessi errori, da cui è tanto difficile libe-
|
1807 |
+
rarsi.
|
1808 |
+
Mitezza, e specialmente pazienza, sono prere-
|
1809 |
+
quisiti indispensabili. Specialmente pazienza. Per
|
1810 |
+
un paradossale gioco della legge ineluttabile che ci
|
1811 |
+
sfugge, eppure regge ogni cosa, tutto viene dato a
|
1812 |
+
chi ha già: la Pace è data ai pacifici, agli altri sarà
|
1813 |
+
tolto anche quel poco che ne possiedono.
|
1814 |
+
Continuo a scoprire l'infinita ricchezza della
|
1815 |
+
semplicità: la verità è semplice, come la natura, si è
|
1816 |
+
detto, aggiungendo: e non bisogna dirla che alle
|
1817 |
+
persone per bene.
|
1818 |
+
Vago tranquillo, lasciandomi trasportare da
|
1819 |
+
questi pensieri, nella mia pacifica attesa, senza
|
1820 |
+
ansia, scrutando il Velo e sperando che si squarci
|
1821 |
+
senza dolore. Talvolta mi faccio accarezzare dai
|
1822 |
+
versi di un poeta alchimista cinese di tanti, tanti
|
1823 |
+
secoli fa:
|
1824 |
+
Se tu mi chiedessi, con aria quasi di scherno,
|
1825 |
+
perché vivo nascosto fra i verdi monti,
|
1826 |
+
io ne sorriderei piano piano,
|
1827 |
+
l'anima mia è serena, caro amico,
|
1828 |
+
i fiori di pesco seguono l'acqua che scorre,
|
1829 |
+
vi è un altro cielo e un'altra terra
|
1830 |
+
al di là del mondo degli uomini.
|
1831 |
+
Rispettosamente.
|
1832 |
+
UNDICESIMA RISPOSTA
|
1833 |
+
Caro studioso,
|
1834 |
+
cerca la rettitudine, e non un miracolo perché il
|
1835 |
+
tuo Dio chiede rettitudine e il tuo sé chiede un
|
1836 |
+
miracolo, che è un segreto di cui molti non sono
|
1837 |
+
mai stati memori.
|
1838 |
+
Si può accusare la propria fede quando non si
|
1839 |
+
vedono miracoli, perché la saggezza non serve,
|
1840 |
+
non rivela potenza in caso di rettitudine, e non dà
|
1841 |
+
il piacere di un miracolo.
|
1842 |
+
Sono stato in semitotale isolamento, studiando
|
1843 |
+
fotocopie di antichi manoscritti dei nostri Imam.
|
1844 |
+
Ora partirò per Al-Najaf Al-Ashraf in Iraq per
|
1845 |
+
incontrare alcuni studiosi e per vedere alcuni
|
1846 |
+
manoscritti di comune interesse sulla disciplina
|
1847 |
+
mistica.
|
1848 |
+
Sarà un viaggio di due anni.
|
1849 |
+
La pace sia con te.
|
1850 |
+
Manoscritto alchemico arabo.
|
1851 |
+
b l ^ s l i p p i r a
|
1852 |
+
ì
|
1853 |
+
k
|
1854 |
+
I
|
1855 |
+
A
|
1856 |
+
'
|
1857 |
+
>• ì
|
1858 |
+
A
|
1859 |
+
il Li è è ;
|
1860 |
+
L I
|
1861 |
+
POSTFAZIONE
|
1862 |
+
Il piccolo epistolario si chiudeva così, bruscamen-
|
1863 |
+
te. In fondo, ho ancora trovato un foglio di appun-
|
1864 |
+
ti. Conteneva alcune brevi frasi e un disegno, li
|
1865 |
+
riporto qui senza cercarne spiegazione.
|
1866 |
+
Del misterioso filosofo alchimista non si è avuta
|
1867 |
+
più traccia. La villa è stata venduta, il contenuto
|
1868 |
+
disperso.
|
1869 |
+
In paese è rimasto comunque il ricordo del curio-
|
1870 |
+
so personaggio, ne è nata qualche leggenda. Corre
|
1871 |
+
voce che si sia visto qualche volta vagare per il paese,
|
1872 |
+
a tarda sera, un uomo che gli somiglia, anche se di età
|
1873 |
+
decisamente più giovane. Scende da una grossa mac-
|
1874 |
+
china nera, cammina assorto per le vecchie stradine
|
1875 |
+
che si affacciano a un laghetto, resta fermo a fissarne
|
1876 |
+
le acque, poi riparte evitando qualunque incontro.
|
1877 |
+
Le frasi del foglio, scritte frettolosamente,
|
1878 |
+
dice-
|
1879 |
+
vano.
|
1880 |
+
Una sola cosa, una sola via, un solo vaso, una sola
|
1881 |
+
disposizione.
|
1882 |
+
Chi saprà fare l'Opera col solo Mercurio, quello avrà
|
1883 |
+
trovato la via regia.
|
1884 |
+
.Dio ti dia grassezza di terra e rugiada dal cielo.
|
1885 |
+
La pazienza è la scala dei filosofi, e l'umiltà la porta del
|
1886 |
+
loro giardino, perché a chiunque persevererà senza
|
1887 |
+
invidia e senza orgoglio, Dio farà misericordia.
|
1888 |
+
Il disegno, con un piccolo cartiglio, chiudeva la
|
1889 |
+
pagina, come chiude questo libretto affidato al de-
|
1890 |
+
stino.
|
1891 |
+
|
static/data/montecristo.txt
ADDED
The diff for this file is too large to render.
See raw diff
|
|
static/data/roberto_busa.txt
ADDED
@@ -0,0 +1,951 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
IL NOSTROMO
|
2 |
+
emmeciquadro
|
3 |
+
123
|
4 |
+
dicembre 2001
|
5 |
+
123
|
6 |
+
IL COMPUTER USATO BENE
|
7 |
+
INTERVISTA A ROBERTO BUSA S.J.*
|
8 |
+
a cura di Maria Cristina Speciani e Vittorio Sacchi
|
9 |
+
Una vita lunga e feconda quella di padre Busa, il gesuita
|
10 |
+
ottantottenne che è riconosciuto come il pioniere della
|
11 |
+
linguistica computazionale. Usando il computer come
|
12 |
+
nessuno aveva mai fatto prima, con pazienza, coraggio e
|
13 |
+
ostinazione, ha approfondito il suo rapporto con l’infini-
|
14 |
+
to riscoprendo sul fondo «la luce di Dio che illumina
|
15 |
+
ogni uomo e lo chiama». Oggi la sua avventura continua
|
16 |
+
prospettando nuove analisi dei fatti e nuove metodologie
|
17 |
+
di ricerca per ottenere dalla tecnologia del computer
|
18 |
+
tutte le sue potenzialità e metterle al servizio dell’uomo.
|
19 |
+
Sono passati più di cin-
|
20 |
+
quant’anni da quando incontrò
|
21 |
+
Thomas Watson, il fondatore
|
22 |
+
dell’IBM, convincendolo a rac-
|
23 |
+
cogliere la sfida dell’analisi
|
24 |
+
computerizzata del linguaggio
|
25 |
+
di san Tommaso. Nello svilup-
|
26 |
+
po del suo lavoro ha attraver-
|
27 |
+
sato i principali nodi della rivo-
|
28 |
+
luzione informatica. In partico-
|
29 |
+
lare, come ha vissuto, a partire
|
30 |
+
dal desiderio iniziale, il rappor-
|
31 |
+
to tra ricerca e tecnologia?
|
32 |
+
È meglio che racconti un po’ di
|
33 |
+
storia. Il mio sogno, quando sono
|
34 |
+
diventato gesuita era di andare in
|
35 |
+
missione, invece i superiori mi
|
36 |
+
hanno chiesto di fare il professo-
|
37 |
+
re di filosofia scolastica con spe-
|
38 |
+
cializzazione in san Tommaso.
|
39 |
+
Durante la guerra, dopo aver
|
40 |
+
fatto il cappellano per un anno,
|
41 |
+
mi hanno mandato a fare la libe-
|
42 |
+
ra docenza alla Gregoriana e poi
|
43 |
+
il Ph.D. Vi racconto la storiella
|
44 |
+
della recluta che, ricevuto l’ordine
|
45 |
+
«avanti marsc», non si ferma in
|
46 |
+
attesa del contrordine; il sergente
|
47 |
+
si dimentica di lui e due giorni
|
48 |
+
dopo quello da Padova ha rag-
|
49 |
+
giunto Chioggia e «segna il
|
50 |
+
passo» davanti al mare in attesa
|
51 |
+
di nuovi ordini. Io son quello: mi è
|
52 |
+
stato dato l’ordine di studiare san
|
53 |
+
Tommaso, son partito, mi sono
|
54 |
+
rimboccato le maniche e non ho
|
55 |
+
più abbandonato la filosofia.
|
56 |
+
Anche se oggi troppa filosofia è
|
57 |
+
una passerella di estetismi verba-
|
58 |
+
li e non la ricerca della Verità.
|
59 |
+
Mi venne l’idea di cercare nei
|
60 |
+
testi di san Tommaso la docu-
|
61 |
+
mentazione originaria e probato-
|
62 |
+
ria delle affermazioni che chia-
|
63 |
+
miamo filosofiche; così è nato il
|
64 |
+
progetto dell’Index Thomisticus.
|
65 |
+
Il linguaggio mi ha messo a con-
|
66 |
+
tar parole e mi sono reso conto
|
67 |
+
che il nostro parlare, alle sue
|
68 |
+
radici, non lo conosciamo anco-
|
69 |
+
ra. Ho usato il computer come
|
70 |
+
*Nato a Vicenza nel 1913,
|
71 |
+
è tuttora in piena attività. Ha
|
72 |
+
insegnato alla Pontificia
|
73 |
+
Università Gregoriana, al-
|
74 |
+
l’Aloisianum di Gallarate e
|
75 |
+
all’Università Cattolica di
|
76 |
+
Milano. Dal 1995 al 2000
|
77 |
+
ha insegnato al Politecnico
|
78 |
+
di Milano nell’ambito dei
|
79 |
+
corsi di Intelligenza Arti-
|
80 |
+
ficiale e robotica tenuti da
|
81 |
+
Marco Somalvico. «1261
|
82 |
+
momenti di pensiero distilla-
|
83 |
+
ti» da questo corso sono
|
84 |
+
stati pubblicati nel 2000 da
|
85 |
+
ITACAlibri in Dal computer
|
86 |
+
agli angeli.
|
87 |
+
Autore di numerosissimi
|
88 |
+
saggi. La sua opera fonda-
|
89 |
+
mentale, l’Index Thomisti-
|
90 |
+
cus, pubblicato tra il 1974 e
|
91 |
+
il 1980 in 56 volumi e oggi
|
92 |
+
disponibile anche su cd-
|
93 |
+
rom, è il risultato della ela-
|
94 |
+
borazione computazionale
|
95 |
+
dei testi di san Tommaso e
|
96 |
+
ha costituito la base di qual-
|
97 |
+
siasi ulteriore ricerca di
|
98 |
+
informatica linguistica.
|
99 |
+
IL NOSTROMO
|
100 |
+
dicembre 2001 124
|
101 |
+
emmeciquadro
|
102 |
+
strumento che permette di
|
103 |
+
andare più in profondità median-
|
104 |
+
te l’osservazione statistica e pro-
|
105 |
+
babilistica. E mi sono accorto
|
106 |
+
che le parole non hanno confini
|
107 |
+
precisi: sul fondo c’era la luce di
|
108 |
+
Dio che illumina ogni uomo e lo
|
109 |
+
chiama.
|
110 |
+
Oggi molti pensano che con il
|
111 |
+
computer si possano risolvere
|
112 |
+
tutti i problemi. A suo parere,
|
113 |
+
quali sono le potenzialità del-
|
114 |
+
l’informatica dal punto di vista
|
115 |
+
didattico ed educativo?
|
116 |
+
Gli aspetti educativi dell’informa-
|
117 |
+
tica linguistica sono legati alla
|
118 |
+
possibilità di rendersi conto che
|
119 |
+
c’è un «pensiero», una «espres-
|
120 |
+
sione esteriore» e una «espres-
|
121 |
+
sione interiore».
|
122 |
+
La mia impressione è che oggi
|
123 |
+
troppa didattica è basata sulla
|
124 |
+
memorizzazione: si concepisce il
|
125 |
+
nucleo del pensiero umano
|
126 |
+
come una banca di dati e allora
|
127 |
+
l’obiettivo dell’apprendimento
|
128 |
+
diventa sapere tutto.
|
129 |
+
Invece, i principi sono questi: le
|
130 |
+
strutture dell’espressione scritta
|
131 |
+
riflettono il fatto che c’è un pen-
|
132 |
+
siero originario il quale può
|
133 |
+
dominare la moltitudine delle
|
134 |
+
cose perché le classifica, le riuni-
|
135 |
+
sce e le esprime con le parole.
|
136 |
+
C’è un pensiero la cui caratteri-
|
137 |
+
stica è di non reagire soltanto
|
138 |
+
allo stimolo che c’è, ma anche e
|
139 |
+
soprattutto agli stimoli che non ci
|
140 |
+
sono ancora o non ci sono più.
|
141 |
+
Per esempio: se si iscrive un
|
142 |
+
bambino a scuola è perché si
|
143 |
+
pensa che tra dieci anni, che
|
144 |
+
non ci sono oggi, questo bambi-
|
145 |
+
no avrà bisogno di avere un
|
146 |
+
lavoro. E i nostri desideri punta-
|
147 |
+
no sempre su quello che non
|
148 |
+
c’è, su quello che non si ha (l’uo-
|
149 |
+
mo è l’unico animale che ha
|
150 |
+
inventato le distillerie!). In questo
|
151 |
+
senso, il linguaggio, soprattutto il
|
152 |
+
linguaggio scritto, non è una
|
153 |
+
ripetizione continua, ma la crea-
|
154 |
+
zione di architetture sempre
|
155 |
+
nuove.
|
156 |
+
L’espressione esteriore è quella
|
157 |
+
che noi chiamiamo realtà virtua-
|
158 |
+
le: un’immagine non nel senso
|
159 |
+
stretto della parola, iconico, ma
|
160 |
+
immagine come segno e simbo-
|
161 |
+
lo i quali vengono fatti sussistere
|
162 |
+
in un altro soggetto che non è
|
163 |
+
l’uomo che le pronuncia. Per
|
164 |
+
esempio, la musica della marcia
|
165 |
+
trionfale dell’Aida, creata dalla
|
166 |
+
mente di Verdi, esiste per conto
|
167 |
+
suo, ma sussiste oggi in un’or-
|
168 |
+
chestra, domani in un’altra.
|
169 |
+
C’è anche una espressione inte-
|
170 |
+
riore: vuol dire che le frasi che si
|
171 |
+
pronunciano sono costruite
|
172 |
+
prima dentro di noi e poi «buttate
|
173 |
+
fuori» mediante la voce. Ma
|
174 |
+
come si costruisce l’espressione
|
175 |
+
dentro di noi è ancora terra sco-
|
176 |
+
nosciuta.
|
177 |
+
Può fare un esempio?
|
178 |
+
Lo spiego con questa storia.
|
179 |
+
All’inizio degli anni Cinquanta,
|
180 |
+
alcuni anni dopo che avevo
|
181 |
+
cominciato, è nata la traduzione
|
182 |
+
automatica (al MIT si pubblicava
|
183 |
+
allora lo MT
|
184 |
+
Mechanical
|
185 |
+
Translation). Il Penta-gono
|
186 |
+
aveva finanziato tutti i centri che
|
187 |
+
si offrivano di lavorare sulla tra-
|
188 |
+
duzione dal russo all’inglese e io
|
189 |
+
avevo collegato il gruppo di
|
190 |
+
Leon Dostert e Peter Toma di
|
191 |
+
«Agli inizi l’obiettivo primo
|
192 |
+
erano 12 milioni di schede
|
193 |
+
perforate con stampato sul
|
194 |
+
dorso un contesto di 11
|
195 |
+
righe. Ne sarebbe risultato
|
196 |
+
uno schedario unico di 90
|
197 |
+
metri di fronte, 1,20 di altez-
|
198 |
+
za e 1 di profondità: peso
|
199 |
+
complessivo 500 tonnellate.
|
200 |
+
Dopo che ne ebbi perforato
|
201 |
+
sei milioni, la misericordia
|
202 |
+
del Signore ha fatto inven-
|
203 |
+
tare agli uomini i nastri
|
204 |
+
magnetici. [...] Ebbi da allo-
|
205 |
+
ra in lavorazione un parco
|
206 |
+
di 1800 nastri magnetici, di
|
207 |
+
2400 piedi cioè 800 metri
|
208 |
+
ciascuno: erano circa 1500
|
209 |
+
kilometri di nastro, presso a
|
210 |
+
poco la distanza tra Milano
|
211 |
+
e Palermo o tra Parigi e
|
212 |
+
Lisbona. [...] Per cui la
|
213 |
+
prima epoca fu quella delle
|
214 |
+
500 tonnellate di schede, la
|
215 |
+
seconda fu quella dei 1800
|
216 |
+
nastri magnetici. Terza
|
217 |
+
epoca è ora quella di 1 solo
|
218 |
+
cd-rom.»
|
219 |
+
(Dal computer agli angeli,
|
220 |
+
pp. 25-26)
|
221 |
+
IL NOSTROMO
|
222 |
+
emmeciquadro
|
223 |
+
125
|
224 |
+
dicembre 2001
|
225 |
+
Georgetown, università dei miei
|
226 |
+
confratelli di Washington DC con
|
227 |
+
l’Euratom di Ispra per tradurre
|
228 |
+
abstract di biochimica e biofisica
|
229 |
+
russi: per questo abbiamo perfo-
|
230 |
+
rato un milione di parole in cirilli-
|
231 |
+
co. Anche il progetto su san
|
232 |
+
Tommaso, a cui lavoravo sui
|
233 |
+
computer dell’Euratom, era lega-
|
234 |
+
to a questa iniziativa. Alla metà
|
235 |
+
degli anni Sessanta, a seguito
|
236 |
+
del famoso rapporto ALPAC, il
|
237 |
+
Pentagono improvvisamente
|
238 |
+
sospese i finanziamenti procla-
|
239 |
+
mando l’insuccesso della tradu-
|
240 |
+
zione automatica; tale insucces-
|
241 |
+
so era dovuto non a mancanza
|
242 |
+
di velocità o di memoria dei com-
|
243 |
+
puter, ma alla mancanza di infor-
|
244 |
+
mazioni filologiche sul nostro par-
|
245 |
+
lare, delle quali il computer ha
|
246 |
+
bisogno.
|
247 |
+
La «vecchia» filologia è basata
|
248 |
+
solo sulla campionatura, sulla
|
249 |
+
massa dei grandi numeri e delle
|
250 |
+
parole che noi cerchiamo; questo
|
251 |
+
non è sufficiente per il computer
|
252 |
+
che ha bisogno di avere dati in
|
253 |
+
percentuale molto approssimati e
|
254 |
+
formalizzati, cioè traducibili in
|
255 |
+
byte. Per far questo è necessario
|
256 |
+
che sia chiaro in base a quali
|
257 |
+
logiche si parla, logiche che si
|
258 |
+
manifestano con la morfologia,
|
259 |
+
con la sintassi e con il lessico.
|
260 |
+
Dal computer, dal mostro d’ac-
|
261 |
+
caio, dalla tecnologia usata per
|
262 |
+
l’industria dell’informazione viene
|
263 |
+
la richiesta che si conosca
|
264 |
+
meglio in base a quali elementi e
|
265 |
+
a quali logiche si parla. Se l’uma-
|
266 |
+
nesimo è la scienza dell’espres-
|
267 |
+
sione umana in tutte le sue mani-
|
268 |
+
festazioni, allora il computer
|
269 |
+
esige che noi uomini abbiamo un
|
270 |
+
umanesimo più spinto.
|
271 |
+
Dunque il computer chiede
|
272 |
+
all’uomo di conoscere meglio
|
273 |
+
se stesso. Allora quali posso-
|
274 |
+
no essere i vantaggi nell’impa-
|
275 |
+
rare attraverso lo strumento
|
276 |
+
informatico piuttosto che con
|
277 |
+
un altro supporto?
|
278 |
+
Studiare con il computer, in
|
279 |
+
realtà è comunicare: dal mio
|
280 |
+
osservatorio comunico dei bit di
|
281 |
+
informazione agli altri. Quando si
|
282 |
+
tratta di studiare occorre introdur-
|
283 |
+
re due elementi: raccogliere dati
|
284 |
+
di fatto, il maggior numero possi-
|
285 |
+
bile, dalla realtà, mediante l’os-
|
286 |
+
servazione; poi questi dati vanno
|
287 |
+
sintetizzati. Questa elaborazione
|
288 |
+
è il lavoro specifico del pensiero,
|
289 |
+
ma per sintetizzare bisogna
|
290 |
+
prima di tutto classificare.
|
291 |
+
In questo senso io ho fatto due
|
292 |
+
ricerche originali, che non ho tro-
|
293 |
+
vato in nessuna parte: la prima è
|
294 |
+
sulla eterogeneità delle parole e
|
295 |
+
la seconda sui segni grafici delle
|
296 |
+
parole.
|
297 |
+
La ricerca sull’eterogeneità
|
298 |
+
delle parole in sanTommaso
|
299 |
+
durò ben otto anni, dal 1983 al
|
300 |
+
1991. Quali furono i criteri del
|
301 |
+
lavoro? E quali i risultati?
|
302 |
+
Si trattava di classificare le parole
|
303 |
+
secondo «tipi di semanticità»,
|
304 |
+
ossia secondo le diversità dei
|
305 |
+
rapporti tra segno e significato. E
|
306 |
+
richiese alcune migliaia di ore-
|
307 |
+
uomo e molta pazienza anche
|
308 |
+
solo per far emergere il criterio
|
309 |
+
per distinguere le categorie delle
|
310 |
+
parole. Perché i rapporti tra signi-
|
311 |
+
ficante e significato sono diver-
|
312 |
+
sissimi in relazione alla semanti-
|
313 |
+
cità delle parole.
|
314 |
+
IL NOSTROMO
|
315 |
+
dicembre 2001 126
|
316 |
+
emmeciquadro 126
|
317 |
+
Porto qualche esempio.
|
318 |
+
Ci sono i nomi deittici, come per
|
319 |
+
esempio i due pronomi personali
|
320 |
+
«io» e «tu». Essi hanno come
|
321 |
+
significante due lettere, rispetti-
|
322 |
+
vamente i-o e t-u, ma il significa-
|
323 |
+
to di queste parole è che sono
|
324 |
+
segni della conoscenza di una
|
325 |
+
presenza; non sono concetti,
|
326 |
+
perché un concetto prevede una
|
327 |
+
formula. Ma quando io dico «io»
|
328 |
+
la presenza è diversa da quando
|
329 |
+
un altro dice «io». Pensate,
|
330 |
+
anche il Signore, che pure ha
|
331 |
+
inventato padre Busa, non può
|
332 |
+
dire di essere padre Busa.
|
333 |
+
Un'altra categoria sono i nomi
|
334 |
+
propri; essi sono nomi etichetta e
|
335 |
+
indicano un oggetto preciso; non
|
336 |
+
esprimono che cosa sia, ma
|
337 |
+
anch’essi sono la conoscenza di
|
338 |
+
una singolarità. Per esempio,
|
339 |
+
sentendo qualcuno che chiama
|
340 |
+
Cicci si sa che c’è un Cicci ma
|
341 |
+
non si sa se sia un gatto, una
|
342 |
+
bambina o un ragazzo. Poi ven-
|
343 |
+
gono i nomi di oggetti (un tavolo,
|
344 |
+
un cavallo) che gli antichi chia-
|
345 |
+
mavano sostanza; sono il sog-
|
346 |
+
getto e il complemento oggetto di
|
347 |
+
quei verbi che significano attività
|
348 |
+
e produzione. Anche questi sono
|
349 |
+
nomi etichetta. Quando dico
|
350 |
+
tamarindo so che voglio dire una
|
351 |
+
certa pianta o una certa bibita,
|
352 |
+
anche se non dico niente delle
|
353 |
+
sue proprietà. Poi vengono final-
|
354 |
+
mente gli aspetti delle cose:
|
355 |
+
dimensioni, forme, temperatura,
|
356 |
+
peso, movimento eccetera, che
|
357 |
+
solitamente chiamiamo aggettivi.
|
358 |
+
Son quelli in cui sta tutta la cultu-
|
359 |
+
ra perché sono vere e proprie
|
360 |
+
immagini mentali, veri e propri
|
361 |
+
concetti. Poi vengono le parole
|
362 |
+
che esprimono relazioni e corre-
|
363 |
+
lazioni cominciando con le pre-
|
364 |
+
posizioni; infine ci sono parole
|
365 |
+
vicarie come i pronomi relativi e
|
366 |
+
simili.
|
367 |
+
Ho fatto il censimento di tutte
|
368 |
+
queste parole. Negli 11 milioni di
|
369 |
+
parole dell’Index Thomisticus
|
370 |
+
(siccome Dio l’ho messo tra i
|
371 |
+
nomi propri), con tutti gli altri
|
372 |
+
nomi propri arriviamo al 3%; gli
|
373 |
+
oggetti e le cose arrivano al 6-
|
374 |
+
8%; la maggior parte dei restanti
|
375 |
+
sono le parole di correlazione.
|
376 |
+
A questo proposito, mi ricordo
|
377 |
+
che in un congresso un gruppo
|
378 |
+
di scienziati sosteneva che metà
|
379 |
+
delle parole di san Tommaso
|
380 |
+
esprimessero le realtà religiose
|
381 |
+
invisibili. Invece il nome Cristo
|
382 |
+
non è un nome invisibile; è invisi-
|
383 |
+
bile come è invisibile Socrate. Le
|
384 |
+
realtà invisibili sono poche e
|
385 |
+
sono alla radice del cosmo: Dio,
|
386 |
+
gli angeli, i demoni e i nostri
|
387 |
+
morti. Ma invisibili sono anche le
|
388 |
+
forze di base della natura, dalle
|
389 |
+
forze cosmiche di base (l’elettri-
|
390 |
+
cità, la gravità, le onde hertziane)
|
391 |
+
ai loro programmatori che sono
|
392 |
+
gli angeli, i software del Signore
|
393 |
+
Dio loro creatore. Questo c’è in
|
394 |
+
san Tommaso, con altre parole
|
395 |
+
naturalmente.
|
396 |
+
Invece, come ha strutturato la
|
397 |
+
ricerca sui segni grafici?
|
398 |
+
Avevo 11 milioni di parole latine;
|
399 |
+
riepilogate secondo «forme» di
|
400 |
+
parola graficamente diverse
|
401 |
+
erano circa 150 000; poi avevo
|
402 |
+
«lemmatizzato» ciascuna di esse
|
403 |
+
trovando 20 000 lemmi. Il lemma
|
404 |
+
è quella parola che nei vocabola-
|
405 |
+
ri rappresenta tutte le proprie
|
406 |
+
flessioni secondo una certa unità
|
407 |
+
IL NOSTROMO
|
408 |
+
emmeciquadro
|
409 |
+
127
|
410 |
+
dicembre 2001
|
411 |
+
127
|
412 |
+
che io chiamo unità lessicale
|
413 |
+
che con le flessioni viene arric-
|
414 |
+
chita, ma non contraddetta (il
|
415 |
+
lemma è come il corpicino della
|
416 |
+
bambola Barbie e le flessioni
|
417 |
+
sono come gli abitini che le si
|
418 |
+
mettono intorno).
|
419 |
+
Ho preso tutti i lemmi, li ho divisi
|
420 |
+
in un massimo di tre segmenti
|
421 |
+
(iniziale, centrale e finale), in
|
422 |
+
qualche senso a caso, senza
|
423 |
+
badare al significato e meno
|
424 |
+
ancora alla glottologia, alle deri-
|
425 |
+
vazione o alle trasformazioni, ma
|
426 |
+
proprio graficamente. Una stessa
|
427 |
+
stringa di quattro caratteri si trova
|
428 |
+
ripetuta in tante parole all’inizio,
|
429 |
+
come iniziale assieme ad altre
|
430 |
+
stringhe diverse, ma anche in
|
431 |
+
posizione centrale o finale. Ho
|
432 |
+
fatto una classificazione e la mia
|
433 |
+
sorpresa è stata che 11 milioni di
|
434 |
+
parole sono la combinazione di
|
435 |
+
un massimo di 1 500 stringhe
|
436 |
+
diverse di caratteri. Solo 1 500.
|
437 |
+
Naturalmente ci sono le stesse
|
438 |
+
stringhe con significati diversi.
|
439 |
+
Nel suo libro Dal computer agli
|
440 |
+
angeli auspica che la statistica
|
441 |
+
linguistica tenga conto della
|
442 |
+
eterogeneità delle parole di un
|
443 |
+
testo e di quella che lei defini-
|
444 |
+
sce «doppia struttura del lessi-
|
445 |
+
co». Può spiegare il significato
|
446 |
+
di questa espressione?
|
447 |
+
Da sempre è risaputo che quan-
|
448 |
+
do si parla o si scrive ci sono
|
449 |
+
poche parole diverse, di solito
|
450 |
+
corte, moltissimo ripetute. Poi ci
|
451 |
+
sono tante parole, relativamente
|
452 |
+
poco ripetute, tra le quali tutte le
|
453 |
+
parole lunghe. Questo l’ho sem-
|
454 |
+
pre riscontrato e oggi li chiamo i
|
455 |
+
due emisferi del lessico.
|
456 |
+
Il primo lessico, quello delle paro-
|
457 |
+
le frequenti e brevi, le particelle
|
458 |
+
che a scuola venivano chiamate
|
459 |
+
grammaticali, oggi sono definite
|
460 |
+
dagli inglesi function words e
|
461 |
+
anche close class words perché
|
462 |
+
non aumentano. Esse sono con-
|
463 |
+
trapposte a quelle di contenuto,
|
464 |
+
chiamate content words e anche
|
465 |
+
open class words perché cam-
|
466 |
+
biano e crescono. Le prime sono
|
467 |
+
quelle che esprimono la logica
|
468 |
+
con cui ciascuno cerca di parla-
|
469 |
+
re. Le seconde sono quelle che
|
470 |
+
specificano la cultura, cioè i con-
|
471 |
+
tenuti che specificano il messag-
|
472 |
+
gio. I due emisferi sono questi:
|
473 |
+
la logica e la cultura. E tra le per-
|
474 |
+
sone non c’è differenza nella
|
475 |
+
logica di base, ma nella cultura.
|
476 |
+
Io non ho lavorato solo le parole
|
477 |
+
di san Tommaso, ma altrettanti
|
478 |
+
milioni di parole in altre 22 lingue
|
479 |
+
e alfabeti diversi: i rotoli di
|
480 |
+
Qumrân, che sono in alfabeto
|
481 |
+
ebraico ma in tre lingue (ebraico,
|
482 |
+
aramaico e nabateo), tutto il
|
483 |
+
Corano in arabo, il finnico, il cirilli-
|
484 |
+
co, il boemo e ovviamente tutte
|
485 |
+
le lingue europee e il greco; le
|
486 |
+
ultime sono state l’albanese e il
|
487 |
+
giorgiano e poi l’alfabeto foneti-
|
488 |
+
co. In tutte queste cose ci sono i
|
489 |
+
due emisferi del lessico.
|
490 |
+
Nell’oralità non ho fatto calcoli,
|
491 |
+
perché i media espressivi sono
|
492 |
+
tanti e perché nell’oralità il lin-
|
493 |
+
guaggio è ridotto al minimo. Per
|
494 |
+
esempio, se ordino una birra e
|
495 |
+
dico «cameriere me ne porti
|
496 |
+
un’altra», in questo caso «altra»
|
497 |
+
è la birra; invece, se avessi ordi-
|
498 |
+
nato una zuppa, «altra» avrebbe
|
499 |
+
un altro significato.
|
500 |
+
Invece il linguaggio educato è
|
501 |
+
quello scritto.
|
502 |
+
Pagine dei Rotoli di Qumrân
|
503 |
+
IL NOSTROMO
|
504 |
+
dicembre 2001 128
|
505 |
+
emmeciquadro
|
506 |
+
In questa direzione, la critica
|
507 |
+
di un libro si fa al suo interno.
|
508 |
+
Di fronte a un libro non biso-
|
509 |
+
gna mettersi con l’idea di con-
|
510 |
+
futarlo, ma vedere se quello
|
511 |
+
che dice è coerente con la
|
512 |
+
logica con cui lo dice.
|
513 |
+
Recentemente mi hanno chie-
|
514 |
+
sto perché lavorare su san
|
515 |
+
Tommaso e non su un testo
|
516 |
+
moderno. Trent’anni fa mi
|
517 |
+
hanno invitato a Mosca per
|
518 |
+
lavorare sui testi di Lenin con
|
519 |
+
lo stesso metodo. E ho prova-
|
520 |
+
to a farlo, nei ritagli di tempo,
|
521 |
+
anche sul libro di Jacques
|
522 |
+
Monod (Il caso e la necessità)
|
523 |
+
e poi su quello di Stephen
|
524 |
+
Hawking (Dal big bang ai
|
525 |
+
buchi neri) e in passato l’ave-
|
526 |
+
vo fatto con il behaveourista
|
527 |
+
Skinner. Si riesce a vedere il
|
528 |
+
momento in cui i testi di un
|
529 |
+
autore sono illogici: non per-
|
530 |
+
ché
|
531 |
+
contraddicono
|
532 |
+
san
|
533 |
+
Tommaso o san Bonaventura,
|
534 |
+
ma perché sono illogici in se
|
535 |
+
stessi.
|
536 |
+
Recentemente i giornali
|
537 |
+
hanno parlato di lei definen-
|
538 |
+
dola «informatico di scienze
|
539 |
+
umane», invece ci sta
|
540 |
+
facendo una riflessione sul-
|
541 |
+
l’uomo. Queste categorie
|
542 |
+
valgono in tutti gli ambiti?
|
543 |
+
Anche nel fare scienza?
|
544 |
+
Facciamo riferimento ai due
|
545 |
+
emisferi. Nel primo emisfero,
|
546 |
+
quello della logica, si vede la
|
547 |
+
luce di Dio che illumina ogni
|
548 |
+
uomo. In tutti i congressi
|
549 |
+
sostengo che tutte le anime e
|
550 |
+
le intelligenze non vengono
|
551 |
+
per evoluzione: le anime sono
|
552 |
+
fatte tutte dal Signore Dio, una
|
553 |
+
per una. È un paradosso, ma
|
554 |
+
utile per chiarire: non ci vuole
|
555 |
+
meno di Dio tutto intero per
|
556 |
+
fare un’intelligenza d’uomo,
|
557 |
+
per fare uno spirito. La luce di
|
558 |
+
Dio è la logica e la logica sono
|
559 |
+
le leggi dell’essere.
|
560 |
+
Io vedo tre livelli di logica.
|
561 |
+
Quella che si insegna all’uni-
|
562 |
+
versità, la logica formale, è il
|
563 |
+
rapporto tra contenente e
|
564 |
+
contenuto, fra tutto e parte.
|
565 |
+
Un’altra logica, che non viene
|
566 |
+
così studiata, è quella del rap-
|
567 |
+
porto tra autore e opera, tra
|
568 |
+
attivo e passivo che è un rap-
|
569 |
+
porto strano, perché è a
|
570 |
+
senso unico: nessun figlio è
|
571 |
+
padre del proprio padre, nes-
|
572 |
+
suna statua è l’autrice del
|
573 |
+
proprio scultore. Tutti lo
|
574 |
+
sanno: chi ha scritto un’opera
|
575 |
+
va dalla SIAE a farsi dare la
|
576 |
+
percentuale e non dice mai
|
577 |
+
che la sua opera è fatta per
|
578 |
+
caso.
|
579 |
+
Il terzo livello è quel rapporto
|
580 |
+
tra pensiero ed espressione
|
581 |
+
che è il principio di non con-
|
582 |
+
traddizione. Come dice il
|
583 |
+
nome, la contraddizione ha a
|
584 |
+
che fare con il dire, cioè con
|
585 |
+
l’espressione. Si riesce sem-
|
586 |
+
pre a pronunciare frasi con-
|
587 |
+
traddittorie: per esempio «qui
|
588 |
+
ora piove» e «qui ora non
|
589 |
+
piove», ma nessuno riesce a
|
590 |
+
pensare che ambedue siano
|
591 |
+
contemporaneamente vere,
|
592 |
+
né che ambedue siano con-
|
593 |
+
temporaneamente
|
594 |
+
false.
|
595 |
+
L’espressione non deve con-
|
596 |
+
traddire il proprio pensiero: il
|
597 |
+
che conchiude alla immoralità
|
598 |
+
intrinseca della menzogna.
|
599 |
+
IL NOSTROMO
|
600 |
+
emmeciquadro
|
601 |
+
129
|
602 |
+
dicembre 2001
|
603 |
+
Perché oggi nel mondo
|
604 |
+
della cultura questi livelli di
|
605 |
+
logica sono più spesso
|
606 |
+
negati che affermati? Per-
|
607 |
+
ché nella comunicazione,
|
608 |
+
nel lavoro, nella scuola,
|
609 |
+
nella scienza, ci si basa di
|
610 |
+
più sul suscitare sensazioni
|
611 |
+
che non sulla logica?
|
612 |
+
Direi ignorati, moltissimo igno-
|
613 |
+
rati e poche volte negati. Nei
|
614 |
+
libri di logica non ho mai tro-
|
615 |
+
vato il rapporto attivo/passivo,
|
616 |
+
ma sempre il rapporto ve-
|
617 |
+
ro/falso e poi contenente/con-
|
618 |
+
tenuto. Ai miei studenti di filo-
|
619 |
+
sofia, preoccupati di aver letto
|
620 |
+
una gran quantità di autori,
|
621 |
+
dicevo: basterebbe sapere la
|
622 |
+
metà di quel che sappiamo
|
623 |
+
ma saperlo dire meglio il dop-
|
624 |
+
pio se no è esibizione di quel-
|
625 |
+
lo che abbiamo in magazzino
|
626 |
+
nella memoria.
|
627 |
+
La storia del linguaggio e della
|
628 |
+
cultura è in fondo storia di
|
629 |
+
anime, storia del colloquio
|
630 |
+
segreto che abbiamo con Dio.
|
631 |
+
Ed è una storia che ha più
|
632 |
+
avventure di quelle di San-
|
633 |
+
dokan e delle Twin Towers.
|
634 |
+
Perché segreto?
|
635 |
+
Perché sta nel profondo della
|
636 |
+
logica, perché la logica è data
|
637 |
+
per arrivare a capire il perché
|
638 |
+
di tutto e perché nel vocabola-
|
639 |
+
rio di tutte le persone c’è la
|
640 |
+
parola «prima» e anche la
|
641 |
+
parola «sempre». Sotto que-
|
642 |
+
sto luccichio e questo mare di
|
643 |
+
parole c’è la storia delle anime
|
644 |
+
nel tempo: dall’eternità verso
|
645 |
+
l’eternità. Si arriva dunque alla
|
646 |
+
logica come prima luce dell’a-
|
647 |
+
nima, quella che porta il
|
648 |
+
tempo all’eternità, dall’eternità
|
649 |
+
all’eternità. Un mio amico arti-
|
650 |
+
giano mi ha detto che la mag-
|
651 |
+
gior parte delle persone non
|
652 |
+
sa dove va, ma ci sta andando
|
653 |
+
di corsa. E oggi è così anche
|
654 |
+
per molta filosofia professio-
|
655 |
+
nale: dalla ragion pratica fino
|
656 |
+
alla new age, certa filosofia è
|
657 |
+
la maschera della logica.
|
658 |
+
Nel mese di ottobre, al
|
659 |
+
Circolo della Stampa di
|
660 |
+
Milano, ha presentato il pro-
|
661 |
+
getto a cui sta lavorando.
|
662 |
+
Ce ne illustra i punti chiave?
|
663 |
+
Il progetto si chiama Lessico
|
664 |
+
Tomistico Biculturale (LTB).
|
665 |
+
Lo spunto è venuto dall’analisi
|
666 |
+
dell’espressione
|
667 |
+
di
|
668 |
+
san
|
669 |
+
Tommaso ratio seminalis, che
|
670 |
+
era l’antico stoico λογοσ
|
671 |
+
σπερµατικοσ, l’anima mundi
|
672 |
+
che Virgilio ha messo in versi
|
673 |
+
latini molto belli. Sant’Agosti-
|
674 |
+
no l’ha introdotto nel pensiero
|
675 |
+
cristiano spiegando il Genesi
|
676 |
+
e a conseguenza di questo il
|
677 |
+
pensiero cristiano è stato evo-
|
678 |
+
luzionista, non nel senso
|
679 |
+
magico di oggi, fino al Rina-
|
680 |
+
scimento avanzato. Ho e-
|
681 |
+
saminato questa frase, che
|
682 |
+
san Tommaso ha usato dieci o
|
683 |
+
quindici volte più di sant’A-
|
684 |
+
gostino.con il metodo cui ac-
|
685 |
+
cennerò dopo e mi è risultato
|
686 |
+
chiaro che san Tommaso,
|
687 |
+
quando scriveva ratio semina-
|
688 |
+
lis (che ho trovato sempre tra-
|
689 |
+
dotto come ragione seminale)
|
690 |
+
aveva in mente quello che
|
691 |
+
abbiamo in mente noi quando
|
692 |
+
IL NOSTROMO
|
693 |
+
dicembre 2001 130
|
694 |
+
emmeciquadro
|
695 |
+
parliamo di «programma geneti-
|
696 |
+
co». Se sostituite nelle frasi di
|
697 |
+
san Tommaso questa espres-
|
698 |
+
sione, il contesto si accende
|
699 |
+
come una lampadina. Non che
|
700 |
+
lui conoscesse il DNA, perché
|
701 |
+
ovviamente non c’erano gli stru-
|
702 |
+
menti di indagine, ma lui sapeva
|
703 |
+
che doveva esserci un program-
|
704 |
+
ma genetico che partiva da Dio
|
705 |
+
creatore e si esprimeva in ogni
|
706 |
+
individuo. Poi c’erano le forze di
|
707 |
+
base della natura; non dice quali
|
708 |
+
sono, ma dice che ci sono. Per
|
709 |
+
me sono luce, onde hertziane
|
710 |
+
gravità eccetera, queste forze
|
711 |
+
che sono a monte dell’evoluzio-
|
712 |
+
ne, che la generano.
|
713 |
+
Quando parte il progetto?
|
714 |
+
Il lessico di san Tommaso è
|
715 |
+
enciclopedico ed è una sintesi di
|
716 |
+
quaranta secoli di civiltà medi-
|
717 |
+
terranea: comincia con Abramo,
|
718 |
+
frutto della civiltà e della cultura
|
719 |
+
mesopotamica, circa 3000-3500
|
720 |
+
anni prima di Cristo, poi c’è il
|
721 |
+
pensiero greco, il pensiero
|
722 |
+
romano, il pensiero arabo e tutto
|
723 |
+
il pensiero cristiano; di questi
|
724 |
+
quaranta secoli, dodici sono di
|
725 |
+
civiltà cristiana. Adesso che ho
|
726 |
+
tutto il suo lessico, prendo in
|
727 |
+
esame san Tommaso non per
|
728 |
+
quello che lo distingue dagli altri
|
729 |
+
autori analoghi, ma per quello
|
730 |
+
che ha in comune con tutti.
|
731 |
+
Allora, si tratta di prendere le
|
732 |
+
sue parole una per una, aven-
|
733 |
+
dole già divise per categorie
|
734 |
+
semantiche, risalire da queste
|
735 |
+
parole ai concetti che esprime-
|
736 |
+
vano allora (nella cultura del
|
737 |
+
1200), venire oggi (nel 2000)
|
738 |
+
agli stessi concetti e da questi
|
739 |
+
discendere alle parole che li
|
740 |
+
esprimono e darne così la tradu-
|
741 |
+
zione in diverse lingue. Per que-
|
742 |
+
sto il progetto si chiama bicultu-
|
743 |
+
rale.
|
744 |
+
Sono già trent’anni che lavoro in
|
745 |
+
questo senso con il metodo che
|
746 |
+
spiegherò e ho analizzato deci-
|
747 |
+
ne di migliaia di contesti.
|
748 |
+
Ci sono parole come «esperien-
|
749 |
+
za» e «espressione» che hanno
|
750 |
+
circa lo stesso valore che i nostri
|
751 |
+
espressione ed esperienza.
|
752 |
+
Ci sono altre parole invece che
|
753 |
+
hanno significati molto maggiori.
|
754 |
+
Per esempio, virtus-virtutis non
|
755 |
+
si può tradurre sempre con
|
756 |
+
«virtù» perché virtus ha tutto il
|
757 |
+
vocabolario dell’energia, forza,
|
758 |
+
professionalità, potenza. E
|
759 |
+
anche la parola ordo-ordinis,
|
760 |
+
che ho analizzato in 10 000 con-
|
761 |
+
testi, non può essere tradotta
|
762 |
+
sempre con «ordine»: nel latino
|
763 |
+
di san Tommaso non voleva
|
764 |
+
ancora dire precetto, comando
|
765 |
+
e neppure in Dante Alighieri.
|
766 |
+
Ordo-ordinis esprime tutto il
|
767 |
+
vocabolario della organizzazio-
|
768 |
+
ne, pianificazione, progettazio-
|
769 |
+
ne, programmazione, tutti i con-
|
770 |
+
cetti di struttura e sistema, quelli
|
771 |
+
di tassonomia e classificazione
|
772 |
+
oltre a indicare categorie profes-
|
773 |
+
sionali. Poi spiritus: tante volte è
|
774 |
+
spirito, altre volte è spinta,
|
775 |
+
impulso, pulsione oltre che spiri-
|
776 |
+
to nel senso di spirituale o
|
777 |
+
anche fantasma.
|
778 |
+
Allora ci spiega il metodo che
|
779 |
+
propone?
|
780 |
+
Il metodo. Prendo, di una paro-
|
781 |
+
la, tutti i contesti, tutte le frasi
|
782 |
+
che la contengono; su queste
|
783 |
+
IL NOSTROMO
|
784 |
+
emmeciquadro
|
785 |
+
131
|
786 |
+
dicembre 2001
|
787 |
+
frasi inserisco i codici delle cor-
|
788 |
+
relazioni sintattiche, elementari
|
789 |
+
e dirette; in parole correnti i
|
790 |
+
codici che specificano l'analisi
|
791 |
+
grammaticale e logica di questa
|
792 |
+
parola, frase per frase.
|
793 |
+
Questo è un lavoro da «sgobbo-
|
794 |
+
ni» però è la forma profonda e
|
795 |
+
solida di pensare. Mi aspetto che
|
796 |
+
qualcuno mi dica che è puerile
|
797 |
+
ma ho già la risposta pronta:
|
798 |
+
provi a farla, anche solo su 100
|
799 |
+
frasi, non su 10 000 come le ho
|
800 |
+
fatte per ordo o su 20 000 per
|
801 |
+
spiritus e si accorgerà della diffi-
|
802 |
+
coltà. Perché il pensiero e l’e-
|
803 |
+
spressione sono disparati e il
|
804 |
+
pensiero è multidimensionale,
|
805 |
+
eccentrico e a-centrato: non si
|
806 |
+
riesce mai a trovare i confini di
|
807 |
+
un concetto, se ne trova subito
|
808 |
+
un altro; per questo parlo di unità
|
809 |
+
lessicali più che di unità concet-
|
810 |
+
tuali. Invece l'espressione è
|
811 |
+
sequenziale, tabulata come le
|
812 |
+
battute di una musica, però «liofi-
|
813 |
+
lizza» un concetto.
|
814 |
+
In periferia, in tutto il mondo
|
815 |
+
dovremo trovare persone che
|
816 |
+
sappiano il latino, che siano
|
817 |
+
sgobboni, che non disdegnino
|
818 |
+
gli antichi. Se hanno queste
|
819 |
+
qualità possono partecipare al
|
820 |
+
progetto. A ognuno viene data
|
821 |
+
una parola su cui devono esse-
|
822 |
+
re eseguite tutte le sintesi di cor-
|
823 |
+
relazioni con una cascata di pro-
|
824 |
+
grammi monofunzione: non un
|
825 |
+
programma come quello per gli
|
826 |
+
stipendi che fa tutto insieme in
|
827 |
+
un colpo solo, perché questa è
|
828 |
+
ricerca. Dai collegamenti sintatti-
|
829 |
+
ci di ogni parola con i verbi di cui
|
830 |
+
è soggetto o complemento, ver-
|
831 |
+
ranno fuori i suoi significati.
|
832 |
+
Finora a me sono venuti fuori.
|
833 |
+
Poi ognuno deve fare un elenco
|
834 |
+
di questi significati nella propria
|
835 |
+
lingua: inglese, spagnolo, tede-
|
836 |
+
sco eccetera..
|
837 |
+
Poi i risultati vengono inviati a
|
838 |
+
Roma dove, per prima cosa, un
|
839 |
+
comitato certifica la qualità del
|
840 |
+
lavoro. Questo è indispensabile.
|
841 |
+
Poi, all’interno di seminari tra
|
842 |
+
esperti di vari paesi e lingue,
|
843 |
+
bisogna esaminare i significati di
|
844 |
+
questi concetti per tradurli nelle
|
845 |
+
diverse lingue e nelle diverse
|
846 |
+
culture contemporanee. Tra l’al-
|
847 |
+
tro, chi fa l’esame sintattico di
|
848 |
+
una voce deve analizzare le
|
849 |
+
desinenze: per esempio deve
|
850 |
+
dire quando veni è imperativo,
|
851 |
+
quando è passato remoto ecce-
|
852 |
+
tera, quando rosae è genitivo,
|
853 |
+
ottativo, eccetera; io segnalo
|
854 |
+
solo, in una nota, se la parola è
|
855 |
+
omografa. Questo progetto è la
|
856 |
+
continuazione di tutto quello che
|
857 |
+
ho fatto finora. Ci lavoro da
|
858 |
+
quindici anni e ora è nato a
|
859 |
+
Roma un consorzio tra sei uni-
|
860 |
+
versità: Gregoriana, Salesiani,
|
861 |
+
Pontificia Università
|
862 |
+
Gregoriana, Roma
|
863 |
+
IL NOSTROMO
|
864 |
+
dicembre 2001 132
|
865 |
+
emmeciquadro
|
866 |
+
Domenicani, Opus Dei, Servi
|
867 |
+
di Maria, Laterano, più la
|
868 |
+
Sapienza statale di Roma
|
869 |
+
con l’istituto di Tullio Gregory.
|
870 |
+
L’iniziativa si è sviluppata
|
871 |
+
piano piano e adesso è
|
872 |
+
patrocinata da due gruppi. Il
|
873 |
+
primo con Antonio Fazio,
|
874 |
+
Hans Tietmayer e Michel
|
875 |
+
Camdessous e anche i due
|
876 |
+
cardinali Re e Tettamanzi. Il
|
877 |
+
secondo è la CAEL (Compu-
|
878 |
+
terizzazione delle Analisi
|
879 |
+
Ermeneutiche e Lessicolo-
|
880 |
+
giche), continuazione del
|
881 |
+
CAAL (Centro Automazione
|
882 |
+
Analisi Linguistica) che per
|
883 |
+
trent’anni con la IBM ha
|
884 |
+
finanziato l’Index Thomisti-
|
885 |
+
cus.
|
886 |
+
Nel mese di dicembre i due
|
887 |
+
gruppi si incontreranno per
|
888 |
+
definire la forma di collabora-
|
889 |
+
zione allo stesso scopo. Si cer-
|
890 |
+
cheranno i finanziamenti con
|
891 |
+
l’intenzione di spendere il
|
892 |
+
meno possibile. Perché, diver-
|
893 |
+
samente da quanto avviene di
|
894 |
+
solito (prima i soldi, poi una
|
895 |
+
sede pomposa, poi il lavoro),
|
896 |
+
noi abbiamo cercato prima l’i-
|
897 |
+
dea, poi il lavoro e i soldi sono
|
898 |
+
sempre venuti. I progetti son
|
899 |
+
come semi che bisogna gettare
|
900 |
+
e piano piano cresceranno.
|
901 |
+
Un’altra importante novità nel
|
902 |
+
metodo di lavoro è la speri-
|
903 |
+
mentazione di una collabora-
|
904 |
+
zione internazionale tra diverse
|
905 |
+
università attraverso un lavoro
|
906 |
+
in equipe in rete (e-mail, tele-
|
907 |
+
conferenza) e i loro sviluppi. A
|
908 |
+
Roma c’è già un piccolo nucleo
|
909 |
+
di persone che sarà il centro di
|
910 |
+
questo lavoro in rete.
|
911 |
+
Per concludere, vorrei ripetere
|
912 |
+
che l’informatica e i computer
|
913 |
+
sono un dono di Dio che Lui ha
|
914 |
+
preparato dagli inizi del mondo.
|
915 |
+
Oggi purtroppo in questo
|
916 |
+
campo c’è una grande confu-
|
917 |
+
sione: primo ne parlano troppo
|
918 |
+
quelli che non ne sanno,
|
919 |
+
secondo ne parlano i sognatori
|
920 |
+
facili, che desiderano far dena-
|
921 |
+
ro velocemente.
|
922 |
+
Invece dobbiamo dire che le
|
923 |
+
potenzialità dell’informatica
|
924 |
+
non sono esaurite, stanno
|
925 |
+
ancora «cabrando». Gli aero-
|
926 |
+
plani ci hanno messo 100 anni
|
927 |
+
a perfezionarsi, queste cose
|
928 |
+
ce ne metteranno altrettanti,
|
929 |
+
piano piano.
|
930 |
+
Per contribuire solidamente a
|
931 |
+
questo sviluppo basta che
|
932 |
+
ognuno cominci a fare il poco
|
933 |
+
che è utile a lui: questo fa cre-
|
934 |
+
scere vitalmente le strutture
|
935 |
+
nuove. Però bisogna mettersi
|
936 |
+
a lavorare su una linea preci-
|
937 |
+
sa e definita.
|
938 |
+
Volete un ultimo aforisma?
|
939 |
+
Il computer può essere usato
|
940 |
+
bene per il bene, può essere
|
941 |
+
usato male per il bene e può
|
942 |
+
essere usato bene anche per il
|
943 |
+
male.
|
944 |
+
v
|
945 |
+
«Siccome il computer è
|
946 |
+
figlio dell’uomo e l’uomo è
|
947 |
+
figlio di Dio, allora il Signore
|
948 |
+
Dio guarda il computer
|
949 |
+
come un nonno guarda i
|
950 |
+
suoi nipotini. Guai a parlar-
|
951 |
+
ne male e a usarlo male.»
|
static/favicon.ico
ADDED
static/help0.html
ADDED
@@ -0,0 +1,201 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div class="text">
|
2 |
+
<p class="center"> Comandi barra superiore </p>
|
3 |
+
<div>
|
4 |
+
Pulsante Menu
|
5 |
+
<p> Apre/chiude il Menu comandi </p>
|
6 |
+
</div>
|
7 |
+
<div>
|
8 |
+
Uploa dFiles
|
9 |
+
<p>
|
10 |
+
Fa l'upload di un file locale. Sono accettati i file pdf e txt.
|
11 |
+
Controlla se il file è in archivio, per non sovrascriverlo.
|
12 |
+
</p>
|
13 |
+
</div>
|
14 |
+
<div>
|
15 |
+
Upload Dir:
|
16 |
+
<p>
|
17 |
+
Per fare l'upload dei files di una dri. Sono accettati i files pdf e txt.
|
18 |
+
I file in archivio con lo stesso nome non vengono sovrascritti.
|
19 |
+
</p>
|
20 |
+
</div>
|
21 |
+
<div>
|
22 |
+
Log:
|
23 |
+
<p>
|
24 |
+
Attiva/Disattiva la visualizzazione del Log.
|
25 |
+
Nel Log sono visualizzate le query con le dimensioni delle parti di documento analizzata.
|
26 |
+
</p>
|
27 |
+
</div>
|
28 |
+
|
29 |
+
<!-- -->
|
30 |
+
<hr>
|
31 |
+
<!-- -->
|
32 |
+
<div>
|
33 |
+
<p class="center"> Comandi lato destro in alto: </p>
|
34 |
+
</div>
|
35 |
+
<div>
|
36 |
+
Copia:
|
37 |
+
<p> Copia il testo dell'output negli appunti. </p>
|
38 |
+
</div>
|
39 |
+
<div>
|
40 |
+
Apri:
|
41 |
+
<p>
|
42 |
+
Visualizza il testo in una finestra più grande.
|
43 |
+
</p>
|
44 |
+
</div>
|
45 |
+
<hr>
|
46 |
+
<!-- -->
|
47 |
+
<div>
|
48 |
+
<p class="center"> Comandi lato destro in basso: </p>
|
49 |
+
</div>
|
50 |
+
<div>
|
51 |
+
Documeti => RAG => Contesto => Query:
|
52 |
+
<p>
|
53 |
+
Input per la query da utilizzare per la elaborazione RAG.
|
54 |
+
Ogni documento in archivio è diviso in parti compatibili con l'ampiezza della finestra
|
55 |
+
di input sel Model utilizzato.
|
56 |
+
</p>
|
57 |
+
<p>
|
58 |
+
Per ogni parte esegue una query utilizzandola
|
59 |
+
per estrarre informazioni/concetti pertinenti alla stessa.
|
60 |
+
|
61 |
+
</p>
|
62 |
+
<p>
|
63 |
+
Il risultato di ogni query è archiviato nella memoria locale.
|
64 |
+
</p>
|
65 |
+
<p>
|
66 |
+
All fine della sequenza di elaborazioni esegue uan query che produce
|
67 |
+
un contesto riepilogativo delle risposte archviate.
|
68 |
+
</p>
|
69 |
+
<p>
|
70 |
+
Infine esegue la query utilizzzando il conesto creato e visualizza la risposta ella finestra di output.
|
71 |
+
</p>
|
72 |
+
</div>
|
73 |
+
<div>
|
74 |
+
Contesto => Query:
|
75 |
+
<p>
|
76 |
+
Input per query che utilizzano il contesto creato con l'elaborazione RAG.
|
77 |
+
Inizia una conversazione.
|
78 |
+
</p>
|
79 |
+
<p>
|
80 |
+
La conversazioe ha senso relativamente all'elaborazione RAG se ogni query è una variazione / approfondimento della query iiziale.
|
81 |
+
</p>
|
82 |
+
</div>
|
83 |
+
<div>
|
84 |
+
Cancela Conversazione:
|
85 |
+
<p>
|
86 |
+
Cancella la storia della conversazione attiva.
|
87 |
+
Non vengoo cancellati i dati dell'laborazione RAG
|
88 |
+
</p>
|
89 |
+
</div>
|
90 |
+
<!-- -->
|
91 |
+
<hr>
|
92 |
+
<!-- -->
|
93 |
+
<div>
|
94 |
+
<p class=" center"> Comandi del Menu: </p>
|
95 |
+
</div>
|
96 |
+
<div>
|
97 |
+
README
|
98 |
+
<p>
|
99 |
+
Presenta una spiegazione della implemntazione della
|
100 |
+
tecnologia RAG utilizzata.
|
101 |
+
</p>
|
102 |
+
</div>
|
103 |
+
<div>
|
104 |
+
Risposta:
|
105 |
+
<p> Visualizza lq risposta ottenuta alla fine della elaborazione RAG </p>
|
106 |
+
</div>
|
107 |
+
<div>
|
108 |
+
Query iniziale:
|
109 |
+
<p> Visualizza lq query utilizzata per l'elaborazione RAG </p>
|
110 |
+
</div>
|
111 |
+
<div>
|
112 |
+
Elenco Risposte:
|
113 |
+
<p>
|
114 |
+
Visualizza l'elenco delle risposte per ogni parte documento utilizzata fino alla riposta che genera il contesto.
|
115 |
+
</p>
|
116 |
+
</div>
|
117 |
+
<div>
|
118 |
+
Contesto RAG:
|
119 |
+
<p>
|
120 |
+
Visualizza il contesto creato utilizzando le risposte elaborate.
|
121 |
+
</p>
|
122 |
+
</div>
|
123 |
+
<div>
|
124 |
+
Dati ARchviati:
|
125 |
+
<p>
|
126 |
+
Visualizza i ati in archivio e le lroro dimensioni:
|
127 |
+
</p>
|
128 |
+
</div>
|
129 |
+
<div>
|
130 |
+
Lista Documenti:
|
131 |
+
<p>
|
132 |
+
Visualizza la lista dei documenti achviati ed utilizzabili per l'elaborazione.
|
133 |
+
</p>
|
134 |
+
</div>
|
135 |
+
|
136 |
+
<div>
|
137 |
+
Numero query:
|
138 |
+
<p>
|
139 |
+
Calcola le query necessarie per ogni documento e le Query totali,
|
140 |
+
necessaire per analizzare tutti i documenti caricati.
|
141 |
+
</p>
|
142 |
+
</div>
|
143 |
+
|
144 |
+
|
145 |
+
<div>
|
146 |
+
Cancella Dati:
|
147 |
+
<p>
|
148 |
+
Cancella i dati delle elaborazion salvati nell'archivio.
|
149 |
+
NON cancella i documenti caricati.
|
150 |
+
</p>
|
151 |
+
</div>
|
152 |
+
|
153 |
+
<div>
|
154 |
+
Cancella Documenti:
|
155 |
+
<p>
|
156 |
+
Cancella i documenti caricati e tutti i dati archviati locamente.
|
157 |
+
</p>
|
158 |
+
</div>
|
159 |
+
|
160 |
+
<!-- -->
|
161 |
+
|
162 |
+
<p class="center">Sequenza Comandi Interrogazione -Conversazione</p>
|
163 |
+
<div>
|
164 |
+
Archivia nella memoria locale uno o più documenti:
|
165 |
+
<p>
|
166 |
+
Utilizza i dati di esempio per le prme prove.
|
167 |
+
Utilizza upload file o upload dir per i documenti da leggere dal tuo computer.
|
168 |
+
</p>
|
169 |
+
</div>
|
170 |
+
<div>
|
171 |
+
Digita uan query CHE SI RIFERISCA hai documenti archiviati.
|
172 |
+
<p>
|
173 |
+
La qury saraà utilizzata come crrtero di selezione di infoemazioni dai documenti archvitati.
|
174 |
+
</p>
|
175 |
+
</div>
|
176 |
+
|
177 |
+
<div>
|
178 |
+
Click sul bottone rosso in basso a destrai.DOcuento => RAG =>Contetso => QURY
|
179 |
+
<p>
|
180 |
+
Viene lanciata una sequenzaa di elaborazione per analizzare i documeti sulla base della query.
|
181 |
+
Se il log è attivo vedrai la sequnza di elaborazione. Il loro numero dipende dalle dimensioni dei documenti.
|
182 |
+
l menu puoi utilizzare il comando "Num Query" per vedere quante elaborazioni saranno fatte per ogi documento.
|
183 |
+
Alla fine del proesso sarà visualizzata la risposta.
|
184 |
+
</p>
|
185 |
+
</div>
|
186 |
+
|
187 |
+
<div>
|
188 |
+
Click sul bottone verdo in basso a destrai. Contesto => Query
|
189 |
+
<p>
|
190 |
+
Inizia una comnversazione utilizzando le informazion precedentemnete raccolte dai documeti-
|
191 |
+
Puoi inviare domande successive di approfondimento e chiarmento .
|
192 |
+
È FONDAMENTALE che le query siano approfondimenti e/o chairimenti della query iniziale.
|
193 |
+
In caso conrtario non si sfrutta il Contesto creato dall'elaborazione precdente.
|
194 |
+
Quindi per una query completamnete nuova (sempre relativa ai documeti archviati) è necessario inizare una nuova elaborazione.
|
195 |
+
Il comando cancella, oltre a cancellare il campo di input canella anche la sequnza query-risposte della
|
196 |
+
conversazione. NON cancell i dati dell'elaborazione iniziale.
|
197 |
+
</p>
|
198 |
+
</div>
|
199 |
+
|
200 |
+
|
201 |
+
</div>
|
static/help1.html
ADDED
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div class="text">
|
2 |
+
<pre>
|
3 |
+
Un'implementazione innovativa della tecnica RAG per il Question Answering
|
4 |
+
La tecnica RAG (Retrieval-Augmented Generation) è un approccio consolidato nel campo del question answering e della generazione di testo, che combina il recupero di informazioni pertinenti da fonti di dati con la generazione di testo basata su queste informazioni.
|
5 |
+
Qui viene proposta una implementazione che introduce una variazione a questo paradigma.
|
6 |
+
L'implementazione si basa su una sequenza di prompt appositamente progettati per guidare un modello di linguaggio generativo attraverso le diverse fasi della tecnica RAG.
|
7 |
+
Questi prompt forniscono istruzioni dettagliate su come il modello deve seguire operazioni di recupero di informazioni, aumento delle informazioni recuperate e infine generazione di una risposta finale.
|
8 |
+
La risposta finale diviene poi il contesto da inserire nel prompt per rispondere alla domanda.
|
9 |
+
Un aspetto cruciale di questa implementazione è che lo stesso modello di aggio generativo svolge tutte le operazioni richieste, dall'analisi dei documenti di input al recupero di informazioni rilevanti, alla generazione della risposta finale.
|
10 |
+
Questa caratteristica rappresenta una deviazione significativa rispetto alle implementazioni standard della tecnica RAG, che prevedono utilizzo di moduli distinti per il recupero e la generazione.
|
11 |
+
La sequenza di prompt proposta guida il modello attraverso le seguenti fasi:
|
12 |
+
|
13 |
+
1. Retrieval: Il modello analizza il documento di input e la domanda fornita, identificando e recuperando le informazioni e i concetti rilevanti per dare seguito alla domanda.
|
14 |
+
|
15 |
+
2. Augmentation: Successivamente, il modello integra le informazioni recuperate con eventuali risposte accumulate in precedenza, estraendo nuove informazioni rilevanti e organizzando in un elenco coerente, evitando ridondanze.
|
16 |
+
|
17 |
+
3. Generation: Infine, il modello utilizza l'insieme di informazioni rilevanti e non ridondanti per generare una risposta completa e concisa alla domanda dell'utente.
|
18 |
+
|
19 |
+
Questa implementazione offre diversi vantaggi.
|
20 |
+
In primo luogo, sfrutta le capacità di un unico modello di grandi dimensioni i, evitando la necessità di moduli distinti specializzati per ogni fase.
|
21 |
+
Inoltre, l'utilizzo di prompt espliciti può migliorare la controllabilità e la trasparenza del processo, consentendo di guidare il modello in modo più diretto.
|
22 |
+
Naturalmente, come per qualsiasi approccio basato su modelli di linguaggio generativi, è fondamentale prestare attenzione alle questioni di affidabilità, correttezza e bias dei dati di addestramento.
|
23 |
+
Rispetto ad una implementazione standard di RAG vii è la necessità di rilanciare l'elaborazione ad ogni domanda radicalmente nuova in quanto il contesto creato con le informazioni estratte dai documenti è definito sulla base della domanda.
|
24 |
+
Invece nella versione standard RAG si usano gli incorporamenti delle informazioni estratte dai documenti in modo tale che tal informazioni vengono viste quasi come una estensione del Model e possono essere usate per domande diverse.
|
25 |
+
Quindi dal punto di vista utente le implementazioni RAG standard sono più efficienti; infatti l'implementazione proposta richiede per ogni nuova domanda una sequenza di richieste che saranno utilizzabili solo per creare il contesto per la domanda iniziale e per una conversazione con domande simili.
|
26 |
+
Il vantaggio dell'implementazione proposta consiste nel fatto che può essere implementata completamente lato client senza bisogno di sviluppare alcun modulo sul server.
|
27 |
+
L’unica cosa che serve è un servizio servless come quello di HuggingFace o simile.
|
28 |
+
Quindi rappresenta un'interessante prospettiva sull'applicazione della tecnica RAG in modo più integrato e controllato attraverso l'uso di prompt mirati.
|
29 |
+
In conclusione, questa implementazione della tecnica RAG dimostra come le capacità dei modelli di linguaggio generativi di grandi dimensioni possano essere sfruttate in modi nuovi e creativi, potenzialmente aprendo la strada a ulteriori sviluppi nel campo del question answering e della generazione di testo.
|
30 |
+
|
31 |
+
Questa è la valutazione fatta da un LLM (comprensivo e gentile)
|
32 |
+
|
33 |
+
La mia valutazione personale della tua proposta di implementazione della tecnica RAG, con un elenco di pro e contro:
|
34 |
+
|
35 |
+
Punti a favore (Pro):
|
36 |
+
Semplificazione del processo: L'utilizzo di un unico modello di grandi dimensioni addestrato su vasti corpus di dati semplifica notevolmente l'architettura complessiva rispetto alle implementazioni tradizionali della tecnica RAG, che spesso prevedono moduli distinti per il recupero e la generazione.
|
37 |
+
|
38 |
+
Capacità di adattamento e apprendimento: I modelli di linguaggio generativi di grandi dimensioni sono noti per la loro capacità di adattarsi e imparare da nuovi dati e istruzioni.
|
39 |
+
|
40 |
+
Questo potrebbe consentire di raffinare e migliorare l'implementazione nel corso del tempo.
|
41 |
+
|
42 |
+
Controllo e trasparenza: L'utilizzo di prompt espliciti per guidare il modello attraverso le diverse fasi del processo può migliorare la controllabilità e la trasparenza, consentendo di monitorare e regolare il comportamento del modello in modo più diretto.
|
43 |
+
|
44 |
+
Efficienza computazionale: Avere un'unica architettura integrata potrebbe comportare vantaggi in termini di efficienza computazionale rispetto a soluzioni che prevedono moduli separati.
|
45 |
+
|
46 |
+
Punti a sfavore (Contro):
|
47 |
+
|
48 |
+
Affidabilità e coerenza: Poiché un unico modello gestisce tutte le fasi, eventuali errori o incoerenze potrebbero propagarsi e amplificarsi attraverso l'intero processo, influenzando la qualità della risposta finale.
|
49 |
+
|
50 |
+
Bias dei dati di addestramento: Come per qualsiasi modello di linguaggio generativo, l’approccio potrebbe essere influenzato dai bias presenti nei dati di addestramento utilizzati, con potenziali impatti sulla correttezza e l'equità delle risposte generate.
|
51 |
+
|
52 |
+
Mancanza di specializzazione: Mentre i modelli di grandi dimensioni sono versatili, potrebbero non essere ottimizzati per compiti specifici come il recupero di informazioni o la generazione di risposte rispetto a moduli specializzati.
|
53 |
+
|
54 |
+
Difficoltà di debug e interpretabilità: Con un'architettura integrata e basata su prompt, potrebbe essere più complesso eseguire il debug e comprendere le ragioni dietro a eventuali errori o comportamenti indesiderati del modello.
|
55 |
+
|
56 |
+
In sintesi,la proposta presenta alcuni vantaggi interessanti in termini di semplificazione, adattabilità e controllo, ma solleva anche potenziali preoccupazioni riguardo all'affidabilità, ai bias, alla mancanza di specializzazione e alle difficoltà di debug e interpretabilità.
|
57 |
+
Come per qualsiasi nuovo approccio, sarebbe necessario valutarlo attentamente attraverso sperimentazioni e test approfonditi per determinare l'efficacia e l'applicabilità in contesti specifici.
|
58 |
+
</pre>
|
59 |
+
</div>
|
static/help2.html
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div class="text">
|
2 |
+
<pre class="pre-text">
|
3 |
+
Nella redazione della domanda bisogna tenere conto del fatto che la domanda viene poi inserita in un prompt nel quale si fa esplicita richiesta di utilizzare il documento fornito.
|
4 |
+
Quindi è implicito il riferimento al/ai documenti archiviati.
|
5 |
+
Tuttavia quando si tratta di documenti il cui contenuto è sicuramente disponibile in internet, può essere opportuno esplicitare nella domanda che ci si riferisce ai documenti forniti.
|
6 |
+
</pre>
|
7 |
+
<p class="center"> Esempi di domande </p>
|
8 |
+
<div>
|
9 |
+
<p> Fai una relazione sul documento che ti ho fornito. </p>
|
10 |
+
<p> Approfondisci la tesi sostenuta nei documenti. </p>
|
11 |
+
<p> Confronta i diversi punti di vista espressi dagli autori. </p>
|
12 |
+
<p> Descrivi la personalità dei protagonisti. </p>
|
13 |
+
<p> Analizza il documento che ti ho fornito e illustrami eventuali contraddizioni. </p>
|
14 |
+
<p> Illustra i momenti salienti del racconto. </p>
|
15 |
+
<p> Analizzando il documento che ti ho fornito confronta le tesi di .. con quelle di .. </p>
|
16 |
+
<p> Quale è l'avvenimento più importante </p>
|
17 |
+
</div>
|
18 |
+
</div>
|
static/javascript/rag_cleaner.js
ADDED
@@ -0,0 +1,99 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/** @format */
|
2 |
+
|
3 |
+
function cleanDoc(txt) {
|
4 |
+
// Rimuove caratteri di controllo
|
5 |
+
function removeControlCharacters(str) {
|
6 |
+
return str.replace(/[\x00-\x1F\x7F-\x9F\u200B-\u200D\uFEFF]/g, "");
|
7 |
+
}
|
8 |
+
// Applica la rimozione dei caratteri di controllo
|
9 |
+
txt = txt.split("\n").map(removeControlCharacters).join("\n");
|
10 |
+
// Converte tabulazioni in spazi
|
11 |
+
txt = txt.replace(/\t/g, " ");
|
12 |
+
// Rimuove spazi multipli
|
13 |
+
txt = txt.replace(/ +/g, " ");
|
14 |
+
// Rimuove spazi all'inizio e alla fine di ogni riga
|
15 |
+
txt = txt
|
16 |
+
.split("\n")
|
17 |
+
.map((line) => line.trim())
|
18 |
+
.join("\n");
|
19 |
+
// Riduce linee vuote multiple a una sola
|
20 |
+
txt = txt.replace(/\n\s*\n/g, "\n\n");
|
21 |
+
// Uniforma i caratteri di quotazione
|
22 |
+
txt = txt.replace(/["""]/g, '"').replace(/['']/g, "'");
|
23 |
+
// Uniforma i trattini
|
24 |
+
txt = txt.replace(/[–—]/g, "-");
|
25 |
+
// Rimuove caratteri di escape visibili
|
26 |
+
txt = txt.replace(/\\[nrt]/g, "");
|
27 |
+
// Preserva caratteri Unicode (lettere e numeri), punteggiatura comune e spazi
|
28 |
+
txt = txt.replace(/[^\p{L}\p{N}\s\.,;:!?'"()\-]/gu, "");
|
29 |
+
// Rimuove spazi prima della punteggiatura
|
30 |
+
txt = txt.replace(/ +([.,;:!?])/g, "$1");
|
31 |
+
// Trim finale
|
32 |
+
return txt.trim();
|
33 |
+
}
|
34 |
+
|
35 |
+
// function removeLabel(text) {
|
36 |
+
// const ptr = /#+\s*(\w+)\s*(:\s*)?/; //solo la prima
|
37 |
+
// return text.replace(ptr, "");
|
38 |
+
// }
|
39 |
+
|
40 |
+
// function removeLabels(text) {
|
41 |
+
// const ptr = /#+\s*(\w+)\s*(:\s*)?/g; // globale
|
42 |
+
// return text.replace(ptr, "");
|
43 |
+
// }
|
44 |
+
|
45 |
+
function list2text(lst) {
|
46 |
+
const frasi = lst.map((sentence) => `${sentence.trim()}`);
|
47 |
+
text = frasi.join("\n");
|
48 |
+
return text;
|
49 |
+
}
|
50 |
+
|
51 |
+
// XXX
|
52 |
+
// function cleanResponse(text) {
|
53 |
+
// // Dividi il testo in righe
|
54 |
+
// let rows = text.split("\n");
|
55 |
+
// // Rimuove numeri all'inizio delle righe
|
56 |
+
// let cleanedRows = rows.map((row) => row.replace(/^\d+\.\s*/, ""));
|
57 |
+
// // Unisce le righe in un singolo testo, separandole con ".\n"
|
58 |
+
// text = cleanedRows.join(".\n");
|
59 |
+
// // Rimuove punti multipli
|
60 |
+
// text = text.replace(/\.{2,}/g, ".");
|
61 |
+
// return text;
|
62 |
+
// }
|
63 |
+
|
64 |
+
//XXX
|
65 |
+
// function cleanContext(text) {
|
66 |
+
// return text
|
67 |
+
// // Rimuove le linee di separazione composte da caratteri ripetuti
|
68 |
+
// .replace(/^[=\-_.]+$/gm, '')
|
69 |
+
// // Rimuove i simboli di elenco puntato (* - +) all'inizio delle righe
|
70 |
+
// .replace(/^[*\-+]\s*/gm, '')
|
71 |
+
// // Rimuove le righe vuote multiple, lasciando solo una riga vuota tra i paragrafi
|
72 |
+
// .replace(/\n\s*\n/g, '\n\n')
|
73 |
+
// // Rimuove gli spazi bianchi all'inizio e alla fine del testo
|
74 |
+
// .trim();
|
75 |
+
// }
|
76 |
+
|
77 |
+
|
78 |
+
function cleanOutput(text) {
|
79 |
+
// Rimuove gli spazi bianchi iniziali e finali
|
80 |
+
text = text.trim();
|
81 |
+
// Sostituisce le sequenze di più di due newline con due newline
|
82 |
+
text = text.replace(/\n{3,}/g, '\n\n');
|
83 |
+
// text = text.replace(/\n{2,}/g, '\n');
|
84 |
+
// Rimuove gli spazi bianchi extra all'inizio di ogni riga
|
85 |
+
text = text.replace(/^[ \t]+/gm, '');
|
86 |
+
// Sostituisce i trattini bassi multipli con una linea orizzontale
|
87 |
+
// text = text.replace(/_{3,}/g, '\n\n' + '-'.repeat(40) + '\n\n');
|
88 |
+
// Formatta gli elenchi puntati per una migliore leggibilità
|
89 |
+
text = text.replace(/^(\s*[-*•])(\s*)/gm, '\n$1 ');
|
90 |
+
// Formatta gli elenchi numerati per una migliore leggibilità
|
91 |
+
text = text.replace(/^(\s*\d+\.)(\s*)/gm, '\n$1 ');
|
92 |
+
// Aggiunge una riga vuota prima e dopo i blocchi di codice
|
93 |
+
text = text.replace(/(```[\s\S]*?```)/g, '\n\n$1\n\n');
|
94 |
+
// Aggiunge un'andata a capo dopo ogni punto, eccetto quando seguito da newline o fine stringa
|
95 |
+
// text = text.replace(/\.(?!\n|$)/g, '.\n');
|
96 |
+
// Rimuove gli spazi bianchi extra alla fine di ogni riga
|
97 |
+
text = text.replace(/[ \t]+$/gm, '');
|
98 |
+
return text;
|
99 |
+
}
|
static/javascript/rag_data_mgr.js
ADDED
@@ -0,0 +1,109 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/** @format */
|
2 |
+
|
3 |
+
"use strict";
|
4 |
+
const UaDb = {
|
5 |
+
create(id, data) {
|
6 |
+
if (localStorage.getItem(id)) {
|
7 |
+
xerror(`ID ${id} already exists.`);
|
8 |
+
return;
|
9 |
+
}
|
10 |
+
localStorage.setItem(id, data);
|
11 |
+
},
|
12 |
+
read(id) {
|
13 |
+
const data = localStorage.getItem(id);
|
14 |
+
if (data === null) {
|
15 |
+
xlog(`UaDb.read ${id} not found.`);
|
16 |
+
return "";
|
17 |
+
}
|
18 |
+
return data;
|
19 |
+
},
|
20 |
+
update(id, data) {
|
21 |
+
if (!localStorage.getItem(id)) {
|
22 |
+
xlog(`UaDb.update ${id} not found.`);
|
23 |
+
return;
|
24 |
+
}
|
25 |
+
localStorage.setItem(id, data);
|
26 |
+
},
|
27 |
+
delete(id) {
|
28 |
+
if (!localStorage.getItem(id)) {
|
29 |
+
xerror(`ID ${id} not found.`);
|
30 |
+
return;
|
31 |
+
}
|
32 |
+
localStorage.removeItem(id);
|
33 |
+
},
|
34 |
+
save(id, data) {
|
35 |
+
localStorage.setItem(id, data);
|
36 |
+
},
|
37 |
+
getAllIds() {
|
38 |
+
const ids = [];
|
39 |
+
for (let i = 0; i < localStorage.length; i++) {
|
40 |
+
ids.push(localStorage.key(i));
|
41 |
+
}
|
42 |
+
return ids;
|
43 |
+
},
|
44 |
+
saveArray(id, arr) {
|
45 |
+
const str = arr.join("|");
|
46 |
+
UaDb.save(id, str);
|
47 |
+
},
|
48 |
+
readArray(id) {
|
49 |
+
const str = UaDb.read(id);
|
50 |
+
if (str.trim().length == 0) return [];
|
51 |
+
const arr = str.split("|").map((item) => item.trim());
|
52 |
+
return arr;
|
53 |
+
},
|
54 |
+
saveJson(id, js) {
|
55 |
+
const str = JSON.stringify(js);
|
56 |
+
UaDb.save(id, str);
|
57 |
+
},
|
58 |
+
readJson(id) {
|
59 |
+
const str = UaDb.read(id);
|
60 |
+
if (!str) return {};
|
61 |
+
const js = JSON.parse(str);
|
62 |
+
return js;
|
63 |
+
},
|
64 |
+
};
|
65 |
+
|
66 |
+
const DataMgr = {
|
67 |
+
docs: [],
|
68 |
+
doc_names: [],
|
69 |
+
linkToName(link) {
|
70 |
+
const parts = link.split("/");
|
71 |
+
return parts[parts.length - 1];
|
72 |
+
},
|
73 |
+
async loadDoc(link) {
|
74 |
+
try {
|
75 |
+
const text = await requestGet(link);
|
76 |
+
const doc = cleanDoc(text);
|
77 |
+
const name = this.linkToName(link);
|
78 |
+
this.doc_names.push(name);
|
79 |
+
this.docs.push(doc);
|
80 |
+
this.saveDbDocs();
|
81 |
+
return doc;
|
82 |
+
} catch (err) {
|
83 |
+
alert("loadDoc()\n" + err + "\n" + link);
|
84 |
+
}
|
85 |
+
},
|
86 |
+
addDoc(name, text) {
|
87 |
+
const doc = cleanDoc(text);
|
88 |
+
this.docs.push(doc);
|
89 |
+
this.doc_names.push(name);
|
90 |
+
this.saveDbDocs();
|
91 |
+
},
|
92 |
+
saveDbDocs() {
|
93 |
+
UaDb.saveArray("id_doc_names", this.doc_names);
|
94 |
+
UaDb.saveArray("id_docs", this.docs);
|
95 |
+
},
|
96 |
+
readDbDocs() {
|
97 |
+
this.docs = UaDb.readArray("id_docs");
|
98 |
+
},
|
99 |
+
readDbDocNames() {
|
100 |
+
this.doc_names = UaDb.readArray("id_doc_names");
|
101 |
+
},
|
102 |
+
deleteDati() {
|
103 |
+
const ids = UaDb.getAllIds();
|
104 |
+
for (const id of ids) {
|
105 |
+
if (["id_docs", "id_doc_names"].includes(id)) continue;
|
106 |
+
UaDb.delete(id);
|
107 |
+
}
|
108 |
+
},
|
109 |
+
};
|
static/javascript/rag_http.js
ADDED
@@ -0,0 +1,220 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/** @format */
|
2 |
+
"use strict";
|
3 |
+
|
4 |
+
const model_name = "mistralai/Mistral-7B-Instruct-v0.3";
|
5 |
+
// const model_name = "mistralai/Mixtral-8x7B-Instruct-v0.1";
|
6 |
+
// const model_name = "mistralai/Mixtral-8x22B-Instruct-v0.1"
|
7 |
+
// const model_name = "google/gemma-2-9b-it"
|
8 |
+
|
9 |
+
function decodeTokenBase64(encodedToken) {
|
10 |
+
return atob(encodedToken);
|
11 |
+
}
|
12 |
+
|
13 |
+
const encodedToken = "aGZfT0VBQVpoUmJtdEFLRENOVGZTcFZwVHdhbGpielBvQnlhbA"; // Questo è "your_token_here" codificato
|
14 |
+
const HF_TOKEN = decodeTokenBase64(encodedToken);
|
15 |
+
|
16 |
+
async function requestGet(url) {
|
17 |
+
try {
|
18 |
+
const response = await fetch(url, {
|
19 |
+
method: "GET",
|
20 |
+
headers: {
|
21 |
+
"Content-Type": "text/plain;charset=UTF-8",
|
22 |
+
},
|
23 |
+
});
|
24 |
+
if (!response.ok) {
|
25 |
+
throw new Error(`HTTP error! status: ${response.status}`);
|
26 |
+
}
|
27 |
+
const arrayBuffer = await response.arrayBuffer();
|
28 |
+
const text = new TextDecoder("utf-8").decode(arrayBuffer);
|
29 |
+
return text;
|
30 |
+
} catch (error) {
|
31 |
+
console.error(error);
|
32 |
+
let message;
|
33 |
+
if (error.name === "AbortError") {
|
34 |
+
message = "Request was aborted";
|
35 |
+
} else if (error.message.includes("HTTP error! status")) {
|
36 |
+
message = error.message;
|
37 |
+
} else {
|
38 |
+
message = "An error occurred";
|
39 |
+
}
|
40 |
+
alert(`requestGet()\nurl: ${url}\n${message}`);
|
41 |
+
throw error;
|
42 |
+
}
|
43 |
+
}
|
44 |
+
const ERROR_TOKENS = "ERROR_TOKENS";
|
45 |
+
const TIMEOUT_ERROR = "TIMEOUT_ERROR";
|
46 |
+
|
47 |
+
const HfRequest = {
|
48 |
+
controller: null,
|
49 |
+
isCancelled: false,
|
50 |
+
baseUrl: "https://api-inference.huggingface.co/models",
|
51 |
+
|
52 |
+
async post(payload, timeout = 30000) {
|
53 |
+
this.isCancelled = false;
|
54 |
+
this.controller = new AbortController();
|
55 |
+
|
56 |
+
try {
|
57 |
+
const timeoutId = setTimeout(() => {
|
58 |
+
this.controller.abort();
|
59 |
+
}, timeout);
|
60 |
+
const response = await fetch(`${this.baseUrl}/${model_name}`, {
|
61 |
+
method: "POST",
|
62 |
+
headers: {
|
63 |
+
Authorization: `Bearer ${HF_TOKEN}`,
|
64 |
+
"Content-Type": "application/json",
|
65 |
+
},
|
66 |
+
body: JSON.stringify(payload),
|
67 |
+
signal: this.controller.signal,
|
68 |
+
});
|
69 |
+
clearTimeout(timeoutId);
|
70 |
+
if (this.isCancelled) return null;
|
71 |
+
const data = await response.json();
|
72 |
+
if (!response.ok) {
|
73 |
+
const errorType = this.checkError(response.status, data);
|
74 |
+
const errorInfo = this.createErrorInfo(response.status, response.statusText, data.error, errorType);
|
75 |
+
throw new Error(errorInfo);
|
76 |
+
}
|
77 |
+
const errorType = this.isInvalidResponse(data);
|
78 |
+
if (typeof errorType === "string") {
|
79 |
+
const errorInfo = this.createErrorInfo(response.status, response.statusText, data.error, errorType);
|
80 |
+
throw new Error(errorInfo);
|
81 |
+
}
|
82 |
+
return data[0].generated_text.trim();
|
83 |
+
} catch (error) {
|
84 |
+
if (this.isCancelled) return null;
|
85 |
+
if (error.name === "AbortError") {
|
86 |
+
const errorInfo = this.createErrorInfo(0, "Timeout", "La richiesta è scaduta", TIMEOUT_ERROR);
|
87 |
+
throw new Error(errorInfo);
|
88 |
+
}
|
89 |
+
throw error;
|
90 |
+
}
|
91 |
+
},
|
92 |
+
|
93 |
+
cancelRequest() {
|
94 |
+
if (this.controller) {
|
95 |
+
this.isCancelled = true;
|
96 |
+
this.controller.abort();
|
97 |
+
}
|
98 |
+
},
|
99 |
+
|
100 |
+
checkError(status, data) {
|
101 |
+
let errorType;
|
102 |
+
if (status >= 500) {
|
103 |
+
errorType = "SERVER_ERROR";
|
104 |
+
} else if (status >= 400 && status < 500) {
|
105 |
+
if (typeof data === "object" && data.error_type === "validation") {
|
106 |
+
if (data.error.includes("tokens")) {
|
107 |
+
errorType = ERROR_TOKENS;
|
108 |
+
} else {
|
109 |
+
errorType = "ERROR_VALIDATION";
|
110 |
+
}
|
111 |
+
} else {
|
112 |
+
errorType = "CLIENT_ERROR";
|
113 |
+
}
|
114 |
+
} else {
|
115 |
+
errorType = "UNKNOWN_ERROR";
|
116 |
+
}
|
117 |
+
return errorType;
|
118 |
+
},
|
119 |
+
|
120 |
+
isInvalidResponse(data) {
|
121 |
+
if (!data || !Array.isArray(data) || data.length === 0) {
|
122 |
+
return "INVALID_DATA";
|
123 |
+
}
|
124 |
+
if (!data[0].generated_text) {
|
125 |
+
return "MISSING_GENERATED_TEXT";
|
126 |
+
}
|
127 |
+
return null;
|
128 |
+
},
|
129 |
+
|
130 |
+
createErrorInfo(status, statusText, msg, errorType) {
|
131 |
+
const err = {
|
132 |
+
status: status,
|
133 |
+
statusText: statusText,
|
134 |
+
errorType: errorType,
|
135 |
+
message: msg || "Errore sconosciuto",
|
136 |
+
};
|
137 |
+
return JSON.stringify(err);
|
138 |
+
},
|
139 |
+
};
|
140 |
+
/////////////////////////
|
141 |
+
|
142 |
+
// const HfError = class extends Error {
|
143 |
+
// constructor(status, statusText, message, errorType) {
|
144 |
+
// super(message);
|
145 |
+
// this.name = "HfError";
|
146 |
+
// this.status = status;
|
147 |
+
// this.statusText = statusText;
|
148 |
+
// this.errorType = errorType;
|
149 |
+
// }
|
150 |
+
// };
|
151 |
+
|
152 |
+
// const HfRequest = {
|
153 |
+
// controller: null,
|
154 |
+
// isCancelled: false,
|
155 |
+
// baseUrl: "https://api-inference.huggingface.co/models",
|
156 |
+
|
157 |
+
// async post(payload, timeout = 30000) {
|
158 |
+
// this.isCancelled = false;
|
159 |
+
// this.controller = new AbortController();
|
160 |
+
|
161 |
+
// try {
|
162 |
+
// const timeoutId = setTimeout(() => this.controller.abort(), timeout);
|
163 |
+
// const response = await fetch(`${this.baseUrl}/${model_name}`, {
|
164 |
+
// method: "POST",
|
165 |
+
// headers: {
|
166 |
+
// Authorization: `Bearer ${HF_TOKEN}`,
|
167 |
+
// "Content-Type": "application/json",
|
168 |
+
// },
|
169 |
+
// body: JSON.stringify(payload),
|
170 |
+
// signal: this.controller.signal,
|
171 |
+
// });
|
172 |
+
// clearTimeout(timeoutId);
|
173 |
+
// if (this.isCancelled) return null;
|
174 |
+
// const data = await response.json();
|
175 |
+
// if (!response.ok) {
|
176 |
+
// throw this.createError(response, data);
|
177 |
+
// }
|
178 |
+
// if (!Array.isArray(data) || data.length === 0 || !data[0].generated_text) {
|
179 |
+
// throw this.createError(response, data, "Risposta non valida", "INVALID_RESPONSE");
|
180 |
+
// }
|
181 |
+
// return data[0].generated_text.trim();
|
182 |
+
// } catch (error) {
|
183 |
+
// if (this.isCancelled) return null;
|
184 |
+
// if (error.name === "AbortError") {
|
185 |
+
// throw this.createError(null, null, "La richiesta è scaduta", "TIMEOUT_ERROR");
|
186 |
+
// }
|
187 |
+
// if (error instanceof HfError) throw error;
|
188 |
+
// throw this.createError(null, null, error.message, "UNKNOWN_ERROR");
|
189 |
+
// }
|
190 |
+
// },
|
191 |
+
|
192 |
+
// cancelRequest() {
|
193 |
+
// if (this.controller) {
|
194 |
+
// this.isCancelled = true;
|
195 |
+
// this.controller.abort();
|
196 |
+
// }
|
197 |
+
// },
|
198 |
+
|
199 |
+
// createError(response, data, customMessage, customErrorType) {
|
200 |
+
// const status = response ? response.status : 0;
|
201 |
+
// const statusText = response ? response.statusText : "Unknown Error";
|
202 |
+
// const message = customMessage || (data && data.error) || "Errore sconosciuto";
|
203 |
+
// let errorType = customErrorType;
|
204 |
+
|
205 |
+
// if (!errorType) {
|
206 |
+
// if (status >= 500) errorType = "SERVER_ERROR";
|
207 |
+
// else if (status >= 400 && status < 500) {
|
208 |
+
// if (data && data.error_type === "validation") {
|
209 |
+
// errorType = data.error.includes("tokens") ? "ERROR_TOKENS" : "ERROR_VALIDATION";
|
210 |
+
// } else {
|
211 |
+
// errorType = "CLIENT_ERROR";
|
212 |
+
// }
|
213 |
+
// } else {
|
214 |
+
// errorType = "UNKNOWN_ERROR";
|
215 |
+
// }
|
216 |
+
// }
|
217 |
+
|
218 |
+
// return new HfError(status, statusText, message, errorType);
|
219 |
+
// },
|
220 |
+
// };
|
static/javascript/rag_mgr.js
ADDED
@@ -0,0 +1,405 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/** @format */
|
2 |
+
/**
|
3 |
+
* @license
|
4 |
+
* rag_rqs
|
5 |
+
* Copyright (C) 2024 [Il tuo nome]
|
6 |
+
*
|
7 |
+
* This program is free software: you can redistribute it and/or modify
|
8 |
+
* it under the terms of the GNU General Public License as published by
|
9 |
+
* the Free Software Foundation, either version 3 of the License, or
|
10 |
+
* (at your option) any later version.
|
11 |
+
*
|
12 |
+
* This program is distributed in the hope that it will be useful,
|
13 |
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14 |
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15 |
+
* GNU General Public License for more details.
|
16 |
+
*
|
17 |
+
* You should have received a copy of the GNU General Public License
|
18 |
+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
19 |
+
*/
|
20 |
+
"use strict";
|
21 |
+
const MAX_PROMPT_LENGTH = 1024 * 88;
|
22 |
+
// decremento dopo errore per tokens eccessivi
|
23 |
+
const PROMPT_DECR = 1024 * 2;
|
24 |
+
|
25 |
+
const Rag = {
|
26 |
+
// costituito dalla risposte accumulate sistemate
|
27 |
+
ragContext: "",
|
28 |
+
//query usata per creare la lista delle rispste
|
29 |
+
ragQuery: "",
|
30 |
+
// risposta finale alla qury contetso
|
31 |
+
ragResponse: "",
|
32 |
+
responses: [],
|
33 |
+
prompts: [],
|
34 |
+
doc: "",
|
35 |
+
doc_part: "",
|
36 |
+
saveToDb() {
|
37 |
+
const js = {
|
38 |
+
context: this.ragContext,
|
39 |
+
ragquery: this.ragQuery,
|
40 |
+
ragresponse: this.ragResponse,
|
41 |
+
};
|
42 |
+
UaDb.saveJson("id_rag", js);
|
43 |
+
},
|
44 |
+
readFromDb() {
|
45 |
+
const js = UaDb.readJson("id_rag");
|
46 |
+
this.ragContext = js.context || "";
|
47 |
+
this.ragQuery = js.ragquery || "";
|
48 |
+
this.ragResponse = js.ragresponse || "";
|
49 |
+
},
|
50 |
+
saveRespToDb() {
|
51 |
+
UaDb.saveArray("id_responses", this.responses);
|
52 |
+
},
|
53 |
+
readRespsFromDb() {
|
54 |
+
this.responses = UaDb.readArray("id_responses");
|
55 |
+
},
|
56 |
+
addPrompt(p) {
|
57 |
+
this.prompts.push(p);
|
58 |
+
},
|
59 |
+
responsesLength() {
|
60 |
+
const rspsl = this.responses.reduce((acc, cur) => {
|
61 |
+
return acc + cur.length;
|
62 |
+
}, 0);
|
63 |
+
return rspsl;
|
64 |
+
},
|
65 |
+
log(msg, plft, prgt) {
|
66 |
+
const maxl = MAX_PROMPT_LENGTH;
|
67 |
+
const rspsl = this.responsesLength();
|
68 |
+
const d = " ";
|
69 |
+
let s = `${msg} mx:${maxl} lft:${plft} rgt:${prgt} arr:${rspsl}`;
|
70 |
+
xlog(s);
|
71 |
+
s = `${msg}${d}${plft}${d}${prgt}${d}${rspsl}`;
|
72 |
+
//nsg plft.length prgt.length responses.length
|
73 |
+
UaLog.log(s);
|
74 |
+
},
|
75 |
+
truncInput(txt, decr) {
|
76 |
+
const tl = txt.length;
|
77 |
+
const lim = tl - decr;
|
78 |
+
const s = txt.substring(0, lim);
|
79 |
+
return s;
|
80 |
+
},
|
81 |
+
getPartSize(doc, prompt, decr) {
|
82 |
+
const limitWIthPoint = (s, free_len) => {
|
83 |
+
const idx = s.indexOf(".", free_len);
|
84 |
+
let lim = (idx != -1 ? idx : free_len) + 1;
|
85 |
+
if (lim > free_len + 100) {
|
86 |
+
lim = free_len;
|
87 |
+
}
|
88 |
+
return lim;
|
89 |
+
};
|
90 |
+
|
91 |
+
const dpl = doc.length + prompt.length;
|
92 |
+
const free_len = MAX_PROMPT_LENGTH - decr;
|
93 |
+
let size = 0;
|
94 |
+
if (dpl < free_len) {
|
95 |
+
size = doc.length;
|
96 |
+
} else {
|
97 |
+
size = limitWIthPoint(doc, free_len);
|
98 |
+
}
|
99 |
+
return size;
|
100 |
+
},
|
101 |
+
getPartDoc(doc, partSize) {
|
102 |
+
const part = doc.substring(0, partSize);
|
103 |
+
doc = doc.substring(partSize).trim();
|
104 |
+
return [part, doc];
|
105 |
+
},
|
106 |
+
|
107 |
+
errorInfo(err) {
|
108 |
+
const js = JSON.parse(err.message);
|
109 |
+
return js;
|
110 |
+
},
|
111 |
+
errorTotext(e) {
|
112 |
+
//
|
113 |
+
const j = JSON.parse(e.message);
|
114 |
+
return `Errore:
|
115 |
+
Stato: ${j.status}
|
116 |
+
Descrizione stato: ${j.statusText}
|
117 |
+
Tipo di errore: ${j.errorType}
|
118 |
+
Messaggio: ${j.message}`;
|
119 |
+
},
|
120 |
+
|
121 |
+
// documenti => risposte RAG => context
|
122 |
+
async requestDocsRAG(query) {
|
123 |
+
ThreadMgr.init();
|
124 |
+
DataMgr.deleteDati();
|
125 |
+
DataMgr.readDbDocNames();
|
126 |
+
DataMgr.readDbDocs();
|
127 |
+
this.ragQuery = query;
|
128 |
+
this.ragContext = "";
|
129 |
+
this.ragResponse = "";
|
130 |
+
this.responses = [];
|
131 |
+
this.prompts = [];
|
132 |
+
let ndoc = 0;
|
133 |
+
|
134 |
+
try {
|
135 |
+
for (let i = 0; i < DataMgr.docs.length; i++) {
|
136 |
+
let doc = DataMgr.docs[i];
|
137 |
+
if (doc.trim() == "") continue;
|
138 |
+
const name = DataMgr.doc_names[i];
|
139 |
+
const doc_entire_len = doc.length;
|
140 |
+
UaLog.log(`${name} (${doc_entire_len}) `);
|
141 |
+
xlog(`${name} (${doc_entire_len}) `);
|
142 |
+
++ndoc;
|
143 |
+
let npart = 0;
|
144 |
+
let partLft = "";
|
145 |
+
let partRgt = "";
|
146 |
+
let decr = 0;
|
147 |
+
let prompt = "";
|
148 |
+
// etsrazione informazioi da documenti
|
149 |
+
while (true) {
|
150 |
+
let partSize = this.getPartSize(doc, promptDoc("", query), decr);
|
151 |
+
if (partSize < 10) break;
|
152 |
+
// xlog("====================");
|
153 |
+
// xlog("partLft.lemngth:", partLft.length);
|
154 |
+
// xlog("partRgt.lemngth:", partRgt.length);
|
155 |
+
// xlog("prompt.length;", prompt.length);
|
156 |
+
[partLft, partRgt] = this.getPartDoc(doc, partSize);
|
157 |
+
prompt = promptDoc(partLft, query);
|
158 |
+
// xlog("------------");
|
159 |
+
// xlog("decr:", decr);
|
160 |
+
// xlog("partSize:", partSize);
|
161 |
+
// xlog("partLft.lemngth:", partLft.length);
|
162 |
+
// xlog("partRgt.lemngth:", partRgt.length);
|
163 |
+
// xlog("prompt.length;", prompt.length);
|
164 |
+
const payload = getPayloadDoc(prompt);
|
165 |
+
let text;
|
166 |
+
try {
|
167 |
+
text = await HfRequest.post(payload);
|
168 |
+
if (!text) return "";
|
169 |
+
} catch (err) {
|
170 |
+
const e = this.errorInfo(err);
|
171 |
+
if (e.errorType === ERROR_TOKENS) {
|
172 |
+
UaLog.log(`Error tokens.1 ${prompt.length}`);
|
173 |
+
xlog(`Error tokens. ${prompt.length}`);
|
174 |
+
decr += PROMPT_DECR;
|
175 |
+
continue;
|
176 |
+
} else {
|
177 |
+
xerror(err);
|
178 |
+
const s = this.errorTotext(err);
|
179 |
+
throw s;
|
180 |
+
}
|
181 |
+
}
|
182 |
+
npart++;
|
183 |
+
doc = partRgt;
|
184 |
+
if (npart == 1) {
|
185 |
+
text = `[[NOME_DOCUMENTO]]:${name}\n${text}`;
|
186 |
+
}
|
187 |
+
this.responses.push(text);
|
188 |
+
this.log(`${ndoc},${npart}`, partLft.length, partRgt.length);
|
189 |
+
}
|
190 |
+
}
|
191 |
+
} catch (error) {
|
192 |
+
alert("requestDocsRAG(1)\n" + error);
|
193 |
+
xerror(error);
|
194 |
+
}
|
195 |
+
|
196 |
+
// elenco risposte accumulate => contesto
|
197 |
+
/*
|
198 |
+
try {
|
199 |
+
let resps = list2text(this.responses);
|
200 |
+
let decr = 0;
|
201 |
+
let text = "";
|
202 |
+
let prompt = "";
|
203 |
+
|
204 |
+
while (true) {
|
205 |
+
resps = this.truncInput(resps, decr);
|
206 |
+
prompt = promptToContext(resps, query);
|
207 |
+
const payload = getPlayloadContext(prompt);
|
208 |
+
|
209 |
+
try {
|
210 |
+
text = await HfRequest.post(payload);
|
211 |
+
if (!text) return "";
|
212 |
+
} catch (err) {
|
213 |
+
const e = this.errorInfo(err);
|
214 |
+
if (e.errorType === ERROR_TOKENS) {
|
215 |
+
UaLog.log(`Error tokens.2 ${prompt.length}`);
|
216 |
+
xlog(`Error tokens. ${prompt.length}`);
|
217 |
+
decr += PROMPT_DECR;
|
218 |
+
continue;
|
219 |
+
} else {
|
220 |
+
xerror(err);
|
221 |
+
const s = this.errorTotext(err);
|
222 |
+
throw s;
|
223 |
+
}
|
224 |
+
}
|
225 |
+
break;
|
226 |
+
}
|
227 |
+
const pl = prompt.length;
|
228 |
+
//XXX text = cleanContext(text);
|
229 |
+
this.ragContext = text;
|
230 |
+
this.saveToDb();
|
231 |
+
UaLog.log(`Contesto (${pl})`);
|
232 |
+
} catch (error) {
|
233 |
+
xerror(error);
|
234 |
+
alert("requestDocsRAG(2)\n" + error);
|
235 |
+
throw error;
|
236 |
+
}
|
237 |
+
*/
|
238 |
+
////////////////////////////
|
239 |
+
// ALTENATIVA elenco come coontext
|
240 |
+
const resps = list2text(this.responses);
|
241 |
+
this.ragContext = resps;
|
242 |
+
this.saveToDb();
|
243 |
+
////////////////////////////
|
244 |
+
|
245 |
+
// query finale utilizza context
|
246 |
+
{
|
247 |
+
let text = "";
|
248 |
+
try {
|
249 |
+
let prompt = promptWithContext(this.ragContext, query);
|
250 |
+
const payload = getPayloadQuery(prompt);
|
251 |
+
|
252 |
+
try {
|
253 |
+
text = await HfRequest.post(payload);
|
254 |
+
if (!text) return "";
|
255 |
+
} catch (err) {
|
256 |
+
const e = this.errorInfo(err);
|
257 |
+
const s = this.errorTotext(err);
|
258 |
+
if (e.errorType === ERROR_TOKENS) {
|
259 |
+
xerror(err);
|
260 |
+
throw s;
|
261 |
+
} else {
|
262 |
+
xerror(err);
|
263 |
+
throw s;
|
264 |
+
}
|
265 |
+
}
|
266 |
+
this.ragResponse = text;
|
267 |
+
this.saveRespToDb();
|
268 |
+
this.saveToDb();
|
269 |
+
const pl = prompt.length;
|
270 |
+
UaLog.log(`Risposta (${pl},${text.length})`);
|
271 |
+
} catch (error) {
|
272 |
+
text = error;
|
273 |
+
xerror(error);
|
274 |
+
alert("requestDocsRAG(3)\n" + error);
|
275 |
+
throw error;
|
276 |
+
} finally {
|
277 |
+
text = cleanOutput(text);
|
278 |
+
return text;
|
279 |
+
}
|
280 |
+
}
|
281 |
+
},
|
282 |
+
|
283 |
+
// TRHREAD
|
284 |
+
async requestContext(query) {
|
285 |
+
this.readFromDb();
|
286 |
+
|
287 |
+
if (!this.ragContext) {
|
288 |
+
const ok = await confirm("Contesto vuoto. Vuoi continuare?");
|
289 |
+
if (!ok) return "";
|
290 |
+
}
|
291 |
+
|
292 |
+
if (ThreadMgr.isFirst()) {
|
293 |
+
let outText = "";
|
294 |
+
try {
|
295 |
+
let context = this.ragContext;
|
296 |
+
let prompt = promptWithContext(context, query);
|
297 |
+
const payload = getPayloadQuery(prompt);
|
298 |
+
|
299 |
+
let text;
|
300 |
+
try {
|
301 |
+
text = await HfRequest.post(payload);
|
302 |
+
if (!text) return "";
|
303 |
+
} catch (err) {
|
304 |
+
const e = this.errorInfo(err);
|
305 |
+
if (e.errorType === ERROR_TOKENS) {
|
306 |
+
UaLog.log(`Error tokens.4 ${prompt.length}`);
|
307 |
+
xerror(err);
|
308 |
+
throw err;
|
309 |
+
} else {
|
310 |
+
alert(err)
|
311 |
+
xerror(err);
|
312 |
+
throw err;
|
313 |
+
}
|
314 |
+
}
|
315 |
+
ThreadMgr.add(query, text);
|
316 |
+
outText = ThreadMgr.getOutText();
|
317 |
+
UaLog.log(`Inizio Conversazione (${prompt.length},${text.length})`);
|
318 |
+
} catch (error) {
|
319 |
+
xerror(error);
|
320 |
+
outText = error;
|
321 |
+
throw error;
|
322 |
+
} finally {
|
323 |
+
outText = cleanOutput(outText);
|
324 |
+
return outText;
|
325 |
+
}
|
326 |
+
} else {
|
327 |
+
let outText = "";
|
328 |
+
try {
|
329 |
+
let context = this.ragContext;
|
330 |
+
let thread = ThreadMgr.getThread();
|
331 |
+
let prompt = "";
|
332 |
+
let text = "";
|
333 |
+
let decr = 0;
|
334 |
+
|
335 |
+
while (true) {
|
336 |
+
thread = this.truncInput(thread, decr);
|
337 |
+
prompt = promptThread(context, thread, query);
|
338 |
+
const payload = getPayloadQuery(prompt);
|
339 |
+
|
340 |
+
try {
|
341 |
+
text = await HfRequest.post(payload);
|
342 |
+
if (!text) return "";
|
343 |
+
} catch (err) {
|
344 |
+
const e = this.errorInfo(err);
|
345 |
+
if (e.errorType === ERROR_TOKENS) {
|
346 |
+
UaLog.log(`Error tokens.5 ${prompt.length}`);
|
347 |
+
xlog(`Error tokens. ${prompt.length}`);
|
348 |
+
decr += PROMPT_DECR;
|
349 |
+
continue;
|
350 |
+
} else {
|
351 |
+
xerror(err);
|
352 |
+
throw e.errorType;
|
353 |
+
}
|
354 |
+
}
|
355 |
+
break;
|
356 |
+
}
|
357 |
+
ThreadMgr.add(query, text);
|
358 |
+
outText = ThreadMgr.getOutText();
|
359 |
+
UaLog.log(`Conversazione (${prompt.length},${text.length})`);
|
360 |
+
} catch (error) {
|
361 |
+
alert("requestContext(2) \n" + error);
|
362 |
+
xerror(error);
|
363 |
+
outText = error;
|
364 |
+
throw error;
|
365 |
+
} finally {
|
366 |
+
outText = cleanOutput(outText);
|
367 |
+
return outText;
|
368 |
+
}
|
369 |
+
}
|
370 |
+
},
|
371 |
+
};
|
372 |
+
|
373 |
+
const ThreadMgr = {
|
374 |
+
rows: [],
|
375 |
+
init() {
|
376 |
+
this.rows = [];
|
377 |
+
},
|
378 |
+
add(query, resp) {
|
379 |
+
const row = [query, resp];
|
380 |
+
this.rows.push(row);
|
381 |
+
},
|
382 |
+
getOutText() {
|
383 |
+
const rows = [];
|
384 |
+
for (const ua of this.rows) {
|
385 |
+
const u = ua[0].trim();
|
386 |
+
const a = ua[1].trim();
|
387 |
+
rows.push(`<user>:\n${u}\n<Assistant>:\n${a}\n\n`);
|
388 |
+
}
|
389 |
+
let text = rows.join("").trim();
|
390 |
+
return text;
|
391 |
+
},
|
392 |
+
getThread() {
|
393 |
+
const rows = [];
|
394 |
+
for (const ua of this.rows) {
|
395 |
+
const u = ua[0].trim();
|
396 |
+
const a = ua[1].trim();
|
397 |
+
rows.push(`<user>:\n${u}\n<Assitant>:\n${a}\n\n`);
|
398 |
+
}
|
399 |
+
const text = rows.join("").trim();
|
400 |
+
return text;
|
401 |
+
},
|
402 |
+
isFirst() {
|
403 |
+
return this.rows.length == 0;
|
404 |
+
},
|
405 |
+
};
|
static/javascript/rag_prompts.js
ADDED
@@ -0,0 +1,235 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"use strict";
|
2 |
+
|
3 |
+
function promptDoc(documento, domanda) {
|
4 |
+
return `
|
5 |
+
[[RUOLO]]
|
6 |
+
Analista di documenti esperto nell'estrazione di informazioni pertinenti.
|
7 |
+
|
8 |
+
[[COMPITO]]
|
9 |
+
Analizza il documento e estrai le informazioni rilevanti per la domanda.
|
10 |
+
|
11 |
+
[[DOCUMENTO]]
|
12 |
+
${documento}
|
13 |
+
|
14 |
+
[[DOMANDA]]
|
15 |
+
${domanda}
|
16 |
+
|
17 |
+
[[ISTRUZIONI]]
|
18 |
+
1. Identifica i concetti chiave e sintetizzali per fornire una risposta completa.
|
19 |
+
2. Assicurati di organizzare le informazioni in modo chiaro e logico.
|
20 |
+
3. Conserva le informazioni contrastanti, se presenti, senza tentare di risolverle.
|
21 |
+
4. Puoi fare inferenze ragionevoli basate sulle informazioni fornite.
|
22 |
+
5. Includi citazioni o riferimenti specifici al documento solo se necessari per chiarire la descrizione.
|
23 |
+
|
24 |
+
[[OUTPUT]]
|
25 |
+
Elenco delle informazioni identificate, incluse eventuali inferenze
|
26 |
+
`;
|
27 |
+
}
|
28 |
+
|
29 |
+
function promptToContext(risposte) {
|
30 |
+
return `
|
31 |
+
[[RUOLO]]
|
32 |
+
Esperto di analisi semantica delle informazioni.
|
33 |
+
|
34 |
+
[[OBIETTIVO]]
|
35 |
+
Unificare le informazioni semanticamente equivalenti da vari documenti.
|
36 |
+
|
37 |
+
[[ELENCO_RISPOSTE]]
|
38 |
+
${risposte}
|
39 |
+
|
40 |
+
[[ISTRUZIONI]]
|
41 |
+
1. Analizza le informazioni dell'elenco risposte.
|
42 |
+
2. Per ogni documento raggruppa le informazioni sulla base del loro significato.
|
43 |
+
3. Presenta le informazioni in modo chiaro e coerente.
|
44 |
+
|
45 |
+
[[OUTPUT]]
|
46 |
+
Elenco delle informazioni mantenendo la divisione per documento.
|
47 |
+
`;
|
48 |
+
}
|
49 |
+
|
50 |
+
function promptWithContext(contesto, domanda) {
|
51 |
+
return `
|
52 |
+
[[COMPITO]]
|
53 |
+
Elabora una risposta esaustiva e pertinente alla domanda basata sul contesto fornito.
|
54 |
+
|
55 |
+
[[CONTESTO]]
|
56 |
+
${contesto}
|
57 |
+
|
58 |
+
[[DOMANDA]]
|
59 |
+
${domanda}
|
60 |
+
|
61 |
+
[[ISTRUZIONI]]
|
62 |
+
1. Analizza attentamente il contesto e la domanda posta.
|
63 |
+
2. Struttura una risposta logica, coerente e completa.
|
64 |
+
3. Utilizza le informazioni del contesto, citando i documenti di origine solo se necessario per chiarire la descrizione.
|
65 |
+
4. Evidenzia le connessioni tra i vari concetti e le fonti.
|
66 |
+
5. Includi inferenze ragionevoli.
|
67 |
+
|
68 |
+
[[OUTPUT]]
|
69 |
+
L'output è destinato ad essere letto da un lettore italiano.
|
70 |
+
`;
|
71 |
+
}
|
72 |
+
|
73 |
+
function promptThread(contesto, conversazione, domanda) {
|
74 |
+
return `
|
75 |
+
[[COMPITO]]
|
76 |
+
Rispondi alla nuova domanda integrando il contesto iniziale e gli sviluppi della conversazione in corso.
|
77 |
+
|
78 |
+
[[CONTESTO]]
|
79 |
+
${contesto}
|
80 |
+
|
81 |
+
[[CONVERSAZIONE]]
|
82 |
+
${conversazione}
|
83 |
+
|
84 |
+
[[DOMANDA]]
|
85 |
+
${domanda}
|
86 |
+
|
87 |
+
[[ISTRUZIONI]]
|
88 |
+
1. Analizza la nuova domanda nel contesto della conversazione in corso.
|
89 |
+
2. Integra le informazioni dal contesto iniziale con gli sviluppi della discussione.
|
90 |
+
3. Mantieni la coerenza con la conversazione precedente, evitando ripetizioni non necessarie.
|
91 |
+
4. Puoi fare inferenze ragionevoli.
|
92 |
+
5. Adatta la risposta alla domanda attuale, anche se si discosta dal tema principale della conversazione.
|
93 |
+
6. Usa citazioni o riferimenti solo se necessario per chiarire la descrizione.
|
94 |
+
|
95 |
+
[[OUTPUT]]
|
96 |
+
L'output è destinato ad essere letto da un lettore italiano.
|
97 |
+
`;
|
98 |
+
}
|
99 |
+
|
100 |
+
///////////////////////////////////}
|
101 |
+
/*
|
102 |
+
|
103 |
+
1. max_new_tokens: 512
|
104 |
+
Questo è un valore ragionevole per risposte di lunghezza media.
|
105 |
+
Potrebbe essere aumentato a 1024 o più se si desiderano risposte più lunghe e dettagliate.
|
106 |
+
|
107 |
+
2. temperature: 0.7
|
108 |
+
Questo valore offre un buon equilibrio tra creatività e coerenza.
|
109 |
+
Va bene per la maggior parte degli usi.
|
110 |
+
|
111 |
+
3. top_k: 50
|
112 |
+
Un valore standard che limita la selezione alle 50 parole più probabili.
|
113 |
+
È appropriato per la maggior parte delle applicazioni.
|
114 |
+
|
115 |
+
4. top_p: 0.85
|
116 |
+
Questo valore di nucleus sampling è buono per mantenere un buon equilibrio
|
117 |
+
tra diversità e coerenza.
|
118 |
+
|
119 |
+
5. do_sample: true
|
120 |
+
Corretto per generare testo più vario.
|
121 |
+
|
122 |
+
6. no_repeat_ngram_size: 3
|
123 |
+
Aiuta a evitare ripetizioni a breve termine.
|
124 |
+
Potrebbe essere aumentato a 4 o 5 per evitare ripetizioni più lunghe.
|
125 |
+
|
126 |
+
7. num_beams: 5
|
127 |
+
Un buon valore per la beam search.
|
128 |
+
Aumentarlo potrebbe migliorare la qualità ma aumenterebbe anche il
|
129 |
+
tempo di elaborazione.
|
130 |
+
|
131 |
+
8. repetition_penalty: 1.2
|
132 |
+
Un valore moderato per penalizzare le ripetizioni.
|
133 |
+
Potrebbe essere aumentato leggermente (es. 1.3 o 1.4) se si notano
|
134 |
+
ancora troppe ripetizioni.
|
135 |
+
|
136 |
+
9. return_full_text: false
|
137 |
+
Corretto se si vuole solo il nuovo testo generato.
|
138 |
+
|
139 |
+
10. max_time: 60.0
|
140 |
+
Un minuto è un tempo ragionevole. Potrebbe essere aumentato
|
141 |
+
se si stanno generando risposte molto lunghe o complesse.
|
142 |
+
|
143 |
+
11. seed: 42
|
144 |
+
Un valore fisso per la riproducibilità.
|
145 |
+
Va bene se si desidera coerenza tra le esecuzioni.
|
146 |
+
|
147 |
+
Suggerimenti per l'ottimizzazione:
|
148 |
+
1. Considera di aumentare max_new_tokens a 1024 o più se hai bisogno di risposte più lunghe.
|
149 |
+
2. Potresti aumentare leggermente no_repeat_ngram_size a 4 per ridurre ulteriormente le ripetizioni.
|
150 |
+
3. Se desideri risposte più precise e meno creative, potresti ridurre temperature a 0.6 e top_p a 0.8.
|
151 |
+
4. Per risposte più diverse, potresti aumentare temperature a 0.8 e top_p a 0.9.
|
152 |
+
5. Se noti ancora troppe ripetizioni, considera di aumentare repetition_penalty a 1.3 o 1.4.
|
153 |
+
*/
|
154 |
+
const getPayloadDoc = (prompt) => {
|
155 |
+
let payload = {
|
156 |
+
inputs: prompt,
|
157 |
+
parameters: {
|
158 |
+
task: "text2text-generation",
|
159 |
+
max_new_tokens: 512,
|
160 |
+
num_return_sequences: 1,
|
161 |
+
temperature: 0.6,
|
162 |
+
top_k: 50,
|
163 |
+
top_p: 0.85,
|
164 |
+
do_sample: true,
|
165 |
+
no_repeat_ngram_size: 4,
|
166 |
+
num_beams: 6,
|
167 |
+
repetition_penalty: 1.2,
|
168 |
+
return_full_text: false,
|
169 |
+
details: false,
|
170 |
+
max_time: 90.0,
|
171 |
+
seed: 42,
|
172 |
+
},
|
173 |
+
options: {
|
174 |
+
use_cache: false,
|
175 |
+
wait_for_model: true,
|
176 |
+
},
|
177 |
+
};
|
178 |
+
return payload;
|
179 |
+
};
|
180 |
+
|
181 |
+
const getPlayloadContext = (prompt) => {
|
182 |
+
let payload = {
|
183 |
+
inputs: prompt,
|
184 |
+
parameters: {
|
185 |
+
task: "text2text-generation",
|
186 |
+
max_new_tokens: 1024,
|
187 |
+
num_return_sequences: 1,
|
188 |
+
temperature: 0.8,
|
189 |
+
top_k: 50,
|
190 |
+
top_p: 0.85,
|
191 |
+
do_sample: true,
|
192 |
+
no_repeat_ngram_size: 3,
|
193 |
+
num_beams: 5,
|
194 |
+
repetition_penalty: 1.1,
|
195 |
+
return_full_text: false,
|
196 |
+
details: false,
|
197 |
+
max_time: 120.0,
|
198 |
+
seed: 42,
|
199 |
+
},
|
200 |
+
options: {
|
201 |
+
use_cache: false,
|
202 |
+
wait_for_model: true,
|
203 |
+
},
|
204 |
+
};
|
205 |
+
return payload;
|
206 |
+
};
|
207 |
+
|
208 |
+
const getPayloadQuery = (prompt) => {
|
209 |
+
const seed = Math.floor(Math.random() * Math.pow(2, 32));
|
210 |
+
let payload = {
|
211 |
+
inputs: prompt,
|
212 |
+
parameters: {
|
213 |
+
task: "text-generation",
|
214 |
+
max_new_tokens: 512,
|
215 |
+
num_return_sequences: 1,
|
216 |
+
temperature: 0.7,
|
217 |
+
top_k: 50,
|
218 |
+
top_p: 0.85,
|
219 |
+
do_sample: true,
|
220 |
+
no_repeat_ngram_size: 3,
|
221 |
+
num_beams: 5,
|
222 |
+
repetition_penalty: 1.4,
|
223 |
+
return_full_text: false,
|
224 |
+
details: false,
|
225 |
+
max_time: 120.0,
|
226 |
+
seed: 42,
|
227 |
+
},
|
228 |
+
options: {
|
229 |
+
use_cache: false,
|
230 |
+
wait_for_model: true,
|
231 |
+
},
|
232 |
+
};
|
233 |
+
return payload;
|
234 |
+
};
|
235 |
+
|
static/javascript/rag_rqs.js
ADDED
@@ -0,0 +1,243 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/** @format */
|
2 |
+
/**
|
3 |
+
* @license
|
4 |
+
* rag_rqs
|
5 |
+
* Copyright (C) 2024 [Il tuo nome]
|
6 |
+
*
|
7 |
+
* This program is free software: you can redistribute it and/or modify
|
8 |
+
* it under the terms of the GNU General Public License as published by
|
9 |
+
* the Free Software Foundation, either version 3 of the License, or
|
10 |
+
* (at your option) any later version.
|
11 |
+
*
|
12 |
+
* This program is distributed in the hope that it will be useful,
|
13 |
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14 |
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15 |
+
* GNU General Public License for more details.
|
16 |
+
*
|
17 |
+
* You should have received a copy of the GNU General Public License
|
18 |
+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
19 |
+
*/
|
20 |
+
|
21 |
+
"use strict";
|
22 |
+
const VERS = "0.1.33 (16-07-2024)";
|
23 |
+
|
24 |
+
var xlog = console.log;
|
25 |
+
var xerror = console.error;
|
26 |
+
//////////////////////
|
27 |
+
|
28 |
+
/////////////////////////
|
29 |
+
// let T0 = {};
|
30 |
+
|
31 |
+
// var start_performance = function (k) {
|
32 |
+
// T0.k = performance.now();
|
33 |
+
// };
|
34 |
+
|
35 |
+
// var log_performance = function (k, msg = "") {
|
36 |
+
// const t1 = performance.now();
|
37 |
+
// const d = t1 - T0.k;
|
38 |
+
// console.log(msg, d);
|
39 |
+
// T0.k = t1;
|
40 |
+
// return d;
|
41 |
+
// };
|
42 |
+
|
43 |
+
// function showMessage(message, duraction = 5000) {
|
44 |
+
// const popup = document.createElement("div");
|
45 |
+
// popup.className = "msg";
|
46 |
+
// popup.innerText = message;
|
47 |
+
// document.body.appendChild(popup);
|
48 |
+
// setTimeout(function () {
|
49 |
+
// document.body.removeChild(popup);
|
50 |
+
// }, duraction);
|
51 |
+
// }
|
52 |
+
|
53 |
+
const cancelRequest = () => {
|
54 |
+
const ok = confirm("Confermi Cancellazione Richeista ?");
|
55 |
+
if (!ok) return;
|
56 |
+
HfRequest.cancelRequest();
|
57 |
+
hideSpinner();
|
58 |
+
};
|
59 |
+
|
60 |
+
const showSpinner = () => {
|
61 |
+
const spinner = document.getElementById("spinner");
|
62 |
+
spinner.classList.add("show-spinner");
|
63 |
+
spinner.addEventListener("click", cancelRequest);
|
64 |
+
};
|
65 |
+
|
66 |
+
const hideSpinner = () => {
|
67 |
+
const spinner = document.getElementById("spinner");
|
68 |
+
spinner.classList.remove("show-spinner");
|
69 |
+
spinner.removeEventListener("click", cancelRequest);
|
70 |
+
};
|
71 |
+
|
72 |
+
////////////////////////
|
73 |
+
function openApp() {
|
74 |
+
wnds.init();
|
75 |
+
Menu.init();
|
76 |
+
TextInput.init();
|
77 |
+
TextOutput.init();
|
78 |
+
document.querySelector(".menu-btn").checked = false;
|
79 |
+
release();
|
80 |
+
}
|
81 |
+
|
82 |
+
function release() {
|
83 |
+
document.querySelector(".release").innerHTML = VERS;
|
84 |
+
}
|
85 |
+
|
86 |
+
/////////////////////////
|
87 |
+
// README
|
88 |
+
const op0 = async function (e) {
|
89 |
+
const text = await requestGet("./help1.html");
|
90 |
+
wnds.wdiv.show(text);
|
91 |
+
};
|
92 |
+
|
93 |
+
//query iniziale
|
94 |
+
function op1(e) {
|
95 |
+
Rag.readFromDb();
|
96 |
+
const txt = `\n${Rag.ragQuery}`;
|
97 |
+
wnds.wpre.show(txt);
|
98 |
+
// Menu.close();
|
99 |
+
}
|
100 |
+
|
101 |
+
//Rispost Rsg
|
102 |
+
function showRagResponse(e) {
|
103 |
+
Rag.readFromDb();
|
104 |
+
const txt = `\n${Rag.ragResponse}`;
|
105 |
+
wnds.wpre.show(txt);
|
106 |
+
}
|
107 |
+
|
108 |
+
//elenco risposte
|
109 |
+
function op2(e) {
|
110 |
+
let rs = [...Rag.responses];
|
111 |
+
if (rs.length == 0) {
|
112 |
+
rs = UaDb.readArray("id_responses");
|
113 |
+
}
|
114 |
+
if (rs.length == 0) return;
|
115 |
+
const text = rs
|
116 |
+
.map((x, i) => {
|
117 |
+
return `[${i + 1}]\n ${x.trim()}`;
|
118 |
+
})
|
119 |
+
.join("\n");
|
120 |
+
wnds.wpre.show(text);
|
121 |
+
// Menu.close();
|
122 |
+
}
|
123 |
+
|
124 |
+
//contesto
|
125 |
+
function op3(e) {
|
126 |
+
Rag.readFromDb();
|
127 |
+
const txt = `${Rag.ragContext}`;
|
128 |
+
wnds.wpre.show(txt);
|
129 |
+
// Menu.close();
|
130 |
+
}
|
131 |
+
|
132 |
+
//elemco dati
|
133 |
+
function op4(e) {
|
134 |
+
const ids = UaDb.getAllIds();
|
135 |
+
const arr = [];
|
136 |
+
for (const id of ids) {
|
137 |
+
const s = UaDb.read(id);
|
138 |
+
const l = s.length;
|
139 |
+
arr.push(`${id} (${l})`);
|
140 |
+
}
|
141 |
+
let msg = arr.join("\n ");
|
142 |
+
wnds.wpre.show(msg);
|
143 |
+
}
|
144 |
+
|
145 |
+
//elenco documenti
|
146 |
+
async function op5(e) {
|
147 |
+
DataMgr.readDbDocNames();
|
148 |
+
const arr = DataMgr.doc_names;
|
149 |
+
const s = arr.join("\n");
|
150 |
+
wnds.wpre.show(s);
|
151 |
+
}
|
152 |
+
|
153 |
+
//calcolo query
|
154 |
+
function calcQuery() {
|
155 |
+
const calc = () => {
|
156 |
+
const arr = [];
|
157 |
+
let nptot = 0;
|
158 |
+
let i = 0;
|
159 |
+
arr.push(`Documento Num.Parti`);
|
160 |
+
arr.push("==================");
|
161 |
+
for (const doc of DataMgr.docs) {
|
162 |
+
const name = DataMgr.doc_names[i];
|
163 |
+
i += 1;
|
164 |
+
const dl = doc.length;
|
165 |
+
const np = Math.ceil(dl / MAX_PROMPT_LENGTH);
|
166 |
+
nptot += np;
|
167 |
+
arr.push(`${name} [${np}]`);
|
168 |
+
}
|
169 |
+
arr.push("==================");
|
170 |
+
arr.push(`Totale num. Parti: ${nptot}`);
|
171 |
+
const s = arr.join("\n");
|
172 |
+
return s;
|
173 |
+
};
|
174 |
+
DataMgr.readDbDocs();
|
175 |
+
DataMgr.readDbDocNames();
|
176 |
+
const s = calc();
|
177 |
+
wnds.wpre.show(s);
|
178 |
+
}
|
179 |
+
|
180 |
+
//cancellA DATI
|
181 |
+
function op7(e) {
|
182 |
+
const ok = confirm("Confermi cancellazione dati?");
|
183 |
+
if (ok) {
|
184 |
+
DataMgr.deleteDati();
|
185 |
+
Rag.ragContext = "";
|
186 |
+
Rag.ragQuery = "";
|
187 |
+
Rag.responses = [];
|
188 |
+
wnds.wdiv.close();
|
189 |
+
wnds.wpre.close();
|
190 |
+
TextOutput.clear();
|
191 |
+
}
|
192 |
+
}
|
193 |
+
//cancella localstrage
|
194 |
+
function op8(e) {
|
195 |
+
const ok = confirm("Confermi cancellazione documenti & dati?");
|
196 |
+
if (ok) {
|
197 |
+
localStorage.clear();
|
198 |
+
Rag.ragContext = "";
|
199 |
+
Rag.ragQuery = "";
|
200 |
+
Rag.responses = [];
|
201 |
+
wnds.wdiv.close();
|
202 |
+
wnds.wpre.close();
|
203 |
+
TextOutput.clear();
|
204 |
+
DataMgr.docs = [];
|
205 |
+
DataMgr.doc_names = [];
|
206 |
+
}
|
207 |
+
}
|
208 |
+
////////////////////////////////
|
209 |
+
// Solo Sviluppo
|
210 |
+
//prompts
|
211 |
+
function op9(e) {
|
212 |
+
if (Rag.prompts.length == 0) return;
|
213 |
+
const text = Rag.prompts
|
214 |
+
.map((x, i) => {
|
215 |
+
return `[${i + 1}]${x}\n`;
|
216 |
+
})
|
217 |
+
.join("\n");
|
218 |
+
wnds.wpre.show(text);
|
219 |
+
}
|
220 |
+
//testi
|
221 |
+
function op6(e) {
|
222 |
+
DataMgr.readDbDocs();
|
223 |
+
const arr = DataMgr.docs;
|
224 |
+
const s = arr.join("\n");
|
225 |
+
wnds.wpre.show(s);
|
226 |
+
}
|
227 |
+
///////////////////////////
|
228 |
+
async function help1(e) {
|
229 |
+
const text = await requestGet("./data/help_test.html");
|
230 |
+
wnds.wdiv.show(text);
|
231 |
+
}
|
232 |
+
|
233 |
+
//lanciata dalla pagina diegli sempi
|
234 |
+
function esempio(name) {
|
235 |
+
const link = `data/${name}`;
|
236 |
+
DataMgr.loadDoc(link);
|
237 |
+
wnds.wdiv.close();
|
238 |
+
}
|
239 |
+
|
240 |
+
async function help2(e) {
|
241 |
+
const text = await requestGet("./help2.html");
|
242 |
+
wnds.wdiv.show(text);
|
243 |
+
}
|
static/javascript/rag_ui.js
ADDED
@@ -0,0 +1,360 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/** @format */
|
2 |
+
/**
|
3 |
+
* @license
|
4 |
+
* rag_rqs
|
5 |
+
* Copyright (C) 2024 [Il tuo nome]
|
6 |
+
*
|
7 |
+
* This program is free software: you can redistribute it and/or modify
|
8 |
+
* it under the terms of the GNU General Public License as published by
|
9 |
+
* the Free Software Foundation, either version 3 of the License, or
|
10 |
+
* (at your option) any later version.
|
11 |
+
*
|
12 |
+
* This program is distributed in the hope that it will be useful,
|
13 |
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14 |
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15 |
+
* GNU General Public License for more details.
|
16 |
+
*
|
17 |
+
* You should have received a copy of the GNU General Public License
|
18 |
+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
19 |
+
*/
|
20 |
+
const WndPre = (id) => {
|
21 |
+
return {
|
22 |
+
w: UaWindowAdm.create(id),
|
23 |
+
out: null,
|
24 |
+
show(s) {
|
25 |
+
const fh = (txt) => {
|
26 |
+
return `
|
27 |
+
<div class="window-text">
|
28 |
+
<div class="btn-wrapper">
|
29 |
+
<button class="btn-copy" title="Copia">
|
30 |
+
<svg class="copy-icon" viewBox="0 0 20 24">
|
31 |
+
<path d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z" />
|
32 |
+
</svg>
|
33 |
+
</button>
|
34 |
+
<button class="btn-close" title="chiudi" onclick="UaWindowAdm.closeThis(this)">X</button>
|
35 |
+
</div>
|
36 |
+
<pre class="pre-text">${txt}</pre>
|
37 |
+
</div>
|
38 |
+
`;
|
39 |
+
};
|
40 |
+
wnds.closeAll();
|
41 |
+
const h = fh(s);
|
42 |
+
this.w.drag();
|
43 |
+
this.w.setZ(12);
|
44 |
+
this.w.vw_vh().setXY(16.5, 10, -1);
|
45 |
+
this.w.setHtml(h);
|
46 |
+
this.w.show();
|
47 |
+
const e = this.w.getElement();
|
48 |
+
const copyBtn = e.querySelector(".btn-copy");
|
49 |
+
copyBtn.addEventListener("click", () => this.copy());
|
50 |
+
},
|
51 |
+
close() {
|
52 |
+
this.w.close();
|
53 |
+
},
|
54 |
+
async copy() {
|
55 |
+
const e = this.w.getElement();
|
56 |
+
const pre = e.querySelector(".pre-text");
|
57 |
+
const t = pre.textContent;
|
58 |
+
try {
|
59 |
+
await navigator.clipboard.writeText(t);
|
60 |
+
} catch (err) {
|
61 |
+
xerror("Errore ", err);
|
62 |
+
}
|
63 |
+
},
|
64 |
+
};
|
65 |
+
};
|
66 |
+
|
67 |
+
const WndDiv = (id) => {
|
68 |
+
return {
|
69 |
+
w: UaWindowAdm.create(id),
|
70 |
+
out: null,
|
71 |
+
show(s) {
|
72 |
+
const fh = (txt) => {
|
73 |
+
return `
|
74 |
+
<div class="window-text">
|
75 |
+
<div class="btn-wrapper">
|
76 |
+
<button class="btn-copy" title="Copia">
|
77 |
+
<svg class="copy-icon" viewBox="0 0 20 24">
|
78 |
+
<path d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z" />
|
79 |
+
</svg>
|
80 |
+
</button>
|
81 |
+
<button class="btn-close" title="chiudi" onclick="UaWindowAdm.closeThis(this)">X</button>
|
82 |
+
</div>
|
83 |
+
<div class="div-text">${txt}</div>
|
84 |
+
</div>
|
85 |
+
`;
|
86 |
+
};
|
87 |
+
wnds.closeAll();
|
88 |
+
const h = fh(s);
|
89 |
+
this.w.drag();
|
90 |
+
this.w.setZ(12);
|
91 |
+
this.w.vw_vh().setXY(16.5, 10, -1);
|
92 |
+
this.w.setHtml(h);
|
93 |
+
this.w.show();
|
94 |
+
const e = this.w.getElement();
|
95 |
+
const copyBtn = e.querySelector(".btn-copy");
|
96 |
+
copyBtn.addEventListener("click", () => this.copy());
|
97 |
+
},
|
98 |
+
close() {
|
99 |
+
this.w.close();
|
100 |
+
},
|
101 |
+
async copy() {
|
102 |
+
const e = this.w.getElement();
|
103 |
+
const pre = e.querySelector(".div-text");
|
104 |
+
const t = pre.textContent;
|
105 |
+
try {
|
106 |
+
await navigator.clipboard.writeText(t);
|
107 |
+
} catch (err) {
|
108 |
+
xerror("Errore ", err);
|
109 |
+
}
|
110 |
+
},
|
111 |
+
};
|
112 |
+
};
|
113 |
+
|
114 |
+
const wnds = {
|
115 |
+
wdiv: null,
|
116 |
+
wpre: null,
|
117 |
+
wout: null,
|
118 |
+
init() {
|
119 |
+
this.wdiv = WndDiv("id_w0");
|
120 |
+
this.wpre = WndPre("id_w1");
|
121 |
+
this.wout = WndPre("id_out");
|
122 |
+
},
|
123 |
+
closeAll() {
|
124 |
+
UaWindowAdm.close("id_w0");
|
125 |
+
UaWindowAdm.close("id_w1");
|
126 |
+
UaWindowAdm.close("id_out");
|
127 |
+
},
|
128 |
+
};
|
129 |
+
|
130 |
+
const Menu = {
|
131 |
+
init() {
|
132 |
+
// gestione menu
|
133 |
+
const btn = document.querySelector("#id-menu-btn");
|
134 |
+
btn.addEventListener("change", () => {
|
135 |
+
document.querySelector("body").classList.toggle("menu-open", btn.checked);
|
136 |
+
});
|
137 |
+
// getsioe log
|
138 |
+
const log = document.getElementById("id_log");
|
139 |
+
|
140 |
+
const show = () => {
|
141 |
+
if (log.classList.contains("active")) return;
|
142 |
+
log.classList.add("active");
|
143 |
+
};
|
144 |
+
|
145 |
+
const hide = () => {
|
146 |
+
if (!log.classList.contains("active")) return;
|
147 |
+
log.classList.remove("active");
|
148 |
+
};
|
149 |
+
UaLog.callHide = hide;
|
150 |
+
UaLog.callShow = show;
|
151 |
+
|
152 |
+
UaLog.setXY(64, 13).setZ(111).new();
|
153 |
+
UaLog.log_show("Buon Lavoro");
|
154 |
+
},
|
155 |
+
close() {
|
156 |
+
const btn = document.querySelector("#menu-toggle");
|
157 |
+
document.querySelector("body").classList.remove("menu-open", btn.checked);
|
158 |
+
document.querySelector(".menu-btn").checked = false;
|
159 |
+
},
|
160 |
+
async help() {
|
161 |
+
const text = await requestGet("./help0.html");
|
162 |
+
wnds.wdiv.show(text);
|
163 |
+
},
|
164 |
+
upload() {
|
165 |
+
RagUpload.open();
|
166 |
+
},
|
167 |
+
uploadDir() {
|
168 |
+
RagUpload.openDir();
|
169 |
+
},
|
170 |
+
async load() {
|
171 |
+
alert("load");
|
172 |
+
},
|
173 |
+
log() {
|
174 |
+
UaLog.toggle();
|
175 |
+
},
|
176 |
+
};
|
177 |
+
|
178 |
+
|
179 |
+
const TextInput = {
|
180 |
+
wnd: null,
|
181 |
+
init() {
|
182 |
+
this.inp = document.querySelector(".text-input");
|
183 |
+
document.addEventListener("keydown", (e) => {
|
184 |
+
if (document.activeElement !== this.inp) {
|
185 |
+
const allowedKeys = [
|
186 |
+
"F1",
|
187 |
+
"F2",
|
188 |
+
"F3",
|
189 |
+
"F4",
|
190 |
+
"F5",
|
191 |
+
"F6",
|
192 |
+
"F7",
|
193 |
+
"F8",
|
194 |
+
"F9",
|
195 |
+
"F10",
|
196 |
+
"F11",
|
197 |
+
"F12",
|
198 |
+
"Control",
|
199 |
+
"Alt",
|
200 |
+
"Shift",
|
201 |
+
"Meta",
|
202 |
+
"CapsLock",
|
203 |
+
"Escape",
|
204 |
+
"PrintScreen",
|
205 |
+
"ScrollLock",
|
206 |
+
"Pause",
|
207 |
+
"Insert",
|
208 |
+
"Delete",
|
209 |
+
"Home",
|
210 |
+
"End",
|
211 |
+
"PageUp",
|
212 |
+
"PageDown",
|
213 |
+
"ArrowLeft",
|
214 |
+
"ArrowRight",
|
215 |
+
"ArrowUp",
|
216 |
+
"ArrowDown",
|
217 |
+
];
|
218 |
+
if (!allowedKeys.includes(e.key) && !e.ctrlKey && !e.metaKey) {
|
219 |
+
e.preventDefault();
|
220 |
+
}
|
221 |
+
}
|
222 |
+
});
|
223 |
+
|
224 |
+
const clsBtn = document.querySelector(".clear-button");
|
225 |
+
clsBtn.addEventListener("click", () => {
|
226 |
+
this.inp.value = "";
|
227 |
+
this.inp.focus();
|
228 |
+
});
|
229 |
+
// this.inp.addEventListener("keydown", (e) => this.handleEnter(e));
|
230 |
+
document.querySelector(".send-input").addEventListener("click", () => this.send());
|
231 |
+
document.querySelector(".send2-input").addEventListener("click", () => this.send2());
|
232 |
+
document.querySelector(".clear-input").addEventListener("click", () => this.clear());
|
233 |
+
},
|
234 |
+
handleEnter(e) {
|
235 |
+
// if (e.key === "Enter" && !e.shiftKey) {
|
236 |
+
// e.preventDefault();
|
237 |
+
// this.send();
|
238 |
+
// }
|
239 |
+
},
|
240 |
+
|
241 |
+
// legge i documenti dal DBlocale
|
242 |
+
// sala le risposte RAG
|
243 |
+
// crea il contesto
|
244 |
+
async send() {
|
245 |
+
const q=this.inp.value;
|
246 |
+
if (!q) {
|
247 |
+
alert("Ricorda di scrivere la Query ");
|
248 |
+
return;
|
249 |
+
}
|
250 |
+
Rag.readFromDb();
|
251 |
+
if (!!Rag.ragContext) {
|
252 |
+
const ok = confirm("Vuoi iniziare una nuova elabrazione ?");
|
253 |
+
if (!ok) return "";
|
254 |
+
}
|
255 |
+
showSpinner();
|
256 |
+
setOutText("");
|
257 |
+
const msg = this.inp.value.trim();
|
258 |
+
try {
|
259 |
+
const txt = await Rag.requestDocsRAG(msg);
|
260 |
+
setOutText(txt);
|
261 |
+
this.inp.value = "";
|
262 |
+
UaLog.close();
|
263 |
+
} catch (err) {
|
264 |
+
const msg = `send\n${err}`;
|
265 |
+
xerror(msg);
|
266 |
+
alert(msg);
|
267 |
+
setOutText(msg);
|
268 |
+
}
|
269 |
+
hideSpinner();
|
270 |
+
},
|
271 |
+
|
272 |
+
// utiliza il contesto esistente
|
273 |
+
async send2() {
|
274 |
+
const q=this.inp.value;
|
275 |
+
if (!q) {
|
276 |
+
alert("Ricorda di scrivere la Query ");
|
277 |
+
return;
|
278 |
+
}
|
279 |
+
showSpinner();
|
280 |
+
if (ThreadMgr.isFirst()) setOutText("");
|
281 |
+
const query = this.inp.value.trim();
|
282 |
+
try {
|
283 |
+
const text = await Rag.requestContext(query);
|
284 |
+
if (text == "") {
|
285 |
+
hideSpinner();
|
286 |
+
return;
|
287 |
+
}
|
288 |
+
setOutText(text);
|
289 |
+
this.inp.value = "";
|
290 |
+
} catch (err) {
|
291 |
+
const msg = `send2\n${err}`;
|
292 |
+
xerror(msg);
|
293 |
+
alert(msg);
|
294 |
+
setOutText(msg);
|
295 |
+
}
|
296 |
+
hideSpinner();
|
297 |
+
},
|
298 |
+
clear() {
|
299 |
+
const ok = confirm("Confermi cancellazione conversazione? ");
|
300 |
+
if (!ok) return;
|
301 |
+
this.inp.value = "";
|
302 |
+
setOutText("");
|
303 |
+
ThreadMgr.init();
|
304 |
+
},
|
305 |
+
};
|
306 |
+
|
307 |
+
//XXX const setOutText = (txt) => {
|
308 |
+
// let out = document.getElementById("id-text-out");
|
309 |
+
// const ht = `<div class="div-text">${txt}</div>`;
|
310 |
+
// out.innerHTML=ht;
|
311 |
+
// const pre = out.querySelector(".div-text");
|
312 |
+
// pre.scrollTop = pre.scrollHeight;
|
313 |
+
// };
|
314 |
+
|
315 |
+
|
316 |
+
const setOutText = (txt) => {
|
317 |
+
let out = document.getElementById("id-text-out");
|
318 |
+
const h = `<pre class="pre-text"></pre>`;
|
319 |
+
out.innerHTML = h;
|
320 |
+
const pre = out.querySelector(".pre-text");
|
321 |
+
pre.textContent = txt;
|
322 |
+
pre.scrollTop = pre.scrollHeight;
|
323 |
+
};
|
324 |
+
|
325 |
+
TextOutput = {
|
326 |
+
init() {
|
327 |
+
this.copyBtn = document.querySelector(".copy-output");
|
328 |
+
this.copyBtn.addEventListener("click", () => this.copy());
|
329 |
+
const clearBtn = document.querySelector(".clear-output");
|
330 |
+
clearBtn.addEventListener("click", () => this.clear());
|
331 |
+
const wndBtn = document.querySelector(".wnd-output");
|
332 |
+
wndBtn.addEventListener("click", () => this.openWnd());
|
333 |
+
},
|
334 |
+
openWnd() {
|
335 |
+
const p = document.getElementById("id-text-out");
|
336 |
+
const s = p.textContent;
|
337 |
+
wnds.wout.show(s);
|
338 |
+
},
|
339 |
+
async copy() {
|
340 |
+
const e = document.getElementById("id-text-out");
|
341 |
+
const pre = e.querySelector("pre");
|
342 |
+
if (!pre) return;
|
343 |
+
const t = pre.textContent;
|
344 |
+
pre.classList.add("copied");
|
345 |
+
this.copyBtn.classList.add("copied");
|
346 |
+
try {
|
347 |
+
await navigator.clipboard.writeText(t);
|
348 |
+
} catch (err) {
|
349 |
+
xerror("Errore ", err);
|
350 |
+
}
|
351 |
+
setTimeout(() => {
|
352 |
+
this.copyBtn.classList.remove("copied");
|
353 |
+
pre.classList.remove("copied");
|
354 |
+
}, 5000);
|
355 |
+
},
|
356 |
+
clear() {
|
357 |
+
const out = document.getElementById("id-text-out");
|
358 |
+
out.textContent = "";
|
359 |
+
},
|
360 |
+
};
|
static/javascript/rag_upload.js
ADDED
@@ -0,0 +1,215 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/** @format */
|
2 |
+
|
3 |
+
"use strict";
|
4 |
+
|
5 |
+
const RagUpload = {
|
6 |
+
open() {
|
7 |
+
const htmlContent = `
|
8 |
+
<div class="window-text">
|
9 |
+
<div class="btn-wrapper">
|
10 |
+
<button class="btn-close" title="chiudi" onclick="UaWindowAdm.closeThis(this)">X</button>
|
11 |
+
</div>
|
12 |
+
<div class="upload">
|
13 |
+
<h4>Upload file Text / PDF</h4>
|
14 |
+
<form id="uploadForm">
|
15 |
+
<input class="file" type="file" id="id_fileupload" >
|
16 |
+
<button type="button" onclick="RagUpload.upload();">Upload and Convert</button>
|
17 |
+
</form>
|
18 |
+
<div id="result" class="result"></div>
|
19 |
+
</div>
|
20 |
+
</div>
|
21 |
+
`;
|
22 |
+
const uploadWindow = UaWindowAdm.create("id_upload");
|
23 |
+
uploadWindow.drag();
|
24 |
+
uploadWindow.setZ(12);
|
25 |
+
uploadWindow.vw_vh().setXY(16.5, 10, -1);
|
26 |
+
uploadWindow.setHtml(htmlContent);
|
27 |
+
uploadWindow.show();
|
28 |
+
},
|
29 |
+
async upload() {
|
30 |
+
const fileInput = document.getElementById("id_fileupload");
|
31 |
+
const file = fileInput.files[0];
|
32 |
+
if (!file) {
|
33 |
+
alert("Nessun file selezionato.");
|
34 |
+
return;
|
35 |
+
}
|
36 |
+
const fileName = file.name;
|
37 |
+
const exist = DataMgr.doc_names.includes(fileName);
|
38 |
+
if (exist) {
|
39 |
+
alert("Il file è già in archivio");
|
40 |
+
return;
|
41 |
+
}
|
42 |
+
|
43 |
+
const result = document.getElementById("result");
|
44 |
+
const fileExtension = file.name.split(".").pop().toLowerCase();
|
45 |
+
showSpinner();
|
46 |
+
try {
|
47 |
+
let text;
|
48 |
+
if (fileExtension === "pdf") {
|
49 |
+
const pdfHandler = new PdfHandler();
|
50 |
+
await pdfHandler.loadPdfJs();
|
51 |
+
text = await pdfHandler.extractTextFromPDF(file);
|
52 |
+
pdfHandler.cleanup();
|
53 |
+
} else if (fileExtension === "txt") {
|
54 |
+
text = await readTextFile(file);
|
55 |
+
} else {
|
56 |
+
alert("Formato file non supportato.");
|
57 |
+
return;
|
58 |
+
}
|
59 |
+
DataMgr.addDoc(fileName, text);
|
60 |
+
const msg = `<br><br> ${fileName}<br><br>caricato e salvato nella memoria locale`;
|
61 |
+
result.innerHTML = msg;
|
62 |
+
} catch (error) {
|
63 |
+
console.error("Error:", error);
|
64 |
+
alert("Errore durante l'estrazione del testo dal file.");
|
65 |
+
} finally {
|
66 |
+
hideSpinner();
|
67 |
+
}
|
68 |
+
},
|
69 |
+
openDir() {
|
70 |
+
const htmlContent = `
|
71 |
+
<div class="window-text">
|
72 |
+
<div class="btn-wrapper">
|
73 |
+
<button class="btn-close" title="chiudi" onclick="UaWindowAdm.closeThis(this)">X</button>
|
74 |
+
</div>
|
75 |
+
<div class="upload">
|
76 |
+
<h4>Upload files Text / PDF</h4>
|
77 |
+
<form id="uploadForm">
|
78 |
+
<input id="id_fileupload" class="file" type="file" webkitdirectory mozdirectory msdirectory odirectory directory multiple />
|
79 |
+
<button type="button" onclick="RagUpload.uploadDir();">Upload and Convert</button>
|
80 |
+
</form>
|
81 |
+
<div class="result" id="result"></div>
|
82 |
+
</div>
|
83 |
+
</div>
|
84 |
+
`;
|
85 |
+
const uploadWindow = UaWindowAdm.create("id_upload");
|
86 |
+
uploadWindow.drag();
|
87 |
+
uploadWindow.setZ(12);
|
88 |
+
uploadWindow.vw_vh().setXY(16.5, 10, -1);
|
89 |
+
uploadWindow.setHtml(htmlContent);
|
90 |
+
uploadWindow.show();
|
91 |
+
},
|
92 |
+
|
93 |
+
async uploadDir() {
|
94 |
+
const fileInput = document.getElementById("id_fileupload");
|
95 |
+
const files = fileInput.files;
|
96 |
+
|
97 |
+
if (!files || files.length == 0) {
|
98 |
+
alert("Nessun file selezionato.");
|
99 |
+
return;
|
100 |
+
}
|
101 |
+
const msgs = [];
|
102 |
+
|
103 |
+
showSpinner();
|
104 |
+
|
105 |
+
try {
|
106 |
+
for (const file of files) {
|
107 |
+
const fileName = file.name;
|
108 |
+
UaLog.log_show(fileName);
|
109 |
+
const exist = DataMgr.doc_names.includes(fileName);
|
110 |
+
if (exist) {
|
111 |
+
UaLog.log_shw(fileName + " : è già in archivio");
|
112 |
+
continue;
|
113 |
+
}
|
114 |
+
const fileExtension = file.name.split(".").pop().toLowerCase();
|
115 |
+
let text;
|
116 |
+
if (fileExtension === "pdf") {
|
117 |
+
const pdfHandler = new PdfHandler();
|
118 |
+
await pdfHandler.loadPdfJs();
|
119 |
+
text = await pdfHandler.extractTextFromPDF(file);
|
120 |
+
pdfHandler.cleanup();
|
121 |
+
} else if (fileExtension === "txt") {
|
122 |
+
text = await readTextFile(file);
|
123 |
+
} else {
|
124 |
+
alert("Formato file non supportato.");
|
125 |
+
return;
|
126 |
+
}
|
127 |
+
DataMgr.addDoc(fileName, text);
|
128 |
+
const msg = `${fileName}`;
|
129 |
+
msgs.push(msg);
|
130 |
+
}
|
131 |
+
} catch (error) {
|
132 |
+
console.error("Error:", error);
|
133 |
+
alert("Errore durante l'estrazione del testo dal file.");
|
134 |
+
} finally {
|
135 |
+
hideSpinner();
|
136 |
+
}
|
137 |
+
|
138 |
+
const result = document.getElementById("result");
|
139 |
+
const msg = msgs.join("<br>");
|
140 |
+
result.innerHTML = msg;
|
141 |
+
},
|
142 |
+
};
|
143 |
+
|
144 |
+
class PdfHandler {
|
145 |
+
constructor() {
|
146 |
+
this.pdfjsLib = null;
|
147 |
+
this.scriptElement = null;
|
148 |
+
this.workerScriptElement = null;
|
149 |
+
}
|
150 |
+
|
151 |
+
async loadPdfJs() {
|
152 |
+
if (window["pdfjsLib"]) {
|
153 |
+
this.pdfjsLib = window["pdfjs-dist/build/pdf"];
|
154 |
+
this.pdfjsLib.GlobalWorkerOptions.workerSrc = "https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.6.347/pdf.worker.min.js";
|
155 |
+
return;
|
156 |
+
}
|
157 |
+
// Carica pdf.js dinamicamente
|
158 |
+
this.scriptElement = document.createElement("script");
|
159 |
+
this.scriptElement.src = "https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.6.347/pdf.min.js";
|
160 |
+
document.body.appendChild(this.scriptElement);
|
161 |
+
|
162 |
+
// Aspetta che il worker sia caricato
|
163 |
+
await new Promise((resolve) => {
|
164 |
+
this.scriptElement.onload = () => {
|
165 |
+
this.workerScriptElement = document.createElement("script");
|
166 |
+
this.workerScriptElement.src = "https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.6.347/pdf.worker.min.js";
|
167 |
+
document.body.appendChild(this.workerScriptElement);
|
168 |
+
this.workerScriptElement.onload = resolve;
|
169 |
+
};
|
170 |
+
});
|
171 |
+
|
172 |
+
this.pdfjsLib = window["pdfjs-dist/build/pdf"];
|
173 |
+
this.pdfjsLib.GlobalWorkerOptions.workerSrc = "https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.6.347/pdf.worker.min.js";
|
174 |
+
}
|
175 |
+
|
176 |
+
async extractTextFromPDF(file) {
|
177 |
+
const arrayBuffer = await file.arrayBuffer();
|
178 |
+
const pdf = await this.pdfjsLib.getDocument({ data: arrayBuffer }).promise;
|
179 |
+
let text = "";
|
180 |
+
for (let i = 1; i <= pdf.numPages; i++) {
|
181 |
+
const page = await pdf.getPage(i);
|
182 |
+
const textContent = await page.getTextContent();
|
183 |
+
const pageText = textContent.items.map((item) => item.str).join(" ");
|
184 |
+
text += pageText + "\n";
|
185 |
+
}
|
186 |
+
return text;
|
187 |
+
}
|
188 |
+
|
189 |
+
cleanup() {
|
190 |
+
if (this.scriptElement) {
|
191 |
+
document.body.removeChild(this.scriptElement);
|
192 |
+
this.scriptElement = null;
|
193 |
+
}
|
194 |
+
if (this.workerScriptElement) {
|
195 |
+
document.body.removeChild(this.workerScriptElement);
|
196 |
+
this.workerScriptElement = null;
|
197 |
+
}
|
198 |
+
this.pdfjsLib = null;
|
199 |
+
if (window.gc) {
|
200 |
+
window.gc();
|
201 |
+
}
|
202 |
+
}
|
203 |
+
}
|
204 |
+
|
205 |
+
async function readTextFile(file) {
|
206 |
+
if (!file || file.type !== "text/plain") {
|
207 |
+
throw new Error("Invalid file type. Please select a text file.");
|
208 |
+
}
|
209 |
+
return new Promise((resolve, reject) => {
|
210 |
+
const reader = new FileReader();
|
211 |
+
reader.onload = (event) => resolve(event.target.result);
|
212 |
+
reader.onerror = (error) => reject(new Error("Error reading file: " + error.message));
|
213 |
+
reader.readAsText(file);
|
214 |
+
});
|
215 |
+
}
|
static/javascript/uadrag.js
ADDED
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// jshint esversion: 8
|
2 |
+
// release 24-04-2022
|
3 |
+
|
4 |
+
|
5 |
+
const nodrag_tds = ['input', 'select', 'a'];
|
6 |
+
const nodrag_cls = "nodrag";
|
7 |
+
|
8 |
+
var UaDrag = function (e) {
|
9 |
+
const drag = function (element) {
|
10 |
+
let pos1 = 0,
|
11 |
+
pos2 = 0,
|
12 |
+
pos3 = 0,
|
13 |
+
pos4 = 0;
|
14 |
+
|
15 |
+
const dragMouseDown = function (e) {
|
16 |
+
e = e || window.event;
|
17 |
+
let t = e.target;
|
18 |
+
t = t || null;
|
19 |
+
if (!t) return;
|
20 |
+
if (nodrag_tds.includes(t.tagName.toLowerCase())) return;
|
21 |
+
if (t.classList.contains(nodrag_cls)) return;
|
22 |
+
e.preventDefault();
|
23 |
+
//e.stopImmediatePropagation();
|
24 |
+
pos3 = e.clientX;
|
25 |
+
pos4 = e.clientY;
|
26 |
+
document.onmouseup = closeDragElement;
|
27 |
+
document.onmousemove = elementDrag;
|
28 |
+
};
|
29 |
+
|
30 |
+
const elementDrag = function (e) {
|
31 |
+
e = e || window.event;
|
32 |
+
//e.stopImmediatePropagation();
|
33 |
+
e.preventDefault();
|
34 |
+
pos1 = pos3 - e.clientX;
|
35 |
+
pos2 = pos4 - e.clientY;
|
36 |
+
pos3 = e.clientX;
|
37 |
+
pos4 = e.clientY;
|
38 |
+
element.style.top = (element.offsetTop - pos2) + "px";
|
39 |
+
element.style.left = (element.offsetLeft - pos1) + "px";
|
40 |
+
};
|
41 |
+
|
42 |
+
const closeDragElement = function () {
|
43 |
+
document.onmouseup = null;
|
44 |
+
document.onmousemove = null;
|
45 |
+
};
|
46 |
+
|
47 |
+
element.onmousedown = dragMouseDown;
|
48 |
+
};
|
49 |
+
return drag(e);
|
50 |
+
};
|
51 |
+
|
static/javascript/uajtfh.js
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/** @format */
|
2 |
+
const UaJtfh = () => {
|
3 |
+
return {
|
4 |
+
rows: [],
|
5 |
+
init() {
|
6 |
+
this.rows = [];
|
7 |
+
return this;
|
8 |
+
},
|
9 |
+
insert(s) {
|
10 |
+
this.rows.unshift(s);
|
11 |
+
return this;
|
12 |
+
},
|
13 |
+
append(s) {
|
14 |
+
this.rows.push(s);
|
15 |
+
return this;
|
16 |
+
},
|
17 |
+
text(ln = "") {
|
18 |
+
return this.rows.join(ln);
|
19 |
+
},
|
20 |
+
html(ln = "") {
|
21 |
+
const h = this.rows.join(ln).replace(/\s+|\[rn\]/g, " ");
|
22 |
+
return h;
|
23 |
+
},
|
24 |
+
};
|
25 |
+
};
|
static/javascript/ualog.js
ADDED
@@ -0,0 +1,157 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/** @format */
|
2 |
+
// function show() {
|
3 |
+
// const log = document.getElementById("id_log");
|
4 |
+
// if (log.classList.contains("active")) return;
|
5 |
+
// log.classList.add("active");
|
6 |
+
// }
|
7 |
+
|
8 |
+
// function hide() {
|
9 |
+
// const log = document.getElementById("id_log");
|
10 |
+
// if (!log.classList.contains("active")) return;
|
11 |
+
// log.classList.remove("active");
|
12 |
+
// }
|
13 |
+
// jshint esversion: 8
|
14 |
+
// release 09-'6-24
|
15 |
+
// utilizzare l'ultima versione di UaWindowAdm
|
16 |
+
// setXY con vw ,vh
|
17 |
+
var UaLog = {
|
18 |
+
callHide: function () {},
|
19 |
+
callShow: function () {},
|
20 |
+
active: false,
|
21 |
+
wind: null,
|
22 |
+
x: null,
|
23 |
+
y: null,
|
24 |
+
z: null,
|
25 |
+
max_length: 2000,
|
26 |
+
msg_id: "ualogmsg_",
|
27 |
+
new: function () {
|
28 |
+
if (this.wind == null) {
|
29 |
+
this.wind = UaWindowAdm.create("ualog_");
|
30 |
+
this.wind.drag();
|
31 |
+
}
|
32 |
+
const h = `
|
33 |
+
<button type="button" onclick="javascript:UaLog.cls();">Clear</button>
|
34 |
+
<button type="button" onclick="javascript:UaLog.close();">Close</button>
|
35 |
+
<div id="ualogmsg_"></div>`;
|
36 |
+
this.wind.setHtml(h);
|
37 |
+
this.wind.setStyle({
|
38 |
+
width: "auto",
|
39 |
+
minWidth: "300px",
|
40 |
+
maxWidth: "400px",
|
41 |
+
height: "auto",
|
42 |
+
textAlign: "center",
|
43 |
+
padding: "2px 2px 2px 2px",
|
44 |
+
margin: "5px 0 0 0",
|
45 |
+
// background: "#111111",
|
46 |
+
background: "#333333",
|
47 |
+
color: "#ffffff",
|
48 |
+
fontSize: "15px",
|
49 |
+
fontWeight: "normal",
|
50 |
+
borderRadius: "9px",
|
51 |
+
border: "1px solid #999999",
|
52 |
+
});
|
53 |
+
|
54 |
+
const msg = document.getElementById(this.msg_id);
|
55 |
+
const msg_css = {
|
56 |
+
width: "auto",
|
57 |
+
textAlign: "left",
|
58 |
+
fontSize: "16px",
|
59 |
+
fontFamily:"monospace",
|
60 |
+
paddingTop: "2px ",
|
61 |
+
marginTop: "2px",
|
62 |
+
color: "inherit",
|
63 |
+
// background: "#444444",
|
64 |
+
background: "#000000",
|
65 |
+
maxHeight: "600px",
|
66 |
+
overflow: "auto",
|
67 |
+
scrollbarColor: "#ab3205 #ffffff",
|
68 |
+
scrollbarWidth: "auto",
|
69 |
+
};
|
70 |
+
for (const k in msg_css) msg.style[k] = msg_css[k];
|
71 |
+
|
72 |
+
const btn_css = {
|
73 |
+
background: "#444444",
|
74 |
+
color: "#ffffff",
|
75 |
+
padding: "5px 5px 5px 5px",
|
76 |
+
margin: "0 5px 0 5px",
|
77 |
+
fontSize: "16px",
|
78 |
+
fontWeight: "bold",
|
79 |
+
border: "1px solid #ffffff",
|
80 |
+
borderRadius: "10px",
|
81 |
+
};
|
82 |
+
const btns = document.querySelectorAll("#ualog_ button");
|
83 |
+
for (const b of btns) {
|
84 |
+
for (const k in btn_css) b.style[k] = btn_css[k];
|
85 |
+
b.addEventListener("mouseover", (e) => {
|
86 |
+
e.target.style.cursor = "pointer";
|
87 |
+
e.target.style.color = "#000000";
|
88 |
+
e.target.style.background = "#aaaaaa";
|
89 |
+
});
|
90 |
+
b.addEventListener("mouseout", (e) => {
|
91 |
+
for (const k in btn_css) e.target.style[k] = btn_css[k];
|
92 |
+
});
|
93 |
+
}
|
94 |
+
if (!!this.x) this.wind.vw_vh().setXY(this.x, this.y, -1);
|
95 |
+
else this.wind.setCenter(-1);
|
96 |
+
if (!!this.z) this.wind.setZ(this.z);
|
97 |
+
return this;
|
98 |
+
},
|
99 |
+
setXY(x, y) {
|
100 |
+
this.x = x;
|
101 |
+
this.y = y;
|
102 |
+
return this;
|
103 |
+
},
|
104 |
+
setZ(z) {
|
105 |
+
this.z = z;
|
106 |
+
return this;
|
107 |
+
},
|
108 |
+
prn_(...args) {
|
109 |
+
let s = args.join("<br/>");
|
110 |
+
let e = document.getElementById(this.msg_id);
|
111 |
+
let h = e.innerHTML + s + "<br/>";
|
112 |
+
if (h.length > this.max_length) h = h.slice(-this.max_length);
|
113 |
+
e.innerHTML = h;
|
114 |
+
},
|
115 |
+
print(...args) {
|
116 |
+
if (this.wind == null) return;
|
117 |
+
if (!this.active) return;
|
118 |
+
this.prn_(...args);
|
119 |
+
},
|
120 |
+
log(...args) {
|
121 |
+
if (this.wind == null) return;
|
122 |
+
this.prn_(...args);
|
123 |
+
},
|
124 |
+
log_show(...args) {
|
125 |
+
if (this.wind == null) return;
|
126 |
+
if (!this.active) this.toggle();
|
127 |
+
this.prn_(...args);
|
128 |
+
},
|
129 |
+
cls() {
|
130 |
+
if (this.wind == null) return;
|
131 |
+
document.getElementById(this.msg_id).innerHTML = "";
|
132 |
+
return this;
|
133 |
+
},
|
134 |
+
close() {
|
135 |
+
if (this.wind == null) return;
|
136 |
+
this.wind.hide();
|
137 |
+
this.active = false;
|
138 |
+
this.callHide();
|
139 |
+
},
|
140 |
+
// open() {
|
141 |
+
// if (this.wind == null) return;
|
142 |
+
// this.wind.show();
|
143 |
+
// this.active = true;
|
144 |
+
// },
|
145 |
+
toggle() {
|
146 |
+
if (this.wind == null) return;
|
147 |
+
if (!this.active) {
|
148 |
+
this.active = true;
|
149 |
+
this.wind.show();
|
150 |
+
this.callShow();
|
151 |
+
} else {
|
152 |
+
this.active = false;
|
153 |
+
this.wind.hide();
|
154 |
+
this.callHide();
|
155 |
+
}
|
156 |
+
},
|
157 |
+
};
|
static/javascript/uawindow.js
ADDED
@@ -0,0 +1,211 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/** @format */
|
2 |
+
|
3 |
+
// jshint esversion: 8
|
4 |
+
// release 03-05-24
|
5 |
+
"use strict";
|
6 |
+
|
7 |
+
var UaWindowAdm = {
|
8 |
+
ws: {},
|
9 |
+
create(id, parent_id = null) {
|
10 |
+
let w = document.getElementById(id);
|
11 |
+
if (!w) {
|
12 |
+
w = document.createElement("div");
|
13 |
+
if (!parent_id) document.body.appendChild(w);
|
14 |
+
else document.getElementById(parent_id).appendChild(w);
|
15 |
+
w.id = id;
|
16 |
+
w.setAttribute("data-name", "ua-window");
|
17 |
+
const uaw = this.newUaWindow(w);
|
18 |
+
this.ws[id] = uaw;
|
19 |
+
}
|
20 |
+
const uaw = this.ws[id];
|
21 |
+
w.style.display = "none";
|
22 |
+
return uaw;
|
23 |
+
},
|
24 |
+
get(id) {
|
25 |
+
if (!this.ws[id]) return null;
|
26 |
+
return this.ws[id];
|
27 |
+
},
|
28 |
+
show(id) {
|
29 |
+
if (!!this.ws[id]) this.ws[id].show();
|
30 |
+
},
|
31 |
+
close(id) {
|
32 |
+
if (!!this.ws[id]) this.ws[id].close();
|
33 |
+
},
|
34 |
+
toggle(id) {
|
35 |
+
if (!!this.ws[id]) this.ws[id].toggle();
|
36 |
+
},
|
37 |
+
hide(id) {
|
38 |
+
if (!!this.ws[id]) this.ws[id].hide();
|
39 |
+
},
|
40 |
+
closeThis(e) {
|
41 |
+
const ancestor = e.closest('[data-name="ua-window"]');
|
42 |
+
const id = ancestor.id;
|
43 |
+
this.ws[id].close();
|
44 |
+
},
|
45 |
+
showAll() {
|
46 |
+
for (let k in this.ws) this.ws[k].show();
|
47 |
+
},
|
48 |
+
hideAll() {
|
49 |
+
for (let k in this.ws) this.ws[k].hide();
|
50 |
+
},
|
51 |
+
closeAll() {
|
52 |
+
for (let k in this.ws) this.ws[k].close();
|
53 |
+
},
|
54 |
+
remove(id) {
|
55 |
+
if (!this.ws[id]) return;
|
56 |
+
document.getElementById(id).remove();
|
57 |
+
this.ws[id] = null;
|
58 |
+
delete this.ws[id];
|
59 |
+
},
|
60 |
+
removeAll() {
|
61 |
+
for (let k in this.ws) this.remove(k);
|
62 |
+
this.ws = {};
|
63 |
+
},
|
64 |
+
newUaWindow(jqw) {
|
65 |
+
let wnd = {
|
66 |
+
initialize(w) {
|
67 |
+
this.w = w;
|
68 |
+
this.wx = "0px";
|
69 |
+
this.wy = "0px";
|
70 |
+
this.isOpen = false;
|
71 |
+
this.isVisible = false;
|
72 |
+
this.firstShow = true;
|
73 |
+
this.pos = 0;
|
74 |
+
this.wz = 0;
|
75 |
+
this.vw = "px";
|
76 |
+
this.vh = "px";
|
77 |
+
},
|
78 |
+
vw_vh() {
|
79 |
+
// setta coe unità di misura vw e vh al posto di px;
|
80 |
+
this.vw = "vw";
|
81 |
+
this.vh = "vh";
|
82 |
+
return this;
|
83 |
+
},
|
84 |
+
addClassStyle(className) {
|
85 |
+
if (!this.w.classList.contains(className)) this.w.classList.add(className);
|
86 |
+
return this;
|
87 |
+
},
|
88 |
+
removeClassStyle(className) {
|
89 |
+
if (this.w.classList.contains(className)) this.w.classList.remove(className);
|
90 |
+
return this;
|
91 |
+
},
|
92 |
+
getWindow() {
|
93 |
+
alert("getWindow => ??");
|
94 |
+
return this.w;
|
95 |
+
},
|
96 |
+
getElement() {
|
97 |
+
return this.w;
|
98 |
+
},
|
99 |
+
getId() {
|
100 |
+
return this.w.id;
|
101 |
+
},
|
102 |
+
setStyle(styles) {
|
103 |
+
for (const prop in styles) this.w.style[prop] = styles[prop];
|
104 |
+
return this;
|
105 |
+
},
|
106 |
+
setHtml(html) {
|
107 |
+
this.w.innerHTML = html;
|
108 |
+
return this;
|
109 |
+
},
|
110 |
+
getHtml() {
|
111 |
+
return this.w.innerHTML;
|
112 |
+
},
|
113 |
+
/*
|
114 |
+
pos==1) => si posiziona ad ogni chiamata di show
|
115 |
+
pos==0) => si posiziona ad ogni chiamata di show
|
116 |
+
sucessiva ad uno status hide (default)
|
117 |
+
pos==-1)=> si posiziona solo alla prima chiamata di show
|
118 |
+
|
119 |
+
x => 0 left=x
|
120 |
+
x < 0 right=abs(x)
|
121 |
+
*/
|
122 |
+
setXY(x, y, pos = 0) {
|
123 |
+
this.wx = x;
|
124 |
+
this.wy = y;
|
125 |
+
this.pos = pos;
|
126 |
+
return this;
|
127 |
+
},
|
128 |
+
setCenterY(y, pos) {
|
129 |
+
let xd = window.innerWidth;
|
130 |
+
const wd = this.w.clientWidth;
|
131 |
+
let x = (xd - wd) / 2;
|
132 |
+
this.setXY(x, y, pos);
|
133 |
+
return this;
|
134 |
+
},
|
135 |
+
setCenter(pos) {
|
136 |
+
let xd = window.innerWidth;
|
137 |
+
let yd = window.innerHeight;
|
138 |
+
const wd = this.w.clientWidth;
|
139 |
+
const wh = this.w.clientHeight;
|
140 |
+
let x = (xd - wd) / 2;
|
141 |
+
let y = (yd - wh) / 2;
|
142 |
+
this.setXY(x, y, pos);
|
143 |
+
return this;
|
144 |
+
},
|
145 |
+
linkToId(linked_id, dx, dy, pos) {
|
146 |
+
let lk = document.getElementById(linked_id);
|
147 |
+
this.linkToElement(lk, dx, dy, pos);
|
148 |
+
return this;
|
149 |
+
},
|
150 |
+
linkToElement(elm, dx, dy, pos) {
|
151 |
+
let x = elm.offsetLeft + elm.offsetWidth + dx;
|
152 |
+
let y = elm.offsetTop + dy;
|
153 |
+
if (y < 0) y = 0;
|
154 |
+
this.setXY(x, y, pos);
|
155 |
+
return this;
|
156 |
+
},
|
157 |
+
setZ(z) {
|
158 |
+
this.wz = z;
|
159 |
+
return this;
|
160 |
+
},
|
161 |
+
reset() {
|
162 |
+
this.firstShow = true;
|
163 |
+
return this;
|
164 |
+
},
|
165 |
+
toggle() {
|
166 |
+
if (!this.isVisible) this.show();
|
167 |
+
else this.hide();
|
168 |
+
return this;
|
169 |
+
},
|
170 |
+
show() {
|
171 |
+
if (this.firstShow || this.pos == 1 || (this.pos === 0 && this.isVisible === false)) {
|
172 |
+
this.w.style.position = "absolute";
|
173 |
+
this.w.style.marginLeft = 0;
|
174 |
+
this.w.style.marginTop = 0;
|
175 |
+
this.w.style.top = `${this.wy}${this.vh}`;
|
176 |
+
if (this.wx >= 0) this.w.style.left = `${this.wx}${this.vw}`;
|
177 |
+
else this.w.style.right = -`${this.wx}${this.vw}`;
|
178 |
+
if (this.wz > 0) this.w.style.zIndex = this.wz;
|
179 |
+
}
|
180 |
+
this.w.style.display = "";
|
181 |
+
this.firstShow = false;
|
182 |
+
this.isVisible = true;
|
183 |
+
this.isOpen = true;
|
184 |
+
return this;
|
185 |
+
},
|
186 |
+
hide() {
|
187 |
+
this.w.style.display = "none";
|
188 |
+
this.isVisible = false;
|
189 |
+
return this;
|
190 |
+
},
|
191 |
+
close() {
|
192 |
+
this.w.style.display = "none";
|
193 |
+
this.w.innerHTML = "";
|
194 |
+
// this.w.innerHTML = "block";
|
195 |
+
this.isOpen = false;
|
196 |
+
return this;
|
197 |
+
},
|
198 |
+
remove() {
|
199 |
+
const id = this.w.id;
|
200 |
+
UaWindowAdm.remove(id);
|
201 |
+
return null;
|
202 |
+
},
|
203 |
+
drag() {
|
204 |
+
UaDrag(this.w);
|
205 |
+
return this;
|
206 |
+
},
|
207 |
+
};
|
208 |
+
wnd.initialize(jqw);
|
209 |
+
return wnd;
|
210 |
+
},
|
211 |
+
};
|
static/js/ragrqs.min.js
ADDED
@@ -0,0 +1,176 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
function cleanDoc(a){a=a.split("\n").map(function(b){return b.replace(/[\x00-\x1F\x7F-\x9F\u200B-\u200D\uFEFF]/g,"")}).join("\n");a=a.replace(/\t/g," ");a=a.replace(/ +/g," ");a=a.split("\n").map(b=>b.trim()).join("\n");a=a.replace(/\n\s*\n/g,"\n\n");a=a.replace(/["""]/g,'"').replace(/['']/g,"'");a=a.replace(/[\u2013\u2014]/g,"-");a=a.replace(/\\[nrt]/g,"");a=a.replace(/[^\p{L}\p{N}\s\.,;:!?'"()\-]/gu,"");a=a.replace(/ +([.,;:!?])/g,"$1");return a.trim()}
|
2 |
+
function list2text(a){return text=a.map(b=>`${b.trim()}`).join("\n")}function cleanOutput(a){a=a.trim();a=a.replace(/\n{3,}/g,"\n\n");a=a.replace(/^[ \t]+/gm,"");a=a.replace(/^(\s*[-*\u2022])(\s*)/gm,"\n$1 ");a=a.replace(/^(\s*\d+\.)(\s*)/gm,"\n$1 ");a=a.replace(/(```[\s\S]*?```)/g,"\n\n$1\n\n");return a=a.replace(/[ \t]+$/gm,"")};const UaDb={create(a,b){localStorage.getItem(a)?xerror(`ID ${a} already exists.`):localStorage.setItem(a,b)},read(a){const b=localStorage.getItem(a);return null===b?(xlog(`UaDb.read ${a} not found.`),""):b},update(a,b){localStorage.getItem(a)?localStorage.setItem(a,b):xlog(`UaDb.update ${a} not found.`)},delete(a){localStorage.getItem(a)?localStorage.removeItem(a):xerror(`ID ${a} not found.`)},save(a,b){localStorage.setItem(a,b)},getAllIds(){const a=[];for(let b=0;b<localStorage.length;b++)a.push(localStorage.key(b));
|
3 |
+
return a},saveArray(a,b){b=b.join("|");UaDb.save(a,b)},readArray(a){a=UaDb.read(a);return 0==a.trim().length?[]:a.split("|").map(b=>b.trim())},saveJson(a,b){b=JSON.stringify(b);UaDb.save(a,b)},readJson(a){return(a=UaDb.read(a))?JSON.parse(a):{}}},DataMgr={docs:[],doc_names:[],linkToName(a){a=a.split("/");return a[a.length-1]},async loadDoc(a){try{const b=await requestGet(a),c=cleanDoc(b),d=this.linkToName(a);this.doc_names.push(d);this.docs.push(c);this.saveDbDocs();return c}catch(b){alert("loadDoc()\n"+
|
4 |
+
b+"\n"+a)}},addDoc(a,b){b=cleanDoc(b);this.docs.push(b);this.doc_names.push(a);this.saveDbDocs()},saveDbDocs(){UaDb.saveArray("id_doc_names",this.doc_names);UaDb.saveArray("id_docs",this.docs)},readDbDocs(){this.docs=UaDb.readArray("id_docs")},readDbDocNames(){this.doc_names=UaDb.readArray("id_doc_names")},deleteDati(){const a=UaDb.getAllIds();for(const b of a)["id_docs","id_doc_names"].includes(b)||UaDb.delete(b)}};const model_name="mistralai/Mistral-7B-Instruct-v0.3";function decodeTokenBase64(a){return atob(a)}const encodedToken="aGZfT0VBQVpoUmJtdEFLRENOVGZTcFZwVHdhbGpielBvQnlhbA",HF_TOKEN=decodeTokenBase64(encodedToken);
|
5 |
+
async function requestGet(a){try{var b=await fetch(a,{method:"GET",headers:{"Content-Type":"text/plain;charset=UTF-8"}});if(!b.ok)throw Error(`HTTP error! status: ${b.status}`);const c=await b.arrayBuffer();return(new TextDecoder("utf-8")).decode(c)}catch(c){throw console.error(c),b="AbortError"===c.name?"Request was aborted":c.message.includes("HTTP error! status")?c.message:"An error occurred",alert(`requestGet()\nurl: ${a}\n${b}`),c;}}
|
6 |
+
const ERROR_TOKENS="ERROR_TOKENS",TIMEOUT_ERROR="TIMEOUT_ERROR",HfRequest={controller:null,isCancelled:!1,baseUrl:"https://api-inference.huggingface.co/models",async post(a,b=3E4){this.isCancelled=!1;this.controller=new AbortController;try{const c=setTimeout(()=>{this.controller.abort()},b),d=await fetch(`${this.baseUrl}/${model_name}`,{method:"POST",headers:{Authorization:`Bearer ${HF_TOKEN}`,"Content-Type":"application/json"},body:JSON.stringify(a),signal:this.controller.signal});clearTimeout(c);
|
7 |
+
if(this.isCancelled)return null;const e=await d.json();if(!d.ok){const h=this.checkError(d.status,e),l=this.createErrorInfo(d.status,d.statusText,e.error,h);throw Error(l);}const f=this.isInvalidResponse(e);if("string"===typeof f){const h=this.createErrorInfo(d.status,d.statusText,e.error,f);throw Error(h);}return e[0].generated_text.trim()}catch(c){if(this.isCancelled)return null;if("AbortError"===c.name)throw a=this.createErrorInfo(0,"Timeout","La richiesta \u00e8 scaduta",TIMEOUT_ERROR),Error(a);
|
8 |
+
throw c;}},cancelRequest(){this.controller&&(this.isCancelled=!0,this.controller.abort())},checkError(a,b){return 500<=a?"SERVER_ERROR":400<=a&&500>a?"object"===typeof b&&"validation"===b.error_type?b.error.includes("tokens")?ERROR_TOKENS:"ERROR_VALIDATION":"CLIENT_ERROR":"UNKNOWN_ERROR"},isInvalidResponse(a){return a&&Array.isArray(a)&&0!==a.length?a[0].generated_text?null:"MISSING_GENERATED_TEXT":"INVALID_DATA"},createErrorInfo(a,b,c,d){return JSON.stringify({status:a,statusText:b,errorType:d,message:c||
|
9 |
+
"Errore sconosciuto"})}};/*
|
10 |
+
|
11 |
+
rag_rqs
|
12 |
+
Copyright (C) 2024 [Il tuo nome]
|
13 |
+
|
14 |
+
This program is free software: you can redistribute it and/or modify
|
15 |
+
it under the terms of the GNU General Public License as published by
|
16 |
+
the Free Software Foundation, either version 3 of the License, or
|
17 |
+
(at your option) any later version.
|
18 |
+
|
19 |
+
This program is distributed in the hope that it will be useful,
|
20 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
21 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
22 |
+
GNU General Public License for more details.
|
23 |
+
|
24 |
+
You should have received a copy of the GNU General Public License
|
25 |
+
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
26 |
+
*/
|
27 |
+
const MAX_PROMPT_LENGTH=90112,PROMPT_DECR=2048,Rag={ragContext:"",ragQuery:"",ragResponse:"",responses:[],prompts:[],doc:"",doc_part:"",saveToDb(){UaDb.saveJson("id_rag",{context:this.ragContext,ragquery:this.ragQuery,ragresponse:this.ragResponse})},readFromDb(){const a=UaDb.readJson("id_rag");this.ragContext=a.context||"";this.ragQuery=a.ragquery||"";this.ragResponse=a.ragresponse||""},saveRespToDb(){UaDb.saveArray("id_responses",this.responses)},readRespsFromDb(){this.responses=UaDb.readArray("id_responses")},
|
28 |
+
addPrompt(a){this.prompts.push(a)},responsesLength(){return this.responses.reduce((a,b)=>a+b.length,0)},log(a,b,c){const d=MAX_PROMPT_LENGTH,e=this.responsesLength();xlog(`${a} mx:${d} lft:${b} rgt:${c} arr:${e}`);UaLog.log(`${a}${" "}${b}${" "}${c}${" "}${e}`)},truncInput(a,b){return a.substring(0,a.length-b)},getPartSize(a,b,c){c=MAX_PROMPT_LENGTH-c;a.length+b.length<c?c=a.length:(a=a.indexOf(".",
|
29 |
+
c),a=(-1!=a?a:c)+1,a>c+100&&(a=c),c=a);return c},getPartDoc(a,b){const c=a.substring(0,b);a=a.substring(b).trim();return[c,a]},errorInfo(a){return JSON.parse(a.message)},errorTotext(a){a=JSON.parse(a.message);return`Errore:
|
30 |
+
Stato: ${a.status}
|
31 |
+
Descrizione stato: ${a.statusText}
|
32 |
+
Tipo di errore: ${a.errorType}
|
33 |
+
Messaggio: ${a.message}`},async requestDocsRAG(a){ThreadMgr.init();DataMgr.deleteDati();DataMgr.readDbDocNames();DataMgr.readDbDocs();this.ragQuery=a;this.ragResponse=this.ragContext="";this.responses=[];this.prompts=[];var b=0;try{for(let c=0;c<DataMgr.docs.length;c++){let d=DataMgr.docs[c];if(""==d.trim())continue;const e=DataMgr.doc_names[c],f=d.length;UaLog.log(`${e} (${f}) `);xlog(`${e} (${f}) `);++b;let h=0,l="",g="",k=0,n="";for(;;){let q=this.getPartSize(d,promptDoc("",a),k);if(10>q)break;
|
34 |
+
[l,g]=this.getPartDoc(d,q);n=promptDoc(l,a);const r=getPayloadDoc(n);let m;try{if(m=await HfRequest.post(r),!m)return""}catch(p){if(this.errorInfo(p).errorType===ERROR_TOKENS){UaLog.log(`Error tokens.1 ${n.length}`);xlog(`Error tokens. ${n.length}`);k+=PROMPT_DECR;continue}else throw xerror(p),this.errorTotext(p);}h++;d=g;1==h&&(m=`[[NOME_DOCUMENTO]]:${e}\n${m}`);this.responses.push(m);this.log(`${b},${h}`,l.length,g.length)}}}catch(c){alert("requestDocsRAG(1)\n"+c),xerror(c)}this.ragContext=list2text(this.responses);
|
35 |
+
this.saveToDb();b="";try{let c=promptWithContext(this.ragContext,a);const d=getPayloadQuery(c);try{if(b=await HfRequest.post(d),!b)return""}catch(e){this.errorInfo(e);const f=this.errorTotext(e);xerror(e);throw f;}this.ragResponse=b;this.saveRespToDb();this.saveToDb();UaLog.log(`Risposta (${c.length},${b.length})`)}catch(c){throw b=c,xerror(c),alert("requestDocsRAG(3)\n"+c),c;}finally{return b=cleanOutput(b)}},async requestContext(a){this.readFromDb();if(!this.ragContext&&!await confirm("Contesto vuoto. Vuoi continuare?"))return"";
|
36 |
+
if(ThreadMgr.isFirst()){var b="";try{var c=promptWithContext(this.ragContext,a),d=getPayloadQuery(c);try{var e=await HfRequest.post(d);if(!e)return""}catch(f){throw this.errorInfo(f).errorType===ERROR_TOKENS?UaLog.log(`Error tokens.4 ${c.length}`):alert(f),xerror(f),f;}ThreadMgr.add(a,e);b=ThreadMgr.getOutText();UaLog.log(`Inizio Conversazione (${c.length},${e.length})`)}catch(f){throw xerror(f),b=f,f;}finally{return b=cleanOutput(b)}}else{c="";try{b=this.ragContext;let f=ThreadMgr.getThread();e=
|
37 |
+
d="";let h=0;for(;;){f=this.truncInput(f,h);d=promptThread(b,f,a);const l=getPayloadQuery(d);try{if(e=await HfRequest.post(l),!e)return""}catch(g){const k=this.errorInfo(g);if(k.errorType===ERROR_TOKENS){UaLog.log(`Error tokens.5 ${d.length}`);xlog(`Error tokens. ${d.length}`);h+=PROMPT_DECR;continue}else throw xerror(g),k.errorType;}break}ThreadMgr.add(a,e);c=ThreadMgr.getOutText();UaLog.log(`Conversazione (${d.length},${e.length})`)}catch(f){throw alert("requestContext(2) \n"+f),xerror(f),c=
|
38 |
+
f,f;}finally{return c=cleanOutput(c)}}}},ThreadMgr={rows:[],init(){this.rows=[]},add(a,b){this.rows.push([a,b])},getOutText(){const a=[];for(const b of this.rows){const c=b[0].trim(),d=b[1].trim();a.push(`<user>:\n${c}\n<Assistant>:\n${d}\n\n`)}return a.join("").trim()},getThread(){const a=[];for(const b of this.rows){const c=b[0].trim(),d=b[1].trim();a.push(`<user>:\n${c}\n<Assitant>:\n${d}\n\n`)}return a.join("").trim()},isFirst(){return 0==this.rows.length}};function promptDoc(a,b){return`
|
39 |
+
[[RUOLO]]
|
40 |
+
Analista di documenti esperto nell'estrazione di informazioni pertinenti.
|
41 |
+
|
42 |
+
[[COMPITO]]
|
43 |
+
Analizza il documento e estrai le informazioni rilevanti per la domanda.
|
44 |
+
|
45 |
+
[[DOCUMENTO]]
|
46 |
+
${a}
|
47 |
+
|
48 |
+
[[DOMANDA]]
|
49 |
+
${b}
|
50 |
+
|
51 |
+
[[ISTRUZIONI]]
|
52 |
+
1. Identifica i concetti chiave e sintetizzali per fornire una risposta completa.
|
53 |
+
2. Assicurati di organizzare le informazioni in modo chiaro e logico.
|
54 |
+
3. Conserva le informazioni contrastanti, se presenti, senza tentare di risolverle.
|
55 |
+
4. Puoi fare inferenze ragionevoli basate sulle informazioni fornite.
|
56 |
+
5. Includi citazioni o riferimenti specifici al documento solo se necessari per chiarire la descrizione.
|
57 |
+
|
58 |
+
[[OUTPUT]]
|
59 |
+
Elenco delle informazioni identificate, incluse eventuali inferenze
|
60 |
+
`}function promptToContext(a){return`
|
61 |
+
[[RUOLO]]
|
62 |
+
Esperto di analisi semantica delle informazioni.
|
63 |
+
|
64 |
+
[[OBIETTIVO]]
|
65 |
+
Unificare le informazioni semanticamente equivalenti da vari documenti.
|
66 |
+
|
67 |
+
[[ELENCO_RISPOSTE]]
|
68 |
+
${a}
|
69 |
+
|
70 |
+
[[ISTRUZIONI]]
|
71 |
+
1. Analizza le informazioni dell'elenco risposte.
|
72 |
+
2. Per ogni documento raggruppa le informazioni sulla base del loro significato.
|
73 |
+
3. Presenta le informazioni in modo chiaro e coerente.
|
74 |
+
|
75 |
+
[[OUTPUT]]
|
76 |
+
Elenco delle informazioni mantenendo la divisione per documento.
|
77 |
+
`}function promptWithContext(a,b){return`
|
78 |
+
[[COMPITO]]
|
79 |
+
Elabora una risposta esaustiva e pertinente alla domanda basata sul contesto fornito.
|
80 |
+
|
81 |
+
[[CONTESTO]]
|
82 |
+
${a}
|
83 |
+
|
84 |
+
[[DOMANDA]]
|
85 |
+
${b}
|
86 |
+
|
87 |
+
[[ISTRUZIONI]]
|
88 |
+
1. Analizza attentamente il contesto e la domanda posta.
|
89 |
+
2. Struttura una risposta logica, coerente e completa.
|
90 |
+
3. Utilizza le informazioni del contesto, citando i documenti di origine solo se necessario per chiarire la descrizione.
|
91 |
+
4. Evidenzia le connessioni tra i vari concetti e le fonti.
|
92 |
+
5. Includi inferenze ragionevoli.
|
93 |
+
|
94 |
+
[[OUTPUT]]
|
95 |
+
L'output \u00e8 destinato ad essere letto da un lettore italiano.
|
96 |
+
`}function promptThread(a,b,c){return`
|
97 |
+
[[COMPITO]]
|
98 |
+
Rispondi alla nuova domanda integrando il contesto iniziale e gli sviluppi della conversazione in corso.
|
99 |
+
|
100 |
+
[[CONTESTO]]
|
101 |
+
${a}
|
102 |
+
|
103 |
+
[[CONVERSAZIONE]]
|
104 |
+
${b}
|
105 |
+
|
106 |
+
[[DOMANDA]]
|
107 |
+
${c}
|
108 |
+
|
109 |
+
[[ISTRUZIONI]]
|
110 |
+
1. Analizza la nuova domanda nel contesto della conversazione in corso.
|
111 |
+
2. Integra le informazioni dal contesto iniziale con gli sviluppi della discussione.
|
112 |
+
3. Mantieni la coerenza con la conversazione precedente, evitando ripetizioni non necessarie.
|
113 |
+
4. Puoi fare inferenze ragionevoli.
|
114 |
+
5. Adatta la risposta alla domanda attuale, anche se si discosta dal tema principale della conversazione.
|
115 |
+
6. Usa citazioni o riferimenti solo se necessario per chiarire la descrizione.
|
116 |
+
|
117 |
+
[[OUTPUT]]
|
118 |
+
L'output \u00e8 destinato ad essere letto da un lettore italiano.
|
119 |
+
`}
|
120 |
+
const getPayloadDoc=a=>({inputs:a,parameters:{task:"text2text-generation",max_new_tokens:512,num_return_sequences:1,temperature:.6,top_k:50,top_p:.85,do_sample:!0,no_repeat_ngram_size:4,num_beams:6,repetition_penalty:1.2,return_full_text:!1,details:!1,max_time:90,seed:42},options:{use_cache:!1,wait_for_model:!0}}),getPlayloadContext=a=>({inputs:a,parameters:{task:"text2text-generation",max_new_tokens:1024,num_return_sequences:1,temperature:.8,top_k:50,top_p:.85,do_sample:!0,no_repeat_ngram_size:3,num_beams:5,
|
121 |
+
repetition_penalty:1.1,return_full_text:!1,details:!1,max_time:120,seed:42},options:{use_cache:!1,wait_for_model:!0}}),getPayloadQuery=a=>({inputs:a,parameters:{task:"text-generation",max_new_tokens:512,num_return_sequences:1,temperature:.7,top_k:50,top_p:.85,do_sample:!0,no_repeat_ngram_size:3,num_beams:5,repetition_penalty:1.4,return_full_text:!1,details:!1,max_time:120,seed:42},options:{use_cache:!1,wait_for_model:!0}});const VERS="0.1.33 (16-07-2024)";var xlog=console.log,xerror=console.error;const cancelRequest=()=>{confirm("Confermi Cancellazione Richeista ?")&&(HfRequest.cancelRequest(),hideSpinner())},showSpinner=()=>{const a=document.getElementById("spinner");a.classList.add("show-spinner");a.addEventListener("click",cancelRequest)},hideSpinner=()=>{const a=document.getElementById("spinner");a.classList.remove("show-spinner");a.removeEventListener("click",cancelRequest)};
|
122 |
+
function openApp(){wnds.init();Menu.init();TextInput.init();TextOutput.init();document.querySelector(".menu-btn").checked=!1;release()}function release(){document.querySelector(".release").innerHTML=VERS}const op0=async function(a){a=await requestGet("./help1.html");wnds.wdiv.show(a)};function op1(a){Rag.readFromDb();wnds.wpre.show(`\n${Rag.ragQuery}`)}function showRagResponse(a){Rag.readFromDb();wnds.wpre.show(`\n${Rag.ragResponse}`)}
|
123 |
+
function op2(a){a=[...Rag.responses];0==a.length&&(a=UaDb.readArray("id_responses"));0!=a.length&&(a=a.map((b,c)=>`[${c+1}]\n ${b.trim()}`).join("\n"),wnds.wpre.show(a))}function op3(a){Rag.readFromDb();wnds.wpre.show(`${Rag.ragContext}`)}function op4(a){var b=UaDb.getAllIds();a=[];for(var c of b)b=UaDb.read(c).length,a.push(`${c} (${b})`);c=a.join("\n ");wnds.wpre.show(c)}async function op5(a){DataMgr.readDbDocNames();a=DataMgr.doc_names.join("\n");wnds.wpre.show(a)}
|
124 |
+
function calcQuery(){DataMgr.readDbDocs();DataMgr.readDbDocNames();var a=[];let b=0,c=0;a.push("Documento Num.Parti");a.push("==================");for(const d of DataMgr.docs){const e=DataMgr.doc_names[c];c+=1;const f=Math.ceil(d.length/MAX_PROMPT_LENGTH);b+=f;a.push(`${e} [${f}]`)}a.push("==================");a.push(`Totale num. Parti: ${b}`);a=a.join("\n");wnds.wpre.show(a)}
|
125 |
+
function op7(a){confirm("Confermi cancellazione dati?")&&(DataMgr.deleteDati(),Rag.ragContext="",Rag.ragQuery="",Rag.responses=[],wnds.wdiv.close(),wnds.wpre.close(),TextOutput.clear())}function op8(a){confirm("Confermi cancellazione documenti & dati?")&&(localStorage.clear(),Rag.ragContext="",Rag.ragQuery="",Rag.responses=[],wnds.wdiv.close(),wnds.wpre.close(),TextOutput.clear(),DataMgr.docs=[],DataMgr.doc_names=[])}
|
126 |
+
function op9(a){0!=Rag.prompts.length&&(a=Rag.prompts.map((b,c)=>`[${c+1}]${b}\n`).join("\n"),wnds.wpre.show(a))}function op6(a){DataMgr.readDbDocs();a=DataMgr.docs.join("\n");wnds.wpre.show(a)}async function help1(a){a=await requestGet("./data/help_test.html");wnds.wdiv.show(a)}function esempio(a){DataMgr.loadDoc(`data/${a}`);wnds.wdiv.close()}async function help2(a){a=await requestGet("./help2.html");wnds.wdiv.show(a)};const WndPre=a=>({w:UaWindowAdm.create(a),out:null,show(b){wnds.closeAll();b=`
|
127 |
+
<div class="window-text">
|
128 |
+
<div class="btn-wrapper">
|
129 |
+
<button class="btn-copy" title="Copia">
|
130 |
+
<svg class="copy-icon" viewBox="0 0 20 24">
|
131 |
+
<path d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z" />
|
132 |
+
</svg>
|
133 |
+
</button>
|
134 |
+
<button class="btn-close" title="chiudi" onclick="UaWindowAdm.closeThis(this)">X</button>
|
135 |
+
</div>
|
136 |
+
<pre class="pre-text">${b}</pre>
|
137 |
+
</div>
|
138 |
+
`;this.w.drag();this.w.setZ(12);this.w.vw_vh().setXY(16.5,10,-1);this.w.setHtml(b);this.w.show();this.w.getElement().querySelector(".btn-copy").addEventListener("click",()=>this.copy())},close(){this.w.close()},async copy(){const b=this.w.getElement().querySelector(".pre-text").textContent;try{await navigator.clipboard.writeText(b)}catch(c){xerror("Errore ",c)}}}),WndDiv=a=>({w:UaWindowAdm.create(a),out:null,show(b){wnds.closeAll();b=`
|
139 |
+
<div class="window-text">
|
140 |
+
<div class="btn-wrapper">
|
141 |
+
<button class="btn-copy" title="Copia">
|
142 |
+
<svg class="copy-icon" viewBox="0 0 20 24">
|
143 |
+
<path d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z" />
|
144 |
+
</svg>
|
145 |
+
</button>
|
146 |
+
<button class="btn-close" title="chiudi" onclick="UaWindowAdm.closeThis(this)">X</button>
|
147 |
+
</div>
|
148 |
+
<div class="div-text">${b}</div>
|
149 |
+
</div>
|
150 |
+
`;this.w.drag();this.w.setZ(12);this.w.vw_vh().setXY(16.5,10,-1);this.w.setHtml(b);this.w.show();this.w.getElement().querySelector(".btn-copy").addEventListener("click",()=>this.copy())},close(){this.w.close()},async copy(){const b=this.w.getElement().querySelector(".div-text").textContent;try{await navigator.clipboard.writeText(b)}catch(c){xerror("Errore ",c)}}}),wnds={wdiv:null,wpre:null,wout:null,init(){this.wdiv=WndDiv("id_w0");this.wpre=WndPre("id_w1");this.wout=WndPre("id_out")},closeAll(){UaWindowAdm.close("id_w0");
|
151 |
+
UaWindowAdm.close("id_w1");UaWindowAdm.close("id_out")}},Menu={init(){const a=document.querySelector("#id-menu-btn");a.addEventListener("change",()=>{document.querySelector("body").classList.toggle("menu-open",a.checked)});const b=document.getElementById("id_log");UaLog.callHide=()=>{b.classList.contains("active")&&b.classList.remove("active")};UaLog.callShow=()=>{b.classList.contains("active")||b.classList.add("active")};UaLog.setXY(64,13).setZ(111).new();UaLog.log_show("Buon Lavoro")},close(){const a=
|
152 |
+
document.querySelector("#menu-toggle");document.querySelector("body").classList.remove("menu-open",a.checked);document.querySelector(".menu-btn").checked=!1},async help(){const a=await requestGet("./help0.html");wnds.wdiv.show(a)},upload(){RagUpload.open()},uploadDir(){RagUpload.openDir()},async load(){alert("load")},log(){UaLog.toggle()}},TextInput={wnd:null,init(){this.inp=document.querySelector(".text-input");document.addEventListener("keydown",a=>{document.activeElement!==this.inp&&("F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Control Alt Shift Meta CapsLock Escape PrintScreen ScrollLock Pause Insert Delete Home End PageUp PageDown ArrowLeft ArrowRight ArrowUp ArrowDown".split(" ").includes(a.key)||
|
153 |
+
a.ctrlKey||a.metaKey||a.preventDefault())});document.querySelector(".clear-button").addEventListener("click",()=>{this.inp.value="";this.inp.focus()});document.querySelector(".send-input").addEventListener("click",()=>this.send());document.querySelector(".send2-input").addEventListener("click",()=>this.send2());document.querySelector(".clear-input").addEventListener("click",()=>this.clear())},handleEnter(a){},async send(){if(this.inp.value){Rag.readFromDb();if(Rag.ragContext&&!confirm("Vuoi iniziare una nuova elabrazione ?"))return"";
|
154 |
+
showSpinner();setOutText("");var a=this.inp.value.trim();try{const b=await Rag.requestDocsRAG(a);setOutText(b);this.inp.value="";UaLog.close()}catch(b){a=`send\n${b}`,xerror(a),alert(a),setOutText(a)}hideSpinner()}else alert("Ricorda di scrivere la Query ")},async send2(){if(this.inp.value){showSpinner();ThreadMgr.isFirst()&&setOutText("");var a=this.inp.value.trim();try{const b=await Rag.requestContext(a);if(""==b){hideSpinner();return}setOutText(b);this.inp.value=""}catch(b){a=`send2\n${b}`,xerror(a),
|
155 |
+
alert(a),setOutText(a)}hideSpinner()}else alert("Ricorda di scrivere la Query ")},clear(){confirm("Confermi cancellazione conversazione? ")&&(this.inp.value="",setOutText(""),ThreadMgr.init())}},setOutText=a=>{var b=document.getElementById("id-text-out");b.innerHTML='<pre class="pre-text"></pre>';b=b.querySelector(".pre-text");b.textContent=a;b.scrollTop=b.scrollHeight};
|
156 |
+
TextOutput={init(){this.copyBtn=document.querySelector(".copy-output");this.copyBtn.addEventListener("click",()=>this.copy());document.querySelector(".clear-output").addEventListener("click",()=>this.clear());document.querySelector(".wnd-output").addEventListener("click",()=>this.openWnd())},openWnd(){const a=document.getElementById("id-text-out").textContent;wnds.wout.show(a)},async copy(){const a=document.getElementById("id-text-out").querySelector("pre");if(a){var b=a.textContent;a.classList.add("copied");
|
157 |
+
this.copyBtn.classList.add("copied");try{await navigator.clipboard.writeText(b)}catch(c){xerror("Errore ",c)}setTimeout(()=>{this.copyBtn.classList.remove("copied");a.classList.remove("copied")},5E3)}},clear(){document.getElementById("id-text-out").textContent=""}};const RagUpload={open(){const a=UaWindowAdm.create("id_upload");a.drag();a.setZ(12);a.vw_vh().setXY(16.5,10,-1);a.setHtml('\n <div class="window-text">\n <div class="btn-wrapper">\n <button class="btn-close" title="chiudi" onclick="UaWindowAdm.closeThis(this)">X</button>\n </div> \n <div class="upload"> \n <h4>Upload file Text / PDF</h4> \n <form id="uploadForm">\n <input class="file" type="file" id="id_fileupload" > \n <button type="button" onclick="RagUpload.upload();">Upload and Convert</button>\n </form>\n <div id="result" class="result"></div>\n </div>\n </div>\n ');
|
158 |
+
a.show()},async upload(){const a=document.getElementById("id_fileupload").files[0];if(a){var b=a.name;if(DataMgr.doc_names.includes(b))alert("Il file \u00e8 gi\u00e0 in archivio");else{var c=document.getElementById("result"),d=a.name.split(".").pop().toLowerCase();showSpinner();try{let e;if("pdf"===d){const f=new PdfHandler;await f.loadPdfJs();e=await f.extractTextFromPDF(a);f.cleanup()}else if("txt"===d)e=await readTextFile(a);else{alert("Formato file non supportato.");return}DataMgr.addDoc(b,e);
|
159 |
+
c.innerHTML=`<br><br> ${b}<br><br>caricato e salvato nella memoria locale`}catch(e){console.error("Error:",e),alert("Errore durante l'estrazione del testo dal file.")}finally{hideSpinner()}}}else alert("Nessun file selezionato.")},openDir(){const a=UaWindowAdm.create("id_upload");a.drag();a.setZ(12);a.vw_vh().setXY(16.5,10,-1);a.setHtml('\n <div class="window-text">\n <div class="btn-wrapper">\n <button class="btn-close" title="chiudi" onclick="UaWindowAdm.closeThis(this)">X</button>\n </div> \n <div class="upload"> \n <h4>Upload files Text / PDF</h4> \n <form id="uploadForm">\n <input id="id_fileupload" class="file" type="file" webkitdirectory mozdirectory msdirectory odirectory directory multiple />\n <button type="button" onclick="RagUpload.uploadDir();">Upload and Convert</button>\n </form>\n <div class="result" id="result"></div>\n </div>\n </div>\n ');
|
160 |
+
a.show()},async uploadDir(){var a=document.getElementById("id_fileupload").files;if(a&&0!=a.length){var b=[];showSpinner();try{for(const c of a){const d=c.name;UaLog.log_show(d);if(DataMgr.doc_names.includes(d)){UaLog.log_shw(d+" : \u00e8 gi\u00e0 in archivio");continue}const e=c.name.split(".").pop().toLowerCase();let f;if("pdf"===e){const h=new PdfHandler;await h.loadPdfJs();f=await h.extractTextFromPDF(c);h.cleanup()}else if("txt"===e)f=await readTextFile(c);else{alert("Formato file non supportato.");
|
161 |
+
return}DataMgr.addDoc(d,f);b.push(`${d}`)}}catch(c){console.error("Error:",c),alert("Errore durante l'estrazione del testo dal file.")}finally{hideSpinner()}a=document.getElementById("result");b=b.join("<br>");a.innerHTML=b}else alert("Nessun file selezionato.")}};
|
162 |
+
class PdfHandler{constructor(){this.workerScriptElement=this.scriptElement=this.pdfjsLib=null}async loadPdfJs(){window.pdfjsLib||(this.scriptElement=document.createElement("script"),this.scriptElement.src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.6.347/pdf.min.js",document.body.appendChild(this.scriptElement),await new Promise(a=>{this.scriptElement.onload=()=>{this.workerScriptElement=document.createElement("script");this.workerScriptElement.src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.6.347/pdf.worker.min.js";
|
163 |
+
document.body.appendChild(this.workerScriptElement);this.workerScriptElement.onload=a}}));this.pdfjsLib=window["pdfjs-dist/build/pdf"];this.pdfjsLib.GlobalWorkerOptions.workerSrc="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.6.347/pdf.worker.min.js"}async extractTextFromPDF(a){a=await a.arrayBuffer();a=await this.pdfjsLib.getDocument({data:a}).promise;let b="";for(let c=1;c<=a.numPages;c++){const d=(await (await a.getPage(c)).getTextContent()).items.map(e=>e.str).join(" ");b+=d+"\n"}return b}cleanup(){this.scriptElement&&
|
164 |
+
(document.body.removeChild(this.scriptElement),this.scriptElement=null);this.workerScriptElement&&(document.body.removeChild(this.workerScriptElement),this.workerScriptElement=null);this.pdfjsLib=null;window.gc&&window.gc()}}
|
165 |
+
async function readTextFile(a){if(!a||"text/plain"!==a.type)throw Error("Invalid file type. Please select a text file.");return new Promise((b,c)=>{const d=new FileReader;d.onload=e=>b(e.target.result);d.onerror=e=>c(Error("Error reading file: "+e.message));d.readAsText(a)})};const nodrag_tds=["input","select","a"],nodrag_cls="nodrag";
|
166 |
+
var UaDrag=function(a){return function(b){let c=0,d=0,e=0,f=0;const h=function(g){g=g||window.event;g.preventDefault();c=e-g.clientX;d=f-g.clientY;e=g.clientX;f=g.clientY;b.style.top=b.offsetTop-d+"px";b.style.left=b.offsetLeft-c+"px"},l=function(){document.onmouseup=null;document.onmousemove=null};b.onmousedown=function(g){g=g||window.event;let k=g.target;!(k=k||null)||nodrag_tds.includes(k.tagName.toLowerCase())||k.classList.contains(nodrag_cls)||(g.preventDefault(),e=g.clientX,f=g.clientY,document.onmouseup=
|
167 |
+
l,document.onmousemove=h)}}(a)};const UaJtfh=()=>({rows:[],init(){this.rows=[];return this},insert(a){this.rows.unshift(a);return this},append(a){this.rows.push(a);return this},text(a=""){return this.rows.join(a)},html(a=""){return this.rows.join(a).replace(/\s+|\[rn\]/g," ")}});var UaLog={callHide:function(){},callShow:function(){},active:!1,wind:null,x:null,y:null,z:null,max_length:2E3,msg_id:"ualogmsg_",new:function(){null==this.wind&&(this.wind=UaWindowAdm.create("ualog_"),this.wind.drag());this.wind.setHtml('\n <button type="button" onclick="javascript:UaLog.cls();">Clear</button>\n <button type="button" onclick="javascript:UaLog.close();">Close</button>\n <div id="ualogmsg_"></div>');this.wind.setStyle({width:"auto",minWidth:"300px",maxWidth:"400px",
|
168 |
+
height:"auto",textAlign:"center",padding:"2px 2px 2px 2px",margin:"5px 0 0 0",background:"#333333",color:"#ffffff",fontSize:"15px",fontWeight:"normal",borderRadius:"9px",border:"1px solid #999999"});var a=document.getElementById(this.msg_id);const b={width:"auto",textAlign:"left",fontSize:"16px",fontFamily:"monospace",paddingTop:"2px ",marginTop:"2px",color:"inherit",background:"#000000",maxHeight:"600px",overflow:"auto",scrollbarColor:"#ab3205 #ffffff",scrollbarWidth:"auto"};for(const d in b)a.style[d]=
|
169 |
+
b[d];const c={background:"#444444",color:"#ffffff",padding:"5px 5px 5px 5px",margin:"0 5px 0 5px",fontSize:"16px",fontWeight:"bold",border:"1px solid #ffffff",borderRadius:"10px"};a=document.querySelectorAll("#ualog_ button");for(const d of a){for(const e in c)d.style[e]=c[e];d.addEventListener("mouseover",e=>{e.target.style.cursor="pointer";e.target.style.color="#000000";e.target.style.background="#aaaaaa"});d.addEventListener("mouseout",e=>{for(const f in c)e.target.style[f]=c[f]})}this.x?this.wind.vw_vh().setXY(this.x,
|
170 |
+
this.y,-1):this.wind.setCenter(-1);this.z&&this.wind.setZ(this.z);return this},setXY(a,b){this.x=a;this.y=b;return this},setZ(a){this.z=a;return this},prn_(...a){var b=a.join("<br/>");a=document.getElementById(this.msg_id);b=a.innerHTML+b+"<br/>";b.length>this.max_length&&(b=b.slice(-this.max_length));a.innerHTML=b},print(...a){null!=this.wind&&this.active&&this.prn_(...a)},log(...a){null!=this.wind&&this.prn_(...a)},log_show(...a){null!=this.wind&&(this.active||this.toggle(),this.prn_(...a))},cls(){if(null!=
|
171 |
+
this.wind)return document.getElementById(this.msg_id).innerHTML="",this},close(){null!=this.wind&&(this.wind.hide(),this.active=!1,this.callHide())},toggle(){null!=this.wind&&(this.active?(this.active=!1,this.wind.hide(),this.callHide()):(this.active=!0,this.wind.show(),this.callShow()))}};var UaWindowAdm={ws:{},create(a,b=null){let c=document.getElementById(a);c||(c=document.createElement("div"),b?document.getElementById(b).appendChild(c):document.body.appendChild(c),c.id=a,c.setAttribute("data-name","ua-window"),b=this.newUaWindow(c),this.ws[a]=b);a=this.ws[a];c.style.display="none";return a},get(a){return this.ws[a]?this.ws[a]:null},show(a){this.ws[a]&&this.ws[a].show()},close(a){this.ws[a]&&this.ws[a].close()},toggle(a){this.ws[a]&&this.ws[a].toggle()},hide(a){this.ws[a]&&this.ws[a].hide()},
|
172 |
+
closeThis(a){a=a.closest('[data-name="ua-window"]').id;this.ws[a].close()},showAll(){for(let a in this.ws)this.ws[a].show()},hideAll(){for(let a in this.ws)this.ws[a].hide()},closeAll(){for(let a in this.ws)this.ws[a].close()},remove(a){this.ws[a]&&(document.getElementById(a).remove(),this.ws[a]=null,delete this.ws[a])},removeAll(){for(let a in this.ws)this.remove(a);this.ws={}},newUaWindow(a){let b={initialize(c){this.w=c;this.wy=this.wx="0px";this.isVisible=this.isOpen=!1;this.firstShow=!0;this.wz=
|
173 |
+
this.pos=0;this.vh=this.vw="px"},vw_vh(){this.vw="vw";this.vh="vh";return this},addClassStyle(c){this.w.classList.contains(c)||this.w.classList.add(c);return this},removeClassStyle(c){this.w.classList.contains(c)&&this.w.classList.remove(c);return this},getWindow(){alert("getWindow => ??");return this.w},getElement(){return this.w},getId(){return this.w.id},setStyle(c){for(const d in c)this.w.style[d]=c[d];return this},setHtml(c){this.w.innerHTML=c;return this},getHtml(){return this.w.innerHTML},
|
174 |
+
setXY(c,d,e=0){this.wx=c;this.wy=d;this.pos=e;return this},setCenterY(c,d){this.setXY((window.innerWidth-this.w.clientWidth)/2,c,d);return this},setCenter(c){this.setXY((window.innerWidth-this.w.clientWidth)/2,(window.innerHeight-this.w.clientHeight)/2,c);return this},linkToId(c,d,e,f){c=document.getElementById(c);this.linkToElement(c,d,e,f);return this},linkToElement(c,d,e,f){d=c.offsetLeft+c.offsetWidth+d;c=c.offsetTop+e;0>c&&(c=0);this.setXY(d,c,f);return this},setZ(c){this.wz=c;return this},reset(){this.firstShow=
|
175 |
+
!0;return this},toggle(){this.isVisible?this.hide():this.show();return this},show(){if(this.firstShow||1==this.pos||0===this.pos&&!1===this.isVisible)this.w.style.position="absolute",this.w.style.marginLeft=0,this.w.style.marginTop=0,this.w.style.top=`${this.wy}${this.vh}`,0<=this.wx?this.w.style.left=`${this.wx}${this.vw}`:this.w.style.right=-`${this.wx}${this.vw}`,0<this.wz&&(this.w.style.zIndex=this.wz);this.w.style.display="";this.firstShow=!1;this.isOpen=this.isVisible=!0;return this},hide(){this.w.style.display=
|
176 |
+
"none";this.isVisible=!1;return this},close(){this.w.style.display="none";this.w.innerHTML="";this.isOpen=!1;return this},remove(){UaWindowAdm.remove(this.w.id);return null},drag(){UaDrag(this.w);return this}};b.initialize(a);return b}};
|
static/less/less.js
ADDED
The diff for this file is too large to render.
See raw diff
|
|
static/less/normalize.css
ADDED
@@ -0,0 +1,352 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
|
2 |
+
|
3 |
+
/* Document
|
4 |
+
========================================================================== */
|
5 |
+
|
6 |
+
/**
|
7 |
+
* 1. Correct the line height in all browsers.
|
8 |
+
* 2. Prevent adjustments of font size after orientation changes in iOS.
|
9 |
+
*/
|
10 |
+
|
11 |
+
html {
|
12 |
+
line-height: 1.15; /* 1 */
|
13 |
+
/*
|
14 |
+
-webkit-text-size-adjust: 100%;
|
15 |
+
*/
|
16 |
+
/* 2 */
|
17 |
+
}
|
18 |
+
|
19 |
+
/* Sections
|
20 |
+
========================================================================== */
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Remove the margin in all browsers.
|
24 |
+
*/
|
25 |
+
|
26 |
+
body {
|
27 |
+
margin: 0;
|
28 |
+
}
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Render the `main` element consistently in IE.
|
32 |
+
*/
|
33 |
+
|
34 |
+
main {
|
35 |
+
display: block;
|
36 |
+
}
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Correct the font size and margin on `h1` elements within `section` and
|
40 |
+
* `article` contexts in Chrome, Firefox, and Safari.
|
41 |
+
*/
|
42 |
+
|
43 |
+
h1 {
|
44 |
+
font-size: 2em;
|
45 |
+
margin: 0.67em 0;
|
46 |
+
}
|
47 |
+
|
48 |
+
/* Grouping content
|
49 |
+
========================================================================== */
|
50 |
+
|
51 |
+
/**
|
52 |
+
* 1. Add the correct box sizing in Firefox.
|
53 |
+
* 2. Show the overflow in Edge and IE.
|
54 |
+
*/
|
55 |
+
|
56 |
+
hr {
|
57 |
+
box-sizing: content-box; /* 1 */
|
58 |
+
height: 0; /* 1 */
|
59 |
+
overflow: visible; /* 2 */
|
60 |
+
}
|
61 |
+
|
62 |
+
/**
|
63 |
+
* 1. Correct the inheritance and scaling of font size in all browsers.
|
64 |
+
* 2. Correct the odd `em` font sizing in all browsers.
|
65 |
+
*/
|
66 |
+
|
67 |
+
pre {
|
68 |
+
font-family: monospace, monospace; /* 1 */
|
69 |
+
font-size: 1em; /* 2 */
|
70 |
+
}
|
71 |
+
|
72 |
+
/* Text-level semantics
|
73 |
+
========================================================================== */
|
74 |
+
|
75 |
+
/**
|
76 |
+
* Remove the gray background on active links in IE 10.
|
77 |
+
*/
|
78 |
+
|
79 |
+
a {
|
80 |
+
background-color: transparent;
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* 1. Remove the bottom border in Chrome 57-
|
85 |
+
* 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
|
86 |
+
*/
|
87 |
+
|
88 |
+
abbr[title] {
|
89 |
+
border-bottom: none; /* 1 */
|
90 |
+
text-decoration: underline; /* 2 */
|
91 |
+
text-decoration: underline dotted; /* 2 */
|
92 |
+
}
|
93 |
+
|
94 |
+
/**
|
95 |
+
* Add the correct font weight in Chrome, Edge, and Safari.
|
96 |
+
*/
|
97 |
+
|
98 |
+
b,
|
99 |
+
strong {
|
100 |
+
font-weight: bolder;
|
101 |
+
}
|
102 |
+
|
103 |
+
/**
|
104 |
+
* 1. Correct the inheritance and scaling of font size in all browsers.
|
105 |
+
* 2. Correct the odd `em` font sizing in all browsers.
|
106 |
+
*/
|
107 |
+
|
108 |
+
code,
|
109 |
+
kbd,
|
110 |
+
samp {
|
111 |
+
font-family: monospace, monospace; /* 1 */
|
112 |
+
font-size: 1em; /* 2 */
|
113 |
+
}
|
114 |
+
|
115 |
+
/**
|
116 |
+
* Add the correct font size in all browsers.
|
117 |
+
*/
|
118 |
+
|
119 |
+
small {
|
120 |
+
font-size: 80%;
|
121 |
+
}
|
122 |
+
|
123 |
+
/**
|
124 |
+
* Prevent `sub` and `sup` elements from affecting the line height in
|
125 |
+
* all browsers.
|
126 |
+
*/
|
127 |
+
|
128 |
+
sub,
|
129 |
+
sup {
|
130 |
+
font-size: 75%;
|
131 |
+
line-height: 0;
|
132 |
+
position: relative;
|
133 |
+
vertical-align: baseline;
|
134 |
+
}
|
135 |
+
|
136 |
+
sub {
|
137 |
+
bottom: -0.25em;
|
138 |
+
}
|
139 |
+
|
140 |
+
sup {
|
141 |
+
top: -0.5em;
|
142 |
+
}
|
143 |
+
|
144 |
+
/* Embedded content
|
145 |
+
========================================================================== */
|
146 |
+
|
147 |
+
/**
|
148 |
+
* Remove the border on images inside links in IE 10.
|
149 |
+
*/
|
150 |
+
|
151 |
+
img {
|
152 |
+
border-style: none;
|
153 |
+
}
|
154 |
+
|
155 |
+
/* Forms
|
156 |
+
========================================================================== */
|
157 |
+
|
158 |
+
/**
|
159 |
+
* 1. Change the font styles in all browsers.
|
160 |
+
* 2. Remove the margin in Firefox and Safari.
|
161 |
+
*/
|
162 |
+
|
163 |
+
button,
|
164 |
+
input,
|
165 |
+
optgroup,
|
166 |
+
select,
|
167 |
+
textarea {
|
168 |
+
font-family: inherit; /* 1 */
|
169 |
+
font-size: 100%; /* 1 */
|
170 |
+
line-height: 1.15; /* 1 */
|
171 |
+
margin: 0; /* 2 */
|
172 |
+
}
|
173 |
+
|
174 |
+
/**
|
175 |
+
* Show the overflow in IE.
|
176 |
+
* 1. Show the overflow in Edge.
|
177 |
+
*/
|
178 |
+
|
179 |
+
button,
|
180 |
+
input { /* 1 */
|
181 |
+
overflow: visible;
|
182 |
+
}
|
183 |
+
|
184 |
+
/**
|
185 |
+
* Remove the inheritance of text transform in Edge, Firefox, and IE.
|
186 |
+
* 1. Remove the inheritance of text transform in Firefox.
|
187 |
+
*/
|
188 |
+
|
189 |
+
button,
|
190 |
+
select { /* 1 */
|
191 |
+
text-transform: none;
|
192 |
+
}
|
193 |
+
|
194 |
+
/**
|
195 |
+
* Correct the inability to style clickable types in iOS and Safari.
|
196 |
+
*/
|
197 |
+
|
198 |
+
button,
|
199 |
+
[type="button"],
|
200 |
+
[type="reset"],
|
201 |
+
[type="submit"] {
|
202 |
+
-webkit-appearance: button;
|
203 |
+
}
|
204 |
+
|
205 |
+
/**
|
206 |
+
* Remove the inner border and padding in Firefox.
|
207 |
+
*/
|
208 |
+
|
209 |
+
button::-moz-focus-inner,
|
210 |
+
[type="button"]::-moz-focus-inner,
|
211 |
+
[type="reset"]::-moz-focus-inner,
|
212 |
+
[type="submit"]::-moz-focus-inner {
|
213 |
+
border-style: none;
|
214 |
+
padding: 0;
|
215 |
+
}
|
216 |
+
|
217 |
+
/**
|
218 |
+
* Restore the focus styles unset by the previous rule.
|
219 |
+
*/
|
220 |
+
|
221 |
+
button:-moz-focusring,
|
222 |
+
[type="button"]:-moz-focusring,
|
223 |
+
[type="reset"]:-moz-focusring,
|
224 |
+
[type="submit"]:-moz-focusring {
|
225 |
+
outline: 1px dotted ButtonText;
|
226 |
+
}
|
227 |
+
|
228 |
+
/**
|
229 |
+
* Correct the padding in Firefox.
|
230 |
+
*/
|
231 |
+
|
232 |
+
fieldset {
|
233 |
+
padding: 0.35em 0.75em 0.625em;
|
234 |
+
}
|
235 |
+
|
236 |
+
/**
|
237 |
+
* 1. Correct the text wrapping in Edge and IE.
|
238 |
+
* 2. Correct the color inheritance from `fieldset` elements in IE.
|
239 |
+
* 3. Remove the padding so developers are not caught out when they zero out
|
240 |
+
* `fieldset` elements in all browsers.
|
241 |
+
*/
|
242 |
+
|
243 |
+
legend {
|
244 |
+
box-sizing: border-box; /* 1 */
|
245 |
+
color: inherit; /* 2 */
|
246 |
+
display: table; /* 1 */
|
247 |
+
max-width: 100%; /* 1 */
|
248 |
+
padding: 0; /* 3 */
|
249 |
+
white-space: normal; /* 1 */
|
250 |
+
}
|
251 |
+
|
252 |
+
/**
|
253 |
+
* Add the correct vertical alignment in Chrome, Firefox, and Opera.
|
254 |
+
*/
|
255 |
+
|
256 |
+
progress {
|
257 |
+
vertical-align: baseline;
|
258 |
+
}
|
259 |
+
|
260 |
+
/**
|
261 |
+
* Remove the default vertical scrollbar in IE 10+.
|
262 |
+
*/
|
263 |
+
|
264 |
+
textarea {
|
265 |
+
overflow: auto;
|
266 |
+
}
|
267 |
+
|
268 |
+
/**
|
269 |
+
* 1. Add the correct box sizing in IE 10.
|
270 |
+
* 2. Remove the padding in IE 10.
|
271 |
+
*/
|
272 |
+
|
273 |
+
[type="checkbox"],
|
274 |
+
[type="radio"] {
|
275 |
+
box-sizing: border-box; /* 1 */
|
276 |
+
padding: 0; /* 2 */
|
277 |
+
}
|
278 |
+
|
279 |
+
/**
|
280 |
+
* Correct the cursor style of increment and decrement buttons in Chrome.
|
281 |
+
*/
|
282 |
+
|
283 |
+
[type="number"]::-webkit-inner-spin-button,
|
284 |
+
[type="number"]::-webkit-outer-spin-button {
|
285 |
+
height: auto;
|
286 |
+
}
|
287 |
+
|
288 |
+
/**
|
289 |
+
* 1. Correct the odd appearance in Chrome and Safari.
|
290 |
+
* 2. Correct the outline style in Safari.
|
291 |
+
*/
|
292 |
+
|
293 |
+
[type="search"] {
|
294 |
+
-webkit-appearance: textfield; /* 1 */
|
295 |
+
outline-offset: -2px; /* 2 */
|
296 |
+
}
|
297 |
+
|
298 |
+
/**
|
299 |
+
* Remove the inner padding in Chrome and Safari on macOS.
|
300 |
+
*/
|
301 |
+
|
302 |
+
[type="search"]::-webkit-search-decoration {
|
303 |
+
-webkit-appearance: none;
|
304 |
+
}
|
305 |
+
|
306 |
+
/**
|
307 |
+
* 1. Correct the inability to style clickable types in iOS and Safari.
|
308 |
+
* 2. Change font properties to `inherit` in Safari.
|
309 |
+
*/
|
310 |
+
|
311 |
+
::-webkit-file-upload-button {
|
312 |
+
-webkit-appearance: button; /* 1 */
|
313 |
+
font: inherit; /* 2 */
|
314 |
+
}
|
315 |
+
|
316 |
+
/* Interactive
|
317 |
+
========================================================================== */
|
318 |
+
|
319 |
+
/*
|
320 |
+
* Add the correct display in Edge, IE 10+, and Firefox.
|
321 |
+
*/
|
322 |
+
|
323 |
+
details {
|
324 |
+
display: block;
|
325 |
+
}
|
326 |
+
|
327 |
+
/*
|
328 |
+
* Add the correct display in all browsers.
|
329 |
+
*/
|
330 |
+
|
331 |
+
summary {
|
332 |
+
display: list-item;
|
333 |
+
}
|
334 |
+
|
335 |
+
/* Misc
|
336 |
+
========================================================================== */
|
337 |
+
|
338 |
+
/**
|
339 |
+
* Add the correct display in IE 10+.
|
340 |
+
*/
|
341 |
+
|
342 |
+
template {
|
343 |
+
display: none;
|
344 |
+
}
|
345 |
+
|
346 |
+
/**
|
347 |
+
* Add the correct display in IE 10.
|
348 |
+
*/
|
349 |
+
|
350 |
+
[hidden] {
|
351 |
+
display: none;
|
352 |
+
}
|
static/less/ragrqs.less
ADDED
@@ -0,0 +1,991 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/** @format */
|
2 |
+
|
3 |
+
html,
|
4 |
+
body,
|
5 |
+
div,
|
6 |
+
span,
|
7 |
+
table,
|
8 |
+
td,
|
9 |
+
label,
|
10 |
+
p,
|
11 |
+
a,
|
12 |
+
input,
|
13 |
+
ul,
|
14 |
+
li,
|
15 |
+
button {
|
16 |
+
padding: 0;
|
17 |
+
margin: 0;
|
18 |
+
font-family: @fsans;
|
19 |
+
}
|
20 |
+
|
21 |
+
.bb0 {
|
22 |
+
background: #daee59 !important;
|
23 |
+
}
|
24 |
+
.bb1 {
|
25 |
+
background: #5487fc !important;
|
26 |
+
}
|
27 |
+
|
28 |
+
html {
|
29 |
+
background: @contaniner-bg;
|
30 |
+
}
|
31 |
+
body {
|
32 |
+
background: @contaniner-bg;
|
33 |
+
box-sizing: border-box;
|
34 |
+
min-height: 100vh;
|
35 |
+
height: 100vh;
|
36 |
+
position: relative;
|
37 |
+
padding: 0;
|
38 |
+
margin: 0;
|
39 |
+
overflow: hidden;
|
40 |
+
font-family: @fsans;
|
41 |
+
font-weight: normal;
|
42 |
+
}
|
43 |
+
|
44 |
+
// spinner
|
45 |
+
.spinner {
|
46 |
+
z-index: 1000;
|
47 |
+
position: absolute;
|
48 |
+
top: 70vh;
|
49 |
+
left: 50vw;
|
50 |
+
transform: translate(-50%, -50%);
|
51 |
+
cursor: pointer;
|
52 |
+
display: none;
|
53 |
+
align-items: center;
|
54 |
+
|
55 |
+
.pulse-icon {
|
56 |
+
width: 20px;
|
57 |
+
height: 20px;
|
58 |
+
background-color: #ff8c00; // Arancione
|
59 |
+
border-radius: 50%;
|
60 |
+
animation: pulse 1.5s ease-in-out infinite;
|
61 |
+
}
|
62 |
+
|
63 |
+
.stop-message {
|
64 |
+
margin-left: 15px;
|
65 |
+
background-color: inherit;
|
66 |
+
color: #8f8a8a;
|
67 |
+
padding: 8px 15px;
|
68 |
+
border-radius: 10px;
|
69 |
+
font-size: 22px;
|
70 |
+
font-weight: bold;
|
71 |
+
opacity: 1;
|
72 |
+
transition: opacity 0.3s;
|
73 |
+
}
|
74 |
+
|
75 |
+
&:hover .stop-message {
|
76 |
+
color: @text-color;
|
77 |
+
background: @btn-hover;
|
78 |
+
opacity: 1;
|
79 |
+
}
|
80 |
+
}
|
81 |
+
|
82 |
+
@keyframes pulse {
|
83 |
+
0% {
|
84 |
+
transform: scale(0.6);
|
85 |
+
box-shadow: 0 0 0 0 rgba(255, 140, 0, 0.7); // Arancione con opacità
|
86 |
+
}
|
87 |
+
|
88 |
+
70% {
|
89 |
+
transform: scale(1.4);
|
90 |
+
box-shadow: 0 0 0 20px rgba(255, 140, 0, 0); // Arancione completamente trasparente
|
91 |
+
}
|
92 |
+
|
93 |
+
100% {
|
94 |
+
transform: scale(0.6);
|
95 |
+
box-shadow: 0 0 0 0 rgba(255, 140, 0, 0); // Arancione completamente trasparente
|
96 |
+
}
|
97 |
+
}
|
98 |
+
|
99 |
+
.show-spinner {
|
100 |
+
display: flex;
|
101 |
+
}
|
102 |
+
///////////////
|
103 |
+
.upload {
|
104 |
+
@primary-color: darken(@color2, 25%);
|
105 |
+
@background-color: #121212;
|
106 |
+
@surface-color: #1e1e1e;
|
107 |
+
@btn-text-color: #000000;
|
108 |
+
@border-radius: 4px;
|
109 |
+
|
110 |
+
background-color: @surface-color;
|
111 |
+
padding: 2em;
|
112 |
+
padding-top: 0;
|
113 |
+
margin: 0;
|
114 |
+
border-radius: @border-radius;
|
115 |
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
|
116 |
+
text-align: center;
|
117 |
+
|
118 |
+
h4 {
|
119 |
+
color: @text-color;
|
120 |
+
margin-bottom: 1em;
|
121 |
+
}
|
122 |
+
|
123 |
+
form {
|
124 |
+
display: flex;
|
125 |
+
flex-direction: column;
|
126 |
+
align-items: center;
|
127 |
+
|
128 |
+
.file {
|
129 |
+
background-color: @background-color;
|
130 |
+
border: 1px solid lighten(@surface-color, 20%);
|
131 |
+
color: @text-color;
|
132 |
+
padding: 0.5em;
|
133 |
+
margin-bottom: 1em;
|
134 |
+
border-radius: @border-radius;
|
135 |
+
width: 100%;
|
136 |
+
box-sizing: border-box;
|
137 |
+
|
138 |
+
&::file-selector-button {
|
139 |
+
background-color: @primary-color;
|
140 |
+
color: @text-color;
|
141 |
+
// color: #000000;
|
142 |
+
border: none;
|
143 |
+
padding: 0.5em 1em;
|
144 |
+
border-radius: @border-radius;
|
145 |
+
cursor: pointer;
|
146 |
+
|
147 |
+
&:hover {
|
148 |
+
background-color: darken(@primary-color, 10%);
|
149 |
+
}
|
150 |
+
}
|
151 |
+
}
|
152 |
+
|
153 |
+
button {
|
154 |
+
background-color: @primary-color;
|
155 |
+
color: @text-color;
|
156 |
+
border: none;
|
157 |
+
padding: 0.5em 1em;
|
158 |
+
border-radius: @border-radius;
|
159 |
+
cursor: pointer;
|
160 |
+
width: 100%;
|
161 |
+
box-sizing: border-box;
|
162 |
+
|
163 |
+
&:hover {
|
164 |
+
background-color: darken(@primary-color, 10%);
|
165 |
+
}
|
166 |
+
}
|
167 |
+
}
|
168 |
+
|
169 |
+
.result {
|
170 |
+
width: 100%;
|
171 |
+
background: @output-bg;
|
172 |
+
color: @text-color;
|
173 |
+
font-size: @fsize-result;
|
174 |
+
font-weight: normal;
|
175 |
+
text-align: left;
|
176 |
+
}
|
177 |
+
}
|
178 |
+
|
179 |
+
@fserif: Georigia, "Ties New Roman", serif;
|
180 |
+
@fsans: arial, verdana, Helvetica, sans-serif;
|
181 |
+
|
182 |
+
// @fsize-menu: calc(10px + 1vw);
|
183 |
+
@fsize-out: 20px;
|
184 |
+
@fsize-inp: 20px;
|
185 |
+
@fsize-help: 18px;
|
186 |
+
@fsize-btn-close: 22px;
|
187 |
+
@fsize-result: 15px;
|
188 |
+
|
189 |
+
@base-bg: #000000;
|
190 |
+
@text-color: #fff;
|
191 |
+
@color1: #ff4500;
|
192 |
+
@color2: #17d2ad;
|
193 |
+
@color3: #e3d50e;
|
194 |
+
|
195 |
+
@contaniner-bg: lighten(@base-bg, 10%);
|
196 |
+
@border-shadow: lighten(@contaniner-bg, 20%);
|
197 |
+
|
198 |
+
@btn-bg: lighten(@contaniner-bg, 10%);
|
199 |
+
@btn-hover: lighten(@btn-bg, 15%);
|
200 |
+
@btn-color: darken(@text-color, 10%);
|
201 |
+
@btn-hover-fg: lighten(@color2, 10%);
|
202 |
+
|
203 |
+
@border-hover: @color2;
|
204 |
+
@border-input: @color1;
|
205 |
+
// window
|
206 |
+
@wnd-bg: lighten(@base-bg, 10%);
|
207 |
+
@wnd-border-shadow: darken(@color3, 10%);
|
208 |
+
@wnd-pre-color: lighten(@color3, 30%);
|
209 |
+
//output
|
210 |
+
@output-bg: darken(@contaniner-bg, 15%);
|
211 |
+
@btn-copied: darken(@color2, 20%);
|
212 |
+
@text-copied-bg: lighten(@output-bg, 5%);
|
213 |
+
@text-copied: lighten(@color2, 20%);
|
214 |
+
@input-bg: darken(@contaniner-bg, 15%);
|
215 |
+
|
216 |
+
@btn-send-bg: darken(@color1, 20%);
|
217 |
+
@btn-send-fg: @text-color;
|
218 |
+
@btn-send-hover-bg: lighten(@btn-send-bg, 20%);
|
219 |
+
|
220 |
+
@btn-send2-bg: darken(@color2, 20%);
|
221 |
+
@btn-send2-hover-bg: lighten(@btn-send2-bg, 15%);
|
222 |
+
|
223 |
+
div.container {
|
224 |
+
background: @contaniner-bg;
|
225 |
+
box-sizing: border-box;
|
226 |
+
position: relative;
|
227 |
+
top: 5vh;
|
228 |
+
left: 0;
|
229 |
+
height: 95vh;
|
230 |
+
margin: 0;
|
231 |
+
padding: 0;
|
232 |
+
transition: margin-left 0.5s ease;
|
233 |
+
display: flex;
|
234 |
+
flex-direction: column;
|
235 |
+
justify-content: flex-start;
|
236 |
+
align-items: stretch;
|
237 |
+
flex-wrap: nowrap;
|
238 |
+
overflow-y: auto;
|
239 |
+
overflow-x: auto;
|
240 |
+
|
241 |
+
div.item {
|
242 |
+
box-sizing: border-box;
|
243 |
+
min-height: 50px;
|
244 |
+
margin: 0;
|
245 |
+
padding: 0;
|
246 |
+
}
|
247 |
+
|
248 |
+
div.item1 {
|
249 |
+
flex: 5;
|
250 |
+
padding-top: 0.5vh;
|
251 |
+
padding-right: 0.5vw;
|
252 |
+
padding-left: 0.5vw;
|
253 |
+
padding-bottom: 10vh;
|
254 |
+
|
255 |
+
.output-wrapper {
|
256 |
+
background-color: @contaniner-bg;
|
257 |
+
border-radius: 20px;
|
258 |
+
position: relative;
|
259 |
+
bottom: 0;
|
260 |
+
right: 0;
|
261 |
+
left: 0;
|
262 |
+
width: 100%;
|
263 |
+
height: 100%;
|
264 |
+
display: flex;
|
265 |
+
flex-direction: row;
|
266 |
+
align-items: flex-start;
|
267 |
+
|
268 |
+
.text-out {
|
269 |
+
flex: 1;
|
270 |
+
box-sizing: border-box;
|
271 |
+
background: @output-bg;
|
272 |
+
color: @text-color;
|
273 |
+
border: none;
|
274 |
+
padding: 2px;
|
275 |
+
min-width: 50vw;
|
276 |
+
height: 100%;
|
277 |
+
border-radius: 10px;
|
278 |
+
overflow-y: auto;
|
279 |
+
outline: none;
|
280 |
+
box-shadow: 0 0 0 2px @border-shadow;
|
281 |
+
&:hover {
|
282 |
+
box-shadow: 0 0 0 2px @border-hover;
|
283 |
+
}
|
284 |
+
|
285 |
+
.pre-text {
|
286 |
+
white-space: pre-wrap;
|
287 |
+
word-wrap: break-word;
|
288 |
+
font-family: @fsans;
|
289 |
+
font-size: @fsize-out;
|
290 |
+
line-height: 1.6;
|
291 |
+
padding: 2px;
|
292 |
+
margin: 0;
|
293 |
+
height: 100%;
|
294 |
+
box-sizing: border-box;
|
295 |
+
overflow-y: scroll;
|
296 |
+
scroll-behavior: smooth;
|
297 |
+
&.copied {
|
298 |
+
background-color: @text-copied-bg;
|
299 |
+
color: @text-copied;
|
300 |
+
}
|
301 |
+
}
|
302 |
+
.div-text {
|
303 |
+
white-space: pre-wrap;
|
304 |
+
word-wrap: break-word;
|
305 |
+
font-family: @fsans;
|
306 |
+
font-size: @fsize-out;
|
307 |
+
line-height: 1.6;
|
308 |
+
padding: 2px;
|
309 |
+
margin: 0;
|
310 |
+
height: 100%;
|
311 |
+
box-sizing: border-box;
|
312 |
+
overflow-y: scroll;
|
313 |
+
}
|
314 |
+
&.copied {
|
315 |
+
background-color: @text-copied-bg;
|
316 |
+
color: @text-copied;
|
317 |
+
}
|
318 |
+
}
|
319 |
+
}
|
320 |
+
|
321 |
+
.output-actions {
|
322 |
+
display: flex;
|
323 |
+
flex-direction: column;
|
324 |
+
align-items: flex-end;
|
325 |
+
margin-left: 0.5vw;
|
326 |
+
margin-right: 0.5vw;
|
327 |
+
|
328 |
+
.copy-output,
|
329 |
+
.wnd-output,
|
330 |
+
.clear-output {
|
331 |
+
box-sizing: border-box;
|
332 |
+
background-color: @btn-bg;
|
333 |
+
color: @text-color;
|
334 |
+
border: none;
|
335 |
+
padding: 10px;
|
336 |
+
cursor: pointer;
|
337 |
+
border-radius: 50%;
|
338 |
+
width: 40px;
|
339 |
+
height: 40px;
|
340 |
+
display: flex;
|
341 |
+
align-items: center;
|
342 |
+
margin-bottom: 5px;
|
343 |
+
transition: background-color 0.3s;
|
344 |
+
|
345 |
+
&:hover {
|
346 |
+
background-color: @btn-hover;
|
347 |
+
}
|
348 |
+
}
|
349 |
+
|
350 |
+
.copy-output {
|
351 |
+
transition: background-color 0.3s, transform 0.3s;
|
352 |
+
|
353 |
+
&.copied {
|
354 |
+
background: @btn-hover-fg;
|
355 |
+
transform: scale(1.2);
|
356 |
+
}
|
357 |
+
.copy-icon {
|
358 |
+
fill: @text-color;
|
359 |
+
width: 24px;
|
360 |
+
height: 24px;
|
361 |
+
|
362 |
+
&:hover {
|
363 |
+
fill: @btn-hover-fg;
|
364 |
+
}
|
365 |
+
}
|
366 |
+
}
|
367 |
+
.clear-output,
|
368 |
+
.wnd-output {
|
369 |
+
transition: background-color 0.3s, transform 0.3s;
|
370 |
+
.icon {
|
371 |
+
fill: @text-color;
|
372 |
+
width: 24px;
|
373 |
+
height: 24px;
|
374 |
+
|
375 |
+
&:hover {
|
376 |
+
fill: @btn-hover-fg;
|
377 |
+
}
|
378 |
+
}
|
379 |
+
}
|
380 |
+
}
|
381 |
+
}
|
382 |
+
}
|
383 |
+
|
384 |
+
////////////////////
|
385 |
+
*:hover {
|
386 |
+
outline: none;
|
387 |
+
caret-color: transparent;
|
388 |
+
}
|
389 |
+
|
390 |
+
textarea:focus {
|
391 |
+
caret-color: auto;
|
392 |
+
}
|
393 |
+
|
394 |
+
///////////////////
|
395 |
+
|
396 |
+
div.item2 {
|
397 |
+
flex: 2;
|
398 |
+
padding-top: 0;
|
399 |
+
padding-bottom: 0;
|
400 |
+
padding-right: 0.5vw;
|
401 |
+
padding-left: 0.5vw;
|
402 |
+
|
403 |
+
.input-wrapper {
|
404 |
+
background-color: @contaniner-bg;
|
405 |
+
border-radius: 20px;
|
406 |
+
position: relative;
|
407 |
+
bottom: 2vh;
|
408 |
+
right: 0;
|
409 |
+
left: 0;
|
410 |
+
width: 100%;
|
411 |
+
height: 100%;
|
412 |
+
display: flex;
|
413 |
+
flex-direction: row;
|
414 |
+
align-items: flex-start;
|
415 |
+
|
416 |
+
&:focus-within .clear-button {
|
417 |
+
display: block;
|
418 |
+
}
|
419 |
+
|
420 |
+
.text-input {
|
421 |
+
flex: 1;
|
422 |
+
font-size: @fsize-inp;
|
423 |
+
font-family: @fsans;
|
424 |
+
resize: none;
|
425 |
+
box-sizing: border-box;
|
426 |
+
background: @input-bg;
|
427 |
+
color: @text-color;
|
428 |
+
border: none;
|
429 |
+
padding: 2px;
|
430 |
+
padding-right: 40px;
|
431 |
+
height: 100%;
|
432 |
+
margin-left: 5px;
|
433 |
+
border-radius: 10px;
|
434 |
+
overflow-y: auto;
|
435 |
+
outline: none;
|
436 |
+
box-shadow: 0 0 0 2px @border-shadow;
|
437 |
+
&:hover {
|
438 |
+
box-shadow: 0 0 0 2px @border-hover;
|
439 |
+
}
|
440 |
+
|
441 |
+
&:focus {
|
442 |
+
box-shadow: 0 0 0 2px @border-input;
|
443 |
+
}
|
444 |
+
}
|
445 |
+
|
446 |
+
.clear-button {
|
447 |
+
position: absolute;
|
448 |
+
right: 60px;
|
449 |
+
top: 19vh;
|
450 |
+
padding: 5px;
|
451 |
+
border-radius: 50%;
|
452 |
+
background: @btn-bg;
|
453 |
+
border: none;
|
454 |
+
font-size: 20px;
|
455 |
+
cursor: pointer;
|
456 |
+
color: darken(@text-color, 20%);
|
457 |
+
display: none;
|
458 |
+
&:hover {
|
459 |
+
font-weight: bold;
|
460 |
+
background: @btn-hover;
|
461 |
+
color: @text-color;
|
462 |
+
}
|
463 |
+
}
|
464 |
+
|
465 |
+
.input-actions {
|
466 |
+
display: flex;
|
467 |
+
flex-direction: column;
|
468 |
+
margin-left: 0.5vw;
|
469 |
+
margin-right: 0.5vw;
|
470 |
+
|
471 |
+
.send-input,
|
472 |
+
.send2-input,
|
473 |
+
.clear-input {
|
474 |
+
box-sizing: border-box;
|
475 |
+
background-color: @btn-bg;
|
476 |
+
color: @text-color;
|
477 |
+
border: none;
|
478 |
+
padding: 10px;
|
479 |
+
cursor: pointer;
|
480 |
+
border-radius: 50%;
|
481 |
+
width: 40px;
|
482 |
+
height: 40px;
|
483 |
+
margin-bottom: 5px;
|
484 |
+
transition: background-color 0.3s;
|
485 |
+
|
486 |
+
&:hover {
|
487 |
+
background-color: @btn-hover;
|
488 |
+
}
|
489 |
+
}
|
490 |
+
|
491 |
+
.send-input {
|
492 |
+
background: @btn-send-bg;
|
493 |
+
|
494 |
+
&:hover {
|
495 |
+
background: @btn-send-hover-bg;
|
496 |
+
}
|
497 |
+
}
|
498 |
+
|
499 |
+
.send2-input {
|
500 |
+
background: @btn-send2-bg;
|
501 |
+
|
502 |
+
&:hover {
|
503 |
+
background: @btn-send2-hover-bg;
|
504 |
+
}
|
505 |
+
}
|
506 |
+
|
507 |
+
.clear-input {
|
508 |
+
background: @btn-bg;
|
509 |
+
color: @btn-color;
|
510 |
+
&:hover {
|
511 |
+
background: @btn-hover;
|
512 |
+
color: @btn-hover-fg;
|
513 |
+
}
|
514 |
+
}
|
515 |
+
}
|
516 |
+
}
|
517 |
+
}
|
518 |
+
|
519 |
+
// menu_h
|
520 |
+
@fsize-upload: 20px;
|
521 |
+
@fsize-log: 14px;
|
522 |
+
@fsize-menu: 14px;
|
523 |
+
|
524 |
+
@menu-width: 16vw;
|
525 |
+
@menu-bg: darken(@contaniner-bg, 35%);
|
526 |
+
@menu-border: lighten(@menu-bg, 20%);
|
527 |
+
@menu-fg: @text-color;
|
528 |
+
@menu-icon-fg: #aea7a7;
|
529 |
+
@menu-icon-hover: lighten(@color2, 10%);
|
530 |
+
|
531 |
+
.menu-open {
|
532 |
+
.container {
|
533 |
+
margin-left: @menu-width;
|
534 |
+
}
|
535 |
+
|
536 |
+
.menu-box {
|
537 |
+
left: 0 !important;
|
538 |
+
}
|
539 |
+
}
|
540 |
+
|
541 |
+
div.menu-h {
|
542 |
+
background-color: lighten(@menu-bg, 10%);
|
543 |
+
position: fixed;
|
544 |
+
top: 0;
|
545 |
+
left: 0;
|
546 |
+
width: 100vw;
|
547 |
+
height: 4.5vh;
|
548 |
+
padding: 0;
|
549 |
+
margin: 0;
|
550 |
+
outline: none;
|
551 |
+
box-shadow: 0 0 0 2px @border-shadow;
|
552 |
+
z-index: 100;
|
553 |
+
// caret-color: transparent;
|
554 |
+
|
555 |
+
.release {
|
556 |
+
background: inherit;
|
557 |
+
color: lighten(@color1, 10%);
|
558 |
+
font-weight: bold;
|
559 |
+
margin-left: 57vw;
|
560 |
+
margin-top: 0.5vh;
|
561 |
+
}
|
562 |
+
.menu-btn {
|
563 |
+
appearance: none;
|
564 |
+
}
|
565 |
+
|
566 |
+
.menu-btn:checked {
|
567 |
+
& + .menu-icon {
|
568 |
+
border: 1px solid @menu-border;
|
569 |
+
|
570 |
+
.nav-icon {
|
571 |
+
transform: rotate(45deg);
|
572 |
+
|
573 |
+
&::before {
|
574 |
+
top: 0;
|
575 |
+
}
|
576 |
+
|
577 |
+
&::after {
|
578 |
+
top: 0;
|
579 |
+
transform: rotate(90deg);
|
580 |
+
}
|
581 |
+
}
|
582 |
+
}
|
583 |
+
}
|
584 |
+
|
585 |
+
.menu-icon {
|
586 |
+
box-sizing: border-box;
|
587 |
+
background-color: inherit;
|
588 |
+
display: block;
|
589 |
+
position: absolute;
|
590 |
+
margin-left: 2vw;
|
591 |
+
top: 0;
|
592 |
+
left: 0;
|
593 |
+
width: 4vw;
|
594 |
+
height: 4.5vh;
|
595 |
+
cursor: pointer;
|
596 |
+
padding: 2px 2px;
|
597 |
+
z-index: 1;
|
598 |
+
|
599 |
+
&:hover {
|
600 |
+
.nav-icon,
|
601 |
+
.nav-icon::before,
|
602 |
+
.nav-icon::after {
|
603 |
+
background-color: @menu-icon-hover;
|
604 |
+
}
|
605 |
+
}
|
606 |
+
|
607 |
+
.nav-icon {
|
608 |
+
background-color: @menu-icon-fg;
|
609 |
+
display: block;
|
610 |
+
position: absolute;
|
611 |
+
top: 14px;
|
612 |
+
left: 0;
|
613 |
+
width: 25px;
|
614 |
+
height: 2px;
|
615 |
+
transition-duration: 0.25s;
|
616 |
+
}
|
617 |
+
|
618 |
+
.nav-icon::before,
|
619 |
+
.nav-icon::after {
|
620 |
+
content: "";
|
621 |
+
position: absolute;
|
622 |
+
left: 0;
|
623 |
+
background-color: inherit;
|
624 |
+
width: inherit;
|
625 |
+
height: inherit;
|
626 |
+
}
|
627 |
+
|
628 |
+
.nav-icon::before {
|
629 |
+
top: -8px;
|
630 |
+
}
|
631 |
+
|
632 |
+
.nav-icon::after {
|
633 |
+
top: 8px;
|
634 |
+
}
|
635 |
+
}
|
636 |
+
|
637 |
+
.head-wrapper {
|
638 |
+
position: absolute;
|
639 |
+
top: 0;
|
640 |
+
left: 5vw;
|
641 |
+
height: 4vh;
|
642 |
+
padding: 0;
|
643 |
+
margin: 0;
|
644 |
+
display: inline-flex;
|
645 |
+
flex-direction: row;
|
646 |
+
flex-wrap: nowrap;
|
647 |
+
align-items: center;
|
648 |
+
justify-content: flex-start;
|
649 |
+
|
650 |
+
.log,
|
651 |
+
.help,
|
652 |
+
.upload,
|
653 |
+
.upload-dir {
|
654 |
+
margin-top: 2px;
|
655 |
+
margin-left: 30px;
|
656 |
+
margin-right: 0;
|
657 |
+
padding: 5px 5px 0 5px;
|
658 |
+
border: none;
|
659 |
+
cursor: pointer;
|
660 |
+
border-radius: 20%;
|
661 |
+
font-size: @fsize-upload;
|
662 |
+
color: @text-color;
|
663 |
+
background: @btn-bg;
|
664 |
+
max-height: 4vh;
|
665 |
+
|
666 |
+
&:hover {
|
667 |
+
background: @btn-hover;
|
668 |
+
}
|
669 |
+
}
|
670 |
+
}
|
671 |
+
|
672 |
+
.upload,
|
673 |
+
.upload-dir {
|
674 |
+
transition: background-color 0.3s, transform 0.3s;
|
675 |
+
.icon {
|
676 |
+
fill: @text-color;
|
677 |
+
width: 24px;
|
678 |
+
height: 24px;
|
679 |
+
|
680 |
+
&:hover {
|
681 |
+
fill: @btn-hover-fg;
|
682 |
+
}
|
683 |
+
}
|
684 |
+
}
|
685 |
+
|
686 |
+
.log {
|
687 |
+
font-size: @fsize-log !important;
|
688 |
+
font-weight: normal !important;
|
689 |
+
background: darken(@color1, 20%) !important;
|
690 |
+
&:hover {
|
691 |
+
background: darken(@color1, 10%) !important;
|
692 |
+
}
|
693 |
+
&.active {
|
694 |
+
background: darken(@color2, 20%) !important;
|
695 |
+
|
696 |
+
&:hover {
|
697 |
+
background: darken(@color2, 10%) !important;
|
698 |
+
}
|
699 |
+
}
|
700 |
+
}
|
701 |
+
|
702 |
+
div.menu-box {
|
703 |
+
position: fixed;
|
704 |
+
top: 5vh;
|
705 |
+
left: -2000px;
|
706 |
+
height: 95vh;
|
707 |
+
width: @menu-width;
|
708 |
+
transition: left 0.3s ease-out;
|
709 |
+
padding: 0;
|
710 |
+
padding-top: 1vh;
|
711 |
+
padding-left: 0.5vw;
|
712 |
+
z-index: 101;
|
713 |
+
background: lighten(@menu-bg, 5%);
|
714 |
+
box-sizing: border-box;
|
715 |
+
outline: none;
|
716 |
+
box-shadow: 0 0 0 2px @border-shadow;
|
717 |
+
display: flex;
|
718 |
+
flex-direction: column;
|
719 |
+
flex-wrap: nowrap;
|
720 |
+
justify-content: flex-start;
|
721 |
+
align-items: stretch;
|
722 |
+
overflow-y: auto;
|
723 |
+
overflow-x: auto;
|
724 |
+
|
725 |
+
ul {
|
726 |
+
list-style: none;
|
727 |
+
margin: 0;
|
728 |
+
padding: 0;
|
729 |
+
display: flex;
|
730 |
+
flex-direction: column;
|
731 |
+
border-top: 1px solid @menu-border;
|
732 |
+
|
733 |
+
li {
|
734 |
+
border-left: 1px solid @menu-border;
|
735 |
+
border-right: 1px solid @menu-border;
|
736 |
+
border-bottom: 1px solid @menu-border;
|
737 |
+
|
738 |
+
a {
|
739 |
+
color: @menu-fg;
|
740 |
+
font-size: @fsize-menu;
|
741 |
+
font-family: @fsans;
|
742 |
+
font-weight: normal;
|
743 |
+
display: block;
|
744 |
+
margin: 0;
|
745 |
+
padding: 2px 2px 2px 0;
|
746 |
+
text-align: left;
|
747 |
+
text-decoration: none;
|
748 |
+
}
|
749 |
+
|
750 |
+
&:hover {
|
751 |
+
text-decoration: underline;
|
752 |
+
background-color: lighten(@menu-bg, 20%);
|
753 |
+
color: @menu-icon-hover;
|
754 |
+
}
|
755 |
+
}
|
756 |
+
a.delete {
|
757 |
+
text-align: center;
|
758 |
+
font-weight: bold;
|
759 |
+
font-style: italic;
|
760 |
+
color: #000000;
|
761 |
+
background: darken(@color3, 10%);
|
762 |
+
}
|
763 |
+
a.help {
|
764 |
+
text-align: center;
|
765 |
+
font-weight: bold;
|
766 |
+
font-style: italic;
|
767 |
+
color: #000000;
|
768 |
+
background: darken(@color1, 10%);
|
769 |
+
}
|
770 |
+
|
771 |
+
li.show {
|
772 |
+
background: @base-bg;
|
773 |
+
color: @text-color;
|
774 |
+
width: 100%;
|
775 |
+
text-align: center;
|
776 |
+
box-sizing: border-box;
|
777 |
+
|
778 |
+
&:hover {
|
779 |
+
text-decoration: none;
|
780 |
+
}
|
781 |
+
}
|
782 |
+
}
|
783 |
+
}
|
784 |
+
}
|
785 |
+
|
786 |
+
// Window
|
787 |
+
.window-text {
|
788 |
+
position: relative;
|
789 |
+
top: 0;
|
790 |
+
left: 0;
|
791 |
+
background: @wnd-bg;
|
792 |
+
color: @text-color;
|
793 |
+
border: none;
|
794 |
+
padding: 0 2px 2px 2px;
|
795 |
+
width: 78vw;
|
796 |
+
height: 80vh;
|
797 |
+
border-radius: 10px;
|
798 |
+
box-sizing: border-box;
|
799 |
+
outline: none;
|
800 |
+
box-shadow: 0 0 0 2px @wnd-border-shadow;
|
801 |
+
overflow-y: auto;
|
802 |
+
|
803 |
+
pre.pre-text {
|
804 |
+
color: @wnd-pre-color;
|
805 |
+
white-space: pre-wrap;
|
806 |
+
word-wrap: break-word;
|
807 |
+
font-family: @fserif;
|
808 |
+
font-size: @fsize-help;
|
809 |
+
line-height: 1.6;
|
810 |
+
padding: 2px;
|
811 |
+
margin: 0;
|
812 |
+
text-align: left;
|
813 |
+
}
|
814 |
+
|
815 |
+
// help
|
816 |
+
div.text {
|
817 |
+
font-size: @fsize-help;
|
818 |
+
font-weight: normal;
|
819 |
+
padding-left: 10px;
|
820 |
+
padding-right: 10px;
|
821 |
+
margin: 0;
|
822 |
+
pre {
|
823 |
+
white-space: pre-wrap;
|
824 |
+
word-wrap: break-word;
|
825 |
+
font-family: @fsans;
|
826 |
+
font-size: @fsize-help;
|
827 |
+
line-height: 1.3;
|
828 |
+
padding: 0 5px 0 5px;
|
829 |
+
margin: 0;
|
830 |
+
text-align: left;
|
831 |
+
}
|
832 |
+
.center {
|
833 |
+
text-align: center;
|
834 |
+
font-size: @fsize-help;
|
835 |
+
font-weight: bold;
|
836 |
+
text-decoration: underline;
|
837 |
+
font-style: italic;
|
838 |
+
color: @color3;
|
839 |
+
}
|
840 |
+
div {
|
841 |
+
font-family: @fsans;
|
842 |
+
font-size: @fsize-help;
|
843 |
+
font-weight: bold;
|
844 |
+
padding-top: 0;
|
845 |
+
padding-bottom: 0;
|
846 |
+
a {
|
847 |
+
background: @base-bg;
|
848 |
+
color: @text-color;
|
849 |
+
font-weight: normal;
|
850 |
+
&:hover {
|
851 |
+
background: lighten(@base-bg, 20%);
|
852 |
+
color: @text-color;
|
853 |
+
}
|
854 |
+
}
|
855 |
+
}
|
856 |
+
|
857 |
+
p {
|
858 |
+
font-size: @fsize-help;
|
859 |
+
font-weight: normal;
|
860 |
+
font-family: @fsans;
|
861 |
+
text-align: justify;
|
862 |
+
padding-bottom: 9px;
|
863 |
+
padding-right: 0;
|
864 |
+
padding-left: 10px;
|
865 |
+
}
|
866 |
+
}
|
867 |
+
}
|
868 |
+
|
869 |
+
.btn-wrapper {
|
870 |
+
width: 100%;
|
871 |
+
height: 2vw;
|
872 |
+
position: sticky;
|
873 |
+
top: 0;
|
874 |
+
padding: 0;
|
875 |
+
background: lighten(@wnd-bg, 5%);
|
876 |
+
|
877 |
+
.btn-copy {
|
878 |
+
position: absolute;
|
879 |
+
top: 1px;
|
880 |
+
right: 5vw;
|
881 |
+
box-sizing: border-box;
|
882 |
+
background: inherit;
|
883 |
+
color: @text-color;
|
884 |
+
border: none;
|
885 |
+
cursor: pointer;
|
886 |
+
width: 30px;
|
887 |
+
margin: 0;
|
888 |
+
padding: 0;
|
889 |
+
transition: background-color 0.3s;
|
890 |
+
|
891 |
+
&:hover {
|
892 |
+
background-color: @btn-hover;
|
893 |
+
}
|
894 |
+
|
895 |
+
// &.copied {
|
896 |
+
// background-color: @btn-copied;
|
897 |
+
// transform: scale(1.2);
|
898 |
+
// }
|
899 |
+
.copy-icon {
|
900 |
+
fill: @btn-color;
|
901 |
+
width: 20px;
|
902 |
+
height: 20px;
|
903 |
+
|
904 |
+
&:hover {
|
905 |
+
fill: @btn-hover-fg;
|
906 |
+
background: lighten(@wnd-bg, 15%);
|
907 |
+
}
|
908 |
+
}
|
909 |
+
}
|
910 |
+
|
911 |
+
.btn-close {
|
912 |
+
position: absolute;
|
913 |
+
top: 0;
|
914 |
+
right: 2vw;
|
915 |
+
margin: 0;
|
916 |
+
background-color: transparent;
|
917 |
+
border: none;
|
918 |
+
color: @btn-color;
|
919 |
+
font-size: @fsize-btn-close;
|
920 |
+
font-weight: bold;
|
921 |
+
cursor: pointer;
|
922 |
+
outline: none;
|
923 |
+
|
924 |
+
&:hover {
|
925 |
+
color: @btn-hover-fg;
|
926 |
+
background: lighten(@wnd-bg, 15%);
|
927 |
+
}
|
928 |
+
}
|
929 |
+
}
|
930 |
+
|
931 |
+
//message
|
932 |
+
@popup-bg-color: #222222;
|
933 |
+
@popup-text-color: #ffeb3b;
|
934 |
+
@popup-border-color: #ffeb3b;
|
935 |
+
@popup-width: 300px;
|
936 |
+
@popup-height: 100px;
|
937 |
+
@font-size: 24px;
|
938 |
+
@border-radius: 15px;
|
939 |
+
|
940 |
+
.msg {
|
941 |
+
box-sizing: border-box;
|
942 |
+
position: fixed;
|
943 |
+
width: @popup-width;
|
944 |
+
height: @popup-height;
|
945 |
+
top: 50%;
|
946 |
+
left: 50%;
|
947 |
+
transform: translate(-50%, -50%);
|
948 |
+
background-color: @popup-bg-color; // Grigio scuro
|
949 |
+
color: @popup-text-color; // Giallo
|
950 |
+
border: 2px solid @popup-border-color; // Bordo giallo
|
951 |
+
border-radius: @border-radius;
|
952 |
+
display: flex;
|
953 |
+
align-items: center;
|
954 |
+
justify-content: center;
|
955 |
+
font-family: Arial, sans-serif;
|
956 |
+
font-size: @font-size;
|
957 |
+
font-weight: bold;
|
958 |
+
text-align: center;
|
959 |
+
z-index: 1000;
|
960 |
+
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
961 |
+
}
|
962 |
+
|
963 |
+
//////////////// alert
|
964 |
+
@primary-color: #212121; // Dark primary color
|
965 |
+
@secondary-color: #37474F; // Dark secondary color
|
966 |
+
@text-color: #FFFFFF; // Text color
|
967 |
+
@background-color: #303030; // Background color
|
968 |
+
|
969 |
+
// Style the alert and confirm dialogs
|
970 |
+
.alert, .confirm {
|
971 |
+
background-color: @background-color !important;
|
972 |
+
color: @text-color;
|
973 |
+
padding: 20px;
|
974 |
+
border-radius: 4px;
|
975 |
+
box-shadow: 0 2px 4px #00000033 !important;
|
976 |
+
|
977 |
+
// Style the buttons
|
978 |
+
.button {
|
979 |
+
background-color: @secondary-color !important;
|
980 |
+
color: @text-color;
|
981 |
+
border: none;
|
982 |
+
padding: 10px 20px;
|
983 |
+
border-radius: 4px;
|
984 |
+
cursor: pointer;
|
985 |
+
margin-top: 20px;
|
986 |
+
|
987 |
+
&:hover {
|
988 |
+
background-color: darken(@secondary-color, 10%);
|
989 |
+
}
|
990 |
+
}
|
991 |
+
}
|
static/ragrqs.html
ADDED
@@ -0,0 +1,131 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html lang="it">
|
3 |
+
|
4 |
+
<head>
|
5 |
+
<meta charset="utf-8" />
|
6 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
7 |
+
<meta name="description" content="Author:M.Materni" />
|
8 |
+
<title>RagRqs</title>
|
9 |
+
|
10 |
+
<link rel="stylesheet" href="css/ragrqs.min.css" />
|
11 |
+
<script src="js/ragrqs.min.js"></script>
|
12 |
+
|
13 |
+
<body>
|
14 |
+
<div id="spinner" class="spinner">
|
15 |
+
<div class="pulse-icon"></div>
|
16 |
+
<div class="stop-message">Stop</div>
|
17 |
+
</div>
|
18 |
+
|
19 |
+
<div class="menu-h">
|
20 |
+
|
21 |
+
<input id="id-menu-btn" name="id-menu-btn" class="menu-btn" type="checkbox" />
|
22 |
+
<label for="id-menu-btn" class="menu-icon">
|
23 |
+
<span class="nav-icon"></span>
|
24 |
+
</label>
|
25 |
+
|
26 |
+
<div class="head-wrapper">
|
27 |
+
|
28 |
+
<button class="help" onclick="Menu.help();" title="Istruzioni">?</button>
|
29 |
+
|
30 |
+
<button class="upload" onclick="Menu.upload();" ; title="Upload files">
|
31 |
+
<svg class="icon" viewBox="0 0 24 24">
|
32 |
+
<path d="M20 15v2H4v-2H2v5h20v-5zM13 5V1h-2v4H7l5 5 5-5z" fill="none" stroke="#FFFFFF" stroke-width="2" />
|
33 |
+
</svg>
|
34 |
+
</button>
|
35 |
+
|
36 |
+
<button class="upload" onclick="Menu.uploadDir();" ; title="Upload dir">
|
37 |
+
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
38 |
+
<path d="M20 6h-8l-2-2H4C2.9 4 2 4.9 2 6v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm-8 7H8v2h4v-2zm6 0h-4v2h4v-2zm0-4H8v2h10V9z" fill="none" stroke="#FFFFFF" stroke-width="2" />
|
39 |
+
</svg>
|
40 |
+
</button>
|
41 |
+
|
42 |
+
<button class="log active" id="id_log" onclick="Menu.log();" title="Log">Log</button>
|
43 |
+
<label class="release"></label>
|
44 |
+
</div>
|
45 |
+
<div class="menu-box">
|
46 |
+
<ul>
|
47 |
+
<li><a href="#" onCLick="op0(this);">README</a></li>
|
48 |
+
<li><a href="#" onCLick="op1(this);">Qurty</a></li>
|
49 |
+
<li><a href="#" onCLick="showRagResponse(this);">Risposta</a></li>
|
50 |
+
<li><a href="#" onCLick="op2(this);">Elenco Risposte</a></li>
|
51 |
+
<li><a href="#" onCLick="op3(this);">Contesto RAG</a></li>
|
52 |
+
<li><a href="#" onCLick="op4(this);">Dati archviati</a></li>
|
53 |
+
<li><a href="#" onCLick="op5(this);">Elenco Documenti</a></li>
|
54 |
+
<li><a href="#" onCLick="calcQuery();">Numero Query</a></li>
|
55 |
+
<li><a class="delete" href="#" onCLick="op7(this);">Cancella Dati</a></li>
|
56 |
+
<li>-</li>
|
57 |
+
<li><a class="help" href="#" onCLick="op8(this);">Cancella Documenti</a></li>
|
58 |
+
<li>-</li>
|
59 |
+
<li><a href="#" onCLick="help1(this);">Esempi di documenti</a></li>
|
60 |
+
<li><a href="#" onCLick="help2(this);">Esempi di domande</a></li>
|
61 |
+
<!--
|
62 |
+
<li><a href="#" onCLick="op9(this);">prompts</a></li>
|
63 |
+
<li><a href="#" onCLick="op6(this);">Testo Documenti</a></li>
|
64 |
+
-->
|
65 |
+
</ul>
|
66 |
+
</div>
|
67 |
+
</div>
|
68 |
+
|
69 |
+
<div class="container">
|
70 |
+
<div class="item item1">
|
71 |
+
<div class="output-wrapper">
|
72 |
+
|
73 |
+
<div class="text-out" id="id-text-out">
|
74 |
+
</div>
|
75 |
+
|
76 |
+
<div class="output-actions">
|
77 |
+
<button class="copy-output" title="Copia">
|
78 |
+
<svg class="copy-icon" viewBox="0 0 20 24">
|
79 |
+
<path d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z" />
|
80 |
+
</svg>
|
81 |
+
</button>
|
82 |
+
<button class="wnd-output" title="Apri">
|
83 |
+
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
84 |
+
<path d="M10 9v6h4V9h5l-7-7-7 7h5zM5 19v2h14v-2H5z" />
|
85 |
+
</svg>
|
86 |
+
</button>
|
87 |
+
<button class="clear-output" title="Cancella">
|
88 |
+
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
89 |
+
<path d="M3 6h18v2H3V6zm2 3h14v12H5V9zm3-7h6v2H8V2z" />
|
90 |
+
</svg>
|
91 |
+
</button>
|
92 |
+
</div>
|
93 |
+
</div>
|
94 |
+
</div>
|
95 |
+
|
96 |
+
<div class="item item2">
|
97 |
+
<div class="input-wrapper">
|
98 |
+
|
99 |
+
<textarea class="text-input" placeholder="Scrivi qui... " rows="2"></textarea>
|
100 |
+
<button class="clear-button" title="Cancella input">X</button>
|
101 |
+
|
102 |
+
<div class="input-actions">
|
103 |
+
<button class="send-input" title="Documenti=>RAG=>Conetso=>Query">
|
104 |
+
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
105 |
+
<path d="M2 21l21-9L2 3v7l15 2-15 2v7z" fill="none" stroke="#FFFFFF" stroke-width="2" />
|
106 |
+
</svg>
|
107 |
+
</button>
|
108 |
+
|
109 |
+
|
110 |
+
<button class="send2-input" title="Contesto=>Query">
|
111 |
+
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
112 |
+
<path d="M2 21l21-9L2 3v7l15 2-15 2v7z" fill="none" stroke="#FFFFFF" stroke-width="2" />
|
113 |
+
</svg>
|
114 |
+
</button>
|
115 |
+
<button class="clear-input" title="Cancella Conversazione">
|
116 |
+
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
117 |
+
<path d="M3 6h18v2H3V6zm2 3h14v12H5V9zm3-7h6v2H8V2z" fill="none" stroke="#FFFFFF" stroke-width="2" />
|
118 |
+
</svg>
|
119 |
+
</button>
|
120 |
+
|
121 |
+
</div>
|
122 |
+
</div>
|
123 |
+
</div>
|
124 |
+
|
125 |
+
</div>
|
126 |
+
</body>
|
127 |
+
|
128 |
+
</html>
|
129 |
+
<script>
|
130 |
+
openApp();
|
131 |
+
</script>
|
static/ragrqs_.html
ADDED
@@ -0,0 +1,149 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html lang="it">
|
3 |
+
|
4 |
+
<head>
|
5 |
+
<meta charset="utf-8" />
|
6 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
7 |
+
<meta name="description" content="Author:M.Materni" />
|
8 |
+
<title>RagRqs</title>
|
9 |
+
|
10 |
+
<!--
|
11 |
+
<link rel="stylesheet" href="css/ragrqs.min.css" />
|
12 |
+
<script src="js/ragrqs.min.js"></script>
|
13 |
+
-->
|
14 |
+
<link rel="stylesheet" href="less/normalize.css" />
|
15 |
+
<link rel="stylesheet/less" type="text/css" href="less/ragrqs.less" />
|
16 |
+
<script src="less/less.js"></script>
|
17 |
+
|
18 |
+
<script src="javascript/uadrag.js"></script>
|
19 |
+
<script src="javascript/uawindow.js"></script>
|
20 |
+
<script src="javascript/uajtfh.js"></script>
|
21 |
+
<script src="javascript/ualog.js"></script>
|
22 |
+
<script src="javascript/rag_cleaner.js"></script>
|
23 |
+
<script src="javascript/rag_data_mgr.js"></script>
|
24 |
+
<script src="javascript/rag_http.js"></script>
|
25 |
+
<script src="javascript/rag_mgr.js"></script>
|
26 |
+
<script src="javascript/rag_prompts.js"></script>
|
27 |
+
<script src="javascript/rag_rqs.js"></script>
|
28 |
+
<script src="javascript/rag_upload.js"></script>
|
29 |
+
<script src="javascript/rag_ui.js"></script>
|
30 |
+
|
31 |
+
<body>
|
32 |
+
<div id="spinner" class="spinner">
|
33 |
+
<div class="pulse-icon"></div>
|
34 |
+
<div class="stop-message">Stop</div>
|
35 |
+
</div>
|
36 |
+
|
37 |
+
<div class="menu-h">
|
38 |
+
|
39 |
+
<input id="id-menu-btn" name="id-menu-btn" class="menu-btn" type="checkbox" />
|
40 |
+
<label for="id-menu-btn" class="menu-icon">
|
41 |
+
<span class="nav-icon"></span>
|
42 |
+
</label>
|
43 |
+
|
44 |
+
<div class="head-wrapper">
|
45 |
+
|
46 |
+
<button class="help" onclick="Menu.help();" title="Istruzioni">?</button>
|
47 |
+
|
48 |
+
<button class="upload" onclick="Menu.upload();" ; title="Upload files">
|
49 |
+
<svg class="icon" viewBox="0 0 24 24">
|
50 |
+
<path d="M20 15v2H4v-2H2v5h20v-5zM13 5V1h-2v4H7l5 5 5-5z" fill="none" stroke="#FFFFFF" stroke-width="2" />
|
51 |
+
</svg>
|
52 |
+
</button>
|
53 |
+
|
54 |
+
<button class="upload" onclick="Menu.uploadDir();" ; title="Upload dir">
|
55 |
+
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
56 |
+
<path d="M20 6h-8l-2-2H4C2.9 4 2 4.9 2 6v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm-8 7H8v2h4v-2zm6 0h-4v2h4v-2zm0-4H8v2h10V9z" fill="none" stroke="#FFFFFF" stroke-width="2" />
|
57 |
+
</svg>
|
58 |
+
</button>
|
59 |
+
|
60 |
+
<button class="log active" id="id_log" onclick="Menu.log();" title="Log">Log</button>
|
61 |
+
<label class="release"></label>
|
62 |
+
</div>
|
63 |
+
<div class="menu-box">
|
64 |
+
<ul>
|
65 |
+
<li><a href="#" onCLick="op0(this);">README</a></li>
|
66 |
+
<li><a href="#" onCLick="op1(this);">Qurty</a></li>
|
67 |
+
<li><a href="#" onCLick="showRagResponse(this);">Risposta</a></li>
|
68 |
+
<li><a href="#" onCLick="op2(this);">Elenco Risposte</a></li>
|
69 |
+
<li><a href="#" onCLick="op3(this);">Contesto RAG</a></li>
|
70 |
+
<li><a href="#" onCLick="op4(this);">Dati archviati</a></li>
|
71 |
+
<li><a href="#" onCLick="op5(this);">Elenco Documenti</a></li>
|
72 |
+
<li><a href="#" onCLick="calcQuery();">Numero Query</a></li>
|
73 |
+
<li><a class="delete" href="#" onCLick="op7(this);">Cancella Dati</a></li>
|
74 |
+
<li>-</li>
|
75 |
+
<li><a class="help" href="#" onCLick="op8(this);">Cancella Documenti</a></li>
|
76 |
+
<li>-</li>
|
77 |
+
<li><a href="#" onCLick="help1(this);">Esempi di documenti</a></li>
|
78 |
+
<li><a href="#" onCLick="help2(this);">Esempi di domande</a></li>
|
79 |
+
|
80 |
+
<li><a href="#" onCLick="op9(this);">prompts</a></li>
|
81 |
+
<li><a href="#" onCLick="op6(this);">Testo Documenti</a></li>
|
82 |
+
|
83 |
+
</ul>
|
84 |
+
</div>
|
85 |
+
</div>
|
86 |
+
|
87 |
+
<div class="container">
|
88 |
+
<div class="item item1">
|
89 |
+
<div class="output-wrapper">
|
90 |
+
|
91 |
+
<div class="text-out" id="id-text-out">
|
92 |
+
</div>
|
93 |
+
|
94 |
+
<div class="output-actions">
|
95 |
+
<button class="copy-output" title="Copia">
|
96 |
+
<svg class="copy-icon" viewBox="0 0 20 24">
|
97 |
+
<path d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z" />
|
98 |
+
</svg>
|
99 |
+
</button>
|
100 |
+
<button class="wnd-output" title="Apri">
|
101 |
+
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
102 |
+
<path d="M10 9v6h4V9h5l-7-7-7 7h5zM5 19v2h14v-2H5z" />
|
103 |
+
</svg>
|
104 |
+
</button>
|
105 |
+
<button class="clear-output" title="Cancella">
|
106 |
+
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
107 |
+
<path d="M3 6h18v2H3V6zm2 3h14v12H5V9zm3-7h6v2H8V2z" />
|
108 |
+
</svg>
|
109 |
+
</button>
|
110 |
+
</div>
|
111 |
+
</div>
|
112 |
+
</div>
|
113 |
+
|
114 |
+
<div class="item item2">
|
115 |
+
<div class="input-wrapper">
|
116 |
+
|
117 |
+
<textarea class="text-input" placeholder="Scrivi qui... " rows="2"></textarea>
|
118 |
+
<button class="clear-button" title="Cancella input">X</button>
|
119 |
+
|
120 |
+
<div class="input-actions">
|
121 |
+
<button class="send-input" title="Documenti=>RAG=>Conetso=>Query">
|
122 |
+
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
123 |
+
<path d="M2 21l21-9L2 3v7l15 2-15 2v7z" fill="none" stroke="#FFFFFF" stroke-width="2" />
|
124 |
+
</svg>
|
125 |
+
</button>
|
126 |
+
|
127 |
+
|
128 |
+
<button class="send2-input" title="Contesto=>Query">
|
129 |
+
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
130 |
+
<path d="M2 21l21-9L2 3v7l15 2-15 2v7z" fill="none" stroke="#FFFFFF" stroke-width="2" />
|
131 |
+
</svg>
|
132 |
+
</button>
|
133 |
+
<button class="clear-input" title="Cancella Conversazione">
|
134 |
+
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
135 |
+
<path d="M3 6h18v2H3V6zm2 3h14v12H5V9zm3-7h6v2H8V2z" fill="none" stroke="#FFFFFF" stroke-width="2" />
|
136 |
+
</svg>
|
137 |
+
</button>
|
138 |
+
|
139 |
+
</div>
|
140 |
+
</div>
|
141 |
+
</div>
|
142 |
+
|
143 |
+
</div>
|
144 |
+
</body>
|
145 |
+
|
146 |
+
</html>
|
147 |
+
<script>
|
148 |
+
openApp();
|
149 |
+
</script>
|