<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>https://wiki.baw.de/de/index.php?action=history&amp;feed=atom&amp;title=Modul%3AJSONutil</id>
	<title>Modul:JSONutil - Versionsgeschichte</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.baw.de/de/index.php?action=history&amp;feed=atom&amp;title=Modul%3AJSONutil"/>
	<link rel="alternate" type="text/html" href="https://wiki.baw.de/de/index.php?title=Modul:JSONutil&amp;action=history"/>
	<updated>2026-04-24T15:54:15Z</updated>
	<subtitle>Versionsgeschichte dieser Seite in BAWiki</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://wiki.baw.de/de/index.php?title=Modul:JSONutil&amp;diff=35064&amp;oldid=prev</id>
		<title>ArxioWikiSysop: 1 Version importiert</title>
		<link rel="alternate" type="text/html" href="https://wiki.baw.de/de/index.php?title=Modul:JSONutil&amp;diff=35064&amp;oldid=prev"/>
		<updated>2020-10-21T14:07:41Z</updated>

		<summary type="html">&lt;p&gt;1 Version importiert&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;de&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Nächstältere Version&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Version vom 21. Oktober 2020, 14:07 Uhr&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;de&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(kein Unterschied)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>ArxioWikiSysop</name></author>
	</entry>
	<entry>
		<id>https://wiki.baw.de/de/index.php?title=Modul:JSONutil&amp;diff=35063&amp;oldid=prev</id>
		<title>en&gt;PerfektesChaos: 2019-07-18</title>
		<link rel="alternate" type="text/html" href="https://wiki.baw.de/de/index.php?title=Modul:JSONutil&amp;diff=35063&amp;oldid=prev"/>
		<updated>2019-07-17T23:02:36Z</updated>

		<summary type="html">&lt;p&gt;2019-07-18&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Neue Seite&lt;/b&gt;&lt;/p&gt;&lt;div&gt;local JSONutil = { suite  = &amp;quot;JSONutil&amp;quot;,&lt;br /&gt;
                   serial = &amp;quot;2019-07-18&amp;quot;,&lt;br /&gt;
                   item   = 63869449 }&lt;br /&gt;
--[=[&lt;br /&gt;
preprocess JSON data&lt;br /&gt;
]=]&lt;br /&gt;
local Failsafe = JSONutil&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
JSONutil.more = 50    -- length of trailing context&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local Fallback = function ()&lt;br /&gt;
    -- Retrieve current default language code&lt;br /&gt;
    --     Returns  string&lt;br /&gt;
    return mw.language.getContentLanguage():getCode()&lt;br /&gt;
                                           :lower()&lt;br /&gt;
end -- Fallback()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
JSONutil.fair = function ( apply )&lt;br /&gt;
    -- Reduce enhanced JSON data to strict JSON&lt;br /&gt;
    -- Parameter:&lt;br /&gt;
    --     apply  -- string, with enhanced JSON&lt;br /&gt;
    -- Returns:&lt;br /&gt;
    --     1    -- string|nil|false, with error keyword&lt;br /&gt;
    --     2    -- string, with JSON or context&lt;br /&gt;
    local m   = 0&lt;br /&gt;
    local n   = 0&lt;br /&gt;
    local s   = mw.text.trim( apply )&lt;br /&gt;
    local sep = string.char( 10 )&lt;br /&gt;
    local i, j, last, r, scan, sep0, sep1, stab, start, stub, suffix&lt;br /&gt;
    local framework = function ( a )&lt;br /&gt;
                              -- syntax analysis outside strings&lt;br /&gt;
                              local k = 1&lt;br /&gt;
                              local c&lt;br /&gt;
                              while k do&lt;br /&gt;
                                  k = a:find( &amp;quot;[{%[%]}]&amp;quot;, k )&lt;br /&gt;
                                  if k then&lt;br /&gt;
                                      c = a:byte( k, k )&lt;br /&gt;
                                      if c == 0x7B then    -- {&lt;br /&gt;
                                          m = m + 1&lt;br /&gt;
                                      elseif c == 0x7D then    -- }&lt;br /&gt;
                                          m = m - 1&lt;br /&gt;
                                      elseif c == 0x5B then    -- [&lt;br /&gt;
                                          n = n + 1&lt;br /&gt;
                                      else    -- ]&lt;br /&gt;
                                          n = n - 1&lt;br /&gt;
                                      end&lt;br /&gt;
                                      k = k + 1&lt;br /&gt;
                                  end&lt;br /&gt;
                              end   -- while k&lt;br /&gt;
                      end    -- framework()&lt;br /&gt;
    local free = function ( a, at, f )&lt;br /&gt;
                     -- Throws: error if /* is not matched by */&lt;br /&gt;
                     local s = a&lt;br /&gt;
                     local i = s:find( &amp;quot;//&amp;quot;, at, true )&lt;br /&gt;
                     local k = s:find( &amp;quot;/*&amp;quot;, at, true )&lt;br /&gt;
                     if i or k then&lt;br /&gt;
                         local m = s:find( sep0, at )&lt;br /&gt;
                         if i   and   ( not m  or  i &amp;lt; m ) then&lt;br /&gt;
                             k = s:find( &amp;quot;\n&amp;quot;,  i + 2,  true )&lt;br /&gt;
                             if k then&lt;br /&gt;
                                 if i == 1 then&lt;br /&gt;
                                     s = s:sub( k + 1 )&lt;br /&gt;
                                 else&lt;br /&gt;
                                     s = s:sub( 1,  i - 1 )   ..&lt;br /&gt;
                                         s:sub( k + 1 )&lt;br /&gt;
                                 end&lt;br /&gt;
                             elseif i &amp;gt; 1 then&lt;br /&gt;
                                 s = s:sub( 1,  i - 1 )&lt;br /&gt;
                             else&lt;br /&gt;
                                 s = &amp;quot;&amp;quot;&lt;br /&gt;
                             end&lt;br /&gt;
                         elseif k   and   ( not m  or  k &amp;lt; m ) then&lt;br /&gt;
                             i = s:find( &amp;quot;*/&amp;quot;,  k + 2,  true )&lt;br /&gt;
                             if i then&lt;br /&gt;
                                 if k == 1 then&lt;br /&gt;
                                     s = s:sub( i + 2 )&lt;br /&gt;
                                 else&lt;br /&gt;
                                     s = s:sub( 1,  k - 1 )   ..&lt;br /&gt;
                                         s:sub( i + 2 )&lt;br /&gt;
                                 end&lt;br /&gt;
                             else&lt;br /&gt;
                                 error( s:sub( k + 2 ), 0 )&lt;br /&gt;
                             end&lt;br /&gt;
                             i = k&lt;br /&gt;
                         else&lt;br /&gt;
                             i = false&lt;br /&gt;
                         end&lt;br /&gt;
                         if i then&lt;br /&gt;
                             s = mw.text.trim( s )&lt;br /&gt;
                             if s:find( &amp;quot;/&amp;quot;, 1, true ) then&lt;br /&gt;
                                 s = f( s, i, f )&lt;br /&gt;
                             end&lt;br /&gt;
                         end&lt;br /&gt;
                     end&lt;br /&gt;
                     return s&lt;br /&gt;
                 end    -- free()&lt;br /&gt;
    if s:sub( 1, 1 ) == &amp;#039;{&amp;#039; then&lt;br /&gt;
        stab = string.char( 9 )&lt;br /&gt;
        s    = s:gsub( string.char( 13, 10 ),  sep )&lt;br /&gt;
                :gsub( string.char( 13 ),  sep )&lt;br /&gt;
        stub = s:gsub( sep, &amp;quot;&amp;quot; ):gsub( stab, &amp;quot;&amp;quot; )&lt;br /&gt;
        scan = string.char( 0x5B, 0x01, 0x2D, 0x1F, 0x5D )    -- [ \-\ ]&lt;br /&gt;
        j    = stub:find( scan )&lt;br /&gt;
        if j then&lt;br /&gt;
            r = &amp;quot;ControlChar&amp;quot;&lt;br /&gt;
            s = mw.text.trim( s:sub( j + 1 ) )&lt;br /&gt;
            s = mw.ustring.sub( s, 1, JSONutil.more )&lt;br /&gt;
        else&lt;br /&gt;
            i    = true&lt;br /&gt;
            j    = 1&lt;br /&gt;
            last = ( stub:sub( -1 ) == &amp;quot;}&amp;quot; )&lt;br /&gt;
            sep0 = string.char( 0x5B, 0x22, 0x27, 0x5D )    -- [ &amp;quot; &amp;#039; ]&lt;br /&gt;
            sep1 = string.char( 0x5B, 0x5C, 0x22, 0x5D )    -- [ \ &amp;quot; ]&lt;br /&gt;
        end&lt;br /&gt;
    else&lt;br /&gt;
        r = &amp;quot;Bracket0&amp;quot;&lt;br /&gt;
        s = mw.ustring.sub( s, 1, JSONutil.more )&lt;br /&gt;
    end&lt;br /&gt;
    while i do&lt;br /&gt;
        i, s = pcall( free, s, j, free )&lt;br /&gt;
        if i then&lt;br /&gt;
            i = s:find( sep0, j )&lt;br /&gt;
        else&lt;br /&gt;
            r = &amp;quot;CommentEnd&amp;quot;&lt;br /&gt;
            s = mw.text.trim( s )&lt;br /&gt;
            s = mw.ustring.sub( s, 1, JSONutil.more )&lt;br /&gt;
        end&lt;br /&gt;
        if i then&lt;br /&gt;
            if j == 1 then&lt;br /&gt;
                framework( s:sub( 1, i - 1 ) )&lt;br /&gt;
            end&lt;br /&gt;
            if s:sub( i, i ) == &amp;#039;&amp;quot;&amp;#039; then&lt;br /&gt;
                stub = s:sub( j,  i - 1 )&lt;br /&gt;
                if stub:find( &amp;#039;[^&amp;quot;]*,%s*[%]}]&amp;#039; ) then&lt;br /&gt;
                    r = &amp;quot;CommaEnd&amp;quot;&lt;br /&gt;
                    s = mw.text.trim( stub )&lt;br /&gt;
                    s = mw.ustring.sub( s, 1, JSONutil.more )&lt;br /&gt;
                    i = false&lt;br /&gt;
                    j = false&lt;br /&gt;
                else&lt;br /&gt;
                    if j &amp;gt; 1 then&lt;br /&gt;
                        framework( stub )&lt;br /&gt;
                    end&lt;br /&gt;
                    i = i + 1&lt;br /&gt;
                    j = i&lt;br /&gt;
                end&lt;br /&gt;
                while j do&lt;br /&gt;
                    j = s:find( sep1, j )&lt;br /&gt;
                    if j then&lt;br /&gt;
                        if s:sub( j, j ) == &amp;#039;&amp;quot;&amp;#039; then&lt;br /&gt;
                            start  = s:sub( 1,  i - 1 )&lt;br /&gt;
                            suffix = s:sub( j )&lt;br /&gt;
                            if j &amp;gt; i then&lt;br /&gt;
                                stub = s:sub( i,  j - 1 )&lt;br /&gt;
                                        :gsub( sep,  &amp;quot;\\n&amp;quot; )&lt;br /&gt;
                                        :gsub( stab, &amp;quot;\\t&amp;quot; )&lt;br /&gt;
                                j = i + stub:len()&lt;br /&gt;
                                s = string.format( &amp;quot;%s%s%s&amp;quot;,&lt;br /&gt;
                                                   start, stub, suffix )&lt;br /&gt;
                            else&lt;br /&gt;
                                s = start .. suffix&lt;br /&gt;
                            end&lt;br /&gt;
                            j = j + 1&lt;br /&gt;
                            break   -- while j&lt;br /&gt;
                        else&lt;br /&gt;
                            j = j + 2&lt;br /&gt;
                        end&lt;br /&gt;
                    else&lt;br /&gt;
                        r = &amp;quot;QouteEnd&amp;quot;&lt;br /&gt;
                        s = mw.text.trim( s:sub( i ) )&lt;br /&gt;
                        s = mw.ustring.sub( s, 1, JSONutil.more )&lt;br /&gt;
                        i = false&lt;br /&gt;
                    end&lt;br /&gt;
                end   -- while j&lt;br /&gt;
            else&lt;br /&gt;
                r = &amp;quot;Qoute&amp;quot;&lt;br /&gt;
                s = mw.text.trim( s:sub( i ) )&lt;br /&gt;
                s = mw.ustring.sub( s, 1, JSONutil.more )&lt;br /&gt;
                i = false&lt;br /&gt;
            end&lt;br /&gt;
        elseif not r then&lt;br /&gt;
            stub = s:sub( j )&lt;br /&gt;
            if stub:find( &amp;#039;[^&amp;quot;]*,%s*[%]}]&amp;#039; ) then&lt;br /&gt;
                r = &amp;quot;CommaEnd&amp;quot;&lt;br /&gt;
                s = mw.text.trim( stub )&lt;br /&gt;
                s = mw.ustring.sub( s, 1, JSONutil.more )&lt;br /&gt;
            else&lt;br /&gt;
                framework( stub )&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
    end   -- while i&lt;br /&gt;
    if not r   and   ( m ~= 0  or  n ~= 0 ) then&lt;br /&gt;
        if m ~= 0 then&lt;br /&gt;
            s = &amp;quot;}&amp;quot;&lt;br /&gt;
            if m &amp;gt; 0 then&lt;br /&gt;
                r = &amp;quot;BracketCloseLack&amp;quot;&lt;br /&gt;
                j = m&lt;br /&gt;
            elseif m &amp;lt; 0 then&lt;br /&gt;
                r = &amp;quot;BracketClosePlus&amp;quot;&lt;br /&gt;
                j = -m&lt;br /&gt;
            end&lt;br /&gt;
        else&lt;br /&gt;
            s = &amp;quot;]&amp;quot;&lt;br /&gt;
            if n &amp;gt; 0 then&lt;br /&gt;
                r = &amp;quot;BracketCloseLack&amp;quot;&lt;br /&gt;
                j = n&lt;br /&gt;
            else&lt;br /&gt;
                r = &amp;quot;BracketClosePlus&amp;quot;&lt;br /&gt;
                j = -n&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
        if j &amp;gt; 1 then&lt;br /&gt;
            s =  string.format( &amp;quot;%d %s&amp;quot;, j, s )&lt;br /&gt;
        end&lt;br /&gt;
    elseif not ( r or last ) then&lt;br /&gt;
        stub = suffix or apply or &amp;quot;&amp;quot;&lt;br /&gt;
        j    = stub:find( &amp;quot;/&amp;quot;, 1, true )&lt;br /&gt;
        if j then&lt;br /&gt;
            i, stub = pcall( free, stub, j, free )&lt;br /&gt;
        else&lt;br /&gt;
            i = true&lt;br /&gt;
        end&lt;br /&gt;
        stub = mw.text.trim( stub )&lt;br /&gt;
        if i then&lt;br /&gt;
            if stub:sub( - 1 ) ~= &amp;quot;}&amp;quot; then&lt;br /&gt;
                r = &amp;quot;Trailing&amp;quot;&lt;br /&gt;
                s = stub:match( &amp;quot;%}%s*(%S[^%}]*)$&amp;quot; )&lt;br /&gt;
                if s then&lt;br /&gt;
                    s = mw.ustring.sub( s, 1, JSONutil.more )&lt;br /&gt;
                else&lt;br /&gt;
                    s = mw.ustring.sub( stub,  - JSONutil.more )&lt;br /&gt;
                end&lt;br /&gt;
            end&lt;br /&gt;
        else&lt;br /&gt;
            r = &amp;quot;CommentEnd&amp;quot;&lt;br /&gt;
            s = mw.ustring.sub( stub, 1, JSONutil.more )&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    if r and s then&lt;br /&gt;
        s = mw.text.encode( s:gsub( sep,  &amp;quot; &amp;quot; ) ):gsub( &amp;quot;|&amp;quot;, &amp;quot;&amp;amp;#124;&amp;quot; )&lt;br /&gt;
    end&lt;br /&gt;
    return r, s&lt;br /&gt;
end -- JSONutil.fair()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
JSONutil.fault = function ( alert, add, adapt )&lt;br /&gt;
    -- Retrieve formatted message&lt;br /&gt;
    -- Parameter:&lt;br /&gt;
    --     alert  -- string, with error keyword, or other text&lt;br /&gt;
    --     add    -- string|nil|false, with context&lt;br /&gt;
    --     adapt  -- function|string|table|nil|false, for I18N&lt;br /&gt;
    -- Returns string, with HTML span&lt;br /&gt;
    local e = mw.html.create( &amp;quot;span&amp;quot; )&lt;br /&gt;
                     :addClass( &amp;quot;error&amp;quot; )&lt;br /&gt;
    local s = alert&lt;br /&gt;
    if type( s ) == &amp;quot;string&amp;quot; then&lt;br /&gt;
        s = mw.text.trim( s )&lt;br /&gt;
        if s == &amp;quot;&amp;quot; then&lt;br /&gt;
            s = &amp;quot;EMPTY JSONutil.fault key&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        if not s:find( &amp;quot; &amp;quot;, 1, true ) then&lt;br /&gt;
            local storage = string.format( &amp;quot;I18n/Module:%s.tab&amp;quot;,&lt;br /&gt;
                                           JSONutil.suite )&lt;br /&gt;
            local lucky, t = pcall( mw.ext.data.get, storage, &amp;quot;_&amp;quot; )&lt;br /&gt;
            if type( t ) == &amp;quot;table&amp;quot; then&lt;br /&gt;
                t = t.data&lt;br /&gt;
                if type( t ) == &amp;quot;table&amp;quot; then&lt;br /&gt;
                    local e&lt;br /&gt;
                    s = &amp;quot;err_&amp;quot; .. s&lt;br /&gt;
                    for i = 1, #t do&lt;br /&gt;
                        e = t[ i ]&lt;br /&gt;
                        if type( e ) == &amp;quot;table&amp;quot; then&lt;br /&gt;
                            if e[ 1 ] == s then&lt;br /&gt;
                                e = e[ 2 ]&lt;br /&gt;
                                if type( e ) == &amp;quot;table&amp;quot; then&lt;br /&gt;
                                    local q = type( adapt )&lt;br /&gt;
                                    if q == &amp;quot;function&amp;quot; then&lt;br /&gt;
                                        s = adapt( e, s )&lt;br /&gt;
                                        t = false&lt;br /&gt;
                                    elseif q == &amp;quot;string&amp;quot; then&lt;br /&gt;
                                        t = mw.text.split( adapt, &amp;quot;%s+&amp;quot; )&lt;br /&gt;
                                    elseif q == &amp;quot;table&amp;quot; then&lt;br /&gt;
                                        t = adapt&lt;br /&gt;
                                    else&lt;br /&gt;
                                        t = { }&lt;br /&gt;
                                    end&lt;br /&gt;
                                    if t then&lt;br /&gt;
                                        table.insert( t, Fallback() )&lt;br /&gt;
                                        table.insert( t, &amp;quot;en&amp;quot; )&lt;br /&gt;
                                        for k = 1, #t do&lt;br /&gt;
                                            q = e[ t[ k ] ]&lt;br /&gt;
                                            if type( q ) == &amp;quot;string&amp;quot; then&lt;br /&gt;
                                                s = q&lt;br /&gt;
                                                break   -- for k&lt;br /&gt;
                                            end&lt;br /&gt;
                                        end   -- for k&lt;br /&gt;
                                    end&lt;br /&gt;
                                else&lt;br /&gt;
                                    s = &amp;quot;JSONutil.fault I18N bad #&amp;quot; ..&lt;br /&gt;
                                        tostring( i )&lt;br /&gt;
                                end&lt;br /&gt;
                                break   -- for i&lt;br /&gt;
                            end&lt;br /&gt;
                        else&lt;br /&gt;
                            break   -- for i&lt;br /&gt;
                        end&lt;br /&gt;
                    end   -- for i&lt;br /&gt;
                else&lt;br /&gt;
                    s = &amp;quot;INVALID JSONutil.fault I18N corrupted&amp;quot;&lt;br /&gt;
                end&lt;br /&gt;
            else&lt;br /&gt;
                s = &amp;quot;INVALID JSONutil.fault commons:Data: &amp;quot; .. type( t )&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
    else&lt;br /&gt;
        s = &amp;quot;INVALID JSONutil.fault key: &amp;quot; .. tostring( s )&lt;br /&gt;
    end&lt;br /&gt;
    if type( add ) == &amp;quot;string&amp;quot; then&lt;br /&gt;
        s = string.format( &amp;quot;%s &amp;amp;#8211; %s&amp;quot;, s, add )&lt;br /&gt;
    end&lt;br /&gt;
    e:wikitext( s )&lt;br /&gt;
    return tostring( e )&lt;br /&gt;
end -- JSONutil.fault()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
JSONutil.fetch = function ( apply, always, adapt )&lt;br /&gt;
    -- Retrieve JSON data, or error message&lt;br /&gt;
    -- Parameter:&lt;br /&gt;
    --     apply   -- string, with presumable JSON text&lt;br /&gt;
    --     always  -- true, if apply is expected to need preprocessing&lt;br /&gt;
    --     adapt   -- function|string|table|nil|false, for I18N&lt;br /&gt;
    -- Returns table, with data, or string, with error as HTML span&lt;br /&gt;
    local lucky, r&lt;br /&gt;
    if not always then&lt;br /&gt;
        lucky, r = pcall( mw.text.jsonDecode, apply )&lt;br /&gt;
    end&lt;br /&gt;
    if not lucky then&lt;br /&gt;
        lucky, r = JSONutil.fair( apply )&lt;br /&gt;
        if lucky then&lt;br /&gt;
            r = JSONutil.fault( lucky, r, adapt )&lt;br /&gt;
        else&lt;br /&gt;
            lucky, r = pcall( mw.text.jsonDecode, r )&lt;br /&gt;
            if not lucky then&lt;br /&gt;
                r = JSONutil.fault( r, false, adapt )&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    return r&lt;br /&gt;
end -- JSONutil.fetch()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Failsafe.failsafe = function ( atleast )&lt;br /&gt;
    -- Retrieve versioning and check for compliance&lt;br /&gt;
    -- Precondition:&lt;br /&gt;
    --     atleast  -- string, with required version or &amp;quot;wikidata&amp;quot; or &amp;quot;~&amp;quot;&lt;br /&gt;
    --                 or false&lt;br /&gt;
    -- Postcondition:&lt;br /&gt;
    --     Returns  string  -- with queried version, also if problem&lt;br /&gt;
    --              false   -- if appropriate&lt;br /&gt;
    local last  = ( atleast == &amp;quot;~&amp;quot; )&lt;br /&gt;
    local since = atleast&lt;br /&gt;
    local r&lt;br /&gt;
    if last  or  since == &amp;quot;wikidata&amp;quot; then&lt;br /&gt;
        local item = Failsafe.item&lt;br /&gt;
        since = false&lt;br /&gt;
        if type( item ) == &amp;quot;number&amp;quot;  and  item &amp;gt; 0 then&lt;br /&gt;
            local entity = mw.wikibase.getEntity( string.format( &amp;quot;Q%d&amp;quot;,&lt;br /&gt;
                                                                 item ) )&lt;br /&gt;
            if type( entity ) == &amp;quot;table&amp;quot; then&lt;br /&gt;
                local vsn = entity:formatPropertyValues( &amp;quot;P348&amp;quot; )&lt;br /&gt;
                if type( vsn ) == &amp;quot;table&amp;quot;  and&lt;br /&gt;
                   type( vsn.value ) == &amp;quot;string&amp;quot;  and&lt;br /&gt;
                   vsn.value ~= &amp;quot;&amp;quot; then&lt;br /&gt;
                    if last  and  vsn.value == Failsafe.serial then&lt;br /&gt;
                        r = false&lt;br /&gt;
                    else&lt;br /&gt;
                        r = vsn.value&lt;br /&gt;
                    end&lt;br /&gt;
                end&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    if type( r ) == &amp;quot;nil&amp;quot; then&lt;br /&gt;
        if not since  or  since &amp;lt;= Failsafe.serial then&lt;br /&gt;
            r = Failsafe.serial&lt;br /&gt;
        else&lt;br /&gt;
            r = false&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    return r&lt;br /&gt;
end -- Failsafe.failsafe()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- Export&lt;br /&gt;
local p = { }&lt;br /&gt;
&lt;br /&gt;
p.failsafe = function ( frame )&lt;br /&gt;
    -- Versioning interface&lt;br /&gt;
    local s = type( frame )&lt;br /&gt;
    local since&lt;br /&gt;
    if s == &amp;quot;table&amp;quot; then&lt;br /&gt;
        since = frame.args[ 1 ]&lt;br /&gt;
    elseif s == &amp;quot;string&amp;quot; then&lt;br /&gt;
        since = frame&lt;br /&gt;
    end&lt;br /&gt;
    if since then&lt;br /&gt;
        since = mw.text.trim( since )&lt;br /&gt;
        if since == &amp;quot;&amp;quot; then&lt;br /&gt;
            since = false&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    return Failsafe.failsafe( since )  or  &amp;quot;&amp;quot;&lt;br /&gt;
end -- p.failsafe()&lt;br /&gt;
&lt;br /&gt;
p.JSONutil = function ()&lt;br /&gt;
    -- Module interface&lt;br /&gt;
    return JSONutil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>en&gt;PerfektesChaos</name></author>
	</entry>
</feed>