if not modules then modules = { } end modules ['mlib-lua'] = {
    version   = 1.001,
    comment   = "companion to mlib-ctx.mkiv",
    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
    copyright = "PRAGMA ADE / ConTeXt Development Team",
    license   = "see context related readme files",
}

local type, tonumber = type, tonumber
local insert, remove = table.insert, table.remove

local trace  = false  trackers.register("metapost.instance",function(v) trace = v end)

local report = logs.reporter("metapost","instance")

local codes = mplib.getcodes()
local types = mplib.gettypes()

table.hashed(codes)
table.hashed(types)

metapost.codes = codes
metapost.types = types

local scan   = mp.scan
local skip   = mp.skip
local get    = mp.get
local inject = mp.inject

local bpfactor   <const> = number.dimenfactors.bp
local currentmpx = nil
local stack      = { }

local function reports(s) report("%a scan %s",  tostring(currentmpx),s) end -- temporary, till we're okay
local function reporti(s) report("%a inject %s",tostring(currentmpx),s) end -- temporary, till we're okay

local scannext       = mplib.scannext
local scanexpression = mplib.scanexpression
local scantoken      = mplib.scantoken
local scansymbol     = mplib.scansymbol
local scanproperty   = mplib.scanproperty
local scannumeric    = mplib.scannumeric
local scaninteger    = mplib.scaninteger
local scanboolean    = mplib.scanboolean
local scanstring     = mplib.scanstring
local scanpair       = mplib.scanpair
local scancolor      = mplib.scancolor
local scancmykcolor  = mplib.scancmykcolor
local scantransform  = mplib.scantransform
local scanpath       = mplib.scanpath
local scanpen        = mplib.scanpen

local skiptoken      = mplib.skiptoken

local gethashentry   = mplib.gethashentry

scan.next       = function(k)     if trace then reporti("next")       end return scannext      (currentmpx,k)     end
scan.expression = function(k)     if trace then reporti("expression") end return scanexpression(currentmpx,k)     end
scan.token      = function(k)     if trace then reporti("token")      end return scantoken     (currentmpx,k)     end
scan.symbol     = function(k,e)   if trace then reporti("symbol")     end return scansymbol    (currentmpx,k,e)   end
scan.property   = function(k)     if trace then reporti("property")   end return scanproperty  (currentmpx,k)     end
scan.numeric    = function()      if trace then reporti("numeric")    end return scannumeric   (currentmpx)       end
scan.integer    = function()      if trace then reporti("integer")    end return scaninteger   (currentmpx)       end
scan.boolean    = function()      if trace then reporti("boolean")    end return scanboolean   (currentmpx)       end
scan.string     = function()      if trace then reporti("string")     end return scanstring    (currentmpx)       end
scan.pair       = function(t)     if trace then reporti("pair")       end return scanpair      (currentmpx,t)     end
scan.color      = function(t)     if trace then reporti("color")      end return scancolor     (currentmpx,t)     end
scan.cmykcolor  = function(t)     if trace then reporti("cmykcolor")  end return scancmykcolor (currentmpx,t)     end
scan.transform  = function(t)     if trace then reporti("transform")  end return scantransform (currentmpx,t)     end
scan.path       = function(t,k,c) if trace then reporti("path")       end return scanpath      (currentmpx,t,k,c) end -- compact kind (prim) check
scan.pen        = function(t)     if trace then reporti("pen")        end return scanpen       (currentmpx,t)     end

skip.token      = function(t) return skiptoken   (currentmpx,t) end
get.hashentry   = function(n) return gethashentry(currentmpx,n) end

local solvepath = mplib.solvepath
local getstatus = mplib.getstatus
local expandtex = mplib.expandtex

mp.solve     = function(...) return solvepath(currentmpx,...) end
mp.expandtex = function(...) return expandtex(currentmpx,...) end

local newbytemap        = mplib.newbytemap
local getbytemap        = mplib.getbytemap
local setbytemap        = mplib.setbytemap
local fillbytemap       = mplib.fillbytemap
local getbytemapdata    = mplib.getbytemapdata
local setbytemapoctave  = mplib.setbytemapoctave
local setbytemapoctave  = mplib.setbytemapoctave
local processbytemap    = mplib.processbytemap
local downsamplebytemap = mplib.downsamplebytemap
local downgradebytemap  = mplib.downgradebytemap

mp.newbytemap        = function(...) return newbytemap       (currentmpx,...) end
mp.getbytemap        = function(...) return getbytemap       (currentmpx,...) end
mp.setbytemap        = function(...) return setbytemap       (currentmpx,...) end
mp.fillbytemap       = function(...) return fillbytemap      (currentmpx,...) end
mp.getbytemapdata    = function(...) return getbytemapdata   (currentmpx,...) end
mp.setbytemapoctave  = function(...) return setbytemapoctave (currentmpx,...) end
mp.processbytemap    = function(...) return processbytemap   (currentmpx,...) end
mp.downsamplebytemap = function(...) return downsamplebytemap(currentmpx,...) end
mp.downgradebytemap  = function(...) return downgradebytemap (currentmpx,...) end

local getlastaddtype = mplib.getlastaddtype

mp.getlastaddtype = function(...) return getlastaddtype(currentmpx,...) end

local injectpath      = mplib.injectpath
local injectnumeric   = mplib.injectnumeric
local injectpair      = mplib.injectpair
local injectboolean   = mplib.injectboolean
local injectinteger   = mplib.injectinteger
local injectstring    = mplib.injectstring
local injectcolor     = mplib.injectcolor
----- injecttriplet   = mplib.injectcolor
local injectcmykcolor = mplib.injectcmykcolor
local injecttransform = mplib.injecttransform
local injectwhatever  = mplib.injectwhatever
local injectvector    = mplib.injectvector
local injectvectors   = mplib.injectvectors
----- injecttokens    = mplib.injecttokens

inject.path      = function(p)               if trace then reporti("path")      end return injectpath     (currentmpx,p)               end
inject.numeric   = function(n)               if trace then reporti("numeric")   end return injectnumeric  (currentmpx,n)               end
inject.pair      = function(x,y)             if trace then reporti("pair")      end return injectpair     (currentmpx,x,y)             end
inject.boolean   = function(b)               if trace then reporti("boolean")   end return injectboolean  (currentmpx,b)               end
inject.integer   = function(i)               if trace then reporti("integer")   end return injectinteger  (currentmpx,i)               end
inject.string    = function(s)               if trace then reporti("string")    end return injectstring   (currentmpx,s)               end
inject.color     = function(r,g,b)           if trace then reporti("color")     end return injectcolor    (currentmpx,r,g,b)           end
-----.triplet    = function(w,h,d)           if trace then reporti("triplet")   end return injectcolor    (currentmpx,w,h,d)           end
inject.cmykcolor = function(c,m,y,k)         if trace then reporti("cmykcolor") end return injectcmykcolor(currentmpx,c,m,y,k)         end
inject.transform = function(x,y,xx,xy,yx,yy) if trace then reporti("transform") end return injecttransform(currentmpx,x,y,xx,xy,yx,yy) end
inject.whatever  = function(...)             if trace then reporti("whatever")  end return injectwhatever (currentmpx,...)             end
inject.vector    = function(v,s)             if trace then reporti("vector")    end return injectvector   (currentmpx,v,s)             end
inject.vectors   = function(v,t,s)           if trace then reporti("vectors")   end return injectvectors  (currentmpx,v,t,s)           end
------.tokens    = function(s)               if trace then reporti("tokens")    end return injecttokens   (currentmpx,s)               end

inject.triplet    = inject.color
inject.quadruplet = inject.cmykcolor

-- these can be optimized for zero:

inject.whd = function(w,h,d) injectcolor  (currentmpx,(tonumber(w) or 0)*bpfactor,(tonumber(h) or 0)*bpfactor,(tonumber(d) or 0)*bpfactor) end
inject.xy  = function(x,y)   injectpair   (currentmpx,(tonumber(x) or 0)*bpfactor,(tonumber(y) or 0)*bpfactor) end
inject.pt  = function(n)     injectnumeric(currentmpx,(tonumber(n) or 0)*bpfactor) end

local function same(p,n)
    local f = p[1]
    local l = p[n]
    local nf = #f
    local nl = #l
    if nf == nl then
        for i=1,nf do
            if f[i] ~= l[i] then
                return false
            end
        end
        return true
    end
    return false
end

-- bonus:

scan  .number    = scan  .numeric
inject.number    = inject.numeric

table.setmetatablecall(inject,function(t,...)
    injectwhatever(currentmpx,...)
end)

-- experiment

function mp.autoinject(m)
    local t = type(m)
    if t == "table" then
        local n = #t
        if n == 2 then
            injectpair(currentmpx,m)
        elseif n == 3 then
            injectcolor(currentmpx,m)
        elseif n == 4 then
            injectcmykcolor(currentmpx,m)
        elseif n == 6 then
            injecttransform(currentmpx,m)
        end
    elseif t == "number" then
        injectnumeric(currentmpx,m)
    elseif t == "string" then
        injectstring(currentmpx,m)
    elseif t == "boolean" then
        injectboolean(currentmpx,m)
    elseif t == "vector" then
        injectvector(currentmpx,m)
    end
end

function metapost.pushscriptrunner(mpx)
    if trace then
        report("%a => %a",tostring(currentmpx),tostring(mpx))
    end
    insert(stack,currentmpx)
    currentmpx = mpx
end

function metapost.popscriptrunner()
    local mpx = remove(stack)
    if trace then
        report("%a <= %a",tostring(mpx),tostring(currentmpx))
    end
    currentmpx = mpx
end

function metapost.currentmpx()
    return currentmpx
end

-- mplib.getstates(): zero is "normal"

function metapost.currentmpxstatus()
    return getstatus(currentmpx) or 0
end
