blob: 56c20a3f0734621b61b8f6b8c241e8574005dff4 [file] [log] [blame]
Jack Jansen8ce72f51997-01-07 16:18:32 +00001/***********************************************************
Jack Jansen42218ce1997-01-31 16:15:11 +00002Copyright 1991-1997 by Stichting Mathematisch Centrum, Amsterdam,
Jack Jansen8ce72f51997-01-07 16:18:32 +00003The Netherlands.
4
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
16
17While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
29
30******************************************************************/
31
32#include "Python.h"
33#include "macglue.h"
34
35extern int ResObj_Convert(PyObject *, Handle *); /* From Resmodule.c */
36
Jack Jansen6143d532001-05-19 12:34:59 +000037#ifdef WITHOUT_FRAMEWORKS
Jack Jansen8f54f2a2002-01-11 12:38:08 +000038#include <InternetConfig.h>
Jack Jansen6143d532001-05-19 12:34:59 +000039#else
40#include <Carbon/Carbon.h>
Jack Jansen6143d532001-05-19 12:34:59 +000041#endif
Jack Jansen8ce72f51997-01-07 16:18:32 +000042
43static PyObject *ErrorObject;
44
Jack Jansen8ce72f51997-01-07 16:18:32 +000045/* ----------------------------------------------------- */
46
47/* Declarations for objects of type ic_instance */
48
49typedef struct {
50 PyObject_HEAD
51 ICInstance inst;
52} iciobject;
53
Jeremy Hylton938ace62002-07-17 16:30:39 +000054static PyTypeObject Icitype;
Jack Jansen8ce72f51997-01-07 16:18:32 +000055
56
57
58/* ---------------------------------------------------------------- */
59
Jack Jansen8ce72f51997-01-07 16:18:32 +000060
61static char ici_ICGetSeed__doc__[] =
62"()->int; Returns int that changes when configuration does"
63;
64
65static PyObject *
Jack Jansen1767f932001-09-04 22:20:39 +000066ici_ICGetSeed(iciobject *self, PyObject *args)
Jack Jansen8ce72f51997-01-07 16:18:32 +000067{
Jack Jansen8f54f2a2002-01-11 12:38:08 +000068 OSStatus err;
Jack Jansen8ce72f51997-01-07 16:18:32 +000069 long seed;
70
71 if (!PyArg_ParseTuple(args, ""))
72 return NULL;
73 if ((err=ICGetSeed(self->inst, &seed)) != 0 )
Jack Jansen8f54f2a2002-01-11 12:38:08 +000074 return PyMac_Error(err);
Jack Jansen8ce72f51997-01-07 16:18:32 +000075 return Py_BuildValue("i", (int)seed);
76}
77
78
79static char ici_ICBegin__doc__[] =
80"(perm)->None; Lock config file for read/write"
81;
82
83static PyObject *
Jack Jansen1767f932001-09-04 22:20:39 +000084ici_ICBegin(iciobject *self, PyObject *args)
Jack Jansen8ce72f51997-01-07 16:18:32 +000085{
Jack Jansen8f54f2a2002-01-11 12:38:08 +000086 OSStatus err;
Jack Jansen8ce72f51997-01-07 16:18:32 +000087 int perm;
88
89 if (!PyArg_ParseTuple(args, "i", &perm))
90 return NULL;
91 if ((err=ICBegin(self->inst, (ICPerm)perm)) != 0 )
Jack Jansen8f54f2a2002-01-11 12:38:08 +000092 return PyMac_Error(err);
Jack Jansen8ce72f51997-01-07 16:18:32 +000093 Py_INCREF(Py_None);
94 return Py_None;
95}
96
97
98static char ici_ICFindPrefHandle__doc__[] =
99"(key, handle)->attrs; Lookup key, store result in handle, return attributes"
100;
101
102static PyObject *
Jack Jansen1767f932001-09-04 22:20:39 +0000103ici_ICFindPrefHandle(iciobject *self, PyObject *args)
Jack Jansen8ce72f51997-01-07 16:18:32 +0000104{
Jack Jansen8f54f2a2002-01-11 12:38:08 +0000105 OSStatus err;
Jack Jansen8ce72f51997-01-07 16:18:32 +0000106 Str255 key;
107 ICAttr attr;
108 Handle h;
109
110 if (!PyArg_ParseTuple(args, "O&O&", PyMac_GetStr255, &key, ResObj_Convert, &h))
111 return NULL;
112 if ((err=ICFindPrefHandle(self->inst, key, &attr, h)) != 0 )
Jack Jansen8f54f2a2002-01-11 12:38:08 +0000113 return PyMac_Error(err);
Jack Jansen8ce72f51997-01-07 16:18:32 +0000114 return Py_BuildValue("i", (int)attr);
115}
116
117
118static char ici_ICSetPref__doc__[] =
119"(key, attr, data)->None; Set preference key to data with attributes"
120;
121
122static PyObject *
Jack Jansen1767f932001-09-04 22:20:39 +0000123ici_ICSetPref(iciobject *self, PyObject *args)
Jack Jansen8ce72f51997-01-07 16:18:32 +0000124{
Jack Jansen8f54f2a2002-01-11 12:38:08 +0000125 OSStatus err;
Jack Jansen8ce72f51997-01-07 16:18:32 +0000126 Str255 key;
127 int attr;
128 char *data;
129 int datalen;
130
131 if (!PyArg_ParseTuple(args, "O&is#", PyMac_GetStr255, &key, &attr,
132 &data, &datalen))
133 return NULL;
134 if ((err=ICSetPref(self->inst, key, (ICAttr)attr, (Ptr)data,
135 (long)datalen)) != 0)
Jack Jansen8f54f2a2002-01-11 12:38:08 +0000136 return PyMac_Error(err);
Jack Jansen8ce72f51997-01-07 16:18:32 +0000137 Py_INCREF(Py_None);
138 return Py_None;
139}
140
141
142static char ici_ICCountPref__doc__[] =
143"()->int; Return number of preferences"
144;
145
146static PyObject *
Jack Jansen1767f932001-09-04 22:20:39 +0000147ici_ICCountPref(iciobject *self, PyObject *args)
Jack Jansen8ce72f51997-01-07 16:18:32 +0000148{
Jack Jansen8f54f2a2002-01-11 12:38:08 +0000149 OSStatus err;
Jack Jansen8ce72f51997-01-07 16:18:32 +0000150 long count;
151
152 if (!PyArg_ParseTuple(args, ""))
153 return NULL;
154 if ((err=ICCountPref(self->inst, &count)) != 0 )
Jack Jansen8f54f2a2002-01-11 12:38:08 +0000155 return PyMac_Error(err);
Jack Jansen8ce72f51997-01-07 16:18:32 +0000156 return Py_BuildValue("i", (int)count);
157}
158
159
160static char ici_ICGetIndPref__doc__[] =
161"(num)->key; Return key of preference with given index"
162;
163
164static PyObject *
Jack Jansen1767f932001-09-04 22:20:39 +0000165ici_ICGetIndPref(iciobject *self, PyObject *args)
Jack Jansen8ce72f51997-01-07 16:18:32 +0000166{
Jack Jansen8f54f2a2002-01-11 12:38:08 +0000167 OSStatus err;
Jack Jansen8ce72f51997-01-07 16:18:32 +0000168 long num;
169 Str255 key;
170
171 if (!PyArg_ParseTuple(args, "l", &num))
172 return NULL;
173 if ((err=ICGetIndPref(self->inst, num, key)) != 0 )
Jack Jansen8f54f2a2002-01-11 12:38:08 +0000174 return PyMac_Error(err);
Jack Jansen8ce72f51997-01-07 16:18:32 +0000175 return Py_BuildValue("O&", PyMac_BuildStr255, key);
176}
177
178
179static char ici_ICDeletePref__doc__[] =
180"(key)->None; Delete preference"
181;
182
183static PyObject *
Jack Jansen1767f932001-09-04 22:20:39 +0000184ici_ICDeletePref(iciobject *self, PyObject *args)
Jack Jansen8ce72f51997-01-07 16:18:32 +0000185{
Jack Jansen8f54f2a2002-01-11 12:38:08 +0000186 OSStatus err;
Jack Jansen8ce72f51997-01-07 16:18:32 +0000187 Str255 key;
188
189 if (!PyArg_ParseTuple(args, "O&", PyMac_GetStr255, key))
190 return NULL;
191 if ((err=ICDeletePref(self->inst, key)) != 0 )
Jack Jansen8f54f2a2002-01-11 12:38:08 +0000192 return PyMac_Error(err);
Jack Jansen8ce72f51997-01-07 16:18:32 +0000193 Py_INCREF(Py_None);
194 return Py_None;
195}
196
197
198static char ici_ICEnd__doc__[] =
199"()->None; Unlock file after ICBegin call"
200;
201
202static PyObject *
Jack Jansen1767f932001-09-04 22:20:39 +0000203ici_ICEnd(iciobject *self, PyObject *args)
Jack Jansen8ce72f51997-01-07 16:18:32 +0000204{
Jack Jansen8f54f2a2002-01-11 12:38:08 +0000205 OSStatus err;
Jack Jansen8ce72f51997-01-07 16:18:32 +0000206
207 if (!PyArg_ParseTuple(args, ""))
208 return NULL;
209 if ((err=ICEnd(self->inst)) != 0 )
Jack Jansen8f54f2a2002-01-11 12:38:08 +0000210 return PyMac_Error(err);
Jack Jansen8ce72f51997-01-07 16:18:32 +0000211 Py_INCREF(Py_None);
212 return Py_None;
213}
214
215
216static char ici_ICEditPreferences__doc__[] =
217"(key)->None; Ask user to edit preferences, staring with key"
218;
219
220static PyObject *
Jack Jansen1767f932001-09-04 22:20:39 +0000221ici_ICEditPreferences(iciobject *self, PyObject *args)
Jack Jansen8ce72f51997-01-07 16:18:32 +0000222{
Jack Jansen8f54f2a2002-01-11 12:38:08 +0000223 OSStatus err;
Jack Jansen8ce72f51997-01-07 16:18:32 +0000224 Str255 key;
225
226 if (!PyArg_ParseTuple(args, "O&", PyMac_GetStr255, key))
227 return NULL;
228 if ((err=ICEditPreferences(self->inst, key)) != 0 )
Jack Jansen8f54f2a2002-01-11 12:38:08 +0000229 return PyMac_Error(err);
Jack Jansen8ce72f51997-01-07 16:18:32 +0000230 Py_INCREF(Py_None);
231 return Py_None;
232}
233
234
235static char ici_ICParseURL__doc__[] =
236"(hint, data, selStart, selEnd, handle)->selStart, selEnd; Find an URL, return in handle"
237;
238
239static PyObject *
Jack Jansen1767f932001-09-04 22:20:39 +0000240ici_ICParseURL(iciobject *self, PyObject *args)
Jack Jansen8ce72f51997-01-07 16:18:32 +0000241{
Jack Jansen8f54f2a2002-01-11 12:38:08 +0000242 OSStatus err;
Jack Jansen8ce72f51997-01-07 16:18:32 +0000243 Str255 hint;
244 char *data;
245 int datalen;
246 long selStart, selEnd;
247 Handle h;
248
249 if (!PyArg_ParseTuple(args, "O&s#llO&", PyMac_GetStr255, hint, &data, &datalen,
250 &selStart, &selEnd, ResObj_Convert, &h))
251 return NULL;
252 if ((err=ICParseURL(self->inst, hint, (Ptr)data, (long)datalen,
253 &selStart, &selEnd, h)) != 0 )
Jack Jansen8f54f2a2002-01-11 12:38:08 +0000254 return PyMac_Error(err);
Jack Jansen8ce72f51997-01-07 16:18:32 +0000255 return Py_BuildValue("ii", (int)selStart, (int)selEnd);
256}
257
258
259static char ici_ICLaunchURL__doc__[] =
260"(hint, data, selStart, selEnd)->None; Find an URL and launch the correct app"
261;
262
263static PyObject *
Jack Jansen1767f932001-09-04 22:20:39 +0000264ici_ICLaunchURL(iciobject *self, PyObject *args)
Jack Jansen8ce72f51997-01-07 16:18:32 +0000265{
Jack Jansen8f54f2a2002-01-11 12:38:08 +0000266 OSStatus err;
Jack Jansen8ce72f51997-01-07 16:18:32 +0000267 Str255 hint;
268 char *data;
269 int datalen;
270 long selStart, selEnd;
271
272 if (!PyArg_ParseTuple(args, "O&s#ll", PyMac_GetStr255, hint, &data, &datalen,
273 &selStart, &selEnd))
274 return NULL;
275 if ((err=ICLaunchURL(self->inst, hint, (Ptr)data, (long)datalen,
276 &selStart, &selEnd)) != 0 )
Jack Jansen8f54f2a2002-01-11 12:38:08 +0000277 return PyMac_Error(err);
Jack Jansen8ce72f51997-01-07 16:18:32 +0000278 return Py_BuildValue("ii", (int)selStart, (int)selEnd);
279}
280
281
282static char ici_ICMapFilename__doc__[] =
283"(filename)->mapinfo; Get filemap info for given filename"
284;
285
286static PyObject *
Jack Jansen1767f932001-09-04 22:20:39 +0000287ici_ICMapFilename(iciobject *self, PyObject *args)
Jack Jansen8ce72f51997-01-07 16:18:32 +0000288{
Jack Jansen8f54f2a2002-01-11 12:38:08 +0000289 OSStatus err;
Jack Jansen8ce72f51997-01-07 16:18:32 +0000290 Str255 filename;
291 ICMapEntry entry;
292
293 if (!PyArg_ParseTuple(args, "O&", PyMac_GetStr255, filename))
294 return NULL;
295 if ((err=ICMapFilename(self->inst, filename, &entry)) != 0 )
Jack Jansen8f54f2a2002-01-11 12:38:08 +0000296 return PyMac_Error(err);
Jack Jansen8ce72f51997-01-07 16:18:32 +0000297 return Py_BuildValue("hO&O&O&lO&O&O&O&O&", entry.version,
Jack Jansen8f54f2a2002-01-11 12:38:08 +0000298 PyMac_BuildOSType, entry.fileType,
299 PyMac_BuildOSType, entry.fileCreator,
300 PyMac_BuildOSType, entry.postCreator,
Jack Jansen8ce72f51997-01-07 16:18:32 +0000301 entry.flags,
302 PyMac_BuildStr255, entry.extension,
Jack Jansen8f54f2a2002-01-11 12:38:08 +0000303 PyMac_BuildStr255, entry.creatorAppName,
304 PyMac_BuildStr255, entry.postAppName,
305 PyMac_BuildStr255, entry.MIMEType,
306 PyMac_BuildStr255, entry.entryName);
Jack Jansen8ce72f51997-01-07 16:18:32 +0000307}
308
309
310static char ici_ICMapTypeCreator__doc__[] =
311"(type, creator, filename)->mapinfo; Get filemap info for given tp/cr/filename"
312;
313
314static PyObject *
Jack Jansen1767f932001-09-04 22:20:39 +0000315ici_ICMapTypeCreator(iciobject *self, PyObject *args)
Jack Jansen8ce72f51997-01-07 16:18:32 +0000316{
Jack Jansen8f54f2a2002-01-11 12:38:08 +0000317 OSStatus err;
Jack Jansen8ce72f51997-01-07 16:18:32 +0000318 OSType type, creator;
319 Str255 filename;
320 ICMapEntry entry;
321
322 if (!PyArg_ParseTuple(args, "O&O&O&",
323 PyMac_GetOSType, &type,
324 PyMac_GetOSType, &creator,
325 PyMac_GetStr255, filename))
326 return NULL;
327 if ((err=ICMapTypeCreator(self->inst, type, creator, filename, &entry)) != 0 )
Jack Jansen8f54f2a2002-01-11 12:38:08 +0000328 return PyMac_Error(err);
Jack Jansen8ce72f51997-01-07 16:18:32 +0000329 return Py_BuildValue("hO&O&O&lO&O&O&O&O&", entry.version,
Jack Jansen8f54f2a2002-01-11 12:38:08 +0000330 PyMac_BuildOSType, entry.fileType,
331 PyMac_BuildOSType, entry.fileCreator,
332 PyMac_BuildOSType, entry.postCreator,
Jack Jansen8ce72f51997-01-07 16:18:32 +0000333 entry.flags,
334 PyMac_BuildStr255, entry.extension,
Jack Jansen8f54f2a2002-01-11 12:38:08 +0000335 PyMac_BuildStr255, entry.creatorAppName,
336 PyMac_BuildStr255, entry.postAppName,
337 PyMac_BuildStr255, entry.MIMEType,
338 PyMac_BuildStr255, entry.entryName);
Jack Jansen8ce72f51997-01-07 16:18:32 +0000339}
340
341
342static struct PyMethodDef ici_methods[] = {
Jack Jansen8ce72f51997-01-07 16:18:32 +0000343 {"ICGetSeed", (PyCFunction)ici_ICGetSeed, METH_VARARGS, ici_ICGetSeed__doc__},
344 {"ICBegin", (PyCFunction)ici_ICBegin, METH_VARARGS, ici_ICBegin__doc__},
345 {"ICFindPrefHandle", (PyCFunction)ici_ICFindPrefHandle, METH_VARARGS, ici_ICFindPrefHandle__doc__},
346 {"ICSetPref", (PyCFunction)ici_ICSetPref, METH_VARARGS, ici_ICSetPref__doc__},
347 {"ICCountPref", (PyCFunction)ici_ICCountPref, METH_VARARGS, ici_ICCountPref__doc__},
348 {"ICGetIndPref", (PyCFunction)ici_ICGetIndPref, METH_VARARGS, ici_ICGetIndPref__doc__},
349 {"ICDeletePref", (PyCFunction)ici_ICDeletePref, METH_VARARGS, ici_ICDeletePref__doc__},
350 {"ICEnd", (PyCFunction)ici_ICEnd, METH_VARARGS, ici_ICEnd__doc__},
351 {"ICEditPreferences", (PyCFunction)ici_ICEditPreferences, METH_VARARGS, ici_ICEditPreferences__doc__},
352 {"ICParseURL", (PyCFunction)ici_ICParseURL, METH_VARARGS, ici_ICParseURL__doc__},
353 {"ICLaunchURL", (PyCFunction)ici_ICLaunchURL, METH_VARARGS, ici_ICLaunchURL__doc__},
354 {"ICMapFilename", (PyCFunction)ici_ICMapFilename, METH_VARARGS, ici_ICMapFilename__doc__},
355 {"ICMapTypeCreator", (PyCFunction)ici_ICMapTypeCreator, METH_VARARGS, ici_ICMapTypeCreator__doc__},
356
357 {NULL, NULL} /* sentinel */
358};
359
360/* ---------- */
361
362
363static iciobject *
364newiciobject(OSType creator)
365{
366 iciobject *self;
Jack Jansen8f54f2a2002-01-11 12:38:08 +0000367 OSStatus err;
Jack Jansen8ce72f51997-01-07 16:18:32 +0000368
369 self = PyObject_NEW(iciobject, &Icitype);
370 if (self == NULL)
371 return NULL;
372 if ((err=ICStart(&self->inst, creator)) != 0 ) {
Jack Jansen8f54f2a2002-01-11 12:38:08 +0000373 (void)PyMac_Error(err);
Jack Jansen0e2f7982002-05-22 14:31:48 +0000374 PyObject_DEL(self);
Jack Jansen8ce72f51997-01-07 16:18:32 +0000375 return NULL;
376 }
377 return self;
378}
379
380
381static void
Jack Jansen1767f932001-09-04 22:20:39 +0000382ici_dealloc(iciobject *self)
Jack Jansen8ce72f51997-01-07 16:18:32 +0000383{
384 (void)ICStop(self->inst);
Jack Jansen0e2f7982002-05-22 14:31:48 +0000385 PyObject_DEL(self);
Jack Jansen8ce72f51997-01-07 16:18:32 +0000386}
387
388static PyObject *
Jack Jansen1767f932001-09-04 22:20:39 +0000389ici_getattr(iciobject *self, char *name)
Jack Jansen8ce72f51997-01-07 16:18:32 +0000390{
391 return Py_FindMethod(ici_methods, (PyObject *)self, name);
392}
393
394static char Icitype__doc__[] =
395"Internet Config instance"
396;
397
398static PyTypeObject Icitype = {
399 PyObject_HEAD_INIT(&PyType_Type)
400 0, /*ob_size*/
Guido van Rossum14648392001-12-08 18:02:58 +0000401 "icglue.ic_instance", /*tp_name*/
Jack Jansen8ce72f51997-01-07 16:18:32 +0000402 sizeof(iciobject), /*tp_basicsize*/
403 0, /*tp_itemsize*/
404 /* methods */
405 (destructor)ici_dealloc, /*tp_dealloc*/
406 (printfunc)0, /*tp_print*/
407 (getattrfunc)ici_getattr, /*tp_getattr*/
408 (setattrfunc)0, /*tp_setattr*/
409 (cmpfunc)0, /*tp_compare*/
410 (reprfunc)0, /*tp_repr*/
411 0, /*tp_as_number*/
412 0, /*tp_as_sequence*/
413 0, /*tp_as_mapping*/
414 (hashfunc)0, /*tp_hash*/
415 (ternaryfunc)0, /*tp_call*/
416 (reprfunc)0, /*tp_str*/
417
418 /* Space for future expansion */
419 0L,0L,0L,0L,
420 Icitype__doc__ /* Documentation string */
421};
422
423/* End of code for ic_instance objects */
424/* -------------------------------------------------------- */
425
426
427static char ic_ICStart__doc__[] =
428"(OSType)->ic_instance; Create an Internet Config instance"
429;
430
431static PyObject *
Jack Jansen1767f932001-09-04 22:20:39 +0000432ic_ICStart(PyObject *self, PyObject *args)
Jack Jansen8ce72f51997-01-07 16:18:32 +0000433{
434 OSType creator;
435
436 if (!PyArg_ParseTuple(args, "O&", PyMac_GetOSType, &creator))
437 return NULL;
438 return (PyObject *)newiciobject(creator);
439}
440
441/* List of methods defined in the module */
442
443static struct PyMethodDef ic_methods[] = {
444 {"ICStart", (PyCFunction)ic_ICStart, METH_VARARGS, ic_ICStart__doc__},
445
446 {NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */
447};
448
449
450/* Initialization function for the module (*must* be called initicglue) */
451
452static char icglue_module_documentation[] =
453"Implements low-level Internet Config interface"
454;
455
456void
Jack Jansen1767f932001-09-04 22:20:39 +0000457initicglue(void)
Jack Jansen8ce72f51997-01-07 16:18:32 +0000458{
459 PyObject *m, *d;
460
461 /* Create the module and add the functions */
462 m = Py_InitModule4("icglue", ic_methods,
463 icglue_module_documentation,
464 (PyObject*)NULL,PYTHON_API_VERSION);
465
466 /* Add some symbolic constants to the module */
467 d = PyModule_GetDict(m);
Jack Jansen8f54f2a2002-01-11 12:38:08 +0000468 ErrorObject = PyMac_GetOSErrException();
469 if (ErrorObject == NULL ||
470 PyDict_SetItemString(d, "error", ErrorObject) != 0)
471 return;
Jack Jansen8ce72f51997-01-07 16:18:32 +0000472
473 /* XXXX Add constants here */
474
475 /* Check for errors */
476 if (PyErr_Occurred())
477 Py_FatalError("can't initialize module icglue");
478}
479