bugGNU Octave - Bugs: bug #53005, Variable editor: slow performance...


bug #53005: Variable editor: slow performance with large arrays

Submitter:  Rik <rik5>
Submitted:  Mon 29 Jan 2018 09:49:58 PM UTC
Category:  GUI Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Performance
Status:  Fixed Assigned to:  None
Originator Name:  Open/Closed:  * Closed
Release:  * dev Operating System:  * Any
Fixed Release:  None Planned Release:  None
* Mandatory Fields

Add a New Comment Rich Markup

Jump to the original submission

Fri 02 Feb 2018 07:16:16 PM UTC, comment #30: 

The regression with pr-output has been cleared.  Marking bug as fixed and closing report.

Rik <rik5>
Group administrator
Fri 02 Feb 2018 05:36:39 PM UTC, comment #29: 

"Yes, the autofit options no longer do anything. They should be removed from the dialog."

I've created a bug report for this:


"I'm not sure what's happening with the bad format choice for zeros(50)..."

Continue with this issue at this bug report:


in which I've also noted a bug in which the alignment jumps from left-align to right-align with the first cell edit.

Dan Sebald <sebald>
Fri 02 Feb 2018 05:03:26 PM UTC, comment #28: 

OK, viewing the workspace of a function while debugging and also examining them in the variable editor does seem to work for me.  I'm not sure what the problem was before.

I saw the pr-output problem.  I think it is fixed now.

Yes, the autofit options no longer do anything.  They should be removed from the dialog.  I just didn't know how to do that quickly.

The current auto-format selection only happens when the tab is first opened.  I made that choice because it seemed wasteful to compute the formula on every update.  But this choice is bad when values change, because the format can be wrong.  Or it can be wrong for the values that are visible, because it is based on the full array, not just the visible part.  But if we limit the format selection to the visible portion it would probably be OK to update it each time the refresh happens.  I will try to take a look at that.

I'm not sure what's happening with the bad format choice for zeros(50).  The display in the terminal window is not bad, and the format selection should be the same.  So maybe there is a minimum width being imposed for the variable editor?  I'll check.

Could we close this report now and continue our discussion on other reports about specific issues?

John W. Eaton <jwe>
Group administrator
Fri 02 Feb 2018 12:53:16 PM UTC, comment #27: 

@comment #23 and JWE's first point in comment #19:
Updating cell contents after dbstep or dbnext has been working from the very start, I've used it a lot and indeed it is really extremly helpful.
But I haven't had a chance to check if it still works ATM.

Philip Nienhuis <philipnienhuis>
Group Member
Fri 02 Feb 2018 05:30:20 AM UTC, comment #26: 

@jwe: probably related to the changes to pr-output, but I now get 4 failures when running 'make check'.

For example:

octave:1> format long
octave:2> pi
ans =     3.1416

Rik <rik5>
Group administrator
Fri 02 Feb 2018 01:55:43 AM UTC, comment #25: 

This bug report is about performance.  I think the question of format might better be continued under bug #53000.

I added bug #53044 about adding an extensible right-click menu that could run user-created callbacks.

One can search through the bug reports using the terms "Variable Editor".  The reports which are still open and relevant are

bug #53000 : display format, including of '0'
bug #51849 : clear should not set everything to 0
bug #51847 : V.E. and display of structs
bug #53033 : editing of empty numeric cells
bug #53004 : segfault with very large arrays
bug #53002 : keyboard shortcuts

Rik <rik5>
Group administrator
Fri 02 Feb 2018 01:54:47 AM UTC, comment #24: 

@Rik, "Why don't you file a report"



(I don't think I can add users to the bug's list.)

Dan Sebald <sebald>
Fri 02 Feb 2018 01:30:41 AM UTC, comment #23: 

@jwe: "The workspace view is no longer upated at the debug prompt"

This works for me.  I used the following script

clear all
x = 0;
openvar x

I use dbnext to advance line by line and the value of x is updated both in the Workspace tab and in the Variable Editor tab.  In fact, 'ans' is also updated so everything really seems to be working.

(file #43156)

Rik <rik5>
Group administrator
Fri 02 Feb 2018 01:27:17 AM UTC, comment #22: 

@Dan: Why don't you file a report about adding a "Optimal Width" selection the right-click context menu.  Feel free to add Torsten to the CC list for that with an explanation that we knew he would be able to implement the feature quicker than anyone else.  But don't assign him the bug report, that should be up to him.  He already assigned himself the job of adding configuration of the V.E. shortcuts to the GUI preferences so he isn't slouching.

Rik <rik5>
Group administrator
Fri 02 Feb 2018 01:14:26 AM UTC, comment #21: 

As a point of process, we should break these new feature additions into separate issue reports.  It gets confusing when one bug report twists and turns and ends up solving many things unrelated to the Summary.  Besides, I enjoy the satisfaction of getting to close bug reports which happens more often when the reports are smaller.

Rik <rik5>
Group administrator
Fri 02 Feb 2018 01:01:46 AM UTC, comment #20: 

I'm testing your recent changes.  I'm not quite clear on the intended behavior so I'll just give general observations.

It sounds from what you wrote that no longer is automatic Autofit used (or "continuous" autofit).  So am I understanding correctly that the "Autofit" checkbox and "By column" selector in preferences no longer control anything?  I.e., that they should be removed and just leave "Default column width"?  I guess I'm just wondering if with this change and those to come it really matters if there is a autofit selection in the preferences.  If the autofit is now fast, why not just always run autofit when opening the variable in the V.E. tab.

"But it would be nice to have a button to force resizing to happen. It can matter because if the data switches from 1.23456 to 1.2345e+22, something usually ends up cut off."

Several of us mentioned buttons on the header or right-mouse-click to activate the search feature.  None of that has been done and that needs to be added.  Should we add Torsten to the list since he's generally the one who oversees GUI mods?

Now, as to the autofit behavior, the one thing we have right now is the double-click to autofit feature that Philip mentioned.  I use that, and the autofit doesn't seem quite right.  As an example, do

x = zeros(50);
openvar x;

There is a great deal of whitespace to the left of the zero when there could be more columns autofit in the view.  Also, if I shrink the width of column 1, say, down to nearly nothing and double-click the line between column 1 and 2, the autofit occurs and goes back to that large-pre-whitespace width.  If I expand the first column so there is a large amount of white space after the zero and double-click the line the the column goes back to the original autofit size.  So it seems that there is more pre-whitespace than necessary or some type of minimum limit on the column width.  Is this happening because the code attempts to align the numbers, i.e., its format is 10 character width numbers so that is somehow the minimum allowable size?

"It would be nice if more than one tab could be visible at once. That way you could easily watch multiple variables while debugging. Super killer feature! Is that possible with the Qt tab widget?"

Certainly, one could derive an object and hand-roll such a thing, but it might already exist.  There could be multiple docking, which is sort of like having multiple V.E.s (i.e., each table gets its own toolbar with copy-paste-print-etc.) but I don't know if that's desired because it would clutter the space too much with all kinds of windows.

However, there looks to be something very close to having multiple tables contained in a single window and just one toolbar in the window.  Go to the main window and open something in the editor and there will be tabs at the bottom "Command Line", "Editor", and possible some other tabs.  In addition to switching between tabs, one can grab/drag the sub window and it becomes undocked and floats until situating it somewhere within the main window.  In other words, what was tabs to switch between now becomes two subwindows viewable at one.  I would think such a thing could be done with the V.E., i.e., the tabulated view could be changed to having multiple tables visible at the same time.

Keep in mind there would only be one variable editor toolbar, so there needs to be some way of indicating what table the toolbar actions will act on.  I'd think that making the "active" table have a white background and grey out all the other tables would be good.  If one clicks in an inactive table, that table's background would become white, etc.

Dan Sebald <sebald>
Thu 01 Feb 2018 09:54:23 PM UTC, comment #19: 

I pushed four new changesets that I think improve the performance and appearance considerably.  The performance should be OK now regardless of variable size, and the appearance should be good for moderately sized arrays.


There's a lot of work left to do, but I'm generally happy with the structure now.  The code in pr-output.{h,cc} could use some love.  I intend to try, and to get data lined up neatly in columns where possible (currently I think lining up numbers on the decimal point only works for double and double complex data).

Some other random things that may not have been discussed but that I've noticed:

  • The workspace view is no longer upated at the debug prompt.  Is there a bug report about that?  If it were, then you could use the variable editor to easily track changes to variables as you step through some code in the debugger.  This would be a really great feature to have.

  • It would be nice if more than one tab could be visible at once.    That way you could easily watch multiple variables while debugging.  Super killer feature!  Is that possible with the Qt tab widget?

  • Columns are automatically scaled now (at least for double and double complex values) when the tab is created.  I agree that resizing on every update is bad.  But it would be nice to have a button to force resizing to happen.  It can matter because if the data switches from 1.23456 to 1.2345e+22, something usually ends up cut off.

  • There are many possibilities for cool features like filling rectangles with a value, deleting or inserting rows or columns (more than one at a time), or inserting another matrix using a command, not just by pasting.  It would be nice to have a generic interface for this so that people could easily add their own actions that are commands defined in .m files.

Anything else?  I hope this works better for those of you who have been testing things recently.

John W. Eaton <jwe>
Group administrator
Thu 01 Feb 2018 04:25:14 PM UTC, comment #18: 

Wow, comment #17 at 2:26 AM PST.  That's really burning the midnight oil; I can see why you need some sleep.

Rik <rik5>
Group administrator
Thu 01 Feb 2018 10:26:46 AM UTC, comment #17: 

The real performance problem is our QVector<cell> thing.  It's totally unnecessary, and because we resize it to the full size of the table before anything has been displayed, we are wasting a lot of memory and time just to fill it with empty objects that can later be used to hold the table data.

We can just eliminate it entirely and the tableview widget will cache whatever it needs for display.  When we need other info about a table element, we can just compute it instead of trying to cache it.  My quick check shows that performace will be a lot better this way.  And the implementation will be simpler if we eliminate our cache of "cells".

I can take care of this change after I get some sleep.

I can also see a path to computing formats in the same way as we use for the terminal display so that decimal points are lined up.  For that, we may want to limit the application to arrays below a certain size, and if so, make that limit configurable.

More "tomorrow".

John W. Eaton <jwe>
Group administrator
Thu 01 Feb 2018 09:12:51 AM UTC, comment #16: 

Well, we're even then - I didn't know about 'right-click on header -> "Optimal Width"'  :-)

The double-click-on-separation-lines-to-autofit-cell-rows/-columns feature is a built-in in all table interfaces I know about; another nice example is the uitable tool (patch #9084).
The good thing is that it works on just one column or row so it is doesn't demand so much CPU time as processing an entire array.

So it seems the Autofit preference we currently have is merely a convenience for e.g., when first displaying an array in the V.E.; the actal functionality was already there.

Philip Nienhuis <philipnienhuis>
Group Member
Wed 31 Jan 2018 10:42:47 PM UTC, comment #15: 

I didn't know about the double-click interface.  That is nice.  I think I would still like to see the option in the right-click menu because I think many people would look for it there.

Rik <rik5>
Group administrator
Wed 31 Jan 2018 09:44:32 PM UTC, comment #14: 

Sure'nough; I didn't know that double-click existed, and it works for rows too.  That's column/row basis.

I'm looking at the V.E. and it has a dock with some widgets.  Alongside the plot-icon drop down menu would be a good place for the global auto-fit menu.

So, the global auto-fit would run on the whole table.  (Should the autofit work to make all column widths the same or allow them to adjust according to its own column entries?)  The double-click works on a column/row basis, good.  Another possible auto-fit method I could see is that in the right-click drop-down menu (one exists already so adding "autofit" shouldn't be too much work) the feature applies to just the selected items.  In other words, say I don't want the autofit for the whole column (because maybe somewhere in a non-visible part of the table there is a long string somewhere), but I want the column to adjust to the autofit width of a particular selection that I can see.  That gives the user a bit of control over the visual spacing of just the contents that are visible within the table.

Dan Sebald <sebald>
Wed 31 Jan 2018 09:23:58 PM UTC, comment #13: 

Double-clicking on the separation "line" between the column headers will also optimize the column width, in Calc and in the variable editor.

Philip Nienhuis <philipnienhuis>
Group Member
Wed 31 Jan 2018 06:49:38 PM UTC, comment #12: 

What Dan is describing is very similar to the way a spreadsheet like LibreOffice Calc works.  Say I have a long number like "123456789".  I shrink the column that contains that number to a width I like.  The user is in control so Calc allows the width I have set to remain, but it now changes the display to "###" to indicate that there is not enough room do display the actual number.  At that point, I can right-click on the column and choose "Optimal Width" and Calc will automatically pick a correct size for display.

That's a pretty good interface.

Rik <rik5>
Group administrator
Wed 31 Jan 2018 06:44:35 PM UTC, comment #11: 

Limiting the size is fine, but I think the better alternative is to make the feature user-driven, not automatic auto-fit.  I can see how what I'm saying about "auto auto" is somewhat obscure.  Imagine there is a button in the header of the V.E.  The user presses the button and Autofit does its job.  (Or if a button isn't preferred, make the action a right-mouse-click which creates a local drop down menu of which "autofit" can be selected.)

The Autofit feature shouldn't run again and again with each processing command.  I find that kind of annoying if I first manually slide the column widths to what I like, run a command and then Octave shrinks all those column widths again.  If I have my table view as desired, run a command, then the table is showing a different collection of columns because of the resize I have to go searching for the columns that were in view previously.

But I can see the usefulness of what I described in the first paragraph, i.e., that as a user I look at the V.E. table and decide it doesn't look correct so I manually initiate an Autofit.  If I happen to have 1000x1000 array and that takes 8 seconds, fine.  It's just once and until I press the Autofit button again, there is no apparent lag in processing even though the V.E. is updating the contents of the cells.

Dan Sebald <sebald>
Wed 31 Jan 2018 05:50:06 PM UTC, comment #10: 

@Dan comment #7
Autofit turns out to be quite useful when editing e.g., cellstr arrays, where cells may have widely different widths (I actually used it quite bit for that purpose). Merely for inspection, I didn't actually edit cells to make them wider, so I don't know if the VE automatically would widen the affected cells then.

I like JWE's idea of setting an array size limit (maybe even configurable) above which Autofit would be disabled for that array.

Philip Nienhuis <philipnienhuis>
Group Member
Wed 31 Jan 2018 04:38:10 AM UTC, comment #9: 

I forgot to add the third screenshot intended for


Autofit_Result_Screenshot_from_2018-01-30_22-16-35.png attached.

Dan Sebald <sebald>
Wed 31 Jan 2018 04:36:24 AM UTC, comment #8: 

I've done some testing in LibreOffice Calc to see what happens with a 1000 x 1000 matrix in a spreadsheet.  You can try this as well.  Attached are some screenshots.

Go to Sheet::Fill Cells::Random Number... and enter a range of $A$1:$ALL$1 then OK.

In that small Navigotor dialog box, click on the top-left Data Range icon.  Note that at the bottom of the LibreOffice Calc window is a "1000 rows, 1000 columns selected".  Now go to Format::Autoformat Styles... window and unselect all the options except for "AutoFit width and height".  Select OK, then mouse-click in a cell somewhere, move the mouse wheel up and down a bit...the wait.

This is an example of the result I see where there are a few columns autofit wide compared to most columns.

OK, as for time, where I noted above that one should wait after selecting AutoFit, I'm seeing a delay of 18 seconds, yes 18.  In Octave's Variable Editor (V.E.) it seems to be a 1/2 or 1/3 fraction of that time probably because L.O. Calc is doing both columns and rows.  Octave V.E. does only columns.

In summary, I don't think there is anything good/bad about Octave's implementation of this Autofit feature, it's just the nature of the spreadsheet-like problem with so much data to loop through.  Given that, I think the answer here is to not have the Autofit feature as an automatic thing, configured in "Preferences".  Instead, take that out of Preferences and instead add the Autofit to the V.E. in some way as a one-time selection by the user.  How?  I don't know.  Some radio button in the header?  Some right-mouse-click-and-drop-down-menu selection?

Dan Sebald <sebald>
Tue 30 Jan 2018 10:37:03 PM UTC, comment #7: 

I just thought: the idea of dynamically adjusting the data content of the displayed table may be a no-go in the sense that the V.E. sliders no longer work in that scenario.

I'm trying out some things in the current V.E.  One thing I notice is that auto-fit works in terms of column-width but not in terms of row height.  I select "Uniform" auto-fit in the Preferences, select OK and when I look at the Preferences again it is back to "By Column".

The main observation though is that when I turn off "Autofit" there is no lag in refresh and the V.E. works great, e.g.,

>> x = rand(1000);
>> x(1:5,1:5) = x(1:5,1:5).^2;

As far as a solution, how about simply getting rid of Autofit feature or perhaps redefining what it means to something else.  For example, autofit might just apply to when someone edits the contents of a cell.  I'd say to try an make the feature something inherent to frameworks table behavior, as opposed to something that loops through each individual cell and update width (if that is what's currently done).

As an example, the current behavior the following is a bit odd.  Turn on Autofit (undock the V.E. to see what is happening) then type:

>> x = zeros(1000);
>> x(999,999) = 123456789;

As far as what's visible, why should every column be widened the same as 999?

Anyway, can one come up with a meaning for Autofit that is still useful but not so global?

Dan Sebald <sebald>
Tue 30 Jan 2018 10:33:47 PM UTC, comment #6: 

"So, yeah, one approach is to fill in the whole data model and let the GUI framework deal with things"

I think you misunderstand what I mean by getting the full value back and what is done with that in the model.

A copy of the octave_value object is returned, but the model/view actually works with a QVector of objects for each cell in the display.  Those should only be filled in with values as needed.  Not all at once on each update.  If that is happening, I think it's an error.

Further, we can limit this to tabs that are actually visible, but then we need another action so that we update when tabs become visible.

It's certainly possible to edit something while Octave is busy.  But the action of that edit will be queued until Octave is otherwise idle.

John W. Eaton <jwe>
Group administrator
Tue 30 Jan 2018 09:01:50 PM UTC, comment #5: 

"But then we get the full value back so we update everything on the next display update...Even so, the variable editor should only have to update the elements that are displayed, not all elements. That is almost sure to be less than the full 1,000,000 elements for a 1000x1000 array."

Exactly.  What is currently visible on the screen in the table is only a small subset of the overall matrix, so when some internal processing is done, the GUI only needs to retrieve a small subset to display or re-display.  However, there are a couple complicating factors.  First, I notice that the table update is a complete restructuring of the layout.  That is, when I expand or contract the column spacing in the variable editor table, that whole layout is shrunk back small after some processing initiated from the command-line tab.  In some sense, that is kind of annoying for the user.  It might be better to try maintaining the same structure and just update the contents of individual cells.  Second, the matrix could be made smaller (bigger) with the processing, e.g., going from 10x10 to 5x5 in which case some cells are going to be lost (added).  If that cell layout remains constant, we at least know what the maximum number of columns/rows and we then have a valid range.

So, yeah, one approach is to fill in the whole data model and let the GUI framework deal with things, but I think the application dictates that can't be done when there is this background process that could change any contents of the table.  If there were some callback or listener (not going to happen because too cumbersome) for which the background process knew what elements to update in the GUI data model, that would be one solution.  But I think the only option is for the GUI to be programmed to only display a subset of data in the table.  It complicates the programming, but not too bad.

Making the cell widths and heights static (as opposed to readjusting with every data update) could help in that programming.  However, for auto-fit (as I understand it) one might need a strategy of retrieving data that, say, starts in the upper-left corner and keeps growing the matrix until all visible space is used up:


x(16,20) x(16,21) x(15,21)

x(17,20) x(17,21) x(17,22) x(16, 22) x(15,22)


if you follow what I'm getting at.

"Currently we don't have a way to mark a variable (or an element of a variable) as modified and I'm not sure we want the overhead of doing that just in case it might be open in a GUI variable editor tab."

Yes, that is what I meant above by "not going to happen"...way too cumbersome and disrupts the concept that the GUI shouldn't be too intertwined with the core.  But I don't know what you have in mind for "open in the GUI variable tab".  Are you thinking that a background process could be running while the person is attempting to edit the variable in the V.E.?  I don't know if that's a good idea.  What might be best is that when a GUI command line issues a command to the core the GUI greys out all the variable editor tables.  The user can't initiate something in the command-line tab if they are editing in V.E., so I don't think that's a problem.  Then when the background core process is complete, turn off the grey background in the V.E. and update the contents.  If the user wants to monitor what's happening in the V.E., s/he will have to introduce a "pause(0)" in their programming loop somewhere.  The variable editor might flash from grey to white momentarily, but that would be a cue to the person watching the screen that the variable contents possibly changed.

Dan Sebald <sebald>
Tue 30 Jan 2018 07:28:01 PM UTC, comment #4: 

Yes, we only perform the indexed assignment of the single value.

But then we get the full value back so we update everything on the next display update.  That part might be easy to fix.  But you also have to consider the possibility of the variable changing in the interpreter, independent of the editor.  Currently we don't have a way to mark a variable (or an element of a variable) as modified and I'm not sure we want the overhead of doing that just in case it might be open in a GUI variable editor tab.  So the variables in the editor are refreshed at the prompt.  Maybe we can do better.  Do you have a concrete suggestion that doesn't impose a performance penalty even when the variable editor is not used?

Even so, the variable editor should only have to update the elements that are displayed, not all elements.  That is almost sure to be less than the full 1,000,000 elements for a 1000x1000 array.  More like a few hundred or a thousand.  But maybe there is a mistake and it is updating all of them for some reason.  It must currently do that if autofit is enabled.  Do you have that feature enabled?

John W. Eaton <jwe>
Group administrator
Mon 29 Jan 2018 11:34:34 PM UTC, comment #3: 

That is rather slow, even the initial creation and display of the 1000 x 1000 table.  That's big, but not huge.  I can imagine a spreadsheet of that size.

As far as update, my thought was that given a general way of processing commands in the background, the variable editor would do something like

[V.E. modifies the value and initiates an update]
[The innards issue an "x(i,j) = newvalue"]
[If there is a success of the above command, then update the cell contents by calling "x(i,j)"]

I would hope that the Qt table can quickly handle the update of that value rather than have to fill in the whole table again.

Dan Sebald <sebald>
Mon 29 Jan 2018 10:06:56 PM UTC, comment #2: 

Yes, it is called every time Octave returns to the prompt.

The reason is that we currently have no way to tag a variable when it has been modified.

I think I can skip the update if the tab is not visible, but I remember having some problems with that so I undid my attempted change.

If the update is limited to only the cells that are visible, then it shouldn't take too much time no matter how large a variable is unless you have a really large monitor and are using a tiny font.  :-)

John W. Eaton <jwe>
Group administrator
Mon 29 Jan 2018 09:57:24 PM UTC, comment #1: 

It really does seem as if the display code is being called every single time Octave returns to the prompt.  If I adjust a column size so it is not the Autofit value, and then just <Return> in the Command Window then all of the GUI pauses for a few seconds while it updates things and then snaps the column size back to the Autofit value.

Rik <rik5>
Group administrator
Mon 29 Jan 2018 09:49:58 PM UTC, original submission:  

With large arrays there seems to be a slowdown whenever the array is updated.  This problem is only present when the preference item "Autofit" is checked.

Sample Code:

x = rand (1000);
openvar x
# There is a delay as something is calculated and then the Variable Editor shows x
y = 1
# There is a delay, approximately the same length as the first one
z = 2
# There is the same delay, after every statement is executed.  It appears as
# if at the end of each event loop the "openvar" command is being re-executed
# despite the fact that I haven't changed 'x'.

Rik <rik5>
Group administrator


(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:


Depends on the following items: None found

Items that depend on this one: None found


Carbon-Copy List
  • -email is unavailable- added by sebald (Posted a comment)
  • -email is unavailable- added by jwe (Posted a comment)
  • -email is unavailable- added by rik5 (Submitted the item)
  • -email is unavailable- added by rik5
  • -email is unavailable- added by rik5

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only group members can vote.


    Follow 9 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2018-02-02 rik5 StatusReady For Test Fixed
        Open/ClosedOpen Closed
    2018-02-02 rik5 Attached File- Added tst_debug.m, #43156
    2018-02-01 jwe StatusConfirmed Ready For Test
    2018-01-31 sebald Attached File- Added Autofit_Result_Screenshot_from_2018-01-30_22-16-35.png, #43131
    2018-01-31 sebald Attached File- Added Filling_1000_x_1000_Cells_With_Random_Screenshot_from_2018-01-30_22-07-33.png, #43129
        Attached File- Added Select_And_Autofit_1000_x_1000_Cells_Screenshot_from_2018-01-30_22-10-49.png, #43130
    2018-01-29 rik5 Carbon-Copy- Added jwe
        Carbon-Copy- Added philipnienhuis

    Back to the top

    Powered by Savane 3.13-b921.
    Corresponding source code