-- Binary, Decimal, Hexadecimal, Octal conversion
-- Author: Tim Kelly and Andrew Stacey
-- Websites: http://w...content-available-to-author-only...s.com/Lua/code/BinDecHex.shtml
--           http://w...content-available-to-author-only...u.no/~stacey/HowDidIDoThat/iPad/Codea.html
-- Licence: See below
 
--[[
/*
 * Copyright (c) 2007 Tim Kelly/Dialectronics
 *
 * Permission is hereby granted, free of charge, to any person obtaining 
 * a copy of this software and associated documentation files (the 
 * "Software"),  to deal in the Software without restriction, including 
 * without limitation the rights to use, copy, modify, merge, publish, 
 * distribute, sublicense, and/or sell copies of the Software, and to permit 
 * persons to whom the Software is furnished to do so, subject to the 
 * following conditions:
 *
 * The above copyright notice and this permission notice shall be 
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT 
 * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 
 * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
 
--]]
 
--[[
Formatting suitable for Codea on iPad together with octal functions by
Andrew Stacey.  Additions released under the original license.
--]]
 
local hex2bin = {
        ["0"] = "0000",
        ["1"] = "0001",
        ["2"] = "0010",
        ["3"] = "0011",
        ["4"] = "0100",
        ["5"] = "0101",
        ["6"] = "0110",
        ["7"] = "0111",
        ["8"] = "1000",
        ["9"] = "1001",
        ["a"] = "1010",
        ["b"] = "1011",
        ["c"] = "1100",
        ["d"] = "1101",
        ["e"] = "1110",
        ["f"] = "1111"
        }
 
 
local bin2hex = {
    ["0000"] = "0",
    ["0001"] = "1",
    ["0010"] = "2",
    ["0011"] = "3",
    ["0100"] = "4",
    ["0101"] = "5",
    ["0110"] = "6",
    ["0111"] = "7",
    ["1000"] = "8",
    ["1001"] = "9",
    ["1010"] = "A",
    ["1011"] = "B",
    ["1100"] = "C",
    ["1101"] = "D",
    ["1110"] = "E",
    ["1111"] = "F"
}
 
local bin2oct = {
    ["000"] = "0",
    ["001"] = "1",
    ["010"] = "2",
    ["011"] = "3",
    ["100"] = "4",
    ["101"] = "5",
    ["110"] = "6",
    ["111"] = "7"
}
 
local oct2bin = {
    ["0"] = "000",
    ["1"] = "001",
    ["2"] = "010",
    ["3"] = "011",
    ["4"] = "100",
    ["5"] = "101",
    ["6"] = "110",
    ["7"] = "111"
}
 
 
-- These functions are big-endian and take up to 32 bits
 
-- Hex2Bin
-- Bin2Hex
-- Hex2Dec
-- Dec2Hex
-- Bin2Dec
-- Dec2Bin
 
 
function Hex2Bin(s)
 
-- s -> hexadecimal string
 
local ret = ""
local i = 0
 
 
    for i in string.gfind(s, ".") do
        i = string.lower(i)
 
        ret = ret..hex2bin[i]
 
    end
 
    return ret
end
 
function Bin2Hex(s)
 
-- s -> binary string
 
local l = 0
local h = ""
local b = ""
local rem
 
l = string.len(s)
rem = l % 4
l = l-1
h = ""
 
    -- need to prepend zeros to eliminate mod 4
    if (rem > 0) then
        s = string.rep("0", 4 - rem)..s
    end
 
    for i = 1, l, 4 do
        b = string.sub(s, i, i+3)
        h = h..bin2hex[b]
    end
 
    return h
 
end
 
function Bin2Oct(s)
 
-- s -> binary string
 
local l = 0
local h = ""
local b = ""
local rem
 
l = string.len(s)
rem = l % 3
l = l-1
h = ""
 
    -- need to prepend zeros to eliminate mod 3
    if (rem > 0) then
        s = string.rep("0", 3 - rem)..s
    end
 
    for i = 1, l, 3 do
        b = string.sub(s, i, i+2)
        h = h..bin2oct[b]
    end
 
    return h
 
end
 
function Oct2Bin(s)
 
-- s -> octal string
 
local ret = ""
local i = 0
 
 
    for i in string.gfind(s, ".") do
        i = string.lower(i)
 
        ret = ret..oct2bin[i]
 
    end
 
    return ret
end
 
function Bin2Dec(s)
 
-- s -> binary string
 
local num = 0
local ex = string.len(s) - 1
local l = 0
 
    l = ex + 1
    for i = 1, l do
        b = string.sub(s, i, i)
        if b == "1" then
            num = num + 2^ex
        end
        ex = ex - 1
    end
 
    return string.format("%u", num)
 
end
 
 
 
function Dec2Bin(s, num)
 
-- s -> Base10 string
-- num  -> string length to extend to
 
local n
 
    if (num == nil) then
        n = 0
    else
        n = num
    end
 
    s = string.format("%x", s)
 
    s = Hex2Bin(s)
 
    while string.len(s) < n do
        s = "0"..s
    end
 
    return s
 
end
 
 
 
 
function Hex2Dec(s)
 
-- s -> hexadecimal string
 
    local s = Hex2Bin(s)
 
    return Bin2Dec(s)
 
end
 
 
 
function Dec2Hex(s)
 
-- s -> Base10 string
 
    s = string.format("%x", s)
 
    return s
 
end
 
function Hex2Oct(s)
 
-- s -> hexadecimal string
 
    local s = Hex2Bin(s)
 
    return Bin2Oct(s)
 
end
 
 
 
function Oct2Hex(s)
 
-- s -> Base8 string
 
    local s = Oct2Bin(s)
 
    return Bin2Hex(s)
 
end
 
function Dec2Oct(s)
 
-- s -> decimal string
 
    s = string.format("%o", s)
 
    return s
 
end
 
 
 
function Oct2Dec(s)
 
-- s -> Base10 string
 
    local s = Oct2Bin(s)
 
    return Bin2Dec(s)
 
end
 
-- These functions are big-endian and will extend to 32 bits
 
-- BMAnd
-- BMNAnd
-- BMOr
-- BMXOr
-- BMNot
 
 
function BMAnd(v, m)
 
-- v    -> hex string to be masked
-- m    -> hex string mask
 
-- s    -> hex string as masked
 
-- bv   -> binary string of v
-- bm   -> binary string mask
 
local bv = Hex2Bin(v)
local bm = Hex2Bin(m)
 
local i = 0
local s = ""
 
        while (string.len(bv) < 32) do
                bv = "0000"..bv
        end
 
        while (string.len(bm) < 32) do
                bm = "0000"..bm
        end
 
 
        for i = 1, 32 do
                cv = string.sub(bv, i, i)
                cm = string.sub(bm, i, i)
                if cv == cm then
                        if cv == "1" then
                                s = s.."1"
                        else
                                s = s.."0"
                        end
                else
                        s = s.."0"
 
                end
        end
 
        return Bin2Hex(s)
 
end
 
 
function BMNAnd(v, m)
 
-- v    -> hex string to be masked
-- m    -> hex string mask
 
-- s    -> hex string as masked
 
-- bv   -> binary string of v
-- bm   -> binary string mask
 
local bv = Hex2Bin(v)
local bm = Hex2Bin(m)
 
local i = 0
local s = ""
 
        while (string.len(bv) < 32) do
                bv = "0000"..bv
        end
 
        while (string.len(bm) < 32) do
                bm = "0000"..bm
        end
 
 
        for i = 1, 32 do
                cv = string.sub(bv, i, i)
                cm = string.sub(bm, i, i)
                if cv == cm then
                        if cv == "1" then
                                s = s.."0"
                        else
                                s = s.."1"
                        end
                else
                        s = s.."1"
 
                end
        end
 
        return Bin2Hex(s)
 
end
 
 
 
function BMOr(v, m)
 
-- v    -> hex string to be masked
-- m    -> hex string mask
 
-- s    -> hex string as masked
 
-- bv   -> binary string of v
-- bm   -> binary string mask
 
local bv = Hex2Bin(v)
local bm = Hex2Bin(m)
 
local i = 0
local s = ""
 
        while (string.len(bv) < 32) do
                bv = "0000"..bv
        end
 
        while (string.len(bm) < 32) do
                bm = "0000"..bm
        end
 
 
        for i = 1, 32 do
                cv = string.sub(bv, i, i)
                cm = string.sub(bm, i, i)
                if cv == "1" then
                                s = s.."1"
                elseif cm == "1" then
                                s = s.."1"
                else
                        s = s.."0"
                end
        end
 
        return Bin2Hex(s)
 
end
 
function BMXOr(v, m)
 
-- v    -> hex string to be masked
-- m    -> hex string mask
 
-- s    -> hex string as masked
 
-- bv   -> binary string of v
-- bm   -> binary string mask
 
local bv = Hex2Bin(v)
local bm = Hex2Bin(m)
 
local i = 0
local s = ""
 
        while (string.len(bv) < 32) do
                bv = "0000"..bv
        end
 
        while (string.len(bm) < 32) do
                bm = "0000"..bm
        end
 
 
        for i = 1, 32 do
                cv = string.sub(bv, i, i)
                cm = string.sub(bm, i, i)
                if cv == "1" then
                        if cm == "0" then
                                s = s.."1"
                        else
                                s = s.."0"
                        end
                elseif cm == "1" then
                        if cv == "0" then
                                s = s.."1"
                        else
                                s = s.."0"
                        end
                else
                        -- cv and cm == "0"
                        s = s.."0"
                end
        end
 
        return Bin2Hex(s)
 
end
 
 
function BMNot(v, m)
 
-- v    -> hex string to be masked
-- m    -> hex string mask
 
-- s    -> hex string as masked
 
-- bv   -> binary string of v
-- bm   -> binary string mask
 
local bv = Hex2Bin(v)
local bm = Hex2Bin(m)
 
local i = 0
local s = ""
 
        while (string.len(bv) < 32) do
                bv = "0000"..bv
        end
 
        while (string.len(bm) < 32) do
                bm = "0000"..bm
        end
 
 
        for i = 1, 32 do
                cv = string.sub(bv, i, i)
                cm = string.sub(bm, i, i)
                if cm == "1" then
                        if cv == "1" then
                                -- turn off
                                s = s.."0"
                        else
                                -- turn on
                                s = s.."1"
                        end
                else
                        -- leave untouched
                        s = s..cv
 
                end
        end
 
        return Bin2Hex(s)
 
end
 
 
-- these functions shift right and left, adding zeros to lost or gained bits
-- returned values are 32 bits long
 
-- BShRight(v, nb)
-- BShLeft(v, nb)
 
 
function BShRight(v, nb)
 
-- v    -> hexstring value to be shifted
-- nb   -> number of bits to shift to the right
 
-- s    -> binary string of v
 
local s = Hex2Bin(v)
 
        while (string.len(s) < 32) do
                s = "0000"..s
        end
 
        s = string.sub(s, 1, 32 - nb)
 
        while (string.len(s) < 32) do
                s = "0"..s
        end
 
        return Bin2Hex(s)
 
end
 
function BShLeft(v, nb)
 
-- v    -> hexstring value to be shifted
-- nb   -> number of bits to shift to the right
 
-- s    -> binary string of v
 
local s = Hex2Bin(v)
 
        while (string.len(s) < 32) do
                s = "0000"..s
        end
 
        s = string.sub(s, nb + 1, 32)
 
        while (string.len(s) < 32) do
                s = s.."0"
        end
 
        return Bin2Hex(s)
 
end
 
 
print(Bin2Hex("11001010"))
				LS0gQmluYXJ5LCBEZWNpbWFsLCBIZXhhZGVjaW1hbCwgT2N0YWwgY29udmVyc2lvbgotLSBBdXRob3I6IFRpbSBLZWxseSBhbmQgQW5kcmV3IFN0YWNleQotLSBXZWJzaXRlczogaHR0cDovL3cuLi5jb250ZW50LWF2YWlsYWJsZS10by1hdXRob3Itb25seS4uLnMuY29tL0x1YS9jb2RlL0JpbkRlY0hleC5zaHRtbAotLSAgICAgICAgICAgaHR0cDovL3cuLi5jb250ZW50LWF2YWlsYWJsZS10by1hdXRob3Itb25seS4uLnUubm8vfnN0YWNleS9Ib3dEaWRJRG9UaGF0L2lQYWQvQ29kZWEuaHRtbAotLSBMaWNlbmNlOiBTZWUgYmVsb3cKCi0tW1sKLyoKICogQ29weXJpZ2h0IChjKSAyMDA3IFRpbSBLZWxseS9EaWFsZWN0cm9uaWNzCiAqCiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyAKICogYSBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIAogKiAiU29mdHdhcmUiKSwgIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyAKICogd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCAKICogZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCAKICogcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIAogKiBmb2xsb3dpbmcgY29uZGl0aW9uczoKICoKICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgCiAqIGluY2x1ZGVkIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgogKgogKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgCiAqIEVYUFJFU1MgT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiAKICogTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiAgCiAqIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIAogKiBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIAogKiBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgCiAqIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLgogKi8KCi0tXV0KCi0tW1sKRm9ybWF0dGluZyBzdWl0YWJsZSBmb3IgQ29kZWEgb24gaVBhZCB0b2dldGhlciB3aXRoIG9jdGFsIGZ1bmN0aW9ucyBieQpBbmRyZXcgU3RhY2V5LiAgQWRkaXRpb25zIHJlbGVhc2VkIHVuZGVyIHRoZSBvcmlnaW5hbCBsaWNlbnNlLgotLV1dCgpsb2NhbCBoZXgyYmluID0gewogICAgICAgIFsiMCJdID0gIjAwMDAiLAogICAgICAgIFsiMSJdID0gIjAwMDEiLAogICAgICAgIFsiMiJdID0gIjAwMTAiLAogICAgICAgIFsiMyJdID0gIjAwMTEiLAogICAgICAgIFsiNCJdID0gIjAxMDAiLAogICAgICAgIFsiNSJdID0gIjAxMDEiLAogICAgICAgIFsiNiJdID0gIjAxMTAiLAogICAgICAgIFsiNyJdID0gIjAxMTEiLAogICAgICAgIFsiOCJdID0gIjEwMDAiLAogICAgICAgIFsiOSJdID0gIjEwMDEiLAogICAgICAgIFsiYSJdID0gIjEwMTAiLAogICAgICAgIFsiYiJdID0gIjEwMTEiLAogICAgICAgIFsiYyJdID0gIjExMDAiLAogICAgICAgIFsiZCJdID0gIjExMDEiLAogICAgICAgIFsiZSJdID0gIjExMTAiLAogICAgICAgIFsiZiJdID0gIjExMTEiCiAgICAgICAgfQoKCmxvY2FsIGJpbjJoZXggPSB7CiAgICBbIjAwMDAiXSA9ICIwIiwKICAgIFsiMDAwMSJdID0gIjEiLAogICAgWyIwMDEwIl0gPSAiMiIsCiAgICBbIjAwMTEiXSA9ICIzIiwKICAgIFsiMDEwMCJdID0gIjQiLAogICAgWyIwMTAxIl0gPSAiNSIsCiAgICBbIjAxMTAiXSA9ICI2IiwKICAgIFsiMDExMSJdID0gIjciLAogICAgWyIxMDAwIl0gPSAiOCIsCiAgICBbIjEwMDEiXSA9ICI5IiwKICAgIFsiMTAxMCJdID0gIkEiLAogICAgWyIxMDExIl0gPSAiQiIsCiAgICBbIjExMDAiXSA9ICJDIiwKICAgIFsiMTEwMSJdID0gIkQiLAogICAgWyIxMTEwIl0gPSAiRSIsCiAgICBbIjExMTEiXSA9ICJGIgp9Cgpsb2NhbCBiaW4yb2N0ID0gewogICAgWyIwMDAiXSA9ICIwIiwKICAgIFsiMDAxIl0gPSAiMSIsCiAgICBbIjAxMCJdID0gIjIiLAogICAgWyIwMTEiXSA9ICIzIiwKICAgIFsiMTAwIl0gPSAiNCIsCiAgICBbIjEwMSJdID0gIjUiLAogICAgWyIxMTAiXSA9ICI2IiwKICAgIFsiMTExIl0gPSAiNyIKfQoKbG9jYWwgb2N0MmJpbiA9IHsKICAgIFsiMCJdID0gIjAwMCIsCiAgICBbIjEiXSA9ICIwMDEiLAogICAgWyIyIl0gPSAiMDEwIiwKICAgIFsiMyJdID0gIjAxMSIsCiAgICBbIjQiXSA9ICIxMDAiLAogICAgWyI1Il0gPSAiMTAxIiwKICAgIFsiNiJdID0gIjExMCIsCiAgICBbIjciXSA9ICIxMTEiCn0KCgotLSBUaGVzZSBmdW5jdGlvbnMgYXJlIGJpZy1lbmRpYW4gYW5kIHRha2UgdXAgdG8gMzIgYml0cwoKLS0gSGV4MkJpbgotLSBCaW4ySGV4Ci0tIEhleDJEZWMKLS0gRGVjMkhleAotLSBCaW4yRGVjCi0tIERlYzJCaW4KCgpmdW5jdGlvbiBIZXgyQmluKHMpCgotLSBzIC0+IGhleGFkZWNpbWFsIHN0cmluZwoKbG9jYWwgcmV0ID0gIiIKbG9jYWwgaSA9IDAKCgogICAgZm9yIGkgaW4gc3RyaW5nLmdmaW5kKHMsICIuIikgZG8KICAgICAgICBpID0gc3RyaW5nLmxvd2VyKGkpCgogICAgICAgIHJldCA9IHJldC4uaGV4MmJpbltpXQoKICAgIGVuZAoKICAgIHJldHVybiByZXQKZW5kCgpmdW5jdGlvbiBCaW4ySGV4KHMpCgotLSBzIC0+IGJpbmFyeSBzdHJpbmcKCmxvY2FsIGwgPSAwCmxvY2FsIGggPSAiIgpsb2NhbCBiID0gIiIKbG9jYWwgcmVtCgpsID0gc3RyaW5nLmxlbihzKQpyZW0gPSBsICUgNApsID0gbC0xCmggPSAiIgoKICAgIC0tIG5lZWQgdG8gcHJlcGVuZCB6ZXJvcyB0byBlbGltaW5hdGUgbW9kIDQKICAgIGlmIChyZW0gPiAwKSB0aGVuCiAgICAgICAgcyA9IHN0cmluZy5yZXAoIjAiLCA0IC0gcmVtKS4ucwogICAgZW5kCgogICAgZm9yIGkgPSAxLCBsLCA0IGRvCiAgICAgICAgYiA9IHN0cmluZy5zdWIocywgaSwgaSszKQogICAgICAgIGggPSBoLi5iaW4yaGV4W2JdCiAgICBlbmQKCiAgICByZXR1cm4gaAoKZW5kCgpmdW5jdGlvbiBCaW4yT2N0KHMpCgotLSBzIC0+IGJpbmFyeSBzdHJpbmcKCmxvY2FsIGwgPSAwCmxvY2FsIGggPSAiIgpsb2NhbCBiID0gIiIKbG9jYWwgcmVtCgpsID0gc3RyaW5nLmxlbihzKQpyZW0gPSBsICUgMwpsID0gbC0xCmggPSAiIgoKICAgIC0tIG5lZWQgdG8gcHJlcGVuZCB6ZXJvcyB0byBlbGltaW5hdGUgbW9kIDMKICAgIGlmIChyZW0gPiAwKSB0aGVuCiAgICAgICAgcyA9IHN0cmluZy5yZXAoIjAiLCAzIC0gcmVtKS4ucwogICAgZW5kCgogICAgZm9yIGkgPSAxLCBsLCAzIGRvCiAgICAgICAgYiA9IHN0cmluZy5zdWIocywgaSwgaSsyKQogICAgICAgIGggPSBoLi5iaW4yb2N0W2JdCiAgICBlbmQKCiAgICByZXR1cm4gaAoKZW5kCgpmdW5jdGlvbiBPY3QyQmluKHMpCgotLSBzIC0+IG9jdGFsIHN0cmluZwoKbG9jYWwgcmV0ID0gIiIKbG9jYWwgaSA9IDAKCgogICAgZm9yIGkgaW4gc3RyaW5nLmdmaW5kKHMsICIuIikgZG8KICAgICAgICBpID0gc3RyaW5nLmxvd2VyKGkpCgogICAgICAgIHJldCA9IHJldC4ub2N0MmJpbltpXQoKICAgIGVuZAoKICAgIHJldHVybiByZXQKZW5kCgpmdW5jdGlvbiBCaW4yRGVjKHMpCgotLSBzIC0+IGJpbmFyeSBzdHJpbmcKCmxvY2FsIG51bSA9IDAKbG9jYWwgZXggPSBzdHJpbmcubGVuKHMpIC0gMQpsb2NhbCBsID0gMAoKICAgIGwgPSBleCArIDEKICAgIGZvciBpID0gMSwgbCBkbwogICAgICAgIGIgPSBzdHJpbmcuc3ViKHMsIGksIGkpCiAgICAgICAgaWYgYiA9PSAiMSIgdGhlbgogICAgICAgICAgICBudW0gPSBudW0gKyAyXmV4CiAgICAgICAgZW5kCiAgICAgICAgZXggPSBleCAtIDEKICAgIGVuZAoKICAgIHJldHVybiBzdHJpbmcuZm9ybWF0KCIldSIsIG51bSkKCmVuZAoKCgpmdW5jdGlvbiBEZWMyQmluKHMsIG51bSkKCi0tIHMgLT4gQmFzZTEwIHN0cmluZwotLSBudW0gIC0+IHN0cmluZyBsZW5ndGggdG8gZXh0ZW5kIHRvCgpsb2NhbCBuCgogICAgaWYgKG51bSA9PSBuaWwpIHRoZW4KICAgICAgICBuID0gMAogICAgZWxzZQogICAgICAgIG4gPSBudW0KICAgIGVuZAoKICAgIHMgPSBzdHJpbmcuZm9ybWF0KCIleCIsIHMpCgogICAgcyA9IEhleDJCaW4ocykKCiAgICB3aGlsZSBzdHJpbmcubGVuKHMpIDwgbiBkbwogICAgICAgIHMgPSAiMCIuLnMKICAgIGVuZAoKICAgIHJldHVybiBzCgplbmQKCgoKCmZ1bmN0aW9uIEhleDJEZWMocykKCi0tIHMgLT4gaGV4YWRlY2ltYWwgc3RyaW5nCgogICAgbG9jYWwgcyA9IEhleDJCaW4ocykKCiAgICByZXR1cm4gQmluMkRlYyhzKQoKZW5kCgoKCmZ1bmN0aW9uIERlYzJIZXgocykKCi0tIHMgLT4gQmFzZTEwIHN0cmluZwoKICAgIHMgPSBzdHJpbmcuZm9ybWF0KCIleCIsIHMpCgogICAgcmV0dXJuIHMKCmVuZAoKZnVuY3Rpb24gSGV4Mk9jdChzKQoKLS0gcyAtPiBoZXhhZGVjaW1hbCBzdHJpbmcKCiAgICBsb2NhbCBzID0gSGV4MkJpbihzKQoKICAgIHJldHVybiBCaW4yT2N0KHMpCgplbmQKCgoKZnVuY3Rpb24gT2N0MkhleChzKQoKLS0gcyAtPiBCYXNlOCBzdHJpbmcKCiAgICBsb2NhbCBzID0gT2N0MkJpbihzKQoKICAgIHJldHVybiBCaW4ySGV4KHMpCgplbmQKCmZ1bmN0aW9uIERlYzJPY3QocykKCi0tIHMgLT4gZGVjaW1hbCBzdHJpbmcKCiAgICBzID0gc3RyaW5nLmZvcm1hdCgiJW8iLCBzKQoKICAgIHJldHVybiBzCgplbmQKCgoKZnVuY3Rpb24gT2N0MkRlYyhzKQoKLS0gcyAtPiBCYXNlMTAgc3RyaW5nCgogICAgbG9jYWwgcyA9IE9jdDJCaW4ocykKCiAgICByZXR1cm4gQmluMkRlYyhzKQoKZW5kCgotLSBUaGVzZSBmdW5jdGlvbnMgYXJlIGJpZy1lbmRpYW4gYW5kIHdpbGwgZXh0ZW5kIHRvIDMyIGJpdHMKCi0tIEJNQW5kCi0tIEJNTkFuZAotLSBCTU9yCi0tIEJNWE9yCi0tIEJNTm90CgoKZnVuY3Rpb24gQk1BbmQodiwgbSkKCi0tIHYgICAgLT4gaGV4IHN0cmluZyB0byBiZSBtYXNrZWQKLS0gbSAgICAtPiBoZXggc3RyaW5nIG1hc2sKCi0tIHMgICAgLT4gaGV4IHN0cmluZyBhcyBtYXNrZWQKCi0tIGJ2ICAgLT4gYmluYXJ5IHN0cmluZyBvZiB2Ci0tIGJtICAgLT4gYmluYXJ5IHN0cmluZyBtYXNrCgpsb2NhbCBidiA9IEhleDJCaW4odikKbG9jYWwgYm0gPSBIZXgyQmluKG0pCgpsb2NhbCBpID0gMApsb2NhbCBzID0gIiIKCiAgICAgICAgd2hpbGUgKHN0cmluZy5sZW4oYnYpIDwgMzIpIGRvCiAgICAgICAgICAgICAgICBidiA9ICIwMDAwIi4uYnYKICAgICAgICBlbmQKCiAgICAgICAgd2hpbGUgKHN0cmluZy5sZW4oYm0pIDwgMzIpIGRvCiAgICAgICAgICAgICAgICBibSA9ICIwMDAwIi4uYm0KICAgICAgICBlbmQKCgogICAgICAgIGZvciBpID0gMSwgMzIgZG8KICAgICAgICAgICAgICAgIGN2ID0gc3RyaW5nLnN1YihidiwgaSwgaSkKICAgICAgICAgICAgICAgIGNtID0gc3RyaW5nLnN1YihibSwgaSwgaSkKICAgICAgICAgICAgICAgIGlmIGN2ID09IGNtIHRoZW4KICAgICAgICAgICAgICAgICAgICAgICAgaWYgY3YgPT0gIjEiIHRoZW4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzID0gcy4uIjEiCiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzID0gcy4uIjAiCiAgICAgICAgICAgICAgICAgICAgICAgIGVuZAogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICBzID0gcy4uIjAiCgogICAgICAgICAgICAgICAgZW5kCiAgICAgICAgZW5kCgogICAgICAgIHJldHVybiBCaW4ySGV4KHMpCgplbmQKCgpmdW5jdGlvbiBCTU5BbmQodiwgbSkKCi0tIHYgICAgLT4gaGV4IHN0cmluZyB0byBiZSBtYXNrZWQKLS0gbSAgICAtPiBoZXggc3RyaW5nIG1hc2sKCi0tIHMgICAgLT4gaGV4IHN0cmluZyBhcyBtYXNrZWQKCi0tIGJ2ICAgLT4gYmluYXJ5IHN0cmluZyBvZiB2Ci0tIGJtICAgLT4gYmluYXJ5IHN0cmluZyBtYXNrCgpsb2NhbCBidiA9IEhleDJCaW4odikKbG9jYWwgYm0gPSBIZXgyQmluKG0pCgpsb2NhbCBpID0gMApsb2NhbCBzID0gIiIKCiAgICAgICAgd2hpbGUgKHN0cmluZy5sZW4oYnYpIDwgMzIpIGRvCiAgICAgICAgICAgICAgICBidiA9ICIwMDAwIi4uYnYKICAgICAgICBlbmQKCiAgICAgICAgd2hpbGUgKHN0cmluZy5sZW4oYm0pIDwgMzIpIGRvCiAgICAgICAgICAgICAgICBibSA9ICIwMDAwIi4uYm0KICAgICAgICBlbmQKCgogICAgICAgIGZvciBpID0gMSwgMzIgZG8KICAgICAgICAgICAgICAgIGN2ID0gc3RyaW5nLnN1YihidiwgaSwgaSkKICAgICAgICAgICAgICAgIGNtID0gc3RyaW5nLnN1YihibSwgaSwgaSkKICAgICAgICAgICAgICAgIGlmIGN2ID09IGNtIHRoZW4KICAgICAgICAgICAgICAgICAgICAgICAgaWYgY3YgPT0gIjEiIHRoZW4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzID0gcy4uIjAiCiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzID0gcy4uIjEiCiAgICAgICAgICAgICAgICAgICAgICAgIGVuZAogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICBzID0gcy4uIjEiCgogICAgICAgICAgICAgICAgZW5kCiAgICAgICAgZW5kCgogICAgICAgIHJldHVybiBCaW4ySGV4KHMpCgplbmQKCgoKZnVuY3Rpb24gQk1Pcih2LCBtKQoKLS0gdiAgICAtPiBoZXggc3RyaW5nIHRvIGJlIG1hc2tlZAotLSBtICAgIC0+IGhleCBzdHJpbmcgbWFzawoKLS0gcyAgICAtPiBoZXggc3RyaW5nIGFzIG1hc2tlZAoKLS0gYnYgICAtPiBiaW5hcnkgc3RyaW5nIG9mIHYKLS0gYm0gICAtPiBiaW5hcnkgc3RyaW5nIG1hc2sKCmxvY2FsIGJ2ID0gSGV4MkJpbih2KQpsb2NhbCBibSA9IEhleDJCaW4obSkKCmxvY2FsIGkgPSAwCmxvY2FsIHMgPSAiIgoKICAgICAgICB3aGlsZSAoc3RyaW5nLmxlbihidikgPCAzMikgZG8KICAgICAgICAgICAgICAgIGJ2ID0gIjAwMDAiLi5idgogICAgICAgIGVuZAoKICAgICAgICB3aGlsZSAoc3RyaW5nLmxlbihibSkgPCAzMikgZG8KICAgICAgICAgICAgICAgIGJtID0gIjAwMDAiLi5ibQogICAgICAgIGVuZAoKCiAgICAgICAgZm9yIGkgPSAxLCAzMiBkbwogICAgICAgICAgICAgICAgY3YgPSBzdHJpbmcuc3ViKGJ2LCBpLCBpKQogICAgICAgICAgICAgICAgY20gPSBzdHJpbmcuc3ViKGJtLCBpLCBpKQogICAgICAgICAgICAgICAgaWYgY3YgPT0gIjEiIHRoZW4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzID0gcy4uIjEiCiAgICAgICAgICAgICAgICBlbHNlaWYgY20gPT0gIjEiIHRoZW4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzID0gcy4uIjEiCiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHMgPSBzLi4iMCIKICAgICAgICAgICAgICAgIGVuZAogICAgICAgIGVuZAoKICAgICAgICByZXR1cm4gQmluMkhleChzKQoKZW5kCgpmdW5jdGlvbiBCTVhPcih2LCBtKQoKLS0gdiAgICAtPiBoZXggc3RyaW5nIHRvIGJlIG1hc2tlZAotLSBtICAgIC0+IGhleCBzdHJpbmcgbWFzawoKLS0gcyAgICAtPiBoZXggc3RyaW5nIGFzIG1hc2tlZAoKLS0gYnYgICAtPiBiaW5hcnkgc3RyaW5nIG9mIHYKLS0gYm0gICAtPiBiaW5hcnkgc3RyaW5nIG1hc2sKCmxvY2FsIGJ2ID0gSGV4MkJpbih2KQpsb2NhbCBibSA9IEhleDJCaW4obSkKCmxvY2FsIGkgPSAwCmxvY2FsIHMgPSAiIgoKICAgICAgICB3aGlsZSAoc3RyaW5nLmxlbihidikgPCAzMikgZG8KICAgICAgICAgICAgICAgIGJ2ID0gIjAwMDAiLi5idgogICAgICAgIGVuZAoKICAgICAgICB3aGlsZSAoc3RyaW5nLmxlbihibSkgPCAzMikgZG8KICAgICAgICAgICAgICAgIGJtID0gIjAwMDAiLi5ibQogICAgICAgIGVuZAoKCiAgICAgICAgZm9yIGkgPSAxLCAzMiBkbwogICAgICAgICAgICAgICAgY3YgPSBzdHJpbmcuc3ViKGJ2LCBpLCBpKQogICAgICAgICAgICAgICAgY20gPSBzdHJpbmcuc3ViKGJtLCBpLCBpKQogICAgICAgICAgICAgICAgaWYgY3YgPT0gIjEiIHRoZW4KICAgICAgICAgICAgICAgICAgICAgICAgaWYgY20gPT0gIjAiIHRoZW4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzID0gcy4uIjEiCiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzID0gcy4uIjAiCiAgICAgICAgICAgICAgICAgICAgICAgIGVuZAogICAgICAgICAgICAgICAgZWxzZWlmIGNtID09ICIxIiB0aGVuCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIGN2ID09ICIwIiB0aGVuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcyA9IHMuLiIxIgogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcyA9IHMuLiIwIgogICAgICAgICAgICAgICAgICAgICAgICBlbmQKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgLS0gY3YgYW5kIGNtID09ICIwIgogICAgICAgICAgICAgICAgICAgICAgICBzID0gcy4uIjAiCiAgICAgICAgICAgICAgICBlbmQKICAgICAgICBlbmQKCiAgICAgICAgcmV0dXJuIEJpbjJIZXgocykKCmVuZAoKCmZ1bmN0aW9uIEJNTm90KHYsIG0pCgotLSB2ICAgIC0+IGhleCBzdHJpbmcgdG8gYmUgbWFza2VkCi0tIG0gICAgLT4gaGV4IHN0cmluZyBtYXNrCgotLSBzICAgIC0+IGhleCBzdHJpbmcgYXMgbWFza2VkCgotLSBidiAgIC0+IGJpbmFyeSBzdHJpbmcgb2YgdgotLSBibSAgIC0+IGJpbmFyeSBzdHJpbmcgbWFzawoKbG9jYWwgYnYgPSBIZXgyQmluKHYpCmxvY2FsIGJtID0gSGV4MkJpbihtKQoKbG9jYWwgaSA9IDAKbG9jYWwgcyA9ICIiCgogICAgICAgIHdoaWxlIChzdHJpbmcubGVuKGJ2KSA8IDMyKSBkbwogICAgICAgICAgICAgICAgYnYgPSAiMDAwMCIuLmJ2CiAgICAgICAgZW5kCgogICAgICAgIHdoaWxlIChzdHJpbmcubGVuKGJtKSA8IDMyKSBkbwogICAgICAgICAgICAgICAgYm0gPSAiMDAwMCIuLmJtCiAgICAgICAgZW5kCgoKICAgICAgICBmb3IgaSA9IDEsIDMyIGRvCiAgICAgICAgICAgICAgICBjdiA9IHN0cmluZy5zdWIoYnYsIGksIGkpCiAgICAgICAgICAgICAgICBjbSA9IHN0cmluZy5zdWIoYm0sIGksIGkpCiAgICAgICAgICAgICAgICBpZiBjbSA9PSAiMSIgdGhlbgogICAgICAgICAgICAgICAgICAgICAgICBpZiBjdiA9PSAiMSIgdGhlbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0tIHR1cm4gb2ZmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcyA9IHMuLiIwIgogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLS0gdHVybiBvbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMgPSBzLi4iMSIKICAgICAgICAgICAgICAgICAgICAgICAgZW5kCiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIC0tIGxlYXZlIHVudG91Y2hlZAogICAgICAgICAgICAgICAgICAgICAgICBzID0gcy4uY3YKCiAgICAgICAgICAgICAgICBlbmQKICAgICAgICBlbmQKCiAgICAgICAgcmV0dXJuIEJpbjJIZXgocykKCmVuZAoKCi0tIHRoZXNlIGZ1bmN0aW9ucyBzaGlmdCByaWdodCBhbmQgbGVmdCwgYWRkaW5nIHplcm9zIHRvIGxvc3Qgb3IgZ2FpbmVkIGJpdHMKLS0gcmV0dXJuZWQgdmFsdWVzIGFyZSAzMiBiaXRzIGxvbmcKCi0tIEJTaFJpZ2h0KHYsIG5iKQotLSBCU2hMZWZ0KHYsIG5iKQoKCmZ1bmN0aW9uIEJTaFJpZ2h0KHYsIG5iKQoKLS0gdiAgICAtPiBoZXhzdHJpbmcgdmFsdWUgdG8gYmUgc2hpZnRlZAotLSBuYiAgIC0+IG51bWJlciBvZiBiaXRzIHRvIHNoaWZ0IHRvIHRoZSByaWdodAoKLS0gcyAgICAtPiBiaW5hcnkgc3RyaW5nIG9mIHYKCmxvY2FsIHMgPSBIZXgyQmluKHYpCgogICAgICAgIHdoaWxlIChzdHJpbmcubGVuKHMpIDwgMzIpIGRvCiAgICAgICAgICAgICAgICBzID0gIjAwMDAiLi5zCiAgICAgICAgZW5kCgogICAgICAgIHMgPSBzdHJpbmcuc3ViKHMsIDEsIDMyIC0gbmIpCgogICAgICAgIHdoaWxlIChzdHJpbmcubGVuKHMpIDwgMzIpIGRvCiAgICAgICAgICAgICAgICBzID0gIjAiLi5zCiAgICAgICAgZW5kCgogICAgICAgIHJldHVybiBCaW4ySGV4KHMpCgplbmQKCmZ1bmN0aW9uIEJTaExlZnQodiwgbmIpCgotLSB2ICAgIC0+IGhleHN0cmluZyB2YWx1ZSB0byBiZSBzaGlmdGVkCi0tIG5iICAgLT4gbnVtYmVyIG9mIGJpdHMgdG8gc2hpZnQgdG8gdGhlIHJpZ2h0CgotLSBzICAgIC0+IGJpbmFyeSBzdHJpbmcgb2YgdgoKbG9jYWwgcyA9IEhleDJCaW4odikKCiAgICAgICAgd2hpbGUgKHN0cmluZy5sZW4ocykgPCAzMikgZG8KICAgICAgICAgICAgICAgIHMgPSAiMDAwMCIuLnMKICAgICAgICBlbmQKCiAgICAgICAgcyA9IHN0cmluZy5zdWIocywgbmIgKyAxLCAzMikKCiAgICAgICAgd2hpbGUgKHN0cmluZy5sZW4ocykgPCAzMikgZG8KICAgICAgICAgICAgICAgIHMgPSBzLi4iMCIKICAgICAgICBlbmQKCiAgICAgICAgcmV0dXJuIEJpbjJIZXgocykKCmVuZAoKCnByaW50KEJpbjJIZXgoIjExMDAxMDEwIikp