 My speech will be oriented towards how has Cryptforge been implemented and not about functionalities, of much less, about functionalities. Last year I used the same first cover page this year, except that the Python word was between square brackets, so Python was announced, and this year the brackets have been removed and my speech will be mostly about the implementation of the Python interface towards the Scriptforge API. Scriptforge is a set of 21 services, each having a collection of methods and properties, as you heard already, for a total of above 400 methods and properties. The total number of lines of code is in 7.2 plus minus 33,000, hopefully where written and readable looks. The services here are presented in functional categories. The first one is about enhancement of the basic language. A number of things that we have in Python we do not have in basic, and those services are not or only partially available in Python. The second category about documents is manipulation of documents and manipulation of data, especially in calc and base documents. Then about user interfaces, mainly by using basic dialogues, only basic dialogues, but available from Python as well, and forms stored in draw pages, supported forms may reside in base, calc, or writer documents. Also utilities about a number of things, for instance about what is the actual running environment, or about translation using portable object formats. The basic service in utilities is, it's a paradox, only available from Python. I do not want to give more details here about the content of the services. Everything is available in the standard HALAP pages, at least in English. So you have there the URL, just go to there and read. Now in 7.2, technically each service is stored in a separate module. Modules are gathered in libraries, one core library, scriptforge, and a number of associated libraries. Only scriptforge needs to be loaded by the user. The number of libraries may evolve with the time. So we can have more libraries in the future, it's quite easy to do. Services with an asterisk have been improved, and with a double asterisk have been significantly improved in 7.2 versus 7.1. And services in red are new in 7.2. You have here the elements that are stored in the LibreOffice repository. Below additionally, you have there a number of elements that are available in our, let's say, private GitLab repository. In particular, there exists a test suite. It is implemented both in basic and Python, but it is not integrated today into the LibreOffice repository. The target of the project, why have we built a new library of scripts? Well, first of all, with a few exceptions that we will see, propose the same API both in basic and Python. So the end user should not be aware when he's executing either basic or Python script. He should have the same user interface, also for arrows or several boxes, whatever. You know knowledge is not necessary. However, some properties return anywhere you know object, and as such facilitate access to you know instances. The API is inspired by Microsoft Extensions to VBA, also by a huge number of Python built-in functions, also other PHP and other IDs that we had, also by a pre-existing library known as the basic primitives that was designed by Jean-François Nifnike. So in the beginning, we had the question, should we implement the API in basic or in Python? There were a number of prerequisites to decide what we should do. We wanted object-oriented API, basic is obviously weak in that matter. We cannot have inner returns in basic and we have a constraint that a basic object should be created inside the library. Afterwards, it can however be used anywhere. We needed persistent memory, why is that? Well, scripts are not only executed in batch. They are often executed in start-stop mode. It's just thing to events, so scripts are executed intermittently. Also to store, let's say error messages in the user's language, or to store a lot of debug info, or to keep a list of services that are available somewhere, we needed persistent memory basic as a good solution for that with global variables that last as long as the LO session lasts. And we had a lag there to use easily that kind of thing in Python. And we needed namespaces because when we make an API with a huge number of functions, we must be able to segment the names and basic is very bad in that matter. So in the first step, we were very impressed. We could not make the choice and we had here a number of reflections about namespaces in basic. Well, to be able to define completely a function, we need to qualify it with global scopes, for instance, the library name, module function. This is the full qualification that is minimum to prevent completely collisions. But this is also not known probably. Well, it's quite easy to define a module as basic object. And you can assign a module to a variable and you can reassign it. And from that variable, you can call a function like you see here. So we revised our first judgment and we decided to make the API mainly in basic. Okay, Street Forge is said service oriented. What does it mean exactly? Well, everything starts from the already described create script service function. In basic or Python, same syntax. An object is returned on the object, apply methods and properties. So writing user scripts is very easy. You have here comparison of copy file, delete folder, methods on the same file system service that is proposed in the API. Create script service returns either a real basic or Python object referring to a module or it returns a basic class instance. In that case, arguments can be passed in the create script service method itself. Well, what happens behind the scenes? I don't want you to give details. You can read it on your own if you want later. The idea is that we defined, in fact, a framework making the addition of a new service very straightforward. And that's important to understand. So adding a new library, new service is really easy. Okay, now the syntax must be identical, but there are also other things to consider when we compare the implementation basic and Python. So first of all, we need an identical programming interface so that the user is not aware of executing a basic or a Python script. To call a method from one word to the other one, we use the script provider mechanism and we must be able to do that in both directions. There were a number of limitations in that mechanism. Not all data types are processed equally. Critical updates because any language or any database or call gets on and so on. Every application has its own internal representation of dates and that's an issue. Also native objects cannot be transferred from one word to the other. You cannot transfer a basic object to Python and you cannot transfer a Python object to basic. So we had to define a protocol. The protocol is not very complex but has to handle a number of things like data types. Example, all dates are transferred both for the arguments or for the return value as you know, date, time, data types. Are interfaces seen from the user scripts really identical or are they similar? Example, basic is fully case-insensitive, is that managed? Well, just the question that we had. Well, if you look at the code that is here, quite easy. Well, in Python, you just have to import the createScriptService() function from a module that is shipped with allow called scriptforge.py. We create an instance of the database service and we store that in variable A. That opens the database that you probably know as bibliography and we want to have the execution of a select statement to store as an array or the tuple of tuples, in fact, in B. The rows contained as a result of that SQL statement. What do you have in scriptforge.py, sorry, well, quite easy. createScriptService() is here a function at the bottom of the module. You have the SFDatabase class. And a few, really a few definitions of the service. Implementation is done in the basic world. The properties are listed in a dictionary and the item part is just a boolean value indicating whether the property is editable or not. Where is this property and it is not editable. And you have then the method getRows() with its arguments and its default values. And getRows() executes just a standard exec method with a number of parameters and we'll see what this gives. In fact, the SFDatabase class is a subclass of SFServices. And there is the magic. In fact, you have there a number of quite tricky internal methods. The double underscore methods in it getAttribute and setAttribute are not that easy. But for instance, care for having a certain freedom about property names, method names and arguments. So you can use lowercase, propercase or camelcase. Whatever you want or you prefer. Common error handling, you saw probably that the deskier statement given as argument of getRows() is strong. Well, in both cases, you call that from Python, you get the same error message. You see by the way how user-friendly the error messages are. And we have, we had already in basic unlimitation, it was impossible for Scribforz to report the line number of the code line that raised error. That's why we define in the protocol when basic reports an error. Well, Python processes that error and the exception and love Python displays the full stack of lines of code which play the role in the error. And one of them, it's here line 27 in module test SF dot py can be listed. So with Python, we have more information when the scripts go wrong. The counterpart of the, in the protocol at the basic site is implemented in Python dispatcher function. And that function, well, it's quite simple. It processes the input arguments, for instance, dates, call the correct property or method and return what must be returned also after enrichment. I mean here that, for instance, the return values are of course the value itself. But eventually, also the var type of the return value and also other things. This makes reinterpretation of the return values at the pattern, at the Python site possible, if necessary. So we use internally basic objects. And in fact, at the Python site, the object reference, sorry, is the entry of the basic object in an objects cache that is stored in a persistent memory. For debugging, we use in both environments a function called debug print. It's similar to debug dot print in VBA, but we could not make a debug service because print is reserved for both in Python and in basic. So we use here debug print that we can call from both environments. It's a part of the exception service. What does debug print? Well, it stores and locks records in the persistent memory and those records that those records can be displayed in a model or a non-model so-called console. Well, what is specific here? Python and basic share, the same console. This is an example if we have a piece of code written in Python and another one written in basic. They are identical, but one script is triggered when mouse hovers one dialog console and the other script is triggered when the mouse hovers another console. Both write in the console. Well, you reach this, you can have a mix of messages or debug traces where the origin is in basic or in Python, you can mix them smoothly in the same script for console. An alternative to this is to use a Python shell console. It requires that the AppSore extension is installed. This is, AppSore is for alternative script organizer for Python. You can run immediate statements including statements that call script for API methods. And you can call from basic. You have done all the print statements that you have in your Python code will be issued in the Python shell console and you can have from basic a specific Python print method that will write in the same console here. Chopia, just a quick notice, five minutes left. Okay, well, a bit faster than. Okay, we have also helpers that we defined for both environments. Here, a number of functions. An example here is string. You can hash a string, but it's done thanks to the import of Ashley in a specific script for helper.py. And you can have also a number of basic functions that are made available to Python. The example of message box was already seen with Raphael before. But the number of basic functions that are implemented to be called also from Python is larger than that. Because the two functions are most of, for most of them, well known and quite easy to use. Everything is in the documentation. There is also a special page about how to script in Python for a script for. What will be new in the future, I wanted to stress that also. Well, here we will have a new chart service with a scenario here. The scenario is that we extract data from a database. We copy what we extracted from the database in Calc. Document, the Calc document is hidden and so it's everything happens in the background. We design and customize a chart. We export it to a file and the file can be displayed with a few lines, you see, in image control of a dialog. What we also plan for the future, the first four items are already in master. Also outputs, output documents of export documents to PDF and to printers with a number of options. We will have automatic translation of everything what is fixed content in a dialog into the native language of the user. We will have table consoles in dialogs. The other IDs that we have are already specified and there exist prototypes of them, but they are not yet developed as such and not yet in master in any repository. We think to have SF widgets library with especially pop-up menu service, a functionality that is often requested in forums. We would like to have a number of service about roundings, unit conversions, it's especially designed for managing double variables and also a region service to know, for instance, what time it is in Tokyo when it is 12 o'clock in Brussels or on the Greenwich Meridian and to have a UTC know function, for instance. Okay, the end was a bit faster, but I think I'm still in time. Thank you very much for this clear and great talk. Very great to see this work on Scriptforge. I think as I'm a Python programmer by myself, it's really really nice to see that this is shipped with 7.1 and 7.2 and as you mentioned for the further versions. Thank you very much.