AltME groups: search
Help · search scripts · search articles · search mailing listresults summary
world | hits |
r4wp | 4382 |
r3wp | 44224 |
total: | 48606 |
results window for this page: [start: 19101 end: 19200]
world-name: r3wp
Group: !Cheyenne ... Discussions about the Cheyenne Web Server [web-public] | ||
Pekr: 18-Feb-2009 | Janko - Cheyenne uses Uniserve multiplexing server IIRC. And AFAIK, Uniserve uses two aproaches - if the request can be served quickly, you can use one process, but if your request could last longer, you define handler or something like that, which spawns new process ... | |
Janko: 18-Feb-2009 | yes, that is another problem and I am aware of it (basically that is not a problem here).. the last writer wins... I am just worried if any data corruption can somehow happen | |
Pekr: 18-Feb-2009 | I think that Robert is very brave with his statement :-) I would not bet if data can or can't be opened. If file is not locked, and you use write on it, and another process too, you can corrupt data, no? | |
Janko: 18-Feb-2009 | that is the same if you have a simpler mysql based webapp.. one person starts editing text, another person starts editing , first saves, second saves.. first person looses the changes.. that is basically problem on application level and is the same here as if using RDBMS | |
Janko: 18-Feb-2009 | and if server is uniprocess that can't happen anyway | |
Robert: 18-Feb-2009 | A DB handles this by having one file lock for the database file all the time, taking several request at the same time and doinga DB locking scheme on-top of the filesystem locking. | |
Dockimbel: 18-Feb-2009 | Cheyenne serves static resources from the main process (UniServe process), but CGI and RSP are executed by pre-forked worker processes. So yes, writing to the same file from RSP script can be an issue if you don't have a mean to ensure that write accesses are serialized. I had that issue recently for RSP log/debug file, I had to build a small logger service in the main process to be able to serialize write access (after stress testing different file locking solutions from REBOL, no one seemed reliable enough to me). I thought about adding a synchronization service in Cheyenne that could be used to (but not only) address the write file sync issue. That could work for low sync needs (like writing to a file once every few seconds), but for massive sync needs (dozens or hundreds of sync req/s), I'm afraid that the TCP port overhead would be too costly...(maybe a separate sync server process with persistent TCP connections could be good enough even for heavy uses?) | |
Janko: 18-Feb-2009 | aha, so rsps work on multiple worker processes, interesting.. well I think to me it's not a problem as each user has it's own data files so it's hard to imagine multiple writes could happen at the same time for the same file. And if I would need something reall y heavy duty I would make a server serving files and caching them in ram for speed etc, which would also take care for sync. or something off the shelf | |
Dockimbel: 19-Feb-2009 | You can get file access errors and corrupted data in file (last write wins probably). A simple RSP page may be rendered very fast, but there's situations where it can take much more time. Imagine a complex query on database or using CALL to a third-party command-line tool. With RSP pages rendering in a few ms, the risk for collision is very low, but it's not zero. | |
Robert: 19-Feb-2009 | Oh, and if you really think that's it about it. Wait: If your files is on a Samba network share you have to deal with the Samba way of locking, not the OS where the file is stored on. And Samba locking can be problematic as well. | |
Robert: 19-Feb-2009 | REST & XMLHttpRequest: This question vanished yesterday. Is Cheyenne REST compatible? And, has anyone done a simple way to request an RSP page and put the returned content into the DOM of a current page? Or, which JS framework would be best to take stuff and put it into the DOM? | |
Oldes: 19-Feb-2009 | I don't know what is REST but I see no reason why XMLHttpRequest should not be possible. And I would use JQuery. | |
Robert: 19-Feb-2009 | REST uses not only POST and GET but UPDATE, DELETE and INFO (IIRC) in HTTP requests. And I don't know if the other two need special treatment in the web-server or if everything is just routed to RSP Page and that's it. | |
Janko: 19-Feb-2009 | thanks for all info.. to me it's important difference if (1) last write wins or (2) data get's corrupted meaning you get file that doesn't have a rebol data that could be load-ed any more. Well I think I have been asking too much and should try experimenting and looking what happens. If only (1) can happen with very small probability (because I have many separate small files which don't get edited most of the time) in case of my current app it seems ok, but I will test (also what happens with read and write at the same time.) If (2) can happen at all then I will use/make a centralized file/data server right now so webapp will access no files directly any more and that server will have to take care of locking or serialize all reads writes. | |
Robert: 19-Feb-2009 | It's (1) if you work with filesystem files AND Rebol uses the OS system locking functions (which I expect). | |
Graham: 19-Feb-2009 | I've played a little with jQuery and jQuery UI, and there doesn't seem to be a problem pulling RSP pages into the DOM. | |
Robert: 20-Feb-2009 | REST: Ok, I will give it a try and let you know. | |
Graham: 21-Feb-2009 | If you have a web app, and you send the user to the login.rsp by default, but there is no index.rsp etc, then you get a 404. | |
Graham: 21-Feb-2009 | I had a nasty experience just now. I had spent the last couple of days writing my prototype website .. and got all the ajax stuff working. I decided to reboot because the css wasn't showing properly in chrome but was working in FF. Big mistake. Windows Vista reported a problem booting, and started it's recovery process. At the end of it, all my RSP files I had created, or edited, in the last 2 days were gone! Other files ( html ) were untouched. System restore failed to recover these files and using file recovery tools also was unable to locate them. | |
Graham: 21-Feb-2009 | I guess Windows does not recognize RSP files and decides that they are potentially malicious ie. not a document file, and so removes them :( | |
Izkata: 22-Feb-2009 | I think it's more a Windows problem than anything else. Vista did that to me back during (I think) Thanksgiving with my Warcraft III install, and XP before that with Spore. | |
PeterWood: 22-Feb-2009 | Perhaps a version control system would be a good place to store all your RSPs and all your other code and supporting files for that matter. | |
Henrik: 22-Feb-2009 | jQuery: Have spent the past 3 days with it, and although the syntax is weird, it's far easier to get started with than YUI. | |
Kaj: 22-Feb-2009 | I guess Microsoft has recognised the upcoming threat Cheyenne poses to them, and taken countermeasures ;-) | |
Dockimbel: 23-Feb-2009 | Sessions: when you use session/start, you don't have the SID available immediatly, but the SID is sent in the response. The reason is that RSP session management is done inside the main process and not in the RSP process. So, from the RSP point of vue, the SID is only available on the next client request. I think that this can be changed so that session/start generates a new SID that can be used at once in the RSP. | |
Robert: 24-Feb-2009 | Sessions: I thought RSP processes are started from the main process. So, why not create a new SID (if necessary) in the main process and give it to the new RSP process? | |
Robert: 24-Feb-2009 | Database: Are all database drivers included in Cheyenne or do I need to load them on my own? And if, how? | |
Robert: 24-Feb-2009 | Sessions: Maybe my model of how sessions are handled is wrong. I think/thought it works like this: 1. Main process gets request from client 2. Main process checks if for this client a SID exists, if not creates a unique one 3. Main process starts RSP process and provides SID 4. RSP process either uses SID or not. | |
Robert: 24-Feb-2009 | How about just creating the SID and do the rest as soon as session/start is invoked? | |
Dockimbel: 26-Feb-2009 | A session is a block! of name / value pairs that is kept in Cheyenne's main process and exchanged with worker process. A synchronization system is there to avoid concurrency issues. The SID sent by cookie to the client is just a lookup key. When sent back to the server, this key allows to identify the right session object to pass to the RSP script in a worker process. You are only limited by memory, but remember that the session object is MOLDed / LOADed and exchanged by TCP twice for a RSP request. So, in order to keep your RSP pages fast enough and scale well with a growing number of active users, keep the session block! as small as possible. | |
Dockimbel: 26-Feb-2009 | This is precisely where Cheyenne could benefit a lot from a multihreaded REBOL kernel : no more need to MOLD / LOAD session block and request object, no more need to exchange it through TCP with other processes...That would allow a big boost of RSP performances and reduce Cheyenne's whole memory usage. | |
Graham: 26-Feb-2009 | If I want to keep all the data for a patient in a session .. and have mutliple patients, I was thinking of keeping all the results, consults etc in the session object. | |
Graham: 26-Feb-2009 | Or, if I have just the one patient as an object .. then if I move to a diffferent rsp page, and then back again, I don't have to refetch all the data. | |
Dockimbel: 26-Feb-2009 | Do you really need several megabytes of data to display each page? That sounds very odd to me.You should store your data in a DB on disk and only request from DB the data needed for display. | |
Dockimbel: 26-Feb-2009 | In one of my RSP based app, I have pages with tabs. I use 2 different approach : - for tab panels with data cross-dependencies : I use a unique RSP script generating a page with a unique <FORM> tag and each tab content is simulated by <DIV> sections that I show or hide (with JS) depending on the selected tab. - for tab panels with no cross-dependencies : I use a separate RSP page for each tab content. The tab bar is a unique RSP script included by each "tab content" script. | |
Graham: 26-Feb-2009 | I currently doing the latter ... and I guess it's better to let the client store the data in their browser in a hidden div rather than the server store it in a session. Not sure what you mean by unique form tags though. | |
Janko: 1-Mar-2009 | Any feedback on this filter-validate-process dialect is velcome.. (it is meant for processing posted form data) first word in row is request field name ;;; req | opt is required | optional + default value ;;; than you can have a chain of aditional validators like int , string , email, url , one-word ;;; then you can have check which executes your custom code and if it returns a string it uses it as validation notice ( to check something app specific or in DB for example ) ;;; then you can process the value with do and again custom code the returned value of that block of code is set to that field .. filter-validate-process-example: [ id req and int . username req . email req and email check ( either email-exists email [ "email taken"] [ none ] ) . website opt "" do ( to-visible-url website ) . adress opt "not given" . ] | |
Janko: 1-Mar-2009 | I am not 100% on few things ... should I use short names like req opt or whole required optional ... and more technical about check and do (I will rename this to proc or process ) .. should I create/bind to words that are the same as field names , like this upthere ... or maybe use something like this so you use ( to-visible-url this ) I don't like creating a bunch of words that won't get used mostly... but I thought I need to so I can use this for typical password / retype password example like this ... password req . password2 req check ( either password == password2 [ none ] [ "passwords don't match" ] ) . ... | |
Janko: 1-Mar-2009 | but I figured out I could use current and previous then this example and probably some others will work anyway.. and I can bind in do ( code ) anyway if I really need custom variables password req . password2 req check ( either current == previous ) [ none ] [ "no match" ] ) . I will go with this way | |
BrianH: 2-Mar-2009 | I found a possible bug in RSP yesterday: When RSP gets the values passed to it as get query parameters, it removes url-encoded html tags and comments from the values. This is not correct with values that come from a textarea, or probably other values as well. I haven't tested with multipart/form-data encoding yet. This might be a setting change rather than a bug in RSP, but if so then show.rsp should be changed to not strip tags from values and then html-encode the values when shown. | |
Graham: 2-Mar-2009 | I was playing around with rsp form submission the other day, and I found that values were being persisted. So, even when the values should have been none, it was displaying values from the previous form's submission. I had to explicitly set each value to none prior to parsing the submission data. | |
Dockimbel: 2-Mar-2009 | I'm programming RSP scripts since than more a year now on a daily basis and I never noticed such behaviour with values received from form submission and accessed through request/content (which is the way you should use to access passed values). | |
Graham: 2-Mar-2009 | What I am doing is taking a text screen dump from an AS400 terminal ( see http://synapsedirect.com/forums/permalink/7675/7675/ShowThread.aspx#7675 ) and parsing the data so that I can grab the patient demographics and add them to the database. | |
Graham: 2-Mar-2009 | demographics and import them into the database. This is now saving this user from having to manually enter them ... there being no bridge from the mainframe database. | |
sqlab: 3-Mar-2009 | I once used the telnet scheme from F. Sievertsen to script and query automatically a host system. Maybe this can help too. | |
Graham: 3-Mar-2009 | I guess I need to sit down and recreate this .. but thought I'd mention it make sure it was aberrant behaviour. | |
Dockimbel: 3-Mar-2009 | Let's clarify a few things : - Request/content is working OK in your example, there's no issue with that. - Using variables in PARSE rules without initializing them is a bad programming practice in my book. You *should* initialize them before using them (unless wrapped in a function which will do the work for you). If your parse rule fails, your code may error out (or you may get an unexpected value) when trying to print 'phone because it hasn't been initialized. - You seem to expect that RSP script will be evaluated in a fresh REBOL session each time. This is not the way RSP works. RSP uses persistent pre-forked processes for performances. If you expect a fresh REBOL session each time, then this is the CGI model which is an order of magnitude slower than RSP. - Even if RSP processes are persistent, they can be restarted or killed and you can't control which process will executed your script, so, just as a warning, you can't expect that a "global" variable will be still there for the next RSP script evaluation. If you need value persistency, use a session variable or write it to disk. | |
Dockimbel: 3-Mar-2009 | In theory, it should be possible to set to none each new webapp variables used in RSP scripts by querying the webapp context object. In practice, I'm not sure it can be made 100% reliable because you can always declare words using SET in global context (which would be much more difficult to clean up without breaking the RSP engine). The other reason is that, as a side effect, it allows some dynamic code caching like this one : <% if not value? 'my-lib-loaded? [ do %private/my-lib.r my-lib-loaded: yes ] %> This can be used when you don't want to pre-load some libs from the on-* handler, but load them dynamically, only when needed. So you pay the cost of loading only once for each RSP process when the script is first called (and you can clean it when no more required by, for example, setting the word referring to the lib context to none) | |
Dockimbel: 3-Mar-2009 | I can implement a clean-up routine for RSP variables declared in a webapp context, but this would be a partial solution (won't clean up global space), and in all cases, you *should* initialized all variables before using them either by declaring them in a function! as local words or by explicitely setting them to a default value. Such clean-up routine could be usefull to enhance security by avoiding to reveal other user data in case of a RSP script programming error. Btw, you can already detect uninitialized variables in your RSP code by running Cheyenne with the -w 0 command line option. This would tell Cheyenne to use a single RSP worker process that will be restarted after each request (CGI like beahaviour). An uninitialized variable will likely error out in that case. | |
Dockimbel: 3-Mar-2009 | Having a Cheyenne running locally using a browser window to display VID dialect looks like very doable. I think that even 'move events would work fast enough. That would solve a lot of current View/VID issues while providing a cross-platform GUI. Add a proxy service to Cheyenne, and you got a nice RIA platform with online/offline working capabilities. Anyone rich enough here to sponsor such project? :-) | |
Henrik: 3-Mar-2009 | Dockimbel, that might solve some problems I had with form submission. My intent with forms was to provide an easy way to have all form data provided by the server via an object. When you create a new object it would hold info for when the form was created and a unique ID for the form. Through that you can tie a form instance to a specific browser instance, and when the form is submitted, you can do server-side verification. If the verification fails, the form object remains and the page is redisplayed. If the form object validates, then the form object is removed or copied away from the block of existing form instances and can no longer be used from that form instance, if you attempt to submit again. This would eliminate accidental double submission, although not regular spamming. By having that framework, setting up a flow for how to handle form data, server side, would be simpler. This doesn't sound like so much, but I happen to have an HTML dialect around, where I can create forms as objects in a simple way, and applying actions or handlers to forms, makes it much more like programming a real GUI. It could probably scale down to single text fields and a bit of AJAX. | |
Oldes: 3-Mar-2009 | There should be big sign somewhere, that people should enclose the variables set by parse in context or as function's locals. And it's not only Cheyenne related. | |
Graham: 3-Mar-2009 | I normally do this, but for some reaason I was thinking cgi instead of rsp, and so thought I didn't need to do that. | |
Dockimbel: 3-Mar-2009 | Right, and the same good practice should be applied to all others dialects that include REBOL code, like VID. | |
Kaj: 4-Mar-2009 | I updated the Syllable build recipes for Cheyenne and UniServe to the new versions | |
Kaj: 4-Mar-2009 | The previous versions are included in Syllable Server and the new Cheyenne will be included in the next Syllable Server: | |
Graham: 5-Mar-2009 | I'm running an command encapped version of 9.19 ( I presume there's no difference between the earlier 9.19 and the official release ) | |
Graham: 5-Mar-2009 | This has happened a few times now .. I mentioned it before. And usually only when I am rewriting RSP code. | |
Graham: 5-Mar-2009 | rsp and not cgi | |
Graham: 5-Mar-2009 | If anyone is wonderng what I am doing, I am prefilling in PDF forms and sending them to the client browser | |
Graham: 5-Mar-2009 | the client then fills in the form, and then clicks on the submit buttont to send the data back to me. | |
Graham: 5-Mar-2009 | Robert, xfdf is a deprecated format once used by Adobe to specify the contents of fields in a PDF. So, the above xfdf file will populate the fields TextField1, TextField2, syupdfid with $fname, $surname, and $syupdfid ... ( well, I will replace those before I send the pdf. ) | |
Graham: 5-Mar-2009 | So, I send this tiny xfdf file to the browser. the browser loads up the acrobat plugin. Acrobat now reads the pdf on my website as specified in the href field, and then fills in the fields in that pdf with the values as specified in the xfdf file. | |
Graham: 5-Mar-2009 | You can test this by logging to http://www.compkarori.co.nz:8000, and then using the "locate" button, ( leave the form blank ) and then select any dummy patient. Then on the bottom left menu, click on "test pdf" and then submit. | |
Dockimbel: 5-Mar-2009 | Never tried and I didn't received any feedback from users on that platforms. | |
Graham: 5-Mar-2009 | Ok, seems that the user moved his Cheyenne binary without taking my httpd.cfg which I provided. And so the listen port changed to 80 which is the default that Cheyenne creates. | |
Graham: 5-Mar-2009 | I wonder if the default port should be something else as on Vista and Linux, that port is not allowed by default. | |
Graham: 6-Mar-2009 | Actually I am using your encapped binary and not mine as the localhost server doens't need odbc :) I take your point though. | |
Graham: 6-Mar-2009 | My server app ( with the binary in the browser ) is now able to prefill pdfs, and then when submitted back to the server, able to display previously filled in pdfs :) | |
Graham: 7-Mar-2009 | I start up one instance of Cheyenne on port 8000 which is okay, and then I start another instance running in port 7999. The one I connect to 2nd produces the crash log. | |
Graham: 7-Mar-2009 | are these ports fixed and so I can only have one instance of cheyenne running? | |
Dockimbel: 7-Mar-2009 | Multiple running instances : 1 ) Cheyenne uses a port translation method for task-master to avoid clashing between Cheyenne's instances. This translation is currently triggered by the -p command line option specifying on which port(s) Cheyenne should listen. So the 'listen keyword in config file doesn't trigger the translation. After a quick look, it should be fixable. 2) Logger and RConsole services ports are not translated. This should be fixed too. 3) As a consequence of 1) & 2), Cheyenne can't currently run multiple instances on the same machine. I am running two instances because the web app uses the same database name : 4) I very well aware of this issue and I intend to find a solution asap. OpenSCManager failed : Access is denied : 5) I should load that routine! only if trying to run as a Windows Service without having admin rights. | |
Dockimbel: 7-Mar-2009 | I'm looking for 4) first because it's the quickest and cleaner way to solve your issues. | |
Graham: 7-Mar-2009 | What if I use different names for the database, and then alias them in the webapp init ? Then could i just run the one Cheyenne? | |
Graham: 7-Mar-2009 | So, to use a single instance of cheyenne, I have to go thru all my source and change the database name so that it's different each time I want to run more than one instance of this web app | |
Graham: 7-Mar-2009 | so one set of users access the demo website, and I use the other one. | |
Dockimbel: 8-Mar-2009 | Test this very carefully before taking it in production and report me any issue/bugs related to that patch (be sure to have checked your own code before reporting). | |
Graham: 10-Mar-2009 | and I need an app-init.r in the web-app directory? | |
Graham: 10-Mar-2009 | I tried that .. and got no response | |
Graham: 10-Mar-2009 | I was creating rsp pages writing them to the www directory and trying to browse to them ... and it wasn't working with my test.rsp page | |
Graham: 10-Mar-2009 | All this to avoid a blank Acrobat page appearing. if you call an *.xfdf file, acrobat opens up, and then the browser plugin starts up to load the remote PDF. so, you have this blank PDF on screen as well. But if I use localhost to create a web page that emits the xfdf, then I only get one browser window with the pdf and no more blank Acrobat instance. | |
Graham: 14-Mar-2009 | I've been writing a web app which I have been distributing as a zip archive. People just unzip the latest over their copy, and I ask them to write protect their own changes. | |
Graham: 14-Mar-2009 | Perhaps a Cheyenne rsp script that downloads a catalog, and then downloads any changes to the local site? | |
Gabriele: 14-Mar-2009 | and with some configuration for the auth part, you can also use the CGI for write access. | |
Gabriele: 14-Mar-2009 | git is faster and has more features (hg has been closing the gap on the features but not the speed), but windows people tend to hate it. | |
Graham: 14-Mar-2009 | and mercury is not poisonous to my system | |
Graham: 14-Mar-2009 | I should try and find my old replication script I wrote for uniserve | |
Graham: 14-Mar-2009 | If anyone has the stamina, I did a few videos linked to here http://synapsedirect.com/forums/permalink/7870/7869/ShowThread.aspx#7869 1. Shows the creation of an interactive PDF using Acrobat Pro 9 2. How to register the PDF on my Cheyenne web site 3. How the new registered PDF can be prefilled on download, completed, submitted and retrieved | |
Gabriele: 15-Mar-2009 | well, for your users i'd let the app itself download the updates and so on. | |
Gabriele: 15-Mar-2009 | even if you don't collaborate with anyone, it's still very useful to have the code in a VCS, and a DVCS allows you doing so without needing to set up a server. | |
Janko: 17-Mar-2009 | I am trying to move my webapp to the real server (which runs on debian linux) ... and I have some problems with making cheyenne work with SQLITE on linux.. did anyone do that already? cheyenne runs fine but when I come to the part that includes sqlite.r it crashes... I installed sqlite3 via apt-get, I copied rebol core into same directory as cheyenne (exec) is and also in same directory where sqlite.r is (because after some testing with >> do %sqlite.r << in normal rebol I saw that it searches it in that directory) ... but I get the same error .. I can't test including sqlite in ordinary rebol fully because when I set the right path rebol says >> feature not available in this REBOL << (I have rebol core 2.7.6) | |
Janko: 17-Mar-2009 | ( just for reference , as Doc figured out and can be seen in SQLite group I was having problems because I was using too old version of libsqlite3.so) | |
Janko: 17-Mar-2009 | I was looking at settings and didn't see anything like that but I saw no-compress in new RSP docs | |
Janko: 17-Mar-2009 | I want server to "flush" responses as fast as it can and client render them without compressing/decompressing ... I might be wrong and I will test if there are any differences, but I had bad exper. when we tried to minimize and *gzip* js libs (like they usually) do the website latency actually became much worse with gzip than without | |
Anton: 18-Mar-2009 | Graham, I think using the image link rather than embedding the image does not really protect the image, and requiring an extra web access to get the signature image is more prone to failure, | |
Anton: 19-Mar-2009 | Oh, I think I understand: Before: Acrobat opens xfdf -> pdf -> image Now: Acrobat opens xfdf -> pdf [image] So before, the client Acrobat opens the xfdf file, which links to the pdf on your website, which links to the signature image on your website. Because of the signature image, authentication is required when linking to the image, and Acroforms used in the PDF limits this to Basic Authentication. Now that you've figured out how to embed the image in the pdf, the client Acrobat opens the xfdf file, which links to the pdf on your website, which has the signature image embedded already. Because of the signature image, authentication is required, but because the image is embedded in the pdf container, authentication is required when linking to pdf. (And I presume still limited to BA?) | |
MaxV: 19-Mar-2009 | Hello everybody! I''m new with Rebol, I hav a small server (VIA M-EPIA) and 512Mb of RAM and linux; Is better Apache or Cheyen? I need only PHP, MySQL and linux script (image magick and ffmpeg), what are your opinions? | |
Dockimbel: 26-Mar-2009 | Re MaxV: If you plan to use *only* PHP and MySQL, I think that Apache is a more logical choice. Cheyenne is built mainly for web application programming in REBOL. Support for PHP is here only to avoid installing another web server if you already use Cheyenne (for REBOL apps). | |
Graham: 28-Mar-2009 | If you want to access a web app from Rebol page: open login-url ; a rsp session is sent to you page/locals/headers/set-cookie contains the cookie page: read/custom login-url compose/deep [ POST (auth) [ cookie: (cookie)]] ; where auth is your authentication string eg. "login=user&pass=mypassword" you are now authenticated and if you now what to access a page in the web app page: read/custom web-app-url compose/deep [ GET "" [ cookie: (cookie)]] where you need to use my modified http protocol that allows you to send cookies with read/custom | |
Graham: 2-Apr-2009 | and did you look at the logs? run cheyenne in verbose mode? |
19101 / 48606 | 1 | 2 | 3 | 4 | 5 | ... | 190 | 191 | [192] | 193 | 194 | ... | 483 | 484 | 485 | 486 | 487 |