AltME groups: search
Help · search scripts · search articles · search mailing listresults summary
world | hits |
r4wp | 1023 |
r3wp | 10555 |
total: | 11578 |
results window for this page: [start: 6801 end: 6900]
world-name: r3wp
Group: Core ... Discuss core issues [web-public] | ||
Brock: 9-Oct-2008 | QUESTION: I have a function that takes on parameter. This parameter can be one of many variables. I then want to see what the name of the parameter was that was processed by the function. How do I do this? | |
Claude: 11-Oct-2008 | i would like to do it like in dos windows that the FTP command can take a file as input and then execute all commands in that file | |
BrianH: 11-Oct-2008 | If you do to-word "something" in R2 the word returned will be bound to the global context, so it will only have a value if a word of that name in the global context already has a value. It doesn't matter if you do to-word in a function. | |
BrianH: 11-Oct-2008 | You can use NONE? to do that, or the checker for whatever datatype you are looking for if you want a positive result. The IF function also treats NONE as false, so if you are not looking for logic values you can use it directly. Like this: a: none parse [1 2 3] [set a integer!] ; will return false if a [ ; you found it, do something ] If you think the value you are testing might be an active value (like a function), refer to it with a get-word! for safety, like :a. | |
Terry: 12-Oct-2008 | can't seem to get it to fire.. do you have a working example by chance? | |
Davide: 15-Oct-2008 | hi, I need your help with bind: - I have an object h h: make object! [ q: [] ] append h/q make object! [ f1: func [a][print ["f1" a]] f2: func [b][f1 join "f2 " b] ] if I call f1 and f2 the results are correct: >> h/q/1/f1 "hi" f1 hi >> h/q/1/f2 "hi" f1 f2 hi --------------------- Now, I want to make the code of f2 dynamic, so I add a second param "code" to f2: h/q/1/f2: func [b code][do code] of course this doesn't work, f1 and b aren't bound: >> h/q/1/f2 "hi" [f1 join "f2 " b] ** Script Error: f1 has no value ** Where: f2 ** Near: f1 join "f2 " b I've tried with no luck the followings: h/q/1/f2: func [b code][do bind code 'f2] h/q/1/f2: func [b code][do bind code in h/q/1 'f2] What is the magic word: "do bind code ******* " ? | |
Anton: 15-Oct-2008 | The 'f2 word which you are trying to use as an example word is not bound to the object you want, because you create the function after making the object. If you had defined the function which does the bind directly in the object spec to start with you wouldn't have this problem. But if you need to define the function after creating the object, then you could do any of these: | |
Anton: 15-Oct-2008 | h/q/1/f2: func [b code][do bind bind code 'b h/q/1] h/q/1/f2: func [b code][do bind bind code 'b in h/q/1 'self] h/q/1/f2: func [b code] compose [do bind bind code 'b (h/q/1)] h/q/1/f2: func [b code] compose [do bind bind code 'b (to-lit-word in h/q/1 'self)] h/q/1/f2: func [b code] compose [do bind bind code 'b (to-lit-word in h/q/1 'f1)] | |
amacleod: 16-Oct-2008 | How do I convert: [{some sentence with some carriage returns and tabs}] to: [{some sentence with^/^-some carriage returns^/^-^-and tabs}] | |
amacleod: 16-Oct-2008 | Is there a simple method or do I need to parse through and append each line while inserting the ^/ | |
Geomol: 16-Oct-2008 | I know the concept of a context. I actually use the word CONTEXT in most of my scripts. And reading the BIND help (with ? bind), I see, it binds words to a known word. So I guess, the known word is defining the context, the new words (1. argument of BIND) should bind to. But why, Anton, do you use two binds in your example? I would guess, something like: do bind [code b] h/q/1 should work? | |
Anton: 16-Oct-2008 | do bind [code b] ctx would not do what we want, because it would only bind the two words in the block ('code and 'b) to the context. | |
Anton: 16-Oct-2008 | So BIND selectively "paints" a context over words in a block. BIND recurses into sub-blocks to do this, but does not get the value of words and recurse into them too, if they are blocks. This is why bind [code] ctx does not affect the CODE block; it only affects the 'code word (and only that instance of the 'code word, not any other instances floating around elsewhere in the system, in their own blocks.) | |
Davide: 16-Oct-2008 | Would be easier (for me) to have something like "do/bind-here code", where all words in the code are bound in the context where there is the "do". | |
Geomol: 16-Oct-2008 | Why is it, that b is not auto-bound to the function in this example? >> f: func [b code] [do code] >> f "hi" [print b] ** Script Error: b has no value I mean, passing [print b] as an argument to the function, it's just a block of words without meaning initially. When handed to f, f takes over and will now do it. So f has to find out, what's the meaning of the inside of the block. First it finds the word "print", which makes sense. Then it find the word "b", and this doesn't makes sense to f. Why not? | |
Anton: 16-Oct-2008 | Geomol, when FUNC is evaluated, a new function is created, along with a new "function context", as we say. The words in the function body block are then bound to the new function context. There are only two words in the block, 'do and 'code. So those are the only words affected. This binding only happens *once*, at function creation time. It does not happen again automatically when the function is evaluated for the first time, or any time afterwards. Even if it did, it would not affect the block of words referred to by 'code, because, as I've said above, BIND does not evaluate words to check if they are a block so it can recurse into them. (If it did, that would have far reaching consequences.) Not having to rebind words each time the function is evaluated keeps it efficient. If we want 'foreign' code to be bound to a function's context so it can interact with the function's locals, then we have to do it ourselves; functions created by FUNC won't do it for us. | |
Geomol: 16-Oct-2008 | I used to think, blocks of words didn't have any meaning, until they were e.g. evaluated. In one context, the words mean one thing, in another something else. When I program, I don't think alot about this, I just work with REBOL. Now I some cases, where I might not expect the output, I'm getting. Example: >> a: 1 == 1 >> f: func [a code] [do code] >> f 2 [print a] 1 Before doing this, I would have guessed, 2 was printed. Funny I haven't had such a problem, that I can remember. | |
Gregg: 16-Oct-2008 | By adding the secon ^, it escapes the ^ that marks the newline, so it is no longer a newline. When you write the string out, then it will write out as "a^/^-b^/^-c" which will convert to newlines again when loaded. If you're writing out and loading strings, you may have to convert the data back yourself when you load it, because REBOL won't parse into it to do so. e.g., if you mold an object spec to be on a single line like that, REBOL will convert them on load, but if you just read a file as a string, it won't. | |
Anton: 16-Oct-2008 | amacleod, I think Greg and mine solution both work. They produce a string molded so that the two control characters (newline and tab) are escaped. You just need to ... ahh... here's where I was going to say "just LOAD it." but I get an error message. >> load "^^/" ** Syntax Error: Invalid path -- ^/ ** Near: (line 1) ^/ So maybe do this instead: s: "^/" ; <-- input string s: "^^/" ; <--- specially "molded" string as produced by PARSE or REPLACE above. load rejoin ["{" s "}"] ; <-- specially "loaded" string the result of which should be the same as the input. | |
Gregg: 18-Oct-2008 | From !REBOL3 group, following MattAnton's fbionacci func. Matt, it's a good func, but there are some things to watch out for in REBOL, which are different from many other languages. 1) Undeclared vars in func become global. Use the /local refinement to declare them. 2) Series values in funcs (e.g. your starting block of [0.0 1.0] maintain their value between calls if you don't use COPY. Run your function multiple times to see what happens. It may be that you wanted this to be a memoizing function, but then why UNSET 'fibonacci-block?. I think you also mentioned that the challenge was to do it recursively, which this isn't. That's a case where you would definitely want to memoize. :-) In any case, this is always fun stuff to think about. Here's a modified version for you to play with. Look at some of the other REBOL funcs used, see if you find any bugs, or maybe it will give you ideas for other ways to solve the problem. fibonacci: func [ "Returns a list of fibonacci numbers, up to the specified count." count [integer!] "Number of iterations to run" /trace /local res n-1 n-2 incr step ] [ incr: func [word] [set word 1 + get word] step: does [incr 'n-1 incr 'n-2] res: copy [0.0 1.0] set [n-1 n-2] [1 2] repeat i count [ append res add pick res n-1 pick res n-2 step if trace [print [i last res]] ] res ] print mold fibonacci 3 print mold fibonacci 46 | |
Chris: 25-Oct-2008 | do http://www.rebol.org/download-a-script.r?script-name=form-date.r pad-precise: func [s [number!]][ skip tail rejoin ["0" round/to s 0.1] -4] form-date now "%Y-%m-%dT%H:%M:%SZ%Z" form-date/gmt now "%Y-%m-%dT%H:%M:%s" | |
Graham: 25-Oct-2008 | I do this a lot to make sure there is no text overflow in database fields | |
Graham: 26-Oct-2008 | Actually what I would like to do is modify in-situ cut: func [ 'c n ][ set c copy/part get c n ] but this only works for standalone series and not when series are part of an object | |
Anton: 27-Oct-2008 | It's not in RAMBO. R3 doesn't have this problem, but it seems that clean-path doesn't do anything with tildes. (Maybe R3 clean-path is not using the operating system to do path expansion.) | |
DideC: 31-Oct-2008 | clear-at (its what it does) truncate (its what it seems to do) | |
Graham: 5-Nov-2008 | One thing I do is to remove the outer characters eg. "[Something]" => "Something" | |
Graham: 7-Nov-2008 | Why can't we have functions that return a value to the calling function, but then continue to do something else ? Is this because we lack multithreading? | |
Graham: 7-Nov-2008 | but yes, that is what we have to do at present | |
Pekr: 8-Nov-2008 | Graham: how could single threaded code return, and yet continue to execute recent function? What usability case do you have in mind here? | |
BrianH: 8-Nov-2008 | For that matter, do you mean continue to do something else while the calling function is also doing something with your return value (multitasking) or do you mean picking up where you left off, later (generators)? | |
amacleod: 24-Nov-2008 | How do I download an .exe file and save it locally preserving the icon data. If I download a file trhough my browser the Icon downloads too. How do I do this with rebol? Do I read-thru and write to save it? I seem lose the icon this way. THe windows default .exe icon shows. | |
Gabriele: 26-Nov-2008 | you might be able to use iptables (or equivalent) to do something like that, by basically doing a sort of nat. | |
[unknown: 5]: 29-Nov-2008 | And it has something to do with blocks | |
btiffin: 1-Dec-2008 | Ashley; the connections do eventually timeout? system/schemes/default/timeout is normally 30 seconds. Drop that down to 00:00:01 (or other short reasonable)? | |
Nicolas: 1-Dec-2008 | do I need to have a server on the other computer? | |
Robert: 4-Dec-2008 | At what situations do I get the spining waiting "cursor": | / - \ | ? I want to avoid any output of my script. | |
[unknown: 5]: 8-Dec-2008 | Hmmm.. seems not an easy way to do that? | |
[unknown: 5]: 8-Dec-2008 | for example the actual binary representaton for the number 256 is #{0100} But I can't get that output by doing: >> to-binary [256] == #{00} See that result is incorrect. I'm assuming there is an easier way to do this. | |
Steeve: 8-Dec-2008 | i do this: debase/base to-hex 256 16 | |
Steeve: 8-Dec-2008 | i'm using a preconstructed struct! [] to do the conversion (i don't use debase) , it's fast enough. | |
Steeve: 8-Dec-2008 | so you can do that too: >> to integer! reverse #{00010000} == 256 | |
eFishAnt: 18-Dec-2008 | I have a situation where I wish inside a while loop I could do a continue. There is break, but I just want to go back to the top where my wait sits and wait for the next event coming in. Has anyone done some solution to this? | |
Steeve: 18-Dec-2008 | in fact i remember having to simulate a goto command when i tried to develop a Z80 emulator. i had build a simple engine working like that: code: [ [ some code....] [ some code...] [ some code ... GOTO: 1] ; goto the first line of code ] GOTO: 0 forever [ GOTO: GOTO + 1 do pick code goto ] | |
Steeve: 18-Dec-2008 | yep, even if there is an error in my code, it's very easy to do | |
[unknown: 5]: 18-Dec-2008 | efishant - for what you want to do with the loop just put the while loop inside a function (assuming you manipulation a series) and then have it break out on a conidtion is met and then change the series to the desires position and pass back to the function if needed. Not sure exactly what your trying to accomplish. | |
[unknown: 5]: 18-Dec-2008 | I'm might do some tests here to see myself | |
[unknown: 5]: 18-Dec-2008 | how many characters do you attempt to read each time? | |
[unknown: 5]: 18-Dec-2008 | I copy data from a port using /seek and simply do- to-block port-data and need no other conversion. | |
Steeve: 18-Dec-2008 | each time you do a copy/part a new internal buffer is created, it's better to use always the same buffer. easy to understand. more of that, the profiling script say that it''s faster to read 16ko than 2 times 16 bytes | |
BrianH: 18-Dec-2008 | Do you need to open/direct with read-io? | |
[unknown: 5]: 18-Dec-2008 | I might do a test to see how fast 4 successive picks would be | |
BrianH: 18-Dec-2008 | How often do you need to do these reads, and can they be sorted in batches? | |
Chris: 19-Dec-2008 | A 'bind question: how do I construct an object containing blocks without changing the blocks' contexts? This bad: >> id: #foo == #foo >> blk: [id] == [id] >> reduce blk == [#foo] >> ctx: context append/only [id: #bar bk:] blk >> reduce ctx/bk == [#bar] This good: >> id: #foo == #foo >> blk: [id] == [id] >> reduce blk == [#foo] >> ctx: magic-context append/only [id: #bar bk:] blk >> reduce ctx/bk == [#foo] How to 'magic-context ? | |
Geomol: 20-Dec-2008 | That would require to get access to locals from the outside of a function. I'm not away of a way to do that. | |
Gregg: 20-Dec-2008 | 1) what is the purpose of clearing the locals? 2) how often do you need to do this, where the list is large? i.e. does it indicate a design issue? | |
Geomol: 20-Dec-2008 | Hard to read that setting-to-none line, and I haven't found a way to do it by a function call (like a clear-locals function). | |
Geomol: 20-Dec-2008 | Brian, do you know, if it's possible from outside a function to specity its context? (To be used in the second parameter for BIND.) | |
BrianH: 20-Dec-2008 | You can't get access to a function's context without having a known word that is already bouund to that context. When you do first :f, the words retrn are not bound to the function's context. In R2, when you do third :f you get words that are bound, but you can only guess to what., since words are bound individually. The only safe way to do clear-words is to pass both the function and a known word bound to the function's context, and even then you have to copy the fuunction's argument block and convert any refinements to words before you bind the copy. | |
Steeve: 20-Dec-2008 | i meant, it's better to do a my-var: none when necessary | |
Gabriele: 22-Dec-2008 | I do not think this is a bug, and it may not be trivial to fix it if it was (which means, it'll never get fixed as Carl is not going to spend that much time on R2 for something not important) | |
Geomol: 25-Dec-2008 | When using local blocks in functions, that is called many times, I often define them as: my-block: clear [] instead of my-block: copy [] The idea is to reuse the block (the memory area), so the garbage collection has less to do. Could there be any drawback in this? | |
Henrik: 25-Dec-2008 | I do the same thing, so I would be interested in hearing about draw backs. But it may also be important to specify the size of the block, when it's first created. That gives the garbage collector even less to do. | |
[unknown: 5]: 25-Dec-2008 | Yeah, you don't want to do that. Because with each loop that evaluates the command you actually recreating the pointer. Instead do this: my-block: [] ... clear my-block | |
PeterWood: 26-Dec-2008 | I'm running a CGI script from which I want to 'launch another script to do some housekeeping. The output from the launched script (including the Rebol banners) is returned to the browser. Is there a way to redirect the output from the launched Rebol session? (I am getting this behaviour on both Mac OS X and Linux). | |
Steeve: 29-Dec-2008 | you could write your handler in a context directly, it's the most simple thing to do | |
Davide: 29-Dec-2008 | Now I can ask a more precise question: here is my problem: I have an application object app that "serve" two client c1, c2 app: make object! [ hset: func [c] [k: c/name] hget: func [c] [print ["k=" k]] ] c1: make object! [ name: "pippo" ] c2: make object! [ name: "pluto" ] The handlers of app, use k as internal container, but of course it's shared between clients: >> app/hset c1 == "pippo" >> app/hset c2 == "pluto" >> app/hget c1 k= pluto I would bind k (and every set-word in the handler) to the object passed as parameter so the last line would produce: >> app/hget c1 k= pippo Now I come to this solution, using blocks instead of funcs in app app: make object! [ hset: [k: name] hget: [print ["k=" k]] ] c1: make object! [ name: "pippo" vars: make object! [ k: none ] ] c2: make object! [ name: "pluto" vars: make object! [ k: none ] ] This produce: >> do bind bind app/hset c1/vars c1 == "pippo" >> do bind bind app/hset c2/vars c2 == "pluto" >> do bind bind app/hget c1/vars c1 k= pippo This works, but I have to collect every set-words used in the handler, into the clients (using Ladislav set-words http://www.fm.tul.cz/~ladislav/rebol/set-words.r ) sw: copy [] repeat h next first app [sw: union sw set-words app/:h] b: copy [] repeat w sw [insert tail b reduce [to set-word! w none]] vars: make object! head b c1/vars: vars c2/vars: vars Now, my questions are: 1) Is this approch "rebolish" ? There's a smarter way to do it ? 2) If I need a function in my app like: app: make object! [ hset: [k: avg a b] hget: [print ["k=" k]] avg: func [x y] [aux: x + y aux: aux / 2] ] How can I collect the aux: word in avg function, and bind this function to c1/vars ? | |
Gabriele: 30-Dec-2008 | I don't seem to understand what you're trying to do... why isn't hget defined as func [c] [print c/name] ? | |
Davide: 30-Dec-2008 | If I define aux locally it is shared to every client: app: make object! [ aux: none hset: [avg a b] hget: [print ["avg=" aux]] avg: func [x y] [aux: x + y aux: aux / 2] ] c1: make object! [ a: 2 b: 4 ] c2: make object! [ a: 3 b: 5 ] >> do bind app/hset c1 == 3 >> do bind app/hget c1 avg= 3 >> do bind app/hset c2 == 4 >> do bind app/hget c1 avg= 4 <<< error this shoud be 3 ! | |
[unknown: 5]: 3-Jan-2009 | I have produced some code to do this but curious if others have as well. Seems it could be useful. | |
BrianH: 3-Jan-2009 | Chris, you missed that being able to screen for "bad" functions is what Paul is trying to do. It is much easier to maintain a whitelist than a blacklist, and easier to implement in R2 as well. | |
[unknown: 5]: 3-Jan-2009 | Chris is on to the method that I deploy but I do it recursively. | |
Henrik: 4-Jan-2009 | I want to use the body of an object in a VID layout block, but words are not lit: things: make object! [item-type: 'something] layout compose/deep [button "Hello" with [(things)]] When words are not lit, the layout process goes wrong, because: >> probe things make object! [ item-type: 'something ; yes ] >> third things == [item-type: something] ; no! How do I get lit words there? | |
Henrik: 4-Jan-2009 | thanks, Gregg. I'm assuming now there is no truly quick way to do this. | |
Pekr: 5-Jan-2009 | Graham - what do you mean by IPC? Rebol task to rebol task? | |
Sunanda: 7-Jan-2009 | /secure provides its own seed. Theoretically, that seed is less guessable than the sort of things we are likely to think of in mezzanine code -- like time/precise. But we don't know for sure. All we do know is that with /seed we can provide the same seed and get the same series of random values; while with /secure if is not so easy. | |
Sunanda: 7-Jan-2009 | Or do not have one when using /secure, and expecting /secure to work! | |
Henrik: 7-Jan-2009 | Graham, if you ever (ever) need to do that under win98, you must be careful, because time precision is much lower there. | |
Graham: 7-Jan-2009 | what do people do to create a UUID? | |
Gregg: 7-Jan-2009 | There are a lot of ways to do it. Some people use the GUID API on Windows. Some use a high-low model, kind of like you are by including the PID. Combining clock (with setback checking), counter, machine info, and a key (like PID), is plenty good. | |
Maxim: 8-Jan-2009 | to generate IDs, I do a nasty infalable trick on mysql. i insert directly, in a uid table. | |
btiffin: 19-Jan-2009 | Well normally fifo files are created in blocking mode, so yeah a write won't complete until a read occurs and a read will wait for a writer (by default). I'll be honest, I've not done this from REBOL, but with 2.7.6 and LOAD/LIBRARY freed, we can do any libc6 calls that we want, so you should be able to set a non blocking mode and get true multiple writes and reads that will return empty if no data is queued. For OpenCOBOL I implemented POSIX Message Queues; as MQ_NOTIFY will make a callback when the queue goes from empty to non-empty and you don't have to worry about spinning on a read. If you don't mind playing with make routine! take a look at mq_open and friends (man mq_overview) it might offer more control for IPC. | |
Janko: 20-Jan-2009 | thanks btiffin for such great explanation, yes I was looking at message queues too at first but then someone proposed pipes and they do seem more accessible/simple to start in a way. | |
Pekr: 21-Jan-2009 | insert as an operation does not preserve datatype. It reduces litword to word. Not sure there is a reason to do so ... | |
BrianH: 21-Jan-2009 | INSERT wasn't appending a lit-word, it was appending a word. DO converted the lit-word to a word, not INSERT. | |
BrianH: 21-Jan-2009 | No, it was an expression of the words append and a and a lit-word 'b. DO evaluated the expression, and while doing so evaluated the 'b to create b. Then it passed the b to the function referenced by the word append. | |
BrianH: 21-Jan-2009 | *TARD indeed, because such a function wouldn't be able to call external functions, not even DO :) | |
Oldes: 25-Jan-2009 | When you did call, the black cmd window was always visible. Now you must do call/show to see the window (which you mostly don't want to see) And I think this was just Windows change. I'm not sure how it worls on Linux or in other OSes. | |
Oldes: 25-Jan-2009 | I'm testing it now with cheyenne and it seems not to be working... even if I do: print "Content-type: text/html^/" tmp: copy "" call/output/wait "dir" tmp probe tmp | |
[unknown: 5]: 26-Jan-2009 | I'm not complaining Brian. I always do the same. Which is why it is always best to present mezz type of functions ot the community for scrutiny before they go into any builds. Just a wise way of doing things. | |
Will: 27-Jan-2009 | about my problem (a couple of messages above) I can confirm that the problem doesn't exist with 2.7.5. 2.7.6, supposedly fixed [call] but did it introduce a new bug? has it maybe to do with hevy cpu, timing, rebol dns helper process? | |
Sunanda: 28-Jan-2009 | Nice start, Paul, to pulling the teeth of code you do not want to execute I think you need to handled action!s too, otherwise some executable code can slip by: >> defunction [abs trim change make select remove sort] ;; etc, anything that is an action! == [abs trim change make select remove sort] | |
Tomc: 1-Feb-2009 | I have a 24 bit math implementation to do RSA but never converted to or from other bases. It is from before Holgar did encryption with thebignum library nativly in core/view which renders mine moot | |
Dockimbel: 1-Feb-2009 | I've just hit a serious issue in 2.7.6 on UNIX platforms today. Briefly: CLOSE on TCP ports doesn't work anymore if CALL is used before CLOSE, in a AWAKE handler. To reproduce this bug, get the tests scripts here : write %server.r read http://softinnov.org/tmp/server.r write %client.r read http://softinnov.org/tmp/client.r write %foo.r read http://softinnov.org/tmp/foo.r Then, read the comment section in %server.r and launch it to see by yourself : do %server.r Notes: o Windows is not affected by this issue. o I consider this a major issue for all REBOL server applications working in async mode and spawning processes. o I'm posting first here before RAMBO, so that people can test and point out any possible bad interpretation from me. | |
Oldes: 1-Feb-2009 | I'm almost ready with the lexer for Python's Pygments syntax highlighter. Just need to define the keywords.. All the time I do it I don't know, which one to choose:) | |
Henrik: 5-Feb-2009 | perhaps the decompression length? AFAIK, REBOL needs to know how much needs to be decompressed before it will do it. | |
Oldes: 5-Feb-2009 | but problem is maybe on your side... it's strange that you do to-binary data. If you read the data as text, REBOL changes line breaks so it modifies the content. | |
eFishAnt: 5-Feb-2009 | decompress wants a string, and binary is a string, so that's what made me think to do to-binary... | |
Janko: 8-Feb-2009 | (that was the reason why I wanted to embed smalltalk into game engine, but I would much rather do this with rebol) | |
Janko: 12-Feb-2009 | also.. something para-do could be made so that it would send code blocks to multiple rebol processes via tcp or pipes maybe and collect results back | |
Steeve: 12-Feb-2009 | clearly, it could be faster but i'm not sure of the interest of such thing. If i want a small granularity in a process, i build tiny functions and push them in a to-do stack |
6801 / 11578 | 1 | 2 | 3 | 4 | 5 | ... | 67 | 68 | [69] | 70 | 71 | ... | 112 | 113 | 114 | 115 | 116 |