<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="https://ogobrecht.com/feed_style.xsl" type="text/xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <tabi:metadata xmlns:tabi="https://github.com/welpo/tabi">
        <tabi:base_url>https:&#x2F;&#x2F;ogobrecht.com</tabi:base_url>
        <tabi:separator>
            •
        </tabi:separator>
        <tabi:about_feeds>This is a web feed, also known as an Atom feed. Subscribe by copying the URL from the address bar into your newsreader. Visit About Feeds to learn more and get started. It&#x27;s free.</tabi:about_feeds>
        <tabi:visit_the_site>Visit website</tabi:visit_the_site>
        <tabi:recent_posts>Recent posts</tabi:recent_posts>
        <tabi:last_updated_on>Updated on $DATE</tabi:last_updated_on>
        <tabi:default_theme></tabi:default_theme>
        <tabi:post_listing_date>date</tabi:post_listing_date>
        <tabi:current_section>Plug-in</tabi:current_section>
    </tabi:metadata><title>Ottmar’s Notes - Plug-in</title>
        <subtitle>Mainly about Oracle APEX and PL&#x2F;SQL</subtitle>
    <link href="https://ogobrecht.com/tags/plug-in/atom.xml" rel="self" type="application/atom+xml"/>
    <link href="https://ogobrecht.com/tags/plug-in/" rel="alternate" type="text/html"/>
    <generator uri="https://www.getzola.org/">Zola</generator><updated>2021-10-13T00:00:00+00:00</updated><id>https://ogobrecht.com/tags/plug-in/atom.xml</id><entry xml:lang="en">
        <title>Generate APEX plug-ins on the command line</title>
        <published>2021-10-13T00:00:00+00:00</published>
        <updated>2021-10-13T00:00:00+00:00</updated>
        <author>
            <name>Ottmar Gobrecht</name>
        </author>
        <link rel="alternate" href="https://ogobrecht.com/blog/generate-apex-plug-ins-on-the-command-line/" type="text/html"/>
        <id>https://ogobrecht.com/blog/generate-apex-plug-ins-on-the-command-line/</id>
        
            <content type="html">&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;&#x2F;h2&gt;
&lt;p&gt;Everyone who develops plug-ins for APEX knows the problem: Once a plug-in is finished, future maintenance is usually just a matter of uploading updated JavaScript files to the plug-in and finally downloading the plug-in to make it available to others. This can be a very time consuming process when troubleshooting or implementing a new feature.&lt;&#x2F;p&gt;
&lt;p&gt;So for my latest open source project, I thought about how to shorten the whole process. I already had a file watcher and a build script running anyway, which, when source files are changed, merges the entire project into a single SQL install script. The plug-in was just about updating a JavaScript file (normal and minified). The PL&#x2F;SQL code for the plug-in is in a package and only referenced - this is also a good approach for performance reasons (&lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.danielhochleitner.de&#x2F;2018&#x2F;02&#x2F;11&#x2F;oracle-apex-plugin-performance&#x2F;&quot;&gt;Blog post by Daniel Hochleitner on the topic&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;creating-a-template-from-the-existing-plug-in&quot;&gt;Creating a template from the existing plug-in&lt;&#x2F;h2&gt;
&lt;p&gt;So I downloaded the finished plug-in once and stored it as a template in the project directory. Then I looked at how the files are stored in the SQL script of the plug-in:&lt;&#x2F;p&gt;
&lt;figure&gt;
    &lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;sql&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;begin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    wwv_flow_api.g_varchar2_table :&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; wwv_flow_api.empty_varchar2_table;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    wwv_flow_api.g_varchar2_table(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;) :&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;766172206f69633d7b6f633a7b7d2c6f613a7b7d2c6c6e3a7b7d7d3b6f69632e6c6e2e6572726f723d312c6f69632e6c6e2e7761726e696e673d322c6f69632e6c6e2e696e666f3d332c6f69632e6c6e2e64656275673d342c6f69632e6c6e2e74726163&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    wwv_flow_api.g_varchar2_table(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;) :&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;653d352c6f69632e746f537472696e673d66756e6374696f6e2872297b666f7228766172206f3d22222c653d303b653c722e6c656e6774683b652b2b296f2b3d30213d3d653f2220223a22222c226f626a656374223d3d747970656f6620725b655d3f6f&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    wwv_flow_api.g_varchar2_table(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;3&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;) :&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;2b3d225c6e222b4a534f4e2e737472696e6769667928725b655d2c6e756c6c2c32293a6f2b3d725b655d3b72657475726e206f7d2c6f69632e696e69743d66756e6374696f6e28297b6f69632e6d6573736167653d66756e6374696f6e28722c6f2c652c&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;* snip *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    wwv_flow_api.g_varchar2_table(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;14&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;) :&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;2e6c6e2e6572726f722c722c6e2c692e737461636b292c21317d7d3b&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;end&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;begin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    wwv_flow_api.create_plugin_file (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        p_id           &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; wwv_flow_api.id(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;37195131994077352&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        p_plugin_id    &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; wwv_flow_api.id(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;36295154520053378&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        p_file_name    &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;console.min.js&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        p_mime_type    &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;application&#x2F;javascript&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        p_file_charset &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;utf-8&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        p_file_content &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; wwv_flow_api.varchar2_to_blob(wwv_flow_api.g_varchar2_table) );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;end&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
    &lt;figcaption&gt;Example of a file in the SQL installation script of a plug-in&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;It looks like we have to encode the files somehow - but how? If you take a closer look at the characters, you will notice at some point that only the digits 0 to 9 and the letters a to f are used. So it seems to be a hexadecimal encoding - with 200 characters in each block.&lt;&#x2F;p&gt;
&lt;p&gt;Ok, then in the template we replace the first anonymous PL&#x2F;SQL block with a placeholder:&lt;&#x2F;p&gt;
&lt;figure&gt;
    &lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;sql&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;#CONSOLE_JS_FILE_MIN#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;begin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    wwv_flow_api.create_plugin_file (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        p_id           &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; wwv_flow_api.id(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;37195131994077352&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        p_plugin_id    &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; wwv_flow_api.id(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;36295154520053378&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        p_file_name    &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;console.min.js&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        p_mime_type    &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;application&#x2F;javascript&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        p_file_charset &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;utf-8&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        p_file_content &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; wwv_flow_api.varchar2_to_blob(wwv_flow_api.g_varchar2_table) );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;end&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
    &lt;figcaption&gt;Example of a file in the plug-in template with placeholder&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;Now we need some code to replace the placeholder with the converted source file.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;javascript-helper-functions-for-conversion&quot;&gt;JavaScript helper functions for conversion&lt;&#x2F;h2&gt;
&lt;p&gt;Since I implemented the file watcher and other scripts with Node.js&#x2F;npm, it was obvious to solve this in JavaScript as well. First the needed modules and a md5 hash function:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant z-js&quot;&gt; fs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; require&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;#39;fs&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant z-js&quot;&gt; UglifyJS&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; require&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;#39;uglify-js&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant z-js&quot;&gt; crypto&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; require&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;#39;crypto&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; toMd5Hash&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; function&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; crypto&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;createHash&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;#39;md5&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;update&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-variable z-other z-readwrite&quot;&gt;(string)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;digest&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;#39;hex&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;let&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt; consoleJsCode&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt; minified&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt; version&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt; md5Hash&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt; conf&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then we need a helper function that breaks a string into blocks of 200 characters and returns it as an array:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; toChunks&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; function&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;text&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; size&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant z-js&quot;&gt; numChunks&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; Math&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;ceil&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(text&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;length&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-source&quot;&gt; size)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant z-js&quot;&gt; chunks&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-new&quot;&gt; new&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; Array&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-variable z-other z-readwrite&quot;&gt;(numChunks)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;let&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt; start&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt; numChunks&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ++&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt; start&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-source&quot;&gt; size)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-source&quot;&gt;        chunks[i]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; text&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;substr&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-variable z-other z-readwrite&quot;&gt;(start&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-source&quot;&gt; size)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt; chunks&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Finally, our actual function, which hexadecimally encodes a string (read file) and puts it into the required SQL script form:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; toApexPluginFile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; function&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;text&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant z-js&quot;&gt; hexString&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-new&quot;&gt; new&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; Buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;from&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-variable z-other z-readwrite&quot;&gt;(text)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;toString&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;#39;hex&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant z-js&quot;&gt; chunks&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; toChunks&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-variable z-other z-readwrite&quot;&gt;(hexString&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 200&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt; apexLoadFile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;begin&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;        &amp;#39;  wwv_flow_api.g_varchar2_table := wwv_flow_api.empty_varchar2_table;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;let&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; chunks&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;length&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ++&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-source&quot;&gt;i)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt;        apexLoadFile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; `  wwv_flow_api.g_varchar2_table(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;) := &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt;chunks&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;`&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt;    apexLoadFile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;end;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-punctuation z-definition z-string&quot;&gt;&#x2F;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt; apexLoadFile&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;build-script-to-build-the-plug-in-when-changes-are-made-in-the-source-code&quot;&gt;Build script to build the plug-in when changes are made in the source code&lt;&#x2F;h2&gt;
&lt;p&gt;Everything is assembled by the build script - here is the relevant snippet:&lt;&#x2F;p&gt;
&lt;figure&gt;
    &lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;console&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;log&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;#39;- build file install&#x2F;apex_plugin.sql&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt;consoleJsCode&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; fs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;readFileSync&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;#39;sources&#x2F;apex_plugin_console.js&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;utf8&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt;version&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; fs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;readFileSync&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;#39;sources&#x2F;CONSOLE.pks&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;utf8&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;match&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;c_version&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-character-class z-regexp&quot;&gt;\s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-quantifier z-regexp&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-character-class z-regexp&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-quantifier z-regexp&quot;&gt;*?&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-punctuation z-definition z-group z-regexp&quot;&gt;&amp;#39;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-character-class z-regexp&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-quantifier z-regexp&quot;&gt;*?&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-group z-regexp z-string&quot;&gt;)&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-end&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt;md5Hash&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; toMd5Hash&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-variable z-other z-readwrite&quot;&gt;(consoleJsCode)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; reading the last saved version and md5Hash values as a reference for the comparison&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt;conf&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; JSON&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;parse&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(fs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;readFileSync&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;#39;apexplugin.json&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;utf8&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; (conf&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-property z-js&quot;&gt;version&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !==&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt; version&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; conf&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;jsFile&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-property z-js&quot;&gt;md5Hash&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !==&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-source&quot;&gt; md5Hash)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt;    minified&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; UglifyJS&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;minify&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;console.js&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt; consoleJsCode&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; }, {&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; sourceMap&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-boolean&quot;&gt; true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; }&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; (minified&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-property z-js z-source&quot;&gt;error)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; throw&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; minified&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-property z-js&quot;&gt;error&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    conf&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-property z-js&quot;&gt;version&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt; version&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    conf&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;jsFile&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-property z-js&quot;&gt;md5Hash&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt; md5Hash&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    conf&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;jsFile&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-property z-js&quot;&gt;version&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    fs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;writeFileSync&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;#39;install&#x2F;apex_plugin.sql&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;        &amp;#39;--DO NOT CHANGE THIS FILE - IT IS GENERATED WITH THE BUILD SCRIPT sources&#x2F;build.js&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt;\n\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        fs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;readFileSync&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;#39;sources&#x2F;apex_plugin_template.sql&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;utf8&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;            .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;replace&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;#39;#CONSOLE_VERSION#&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; conf&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-property z-js z-source&quot;&gt;version)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;            .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;replace&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;#39;#FILE_VERSION#&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; conf&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;jsFile&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-property z-js z-source&quot;&gt;version)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;            .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;replace&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;#39;#CONSOLE_JS_FILE#&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; toApexPluginFile&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(fs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;readFileSync&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;#39;sources&#x2F;apex_plugin_console.js&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;utf8&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;            .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;replace&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;#39;#CONSOLE_JS_FILE_MIN#&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; toApexPluginFile&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(minified&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-property z-js z-source&quot;&gt;code))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;            .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;replace&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;#39;#CONSOLE_JS_FILE_MIN_MAP#&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; toApexPluginFile&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(minified&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-property z-js z-source&quot;&gt;map))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    )&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    fs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;writeFileSync&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;#39;apexplugin.json&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt; JSON&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;stringify&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-variable z-other z-readwrite&quot;&gt;(conf&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-null z-js&quot;&gt; null&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
    &lt;figcaption&gt;Example of a build script (excerpt, &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ogobrecht&#x2F;console&#x2F;blob&#x2F;main&#x2F;sources&#x2F;build.js&quot;&gt;here the complete script&lt;&#x2F;a&gt;)&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;It should be noted that we will also have to manage the file version itself - APEX will install it as we create it. For that purpose, we check by means of hash-function whether JavaScript source file has changed and only then we regenerate the plug-in (including minification). This way, we avoid unnecessarily regenerating the plug-in every time we change source code in the repository and thus incrementing the file version.In the build script snippet above, the current file version and hash value is stored in a JSON file (&lt;code&gt;apexplugin.json&lt;&#x2F;code&gt;, last line of code) so that we can use this as a reference in the next build.&lt;&#x2F;p&gt;
&lt;p&gt;Here is the relevant place in the plug-in template where the file version is entered by the build script (placeholder &lt;code&gt;#FILE_VERSION#&lt;&#x2F;code&gt;, last parameter):&lt;&#x2F;p&gt;
&lt;figure&gt;
    &lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;sql&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;prompt &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; application&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;shared_components&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;plugins&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;dynamic_action&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;com_ogobrecht_console&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;begin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    wwv_flow_api.create_plugin (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        p_id                        &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; wwv_flow_api.id(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;36295154520053378&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        p_plugin_type               &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;DYNAMIC ACTION&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        p_name                      &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;COM.OGOBRECHT.CONSOLE&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        p_display_name              &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;Oracle Instrumentation Console&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        p_supported_ui_types        &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;DESKTOP:JQM_SMARTPHONE&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        p_api_version               &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        p_render_function           &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;console.apex_plugin_render&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        p_ajax_function             &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;console.apex_plugin_ajax&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        p_substitute_attributes     &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; true,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        p_subscribe_plugin_settings &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; true,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        p_version_identifier        &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;#CONSOLE_VERSION#&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        p_about_url                 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;https:&#x2F;&#x2F;github.com&#x2F;ogobrecht&#x2F;console&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        p_files_version             &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; #FILE_VERSION# );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;end&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
    &lt;figcaption&gt;Plug-in template with placeholders for file and plug-in version (snippet)&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;In addition, the version number of the plug-in itself is also updated here (placeholder &lt;code&gt;#CONSOLE_VERSION#&lt;&#x2F;code&gt;, third last parameter) - but this depends on the respective circumstances of the project. In my case I write the version number of the PL&#x2F;SQL package CONSOLE also into the plug-in depending on it - so if the version number of the package changes, the plug-in will be rebuilt as well. But here everybody has to see what is needed in the project.&lt;&#x2F;p&gt;
&lt;p&gt;When saving source code changes, the file watcher starts and triggers the build script. This then builds two installation SQL scripts together: That of the logging tool itself (not the focus of this article) and then that for the plug-in. Following this, both scripts are then installed in a dev environment. For this, of course, the default workspace stored in the plug-in and the default application number must be present in the dev environment.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;npm-scripts-for-orchestration&quot;&gt;NPM scripts for orchestration&lt;&#x2F;h2&gt;
&lt;p&gt;I now often manage build and install scripts with the node package manager npm. The reason for this is the good integration with Visual Studio Code, the operating system independence and the possibility to orchestrate the scripts a bit - ok, you have to install Node.js, but don’t you always? With one click you can either start the watch task, which does everything automatically with every save of a source file, or you can conveniently call the scripts individually. If someone else looks into the repository, it is also clearer with the npm scripts what works here and how.&lt;&#x2F;p&gt;
&lt;figure&gt;
    &lt;img alt=&quot;npm script integration in VS Code&quot; src=&quot;&amp;#x2F;img&amp;#x2F;screenshot-npm-scripts.png&quot;&gt;
    &lt;figcaption&gt;npm script integration in VS Code&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;It’s also clear that you don’t write usernames and passwords into the scripts here anymore - that’s already forbidden in principle when the code is checked into version control. On the screenshot you can (hopefully) see that here a wallet with the alias &lt;code&gt;playground&lt;&#x2F;code&gt; is used. For those who only use the instant client and have problems setting up a wallet: &lt;a href=&quot;&#x2F;blog&#x2F;how-to-use-mkstore-and-orapki-with-oracle-instant-client&#x2F;&quot;&gt;How to use mkstore and orapki with Oracle Instant Client&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The scripts are managed in the file &lt;code&gt;package.json&lt;&#x2F;code&gt; on the top level of the project directory. If you want to read more about npm scripts, you can start here:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;medium.freecodecamp.org&#x2F;introduction-to-npm-scripts-1dbb2ae01633&quot;&gt;Introduction to NPM Scripts&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;medium.freecodecamp.org&#x2F;why-i-left-gulp-and-grunt-for-npm-scripts-3d6853dd22b8&quot;&gt;Why I Left Gulp and Grunt for npm Scripts&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;css-tricks.com&#x2F;why-npm-scripts&#x2F;&quot;&gt;Why npm Scripts?&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;a-complete-example&quot;&gt;A complete example&lt;&#x2F;h2&gt;
&lt;p&gt;For those who want to see how everything can work together: I took the examples here in the article from my open source project &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ogobrecht&#x2F;console&quot;&gt;Oracle Instrumentation Console&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;another-way&quot;&gt;Another way&lt;&#x2F;h2&gt;
&lt;p&gt;My focus with this solution was to be able to supply a plug-in locally on the PC with new files. But there is another way: You can upload files or whole directories via script into an installed plug-in of an APEX application and then download the plug-in afterwards. For this purpose there is the Open Souce Project &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;vincentmorneau&#x2F;apex-publish-static-files&quot;&gt;APEX Publish Static Files&lt;&#x2F;a&gt; by Vincent Morneau. This project is also integrated with &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;OraOpenSource&#x2F;apex-nitro&quot;&gt;APEX Nitro&lt;&#x2F;a&gt; which can speed up frontend development in APEX.&lt;&#x2F;p&gt;
&lt;p&gt;Have fun generating plug-ins :-)&lt;&#x2F;p&gt;
&lt;p&gt;Ottmar&lt;&#x2F;p&gt;
</content>
        <summary type="html">Instead of uploading new files to a plug-in, we generate the plug-in via a template on the command line and install it</summary>
        </entry><entry xml:lang="en">
        <title>New Version of D3 Force Network Chart Available</title>
        <published>2019-06-09T00:00:00+00:00</published>
        <updated>2019-06-09T00:00:00+00:00</updated>
        <author>
            <name>Ottmar Gobrecht</name>
        </author>
        <link rel="alternate" href="https://ogobrecht.com/blog/new-version-of-d3-force-network-chart-available/" type="text/html"/>
        <id>https://ogobrecht.com/blog/new-version-of-d3-force-network-chart-available/</id>
        
            <content type="html">&lt;p&gt;&lt;img src=&quot;&#x2F;img&#x2F;d3js-network-link-label.png&quot; alt=&quot;Link label example&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;First of all: Thanks to the community!&lt;&#x2F;p&gt;
&lt;p&gt;From time to time someone has new ideas or questions about the D3 network chart. Some time ago I thought my D3 implementation is more or less feature complete. But in the last weeks I worked again on the code to bring in new feature wishes from the community.&lt;&#x2F;p&gt;
&lt;p&gt;The most visible one in the new version 3.1 is the ability to add labels to links - see the links between Allen, Blake and Ward in the screenshot above. The labels are positioned in a way that they are always readable - this is the reason why they appear sometimes above and sometimes below a link line (they are rotated, if needed). The nice thing is that you can also read both labels when you have links in both directions between two nodes. The other benefit of having labels on links is that they extend the area for the link click and hover events. This improves the usabiltiy in cases where the links should show a tooltip when they are hovered or some action should be executed when they are clicked. This is normally not so easy because the links are so narrow.&lt;&#x2F;p&gt;
&lt;p&gt;There are also new helper methods and one new option - for the full change log see the project on &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ogobrecht&#x2F;d3-force-apex-plugin#changelog&quot;&gt;GitHub&lt;&#x2F;a&gt; and for online demos either the &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ogobrecht.github.io&#x2F;d3-force-apex-plugin&#x2F;tutorial-1-getting-started.html&quot;&gt;standalone version in the docs&lt;&#x2F;a&gt; or the APEX plug-in version on &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;apex.oracle.com&#x2F;pls&#x2F;apex&#x2F;f?p=18290:1&quot;&gt;apex.oracle.com&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Happy networking :-)&lt;&#x2F;p&gt;
&lt;p&gt;Ottmar&lt;&#x2F;p&gt;
</content>
        <summary type="html">Links can now have a label</summary>
        </entry><entry xml:lang="en">
        <title>New Major Version of D3 Force Network Chart Available</title>
        <published>2018-12-02T00:00:00+00:00</published>
        <updated>2018-12-02T00:00:00+00:00</updated>
        <author>
            <name>Ottmar Gobrecht</name>
        </author>
        <link rel="alternate" href="https://ogobrecht.com/blog/new-major-version-of-d3-force-network-chart-available/" type="text/html"/>
        <id>https://ogobrecht.com/blog/new-major-version-of-d3-force-network-chart-available/</id>
        
            <content type="html">&lt;p&gt;&lt;img src=&quot;&#x2F;img&#x2F;d3js-force-directed-network.png&quot; alt=&quot;screenshot of a network graph&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Since APEX version 5 was published with the Universal Theme, I was thinking that I needed something for better responsiveness of the graph. Although it was possible to configure the graph to use the DOM parent width, the responsiveness was not so good because of situations where the window size does not change (we use the window resize event to trigger the change of the width) but the available space for the graph changes. How can the graph react to this?&lt;&#x2F;p&gt;
&lt;p&gt;The problem is that a network chart is not a simple image which can be resized according to the available space. The graph is an SVG with multiple layers to handle the zoom and pan, the lasso, a legend that needs to be in a fixed size…   As you can see, there must be a procedural solution. And for this we need a trigger, which always fires when the (possible) size of the graphs parent DOM element changes.&lt;&#x2F;p&gt;
&lt;p&gt;Fortunately, there is a &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wicg.github.io&#x2F;ResizeObserver&#x2F;&quot;&gt;W3C draft for a resize observer&lt;&#x2F;a&gt; and a &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;que-etc&#x2F;resize-observer-polyfill&quot;&gt;polyfill&lt;&#x2F;a&gt; available.&lt;&#x2F;p&gt;
&lt;p&gt;To put the things together, I had to make breaking changes on the API (the reason for a new major version):&lt;&#x2F;p&gt;
&lt;p&gt;I made the API zoom methods independent of the option &lt;code&gt;zoomMode&lt;&#x2F;code&gt; and set the default to true for the following options:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;zoomToFitOnForceEnd&lt;&#x2F;code&gt; (was false in the past)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;zoomToFitOnResize&lt;&#x2F;code&gt; (new option)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;keepAspectRatioOnResize&lt;&#x2F;code&gt; (new option)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;When setting the option &lt;code&gt;useDomParentWidth&lt;&#x2F;code&gt; to true together with the previous mentioned defaults, you can achieve a responsiveness like with images set to width 100%. Try it out by resizing your browser window.&lt;&#x2F;p&gt;
&lt;p&gt;For the full change log see the project on &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ogobrecht&#x2F;d3-force-apex-plugin#changelog&quot;&gt;GitHub&lt;&#x2F;a&gt; and for a demo the app on &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;apex.oracle.com&#x2F;pls&#x2F;apex&#x2F;f?p=18290:1&quot;&gt;apex.oracle.com&lt;&#x2F;a&gt; (which currently does not use the universal theme, new demo app is work in progress…).&lt;&#x2F;p&gt;
&lt;p&gt;Happy networking :-)&lt;&#x2F;p&gt;
&lt;p&gt;Ottmar&lt;&#x2F;p&gt;
</content>
        <summary type="html">Better responsiveness by implementing a resize observer</summary>
        </entry><entry xml:lang="en">
        <title>jQuery Plugin svg2img</title>
        <published>2017-04-03T00:00:00+00:00</published>
        <updated>2017-04-03T00:00:00+00:00</updated>
        <author>
            <name>Ottmar Gobrecht</name>
        </author>
        <link rel="alternate" href="https://ogobrecht.com/blog/jquery-plugin-svg2img/" type="text/html"/>
        <id>https://ogobrecht.com/blog/jquery-plugin-svg2img/</id>
        
            <content type="html">&lt;p&gt;SVG based charts and visualizations are often used these days. But what if you want to use your browser inline SVGs, generated with some sort of JavaScript and fancy styled with CSS, offline - maybe in a presentation, send by email or printed out large scaled?&lt;&#x2F;p&gt;
&lt;p&gt;You can create a screenshot, of course. But does this look nice when it comes to scaling? You can try to copy the HTML code of the SVG and wrap it into a correct SVG container, but then you will loose in the most cases the stylings, as normally not all CSS definitions are directly attached to the SVG elements. You can also use a browser extension like &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;chrome.google.com&#x2F;webstore&#x2F;detail&#x2F;export-svg-with-style&#x2F;dkjdcaddoplepioppogpckelchefhddi&quot;&gt;this one for Google Chrome&lt;&#x2F;a&gt;, but then you depend on the browser and the extension.&lt;&#x2F;p&gt;
&lt;p&gt;There is now a declarative way with the help of a jQuery plugin, which is 100% client based:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;jQuery&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;#39;#example-graph&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;svg2img&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;There is one default option - you can redeclare it:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;jQuery&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;svg2img&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-property z-js&quot;&gt;defaults&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    debug&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-boolean&quot;&gt; false&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; write debug information to console&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You can also set the debug option at runtime:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;#39;#example-graph&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;svg2img&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;debug&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-boolean&quot;&gt;true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The plugin checks if your selector is a SVG element. If this is not the case, it searches under each selector element for all SVGs and exports it. The name(s) of the file(s) are automatically derived from the element ID (or parent element ID) or set to &lt;code&gt;export&lt;&#x2F;code&gt;. The current date and time is appended to the file name, for example &lt;code&gt;example-graph-20170403-154653.svg&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;You can download all SVGs from one page by setting the selector to the document, body or svg - as you like it. There is no need for a &lt;code&gt;each()&lt;&#x2F;code&gt; call, &lt;code&gt;svg2img&lt;&#x2F;code&gt; works on the whole selection and is chainable:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;svg&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;svg2img&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;css&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;border&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;1px solid red&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you want to use anchors to provide export links then it is recommended to prevent the default action like so:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;html&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; href&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; onclick&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;event&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;preventDefault&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; $&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;#39;#example-graph&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;svg2img&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-text&quot;&gt;SVG&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Otherwise Firefox and IE failing to save. One last thing: Safari has currently (as of this writing) problems with the underlaying &lt;code&gt;savAs()&lt;&#x2F;code&gt; implementation and tries to open the images in a new tab with or without success. See also this &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;eligrey&#x2F;FileSaver.js&#x2F;issues&#x2F;267&quot;&gt;issue on GitHub&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;UPDATE 2017-04-14: After update to macOS Sierra 10.12.4 Safari 10.1 works also - but is as slow as before - collecting CSS styles runs on my MacBook 2800ms in Safari, 20ms in Google Chrome :-(
I stopped to support other image formats then SVG since the canvas export behind the scenes was not really working in too many browsers and the core feature was and is to convert inline SVGs to standalone SVG images.&lt;&#x2F;p&gt;
&lt;p&gt;The project is hosted on &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ogobrecht&#x2F;jquery-plugin-svg2img&quot;&gt;GitHub&lt;&#x2F;a&gt; and MIT licensed.&lt;&#x2F;p&gt;
&lt;p&gt;Happy SVG exporting :-)&lt;&#x2F;p&gt;
&lt;p&gt;Ottmar&lt;&#x2F;p&gt;
</content>
        <summary type="html">Convert inline SVGs to standalone image files without loosing styles</summary>
        </entry><entry xml:lang="en">
        <title>APEX Plugin dhtmlxGantt</title>
        <published>2017-03-14T00:00:00+00:00</published>
        <updated>2017-03-14T00:00:00+00:00</updated>
        <author>
            <name>Ottmar Gobrecht</name>
        </author>
        <link rel="alternate" href="https://ogobrecht.com/blog/apex-plugin-dhtmlx-gantt/" type="text/html"/>
        <id>https://ogobrecht.com/blog/apex-plugin-dhtmlx-gantt/</id>
        
            <content type="html">&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;raw.githubusercontent.com&#x2F;ogobrecht&#x2F;apex-plugin-dhtmlx-gantt&#x2F;master&#x2F;preview.png&quot; alt=&quot;Preview&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Some weeks ago I was asked, if I can create a plugin for the &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dhtmlx.com&#x2F;docs&#x2F;products&#x2F;dhtmlxGantt&#x2F;&quot;&gt;Gantt chart library from dhtmlx.com&lt;&#x2F;a&gt;. I had a look at the library and I thought that it should be possible.&lt;&#x2F;p&gt;
&lt;p&gt;Because all my plugin developments are free time projects it took a while. Now the first public version is available. It is based on the GPLv2 version of the library, which has a reduced set of functionality. If you need advanced features like milestones, auto scheduling or calculating the critical path you can buy a Pro version of the library. I have no relation to the company behind dhtmlx.com, so please do not complain. As I told before I was asked for this plugin (which will be used in a Pro version there…) and I like the visualization from DHTMLX.&lt;&#x2F;p&gt;
&lt;p&gt;You can find the sources and more informations on &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ogobrecht&#x2F;apex-plugin-dhtmlx-gantt&quot;&gt;GitHub&lt;&#x2F;a&gt; and a online demo on &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;apex.oracle.com&#x2F;pls&#x2F;apex&#x2F;f?p=116612:1&quot;&gt;apex.oracle.com&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Maybe the plugin is helpful for someone else…&lt;&#x2F;p&gt;
&lt;p&gt;Happy project planning :-)&lt;&#x2F;p&gt;
&lt;p&gt;Ottmar&lt;&#x2F;p&gt;
</content>
        <summary type="html">HTML5 Gantt chart based on dhtmlx.com library</summary>
        </entry><entry xml:lang="en">
        <title>DokuWiki Plugin Reveal.js</title>
        <published>2017-03-05T00:00:00+00:00</published>
        <updated>2017-03-05T00:00:00+00:00</updated>
        <author>
            <name>Ottmar Gobrecht</name>
        </author>
        <link rel="alternate" href="https://ogobrecht.com/blog/dokuwiki-plugin-revealjs/" type="text/html"/>
        <id>https://ogobrecht.com/blog/dokuwiki-plugin-revealjs/</id>
        
            <content type="html">&lt;p&gt;&lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.dokuwiki.org&quot;&gt;DokuWiki&lt;&#x2F;a&gt; is very good for creating documentation in a team. It is PHP based, needs less resources and is running without a database only on files on nearly every webserver. If your infrastructure is crashed for whatever reason and you have at least access to the files (on the webserver or in a backup) you can read your documentation with a simple text editor, because DokuWiki’s syntax is designed to be readable as possible without any rendering to HTML.&lt;&#x2F;p&gt;
&lt;p&gt;For the APEX connect 2015 I started to use Markdown and &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;pandoc.org&quot;&gt;Pandoc&lt;&#x2F;a&gt; to create HTML based slides. Pandoc supports different HTML slideshow tools - two of them are also available as plugins in DokuWiki: S5 and &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;lab.hakim.se&#x2F;reveal-js&quot;&gt;Reveal.js&lt;&#x2F;a&gt;. Reveal.js is the more modern library and I used this one together with Pandoc.&lt;&#x2F;p&gt;
&lt;p&gt;For the DOAG conference last year I tried to use Reveals.js as a DokuWiki Plugin - I wanted to have at the same time a normal wiki page and the possibility to render this page as a slideshow. Unfortunately the existing plugin was only a base implementation and many features from Reveal.js were not available. I decided to contribute to the existing plugin. The list of my improvements is long - I had fun and learned a lot. The plugin can be found &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.dokuwiki.org&#x2F;plugin:revealjs&quot;&gt;here on the DokuWiki homepage&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Happy presenting :-)&lt;&#x2F;p&gt;
&lt;p&gt;Ottmar&lt;&#x2F;p&gt;
&lt;p&gt;PS: In the meantime I switched complete to Markdown and &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;jekyllrb.com&quot;&gt;Jekyll&lt;&#x2F;a&gt;, a static site generator - but this is another story for another post …&lt;&#x2F;p&gt;
</content>
        <summary type="html">My contributions to an existing DokuWiki slideshow plugin</summary>
        </entry><entry xml:lang="en">
        <title>Markdown for Oracle APEX</title>
        <published>2016-01-01T00:00:00+00:00</published>
        <updated>2016-01-01T00:00:00+00:00</updated>
        <author>
            <name>Ottmar Gobrecht</name>
        </author>
        <link rel="alternate" href="https://ogobrecht.com/blog/markdown-for-oracle-apex/" type="text/html"/>
        <id>https://ogobrecht.com/blog/markdown-for-oracle-apex/</id>
        
            <content type="html">&lt;p&gt;Some years ago I implemented a task board in APEX. For commenting I used the &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;stackexchange.github.io&quot;&gt;stackexchange&lt;&#x2F;a&gt; &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;balpha&#x2F;pagedown&quot;&gt;markdown implementation&lt;&#x2F;a&gt; (&lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;code.google.com&#x2F;archive&#x2F;p&#x2F;pagedown&#x2F;&quot;&gt;old Google code repo&lt;&#x2F;a&gt;), which is a pure JavaScript converter and editor and based on &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;showdownjs&#x2F;showdown&quot;&gt;showdown.js&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Some months ago I had to implement an application, which should be able to have multiple editors on one page and the editors should be able to support a read only mode. Furthermore there were hard limits for the amount of text for each editor. Both things which are not so easy to implement with the rich text editor in APEX - no really read only mode and the amount of text is also a problem because of the HTML overhead.&lt;&#x2F;p&gt;
&lt;p&gt;It was time to rethink my old implementation and to build a plugin, which creates for each text area with the class markdown an own editor. All other non input elements with a class markdown should simply rendered to HTML, which is then also the solution for the read only mode of the editors. APEX standard text area items supports a read only mode and the class markdown from the text area is also rendered by the APEX engine for this mode :-)&lt;&#x2F;p&gt;
&lt;p&gt;The nice side effect is, that I don’t had to reinvent the wheel by creating an own item type - I could reuse the standard APEX text area item and things like the character counter working out of the box.&lt;&#x2F;p&gt;
&lt;p&gt;You can find the sources and more informations on &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ogobrecht&#x2F;markdown-apex-plugin&quot;&gt;GitHub&lt;&#x2F;a&gt; and a demo app on &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;apex.oracle.com&#x2F;pls&#x2F;apex&#x2F;f?p=66154&quot;&gt;apex.oracle.com&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Happy coding :-)&lt;&#x2F;p&gt;
&lt;p&gt;Ottmar&lt;&#x2F;p&gt;
</content>
        <summary type="html">A dynamic action type plugin</summary>
        </entry><entry xml:lang="en">
        <title>D3.js Force-Directed Network Chart</title>
        <published>2015-02-20T00:00:00+00:00</published>
        <updated>2015-02-20T00:00:00+00:00</updated>
        <author>
            <name>Ottmar Gobrecht</name>
        </author>
        <link rel="alternate" href="https://ogobrecht.com/blog/d3js-force-directed-network-chart/" type="text/html"/>
        <id>https://ogobrecht.com/blog/d3js-force-directed-network-chart/</id>
        
            <content type="html">&lt;p&gt;&lt;img src=&quot;&#x2F;img&#x2F;d3js-force-directed-network.png&quot; alt=&quot;screenshot of a network graph&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;My first Oracle APEX plugin and open source project :-)&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Everything started some months ago when I stumbled over this fascinating &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;bl.ocks.org&#x2F;mbostock&#x2F;4062045&quot;&gt;force-directed graph&lt;&#x2F;a&gt;. I immediately had the idea to use this technology to visualize data models in APEX. My experience is, that direct after I documented a data model, this documentation is out of date. I wanted to have a live visualization of the data models. After the first implementation it turned out, that the resulting graph is also useful for other purposes and I decided to build up an APEX plugin for easier integration.&lt;&#x2F;p&gt;
&lt;p&gt;If you use the bare JavaScript files you can run it on every HTML page:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;html&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;div&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; id&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;example&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;div&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&amp;lt;!--the graph container--&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;link&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt;  href&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;&#x2F;d3.js&#x2F;d3-force-3.0.0.css&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; rel&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;stylesheet&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; type&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;text&#x2F;css&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;script&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; src&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;&#x2F;d3.js&#x2F;ResizeObserver-1.5.0.min.js&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;script&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;script&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; src&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;&#x2F;d3.js&#x2F;d3-3.5.6.min.js&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;script&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;script&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; src&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;&#x2F;d3.js&#x2F;d3-force-3.0.0.min.js&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;script&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;script&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;window&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;onload&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; function&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;  window&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-property z-js&quot;&gt;example&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; netGobrechtsD3Force&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;#39;example&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;    .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;height&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;400&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;    .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;width&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;800&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;    .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;useDomParentWidth&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-boolean&quot;&gt;true&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F;for responsive layout&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F;.zoomMode(true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;    .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;lassoMode&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-boolean&quot;&gt;true&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;    .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;wrapLabels&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-boolean&quot;&gt;true&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;    .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;showBorder&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-boolean&quot;&gt;false&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;    .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;debug&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-boolean&quot;&gt;true&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F;to enable the customization wizard&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;    .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;render&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F;sample data is provided when called without data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F;also see https:&#x2F;&#x2F;ogobrecht.github.io&#x2F;d3-force-apex-plugin&#x2F;tutorial-1-getting-started.html&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;script&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I found myself often fiddling around with the parameters of the physical simulation - change config, reload page, not amused, change config…&lt;&#x2F;p&gt;
&lt;p&gt;Really annoying - even I know the implementation behind. So, the question was: What can I do for an easy configuration. My answer was after a while of thinking and trying out: A customization wizard with a live preview of the changes. The link to enter the wizard is shown when the debug mode is switched on or in APEX when the developer bar is shown - try it out on the &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ogobrecht.github.io&#x2F;d3-force-apex-plugin&#x2F;tutorial-1-getting-started.html&quot;&gt;getting started page of the API docs&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;You can find the sources and more informations on &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ogobrecht&#x2F;d3-force-apex-plugin&quot;&gt;GitHub&lt;&#x2F;a&gt; and a demo app on &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;apex.oracle.com&#x2F;pls&#x2F;apex&#x2F;f?p=18290:1&quot;&gt;apex.oracle.com&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Happy networking :-)&lt;&#x2F;p&gt;
&lt;p&gt;Ottmar&lt;&#x2F;p&gt;
</content>
        <summary type="html">A JavaScript standalone implementation and Oracle APEX region type plugin</summary>
        </entry>
</feed>
