diff options
55 files changed, 25628 insertions, 385 deletions
diff --git a/context/data/scite/context/lexers/scite-context-lexer.lua b/context/data/scite/context/lexers/scite-context-lexer.lua index fc16e261a..0a752e412 100644 --- a/context/data/scite/context/lexers/scite-context-lexer.lua +++ b/context/data/scite/context/lexers/scite-context-lexer.lua @@ -8,6 +8,10 @@ local info = { } +-- We need a copy of this file to lexer.lua in the same path. This was not needed +-- before version 10 but I can't figure out what else to do. It looks like there +-- is some loading of lexer.lua but I can't see where. + if lpeg.setmaxstack then lpeg.setmaxstack(1000) end local log = false @@ -19,10 +23,6 @@ local inspect = false -- can save some 15% (maybe easier on scintilla) -- local log = true -- local trace = true --- local f = io.open("e:/tmp/lexers.log","w") --- print = function(...) --- f:write(...,"\n") --- end -- GET GOING -- @@ -236,6 +236,17 @@ local inspect = false -- can save some 15% (maybe easier on scintilla) -- is still not perfect (sometimes hangs) but it was enough reason to spend time on -- making our lexer work with TextAdept and create a setup. -- +-- Some bad news. The interface changed (again) in textadept 10, some for the better +-- (but a bit different from what happens here) and some for the worse, especially +-- moving some code to the init file so we now need some bad hacks. I decided to +-- stay with the old method of defining lexers and because the lexer cannot be run +-- in parallel any more (some change in the binary?) I will probably also cleanup +-- code below as we no longer need to be compatible. Unfortunately textadept is too +-- much a moving target to simply kick in some (tex related) production flow (apart +-- from the fact that it doesn't yet have the scite like realtime console). I'll +-- keep an eye on it. Because we don't need many added features I might as well decide +-- to make a lean and mean instance (after all the license permits forking). + -- TRACING -- -- The advantage is that we now can check more easily with regular Lua(TeX). We can @@ -247,8 +258,8 @@ local inspect = false -- can save some 15% (maybe easier on scintilla) -- -- TODO -- --- It would be nice if we could lods some ConTeXt Lua modules (the basic set) and --- then use resolvers and such. +-- It would be nice if we could loads some ConTeXt Lua modules (the basic set) and +-- then use resolvers and such. But it might not work well with scite. -- -- The current lexer basics are still a mix between old and new. Maybe I should redo -- some more. This is probably easier in TextAdept than in SciTE. @@ -304,7 +315,17 @@ local lpegmatch = lpeg.match local usage = (textadept and "textadept") or (resolvers and "context") or "scite" local nesting = 0 -local print = textadept and ui and ui.print or print +local output = nil + +----- print = textadept and ui and ui.print or print -- crashes when ui is not yet defined + +local function print(...) + if not output then + output = io.open("lexer.log","w") + end + output:write(...,"\n") + output:flush() +end local function report(fmt,str,...) if log then @@ -323,6 +344,36 @@ end inform("loading context lexer module (global table: %s)",tostring(global)) +do + + local floor = math and math.floor + local format = format + local tonumber = tonumber + + if not floor then + + if tonumber(string.match(_VERSION,"%d%.%d")) < 5.3 then + floor = function(n) + return tonumber(format("%d",n)) + end + else + -- 5.3 has a mixed number system and format %d doesn't work with + -- floats any longer ... no fun + floor = function(n) + return (n - n % 1) + end + end + + math = math or { } + + math.floor = floor + + end + +end + +local floor = math.floor + if not package.searchpath then -- Unfortunately the io library is only available when we end up @@ -416,7 +467,9 @@ local default = { local predefined = { "default", "linenumber", "bracelight", "bracebad", "controlchar", - "indentguide", "calltip" + "indentguide", "calltip", + -- seems new + "folddisplaytext" } -- Bah ... ugly ... nicer would be a proper hash .. we now have properties @@ -514,9 +567,16 @@ lexers.property_expanded = setmetatable({ }, { check_main_properties() end -- - return gsub(property[k],"[$%%]%b()", function(k) - return t[sub(k,3,-2)] - end) +-- return gsub(property[k],"[$%%]%b()", function(k) +-- return t[sub(k,3,-2)] +-- end) + local v = property[k] + if v then + v = gsub(v,"[$%%]%b()", function(k) + return t[sub(k,3,-2)] + end) + end + return v end, __newindex = function(t,k,v) report("properties are read-only, '%s' is not changed",k) @@ -839,32 +899,42 @@ function context.loaddefinitions(name) return type(data) == "table" and data end +-- A bit of regression in textadept > 10 so updated ... done a bit different. +-- We don't use this in the context lexers anyway. + function context.word_match(words,word_chars,case_insensitive) - local chars = "%w_" -- maybe just "" when word_chars - if word_chars then - chars = "^([" .. chars .. gsub(word_chars,"([%^%]%-])", "%%%1") .."]+)" - else - chars = "^([" .. chars .."]+)" + -- used to be proper tables ... + if type(words) == "string" then + local clean = gsub(words,"%-%-[^\n]+","") + local split = { } + for s in gmatch(clean,"%S+") do + split[#split+1] = s + end + words = split + end + local list = { } + for i=1,#words do + list[words[i]] = true end if case_insensitive then - local word_list = { } for i=1,#words do - word_list[lower(words[i])] = true + list[lower(words[i])] = true end - return P(function(input, index) - local s, e, word = find(input,chars,index) - return word and word_list[lower(word)] and e + 1 or nil - end) - else - local word_list = { } - for i=1,#words do - word_list[words[i]] = true - end - return P(function(input, index) - local s, e, word = find(input,chars,index) - return word and word_list[word] and e + 1 or nil - end) end + local chars = S(word_chars or "") + for i=1,#words do + chars = chars + S(words[i]) + end + local match = case_insensitive and + function(input,index,word) + -- We can speed mixed case if needed. + return (list[word] or list[lower(word)]) and index or nil + end + or + function(input,index,word) + return list[word] and index or nil + end + return Cmt(chars^1,match) end -- Patterns are grouped in a separate namespace but the regular lexers expect @@ -892,6 +962,11 @@ do local hexadecimal = P("0") * S("xX") * (hexdigit^0 * period * hexdigit^1 + hexdigit^1 * period * hexdigit^0 + hexdigit^1) * (S("pP") * sign^-1 * hexdigit^1)^-1 -- * + local integer = sign^-1 + * (hexadecimal + octal + decimal) + local float = sign^-1 + * (digit^0 * period * digit^1 + digit^1 * period * digit^0 + digit^1) + * S("eE") * sign^-1 * digit^1 -- * patterns.idtoken = idtoken patterns.digit = digit @@ -908,15 +983,13 @@ do patterns.decimal = decimal patterns.octal = octal patterns.hexadecimal = hexadecimal - patterns.float = sign^-1 - * (digit^0 * period * digit^1 + digit^1 * period * digit^0 + digit^1) - * S("eE") * sign^-1 * digit^1 -- * + patterns.float = float patterns.cardinal = decimal patterns.signeddecimal = sign^-1 * decimal patterns.signedoctal = sign^-1 * octal patterns.signedhexadecimal = sign^-1 * hexadecimal - patterns.integer = sign^-1 * (hexadecimal + octal + decimal) + patterns.integer = integer patterns.real = sign^-1 * ( -- at most one digit^1 * period * digit^0 -- 10.0 10. @@ -932,6 +1005,7 @@ do patterns.nospacing = (1-space)^1 patterns.eol = eol patterns.newline = P("\r\n") + eol + patterns.backslash = backslash local endof = S("\n\r\f") @@ -947,7 +1021,7 @@ do lexers.extend = extend lexers.alpha = alpha lexers.digit = digit - lexers.alnum = alnum + lexers.alnum = alpha + digit lexers.lower = lower lexers.upper = upper lexers.xdigit = hexdigit @@ -1038,12 +1112,7 @@ end -- }, -- } -local lists = { } -local disabled = false - -function context.disablewordcheck() - disabled = true -end +local lists = { } function context.setwordlist(tag,limit) -- returns hash (lowercase keys and original values) if not tag or tag == "" then @@ -1136,6 +1205,8 @@ local p_nop = newline local folders = { } +-- Snippets from the > 10 code .. but we do things different so ... + local function fold_by_parsing(text,start_pos,start_line,start_level,lexer) local folder = folders[lexer] if not folder then @@ -1145,6 +1216,12 @@ local function fold_by_parsing(text,start_pos,start_line,start_level,lexer) local fold_symbols = lexer._foldsymbols local fold_pattern = lexer._foldpattern -- use lpeg instead (context extension) -- + -- textadept >= 10 + -- + -- local zerosumlines = lexer.property_int["fold.on.zero.sum.lines"] > 0 -- not done + -- local compact = lexer.property_int['fold.compact'] > 0 -- not done + -- local lowercase = lexer._CASEINSENSITIVEFOLDPOINTS -- useless (utf will distort) + -- if fold_pattern then -- if no functions are found then we could have a faster one fold_pattern = Cp() * C(fold_pattern) / function(s,match) @@ -1177,7 +1254,7 @@ local function fold_by_parsing(text,start_pos,start_line,start_level,lexer) -- the traditional one but a bit optimized local fold_symbols_patterns = fold_symbols._patterns local action_y = function(pos,line) - for j = 1, #fold_symbols_patterns do + for j=1, #fold_symbols_patterns do for s, match in gmatch(line,fold_symbols_patterns[j]) do -- "()(" .. patterns[i] .. ")" local symbols = fold_symbols[style_at[start_pos + pos + s - 1]] local l = symbols and symbols[match] @@ -1320,11 +1397,11 @@ function context.fold(lexer,text,start_pos,start_line,start_level) -- hm, we had if filesize <= threshold_by_parsing then return fold_by_parsing(text,start_pos,start_line,start_level,lexer) end - elseif lexer.properties("fold.by.indentation",1) > 0 then + elseif lexer._FOLDBYINDENTATION or lexer.properties("fold.by.indentation",1) > 0 then if filesize <= threshold_by_indentation then return fold_by_indentation(text,start_pos,start_line,start_level,lexer) end - elseif lexer.properties("fold.by.line",1) > 0 then + elseif lexer._FOLDBYLINE or lexer.properties("fold.by.line",1) > 0 then if filesize <= threshold_by_line then return fold_by_line(text,start_pos,start_line,start_level,lexer) end @@ -1343,6 +1420,20 @@ local function add_rule(lexer,id,rule) -- unchanged lexer._RULEORDER[#lexer._RULEORDER + 1] = id end +local function modify_rule(lexer,id,rule) -- needed for textadept > 10 + if lexer._lexer then + lexer = lexer._lexer + end + lexer._RULES[id] = rule +end + +local function get_rule(lexer,id) -- needed for textadept > 10 + if lexer._lexer then + lexer = lexer._lexer + end + return lexer._RULES[id] +end + -- I finally figured out that adding more styles was an issue because of several -- reasons: -- @@ -1366,12 +1457,12 @@ local function add_style(lexer,token_name,style) -- changed a bit around 3.41 if trace and detail then report("default style '%s' is ignored as extra style",token_name) end - return +-- return elseif predefinedstyles[token_name] then if trace and detail then report("predefined style '%s' is ignored as extra style",token_name) end - return +-- return else if trace and detail then report("adding extra style '%s' as '%s'",token_name,style) @@ -1388,6 +1479,7 @@ local function add_style(lexer,token_name,style) -- changed a bit around 3.41 lexer._TOKENSTYLES[token_name] = num_styles lexer._EXTRASTYLES[token_name] = style lexer._numstyles = num_styles + 1 + -- hm, the original (now) also copies to the parent ._lexer end local function check_styles(lexer) @@ -1437,6 +1529,8 @@ local function join_tokens(lexer) -- slightly different from the original (no 'a end end +-- hm, maybe instead of a grammer just a flat one + local function add_lexer(grammar, lexer) -- mostly the same as the original local token_rule = join_tokens(lexer) local lexer_name = lexer._NAME @@ -1466,7 +1560,10 @@ local function build_grammar(lexer,initial_rule) -- same as the original local children = lexer._CHILDREN local lexer_name = lexer._NAME local preamble = lexer._preamble - if children then + local grammar = lexer._grammar + if grammar then + -- experiment + elseif children then if not initial_rule then initial_rule = lexer_name end @@ -1539,17 +1636,17 @@ local function matched(lexer,grammar,text) else txt = "!no text!" end - report("%4i : %s > %s (%s) (%s)",n/2,ti,tn,s[ti] or "!unset!",txt) + report("%4i : %s > %s (%s) (%s)",floor(n/2),ti,tn,s[ti] or "!unset!",txt) p = tn else break end end end - report("lexer results: %s, length: %s, ranges: %s",lexer._NAME,#text,#t/2) + report("lexer results: %s, length: %s, ranges: %s",lexer._NAME,#text,floor(#t/2)) if collapse then t = collapsed(t) - report("lexer collapsed: %s, length: %s, ranges: %s",lexer._NAME,#text,#t/2) + report("lexer collapsed: %s, length: %s, ranges: %s",lexer._NAME,#text,floor(#t/2)) end elseif collapse then t = collapsed(t) @@ -1559,6 +1656,9 @@ end -- Todo: make nice generic lexer (extra argument with start/stop commands) for -- context itself. +-- +-- In textadept >= 10 grammar building seem to have changed a bit. So, in retrospect +-- I could better have just dropped compatibility and stick to ctx lexers only. function context.lex(lexer,text,init_style) -- local lexer = global._LEXER @@ -1629,30 +1729,9 @@ function context.lex(lexer,text,init_style) hash[init_style] = grammar end if trace then - report("lexing '%s' with initial style '%s' and %s children",lexer._NAME,#lexer._CHILDREN or 0,init_style) + report("lexing '%s' with initial style '%s' and %s children", lexer._NAME,init_style,#lexer._CHILDREN or 0) end return matched(lexer,grammar,text) --- local result = matched(lexer,grammar,text) --- local fil = io.open("e:/tmp/foo.log","w") --- local len = #text --- local old = 1 --- local txt = false --- for i=1,#result,2 do --- local tag = result[i] --- local pos = result[i+1] --- if nxt and tag == "text" then --- local wrd = sub(text,old,pos-1) --- fil:write(tag,"\t",wrd,"\n") --- if txt then --- result[i] = "internal" --- txt = false --- else --- txt = true --- end --- end --- old = pos --- end --- fil:close() else if trace then report("lexing '%s' with initial style '%s'",lexer._NAME,init_style) @@ -1661,7 +1740,8 @@ function context.lex(lexer,text,init_style) end end --- hm, changed in 3.24 .. no longer small table but one table: +-- hm, changed in 3.24 .. no longer small table but one table (so we could remove our +-- agressive optimization which worked quite well) function context.token(name, patt) return patt * Cc(name) * Cp() @@ -1714,6 +1794,8 @@ function context.new(name,filename) -- name = name, filename = filename, + -- +-- _tokenstyles = context.styleset, } if trace then report("initializing lexer tagged '%s' from file '%s'",name,filename or name) @@ -1721,6 +1803,7 @@ function context.new(name,filename) check_whitespace(lexer) check_styles(lexer) check_properties(lexer) + lexer._tokenstyles = context.styleset return lexer end @@ -1826,7 +1909,36 @@ end -- namespace can be automatic: if parent then use name of parent (chain) +-- The original lexer framework had a rather messy user uinterface (e.g. moving +-- stuff from _rules to _RULES at some point but I could live with that. Now it uses +-- add_ helpers. But the subsystem is still not clean and pretty. Now, I can move to +-- the add_ but there is no gain in it so we support a mix which gives somewhat ugly +-- code. In fact, there should be proper subtables for this. I might actually do +-- this because we now always overload the normal lexer (parallel usage seems no +-- longer possible). For SciTE we can actually do a conceptual upgrade (more the +-- context way) because there is no further development there. That way we could +-- make even more advanced lexers. + +local savedrequire = require + +local escapes = { + ["%"] = "%%", + ["."] = "%.", + ["+"] = "%+", ["-"] = "%-", ["*"] = "%*", + ["["] = "%[", ["]"] = "%]", + ["("] = "%(", [")"] = "%)", + -- ["{"] = "%{", ["}"] = "%}" + -- ["^"] = "%^", ["$"] = "%$", +} + function context.loadlexer(filename,namespace) + + if textadept then + require = function(name) + return savedrequire(name == "lexer" and "scite-context-lexer" or name) + end + end + nesting = nesting + 1 if not namespace then namespace = filename @@ -1851,7 +1963,7 @@ function context.loadlexer(filename,namespace) lexer = load_lexer(filename,namespace) or nolexer(filename,namespace) usedlexers[filename] = lexer -- - if not lexer._rules and not lexer._lexer then + if not lexer._rules and not lexer._lexer and not lexer_grammar then -- hmm should be lexer._grammar lexer._lexer = parent_lexer end -- @@ -1883,7 +1995,8 @@ function context.loadlexer(filename,namespace) end -- local _r = lexer._rules - if _r then + local _g = lexer._grammar + if _r or _g then local _s = lexer._tokenstyles if _s then for token, style in next, _s do @@ -1897,6 +2010,9 @@ function context.loadlexer(filename,namespace) end end build_grammar(lexer) + else + -- other lexers + build_grammar(lexer) end -- add_style(lexer, lexer.whitespace, lexers.STYLE_WHITESPACE) @@ -1906,7 +2022,7 @@ function context.loadlexer(filename,namespace) local patterns = foldsymbols._patterns if patterns then for i = 1, #patterns do - patterns[i] = "()(" .. patterns[i] .. ")" + patterns[i] = "()(" .. gsub(patterns[i],".",escapes) .. ")" end end end @@ -1920,6 +2036,10 @@ function context.loadlexer(filename,namespace) context.inspect(lexer) end -- + if textadept then + require = savedrequire + end + -- return lexer end @@ -1997,6 +2117,17 @@ function context.embed_lexer(parent, child, start_rule, end_rule) -- mostly the end end end + -- newer, textadept >= 10, whatever ... + local childsymbols = child._FOLDPOINTS + if childsymbols then + for token, symbols in next, childsymbols do + if token ~= "_SYMBOLS" then + for symbol, v in next, symbols do + lexer:add_fold_point(token_name, symbol, v) + end + end + end + end -- child._lexer = parent parent_lexer = parent @@ -2019,8 +2150,8 @@ lexers.inspect = context.inspect lexers.report = context.report lexers.inform = context.inform --- helper .. alas ... the lexer's lua instance is rather crippled .. not even --- math is part of it +-- helper .. alas ... in scite the lexer's lua instance is rather crippled .. not +-- even math is part of it do @@ -2029,26 +2160,6 @@ do local format = format local tonumber = tonumber - if not floor then - - if tonumber(string.match(_VERSION,"%d%.%d")) < 5.3 then - floor = function(n) - return tonumber(format("%d",n)) - end - else - -- 5.3 has a mixed number system and format %d doesn't work with - -- floats any longer ... no fun - floor = function(n) - return (n - n % 1) - end - end - - math = math or { } - - math.floor = floor - - end - local function utfchar(n) if n < 0x80 then return char(n) @@ -2424,6 +2535,128 @@ function lexers.fold_line_comments(prefix) end end +-- There are some fundamental changes in textadept version 10 and I don't want to +-- adapt again so we go the reverse route: map new to old. This is needed because +-- we need to load other lexers which is teh result of not being able to load the +-- lexer framework in parallel. Something happened in 10 that makes the main lexer +-- always enforced so now we need to really replace that one (and even then it loads +-- twice (i can probably sort that out). Maybe there's now some hard coded magic +-- in the binary. + +if textadept then + + -- Folds are still somewhat weak because of the end condition not being + -- bound to a start .. probably to complex and it seems to work anyhow. As + -- we have extended thinsg we just remap. + + local function add_fold_point(lexer,token_name,start_symbol,end_symbol) + if type(start_symbol) == "string" then + local foldsymbols = lexer._foldsymbols + if not foldsymbols then + foldsymbols = { } + lexer._foldsymbols = foldsymbols + end + local patterns = foldsymbols._patterns + if not patterns then + patterns = { } + usedpatt = { } -- > 10 uses a mixed index/hash (we don't use patterns) + foldsymbols._patterns = patterns + foldsymbols._usedpatt = usedpatt + end + local foldsymbol = foldsymbols[token_name] + if not foldsymbol then + foldsymbol = { } + foldsymbols[token_name] = foldsymbol + end + if not usedpatt[start_symbol] then + patterns[#patterns+1] = start_symbol + usedpatt[start_symbol] = true + end + if type(end_symbol) == "string" then + foldsymbol[start_symbol] = 1 + foldsymbol[end_symbol] = -1 + if not usedpatt[end_symbol] then + patterns[#patterns+1] = end_symbol + usedpatt[end_symbol] = true + end + else + foldsymbol[start_symbol] = end_symbol + end + end + end + + local function add_style(lexer,name,style) + local tokenstyles = lexer._tokenstyles + if not tokenstyles then + tokenstyles = { } + lexer._tokenstyles = tokenstyles + end + tokenstyles[name] = style + end + + local function add_rule(lexer,id,rule) + local rules = lexer._rules + if not rules then + rules = { } + lexer._rules = rules + end + rules[#rules+1] = { id, rule } + end + + local function modify_rule(lexer,id,rule) -- needed for textadept > 10 + if lexer._lexer then + lexer = lexer._lexer + end + local RULES = lexer._RULES + if RULES then + RULES[id] = rule + end + end + + local function get_rule(lexer,id) -- needed for textadept > 10 + if lexer._lexer then + lexer = lexer._lexer + end + local RULES = lexer._RULES + if RULES then + return RULES[id] + end + end + + local new = context.new + local lmt = { + __index = { + + add_rule = add_rule, + modify_rule = modify_rule, + get_rule = get_rule, + add_style = add_style, + add_fold_point = add_fold_point, + + join_tokens = join_tokens, + build_grammar = build_grammar, + + embed = lexers.embed, + lex = lexers.lex, + fold = lexers.fold + + } + } + + function lexers.new(name,options) + local lexer = new(name) + if options then + lexer._LEXBYLINE = options['lex_by_line'] + lexer._FOLDBYINDENTATION = options['fold_by_indentation'] + lexer._CASEINSENSITIVEFOLDPOINTS = options['case_insensitive_fold_points'] + lexer._lexer = options['inherit'] + end + setmetatable(lexer,lmt) + return lexer + end + +end + -- done return lexers diff --git a/context/data/textadept/context/data/scite-context-data-bidi.lua b/context/data/textadept/context/data/scite-context-data-bidi.lua new file mode 100644 index 000000000..4221dee89 --- /dev/null +++ b/context/data/textadept/context/data/scite-context-data-bidi.lua @@ -0,0 +1,10357 @@ +return { + ["comment"]="generated by: mtxrun -- script interface.lua --bidi", + ["directions"]={ + [0]="bn", + "bn", + "bn", + "bn", + "bn", + "bn", + "bn", + "bn", + "bn", + "s", + "b", + "s", + "ws", + "b", + "bn", + "bn", + "bn", + "bn", + "bn", + "bn", + "bn", + "bn", + "bn", + "bn", + "bn", + "bn", + "bn", + "bn", + "b", + "b", + "b", + "s", + "ws", + "on", + "on", + "et", + "et", + "et", + "on", + "on", + "on", + "on", + "on", + "es", + "cs", + "es", + "cs", + "cs", + "en", + "en", + "en", + "en", + "en", + "en", + "en", + "en", + "en", + "en", + "cs", + "on", + "on", + "on", + "on", + "on", + "on", + [91]="on", + [92]="on", + [93]="on", + [94]="on", + [95]="on", + [96]="on", + [123]="on", + [124]="on", + [125]="on", + [126]="on", + [127]="bn", + [128]="bn", + [129]="bn", + [130]="bn", + [131]="bn", + [132]="bn", + [133]="b", + [134]="bn", + [135]="bn", + [136]="bn", + [137]="bn", + [138]="bn", + [139]="bn", + [140]="bn", + [141]="bn", + [142]="bn", + [143]="bn", + [144]="bn", + [145]="bn", + [146]="bn", + [147]="bn", + [148]="bn", + [149]="bn", + [150]="bn", + [151]="bn", + [152]="bn", + [153]="bn", + [154]="bn", + [155]="bn", + [156]="bn", + [157]="bn", + [158]="bn", + [159]="bn", + [160]="cs", + [161]="on", + [162]="et", + [163]="et", + [164]="et", + [165]="et", + [166]="on", + [167]="on", + [168]="on", + [169]="on", + [171]="on", + [172]="on", + [173]="bn", + [174]="on", + [175]="on", + [176]="et", + [177]="et", + [178]="en", + [179]="en", + [180]="on", + [182]="on", + [183]="on", + [184]="on", + [185]="en", + [187]="on", + [188]="on", + [189]="on", + [190]="on", + [191]="on", + [215]="on", + [247]="on", + [697]="on", + [698]="on", + [706]="on", + [707]="on", + [708]="on", + [709]="on", + [710]="on", + [711]="on", + [712]="on", + [713]="on", + [714]="on", + [715]="on", + [716]="on", + [717]="on", + [718]="on", + [719]="on", + [722]="on", + [723]="on", + [724]="on", + [725]="on", + [726]="on", + [727]="on", + [728]="on", + [729]="on", + [730]="on", + [731]="on", + [732]="on", + [733]="on", + [734]="on", + [735]="on", + [741]="on", + [742]="on", + [743]="on", + [744]="on", + [745]="on", + [746]="on", + [747]="on", + [748]="on", + [749]="on", + [751]="on", + [752]="on", + [753]="on", + [754]="on", + [755]="on", + [756]="on", + [757]="on", + [758]="on", + [759]="on", + [760]="on", + [761]="on", + [762]="on", + [763]="on", + [764]="on", + [765]="on", + [766]="on", + [767]="on", + [768]="nsm", + [769]="nsm", + [770]="nsm", + [771]="nsm", + [772]="nsm", + [773]="nsm", + [774]="nsm", + [775]="nsm", + [776]="nsm", + [777]="nsm", + [778]="nsm", + [779]="nsm", + [780]="nsm", + [781]="nsm", + [782]="nsm", + [783]="nsm", + [784]="nsm", + [785]="nsm", + [786]="nsm", + [787]="nsm", + [788]="nsm", + [789]="nsm", + [790]="nsm", + [791]="nsm", + [792]="nsm", + [793]="nsm", + [794]="nsm", + [795]="nsm", + [796]="nsm", + [797]="nsm", + [798]="nsm", + [799]="nsm", + [800]="nsm", + [801]="nsm", + [802]="nsm", + [803]="nsm", + [804]="nsm", + [805]="nsm", + [806]="nsm", + [807]="nsm", + [808]="nsm", + [809]="nsm", + [810]="nsm", + [811]="nsm", + [812]="nsm", + [813]="nsm", + [814]="nsm", + [815]="nsm", + [816]="nsm", + [817]="nsm", + [818]="nsm", + [819]="nsm", + [820]="nsm", + [821]="nsm", + [822]="nsm", + [823]="nsm", + [824]="nsm", + [825]="nsm", + [826]="nsm", + [827]="nsm", + [828]="nsm", + [829]="nsm", + [830]="nsm", + [831]="nsm", + [832]="nsm", + [833]="nsm", + [834]="nsm", + [835]="nsm", + [836]="nsm", + [837]="nsm", + [838]="nsm", + [839]="nsm", + [840]="nsm", + [841]="nsm", + [842]="nsm", + [843]="nsm", + [844]="nsm", + [845]="nsm", + [846]="nsm", + [847]="nsm", + [848]="nsm", + [849]="nsm", + [850]="nsm", + [851]="nsm", + [852]="nsm", + [853]="nsm", + [854]="nsm", + [855]="nsm", + [856]="nsm", + [857]="nsm", + [858]="nsm", + [859]="nsm", + [860]="nsm", + [861]="nsm", + [862]="nsm", + [863]="nsm", + [864]="nsm", + [865]="nsm", + [866]="nsm", + [867]="nsm", + [868]="nsm", + [869]="nsm", + [870]="nsm", + [871]="nsm", + [872]="nsm", + [873]="nsm", + [874]="nsm", + [875]="nsm", + [876]="nsm", + [877]="nsm", + [878]="nsm", + [879]="nsm", + [884]="on", + [885]="on", + [894]="on", + [900]="on", + [901]="on", + [903]="on", + [1014]="on", + [1155]="nsm", + [1156]="nsm", + [1157]="nsm", + [1158]="nsm", + [1159]="nsm", + [1160]="nsm", + [1161]="nsm", + [1418]="on", + [1421]="on", + [1422]="on", + [1423]="et", + [1425]="nsm", + [1426]="nsm", + [1427]="nsm", + [1428]="nsm", + [1429]="nsm", + [1430]="nsm", + [1431]="nsm", + [1432]="nsm", + [1433]="nsm", + [1434]="nsm", + [1435]="nsm", + [1436]="nsm", + [1437]="nsm", + [1438]="nsm", + [1439]="nsm", + [1440]="nsm", + [1441]="nsm", + [1442]="nsm", + [1443]="nsm", + [1444]="nsm", + [1445]="nsm", + [1446]="nsm", + [1447]="nsm", + [1448]="nsm", + [1449]="nsm", + [1450]="nsm", + [1451]="nsm", + [1452]="nsm", + [1453]="nsm", + [1454]="nsm", + [1455]="nsm", + [1456]="nsm", + [1457]="nsm", + [1458]="nsm", + [1459]="nsm", + [1460]="nsm", + [1461]="nsm", + [1462]="nsm", + [1463]="nsm", + [1464]="nsm", + [1465]="nsm", + [1466]="nsm", + [1467]="nsm", + [1468]="nsm", + [1469]="nsm", + [1470]="r", + [1471]="nsm", + [1472]="r", + [1473]="nsm", + [1474]="nsm", + [1475]="r", + [1476]="nsm", + [1477]="nsm", + [1478]="r", + [1479]="nsm", + [1488]="r", + [1489]="r", + [1490]="r", + [1491]="r", + [1492]="r", + [1493]="r", + [1494]="r", + [1495]="r", + [1496]="r", + [1497]="r", + [1498]="r", + [1499]="r", + [1500]="r", + [1501]="r", + [1502]="r", + [1503]="r", + [1504]="r", + [1505]="r", + [1506]="r", + [1507]="r", + [1508]="r", + [1509]="r", + [1510]="r", + [1511]="r", + [1512]="r", + [1513]="r", + [1514]="r", + [1520]="r", + [1521]="r", + [1522]="r", + [1523]="r", + [1524]="r", + [1536]="an", + [1537]="an", + [1538]="an", + [1539]="an", + [1540]="an", + [1541]="an", + [1542]="on", + [1543]="on", + [1544]="al", + [1545]="et", + [1546]="et", + [1547]="al", + [1548]="cs", + [1549]="al", + [1550]="on", + [1551]="on", + [1552]="nsm", + [1553]="nsm", + [1554]="nsm", + [1555]="nsm", + [1556]="nsm", + [1557]="nsm", + [1558]="nsm", + [1559]="nsm", + [1560]="nsm", + [1561]="nsm", + [1562]="nsm", + [1563]="al", + [1564]="al", + [1566]="al", + [1567]="al", + [1568]="al", + [1569]="al", + [1570]="al", + [1571]="al", + [1572]="al", + [1573]="al", + [1574]="al", + [1575]="al", + [1576]="al", + [1577]="al", + [1578]="al", + [1579]="al", + [1580]="al", + [1581]="al", + [1582]="al", + [1583]="al", + [1584]="al", + [1585]="al", + [1586]="al", + [1587]="al", + [1588]="al", + [1589]="al", + [1590]="al", + [1591]="al", + [1592]="al", + [1593]="al", + [1594]="al", + [1595]="al", + [1596]="al", + [1597]="al", + [1598]="al", + [1599]="al", + [1600]="al", + [1601]="al", + [1602]="al", + [1603]="al", + [1604]="al", + [1605]="al", + [1606]="al", + [1607]="al", + [1608]="al", + [1609]="al", + [1610]="al", + [1611]="nsm", + [1612]="nsm", + [1613]="nsm", + [1614]="nsm", + [1615]="nsm", + [1616]="nsm", + [1617]="nsm", + [1618]="nsm", + [1619]="nsm", + [1620]="nsm", + [1621]="nsm", + [1622]="nsm", + [1623]="nsm", + [1624]="nsm", + [1625]="nsm", + [1626]="nsm", + [1627]="nsm", + [1628]="nsm", + [1629]="nsm", + [1630]="nsm", + [1631]="nsm", + [1632]="an", + [1633]="an", + [1634]="an", + [1635]="an", + [1636]="an", + [1637]="an", + [1638]="an", + [1639]="an", + [1640]="an", + [1641]="an", + [1642]="et", + [1643]="an", + [1644]="an", + [1645]="al", + [1646]="al", + [1647]="al", + [1648]="nsm", + [1649]="al", + [1650]="al", + [1651]="al", + [1652]="al", + [1653]="al", + [1654]="al", + [1655]="al", + [1656]="al", + [1657]="al", + [1658]="al", + [1659]="al", + [1660]="al", + [1661]="al", + [1662]="al", + [1663]="al", + [1664]="al", + [1665]="al", + [1666]="al", + [1667]="al", + [1668]="al", + [1669]="al", + [1670]="al", + [1671]="al", + [1672]="al", + [1673]="al", + [1674]="al", + [1675]="al", + [1676]="al", + [1677]="al", + [1678]="al", + [1679]="al", + [1680]="al", + [1681]="al", + [1682]="al", + [1683]="al", + [1684]="al", + [1685]="al", + [1686]="al", + [1687]="al", + [1688]="al", + [1689]="al", + [1690]="al", + [1691]="al", + [1692]="al", + [1693]="al", + [1694]="al", + [1695]="al", + [1696]="al", + [1697]="al", + [1698]="al", + [1699]="al", + [1700]="al", + [1701]="al", + [1702]="al", + [1703]="al", + [1704]="al", + [1705]="al", + [1706]="al", + [1707]="al", + [1708]="al", + [1709]="al", + [1710]="al", + [1711]="al", + [1712]="al", + [1713]="al", + [1714]="al", + [1715]="al", + [1716]="al", + [1717]="al", + [1718]="al", + [1719]="al", + [1720]="al", + [1721]="al", + [1722]="al", + [1723]="al", + [1724]="al", + [1725]="al", + [1726]="al", + [1727]="al", + [1728]="al", + [1729]="al", + [1730]="al", + [1731]="al", + [1732]="al", + [1733]="al", + [1734]="al", + [1735]="al", + [1736]="al", + [1737]="al", + [1738]="al", + [1739]="al", + [1740]="al", + [1741]="al", + [1742]="al", + [1743]="al", + [1744]="al", + [1745]="al", + [1746]="al", + [1747]="al", + [1748]="al", + [1749]="al", + [1750]="nsm", + [1751]="nsm", + [1752]="nsm", + [1753]="nsm", + [1754]="nsm", + [1755]="nsm", + [1756]="nsm", + [1757]="an", + [1758]="on", + [1759]="nsm", + [1760]="nsm", + [1761]="nsm", + [1762]="nsm", + [1763]="nsm", + [1764]="nsm", + [1765]="al", + [1766]="al", + [1767]="nsm", + [1768]="nsm", + [1769]="on", + [1770]="nsm", + [1771]="nsm", + [1772]="nsm", + [1773]="nsm", + [1774]="al", + [1775]="al", + [1776]="en", + [1777]="en", + [1778]="en", + [1779]="en", + [1780]="en", + [1781]="en", + [1782]="en", + [1783]="en", + [1784]="en", + [1785]="en", + [1786]="al", + [1787]="al", + [1788]="al", + [1789]="al", + [1790]="al", + [1791]="al", + [1792]="al", + [1793]="al", + [1794]="al", + [1795]="al", + [1796]="al", + [1797]="al", + [1798]="al", + [1799]="al", + [1800]="al", + [1801]="al", + [1802]="al", + [1803]="al", + [1804]="al", + [1805]="al", + [1807]="al", + [1808]="al", + [1809]="nsm", + [1810]="al", + [1811]="al", + [1812]="al", + [1813]="al", + [1814]="al", + [1815]="al", + [1816]="al", + [1817]="al", + [1818]="al", + [1819]="al", + [1820]="al", + [1821]="al", + [1822]="al", + [1823]="al", + [1824]="al", + [1825]="al", + [1826]="al", + [1827]="al", + [1828]="al", + [1829]="al", + [1830]="al", + [1831]="al", + [1832]="al", + [1833]="al", + [1834]="al", + [1835]="al", + [1836]="al", + [1837]="al", + [1838]="al", + [1839]="al", + [1840]="nsm", + [1841]="nsm", + [1842]="nsm", + [1843]="nsm", + [1844]="nsm", + [1845]="nsm", + [1846]="nsm", + [1847]="nsm", + [1848]="nsm", + [1849]="nsm", + [1850]="nsm", + [1851]="nsm", + [1852]="nsm", + [1853]="nsm", + [1854]="nsm", + [1855]="nsm", + [1856]="nsm", + [1857]="nsm", + [1858]="nsm", + [1859]="nsm", + [1860]="nsm", + [1861]="nsm", + [1862]="nsm", + [1863]="nsm", + [1864]="nsm", + [1865]="nsm", + [1866]="nsm", + [1869]="al", + [1870]="al", + [1871]="al", + [1872]="al", + [1873]="al", + [1874]="al", + [1875]="al", + [1876]="al", + [1877]="al", + [1878]="al", + [1879]="al", + [1880]="al", + [1881]="al", + [1882]="al", + [1883]="al", + [1884]="al", + [1885]="al", + [1886]="al", + [1887]="al", + [1888]="al", + [1889]="al", + [1890]="al", + [1891]="al", + [1892]="al", + [1893]="al", + [1894]="al", + [1895]="al", + [1896]="al", + [1897]="al", + [1898]="al", + [1899]="al", + [1900]="al", + [1901]="al", + [1902]="al", + [1903]="al", + [1904]="al", + [1905]="al", + [1906]="al", + [1907]="al", + [1908]="al", + [1909]="al", + [1910]="al", + [1911]="al", + [1912]="al", + [1913]="al", + [1914]="al", + [1915]="al", + [1916]="al", + [1917]="al", + [1918]="al", + [1919]="al", + [1920]="al", + [1921]="al", + [1922]="al", + [1923]="al", + [1924]="al", + [1925]="al", + [1926]="al", + [1927]="al", + [1928]="al", + [1929]="al", + [1930]="al", + [1931]="al", + [1932]="al", + [1933]="al", + [1934]="al", + [1935]="al", + [1936]="al", + [1937]="al", + [1938]="al", + [1939]="al", + [1940]="al", + [1941]="al", + [1942]="al", + [1943]="al", + [1944]="al", + [1945]="al", + [1946]="al", + [1947]="al", + [1948]="al", + [1949]="al", + [1950]="al", + [1951]="al", + [1952]="al", + [1953]="al", + [1954]="al", + [1955]="al", + [1956]="al", + [1957]="al", + [1958]="nsm", + [1959]="nsm", + [1960]="nsm", + [1961]="nsm", + [1962]="nsm", + [1963]="nsm", + [1964]="nsm", + [1965]="nsm", + [1966]="nsm", + [1967]="nsm", + [1968]="nsm", + [1969]="al", + [1984]="r", + [1985]="r", + [1986]="r", + [1987]="r", + [1988]="r", + [1989]="r", + [1990]="r", + [1991]="r", + [1992]="r", + [1993]="r", + [1994]="r", + [1995]="r", + [1996]="r", + [1997]="r", + [1998]="r", + [1999]="r", + [2000]="r", + [2001]="r", + [2002]="r", + [2003]="r", + [2004]="r", + [2005]="r", + [2006]="r", + [2007]="r", + [2008]="r", + [2009]="r", + [2010]="r", + [2011]="r", + [2012]="r", + [2013]="r", + [2014]="r", + [2015]="r", + [2016]="r", + [2017]="r", + [2018]="r", + [2019]="r", + [2020]="r", + [2021]="r", + [2022]="r", + [2023]="r", + [2024]="r", + [2025]="r", + [2026]="r", + [2027]="nsm", + [2028]="nsm", + [2029]="nsm", + [2030]="nsm", + [2031]="nsm", + [2032]="nsm", + [2033]="nsm", + [2034]="nsm", + [2035]="nsm", + [2036]="r", + [2037]="r", + [2038]="on", + [2039]="on", + [2040]="on", + [2041]="on", + [2042]="r", + [2048]="r", + [2049]="r", + [2050]="r", + [2051]="r", + [2052]="r", + [2053]="r", + [2054]="r", + [2055]="r", + [2056]="r", + [2057]="r", + [2058]="r", + [2059]="r", + [2060]="r", + [2061]="r", + [2062]="r", + [2063]="r", + [2064]="r", + [2065]="r", + [2066]="r", + [2067]="r", + [2068]="r", + [2069]="r", + [2070]="nsm", + [2071]="nsm", + [2072]="nsm", + [2073]="nsm", + [2074]="r", + [2075]="nsm", + [2076]="nsm", + [2077]="nsm", + [2078]="nsm", + [2079]="nsm", + [2080]="nsm", + [2081]="nsm", + [2082]="nsm", + [2083]="nsm", + [2084]="r", + [2085]="nsm", + [2086]="nsm", + [2087]="nsm", + [2088]="r", + [2089]="nsm", + [2090]="nsm", + [2091]="nsm", + [2092]="nsm", + [2093]="nsm", + [2096]="r", + [2097]="r", + [2098]="r", + [2099]="r", + [2100]="r", + [2101]="r", + [2102]="r", + [2103]="r", + [2104]="r", + [2105]="r", + [2106]="r", + [2107]="r", + [2108]="r", + [2109]="r", + [2110]="r", + [2112]="r", + [2113]="r", + [2114]="r", + [2115]="r", + [2116]="r", + [2117]="r", + [2118]="r", + [2119]="r", + [2120]="r", + [2121]="r", + [2122]="r", + [2123]="r", + [2124]="r", + [2125]="r", + [2126]="r", + [2127]="r", + [2128]="r", + [2129]="r", + [2130]="r", + [2131]="r", + [2132]="r", + [2133]="r", + [2134]="r", + [2135]="r", + [2136]="r", + [2137]="nsm", + [2138]="nsm", + [2139]="nsm", + [2142]="r", + [2144]="al", + [2145]="al", + [2146]="al", + [2147]="al", + [2148]="al", + [2149]="al", + [2150]="al", + [2151]="al", + [2152]="al", + [2153]="al", + [2154]="al", + [2208]="al", + [2209]="al", + [2210]="al", + [2211]="al", + [2212]="al", + [2213]="al", + [2214]="al", + [2215]="al", + [2216]="al", + [2217]="al", + [2218]="al", + [2219]="al", + [2220]="al", + [2221]="al", + [2222]="al", + [2223]="al", + [2224]="al", + [2225]="al", + [2226]="al", + [2227]="al", + [2228]="al", + [2230]="al", + [2231]="al", + [2232]="al", + [2233]="al", + [2234]="al", + [2235]="al", + [2236]="al", + [2237]="al", + [2260]="nsm", + [2261]="nsm", + [2262]="nsm", + [2263]="nsm", + [2264]="nsm", + [2265]="nsm", + [2266]="nsm", + [2267]="nsm", + [2268]="nsm", + [2269]="nsm", + [2270]="nsm", + [2271]="nsm", + [2272]="nsm", + [2273]="nsm", + [2274]="an", + [2275]="nsm", + [2276]="nsm", + [2277]="nsm", + [2278]="nsm", + [2279]="nsm", + [2280]="nsm", + [2281]="nsm", + [2282]="nsm", + [2283]="nsm", + [2284]="nsm", + [2285]="nsm", + [2286]="nsm", + [2287]="nsm", + [2288]="nsm", + [2289]="nsm", + [2290]="nsm", + [2291]="nsm", + [2292]="nsm", + [2293]="nsm", + [2294]="nsm", + [2295]="nsm", + [2296]="nsm", + [2297]="nsm", + [2298]="nsm", + [2299]="nsm", + [2300]="nsm", + [2301]="nsm", + [2302]="nsm", + [2303]="nsm", + [2304]="nsm", + [2305]="nsm", + [2306]="nsm", + [2362]="nsm", + [2364]="nsm", + [2369]="nsm", + [2370]="nsm", + [2371]="nsm", + [2372]="nsm", + [2373]="nsm", + [2374]="nsm", + [2375]="nsm", + [2376]="nsm", + [2381]="nsm", + [2385]="nsm", + [2386]="nsm", + [2387]="nsm", + [2388]="nsm", + [2389]="nsm", + [2390]="nsm", + [2391]="nsm", + [2402]="nsm", + [2403]="nsm", + [2433]="nsm", + [2492]="nsm", + [2497]="nsm", + [2498]="nsm", + [2499]="nsm", + [2500]="nsm", + [2509]="nsm", + [2530]="nsm", + [2531]="nsm", + [2546]="et", + [2547]="et", + [2555]="et", + [2561]="nsm", + [2562]="nsm", + [2620]="nsm", + [2625]="nsm", + [2626]="nsm", + [2631]="nsm", + [2632]="nsm", + [2635]="nsm", + [2636]="nsm", + [2637]="nsm", + [2641]="nsm", + [2672]="nsm", + [2673]="nsm", + [2677]="nsm", + [2689]="nsm", + [2690]="nsm", + [2748]="nsm", + [2753]="nsm", + [2754]="nsm", + [2755]="nsm", + [2756]="nsm", + [2757]="nsm", + [2759]="nsm", + [2760]="nsm", + [2765]="nsm", + [2786]="nsm", + [2787]="nsm", + [2801]="et", + [2810]="nsm", + [2811]="nsm", + [2812]="nsm", + [2813]="nsm", + [2814]="nsm", + [2815]="nsm", + [2817]="nsm", + [2876]="nsm", + [2879]="nsm", + [2881]="nsm", + [2882]="nsm", + [2883]="nsm", + [2884]="nsm", + [2893]="nsm", + [2902]="nsm", + [2914]="nsm", + [2915]="nsm", + [2946]="nsm", + [3008]="nsm", + [3021]="nsm", + [3059]="on", + [3060]="on", + [3061]="on", + [3062]="on", + [3063]="on", + [3064]="on", + [3065]="et", + [3066]="on", + [3072]="nsm", + [3134]="nsm", + [3135]="nsm", + [3136]="nsm", + [3142]="nsm", + [3143]="nsm", + [3144]="nsm", + [3146]="nsm", + [3147]="nsm", + [3148]="nsm", + [3149]="nsm", + [3157]="nsm", + [3158]="nsm", + [3170]="nsm", + [3171]="nsm", + [3192]="on", + [3193]="on", + [3194]="on", + [3195]="on", + [3196]="on", + [3197]="on", + [3198]="on", + [3201]="nsm", + [3260]="nsm", + [3276]="nsm", + [3277]="nsm", + [3298]="nsm", + [3299]="nsm", + [3328]="nsm", + [3329]="nsm", + [3387]="nsm", + [3388]="nsm", + [3393]="nsm", + [3394]="nsm", + [3395]="nsm", + [3396]="nsm", + [3405]="nsm", + [3426]="nsm", + [3427]="nsm", + [3530]="nsm", + [3538]="nsm", + [3539]="nsm", + [3540]="nsm", + [3542]="nsm", + [3633]="nsm", + [3636]="nsm", + [3637]="nsm", + [3638]="nsm", + [3639]="nsm", + [3640]="nsm", + [3641]="nsm", + [3642]="nsm", + [3647]="et", + [3655]="nsm", + [3656]="nsm", + [3657]="nsm", + [3658]="nsm", + [3659]="nsm", + [3660]="nsm", + [3661]="nsm", + [3662]="nsm", + [3761]="nsm", + [3764]="nsm", + [3765]="nsm", + [3766]="nsm", + [3767]="nsm", + [3768]="nsm", + [3769]="nsm", + [3771]="nsm", + [3772]="nsm", + [3784]="nsm", + [3785]="nsm", + [3786]="nsm", + [3787]="nsm", + [3788]="nsm", + [3789]="nsm", + [3864]="nsm", + [3865]="nsm", + [3893]="nsm", + [3895]="nsm", + [3897]="nsm", + [3898]="on", + [3899]="on", + [3900]="on", + [3901]="on", + [3953]="nsm", + [3954]="nsm", + [3955]="nsm", + [3956]="nsm", + [3957]="nsm", + [3958]="nsm", + [3959]="nsm", + [3960]="nsm", + [3961]="nsm", + [3962]="nsm", + [3963]="nsm", + [3964]="nsm", + [3965]="nsm", + [3966]="nsm", + [3968]="nsm", + [3969]="nsm", + [3970]="nsm", + [3971]="nsm", + [3972]="nsm", + [3974]="nsm", + [3975]="nsm", + [3981]="nsm", + [3982]="nsm", + [3983]="nsm", + [3984]="nsm", + [3985]="nsm", + [3986]="nsm", + [3987]="nsm", + [3988]="nsm", + [3989]="nsm", + [3990]="nsm", + [3991]="nsm", + [3993]="nsm", + [3994]="nsm", + [3995]="nsm", + [3996]="nsm", + [3997]="nsm", + [3998]="nsm", + [3999]="nsm", + [4000]="nsm", + [4001]="nsm", + [4002]="nsm", + [4003]="nsm", + [4004]="nsm", + [4005]="nsm", + [4006]="nsm", + [4007]="nsm", + [4008]="nsm", + [4009]="nsm", + [4010]="nsm", + [4011]="nsm", + [4012]="nsm", + [4013]="nsm", + [4014]="nsm", + [4015]="nsm", + [4016]="nsm", + [4017]="nsm", + [4018]="nsm", + [4019]="nsm", + [4020]="nsm", + [4021]="nsm", + [4022]="nsm", + [4023]="nsm", + [4024]="nsm", + [4025]="nsm", + [4026]="nsm", + [4027]="nsm", + [4028]="nsm", + [4038]="nsm", + [4141]="nsm", + [4142]="nsm", + [4143]="nsm", + [4144]="nsm", + [4146]="nsm", + [4147]="nsm", + [4148]="nsm", + [4149]="nsm", + [4150]="nsm", + [4151]="nsm", + [4153]="nsm", + [4154]="nsm", + [4157]="nsm", + [4158]="nsm", + [4184]="nsm", + [4185]="nsm", + [4190]="nsm", + [4191]="nsm", + [4192]="nsm", + [4209]="nsm", + [4210]="nsm", + [4211]="nsm", + [4212]="nsm", + [4226]="nsm", + [4229]="nsm", + [4230]="nsm", + [4237]="nsm", + [4253]="nsm", + [4957]="nsm", + [4958]="nsm", + [4959]="nsm", + [5008]="on", + [5009]="on", + [5010]="on", + [5011]="on", + [5012]="on", + [5013]="on", + [5014]="on", + [5015]="on", + [5016]="on", + [5017]="on", + [5120]="on", + [5760]="ws", + [5787]="on", + [5788]="on", + [5906]="nsm", + [5907]="nsm", + [5908]="nsm", + [5938]="nsm", + [5939]="nsm", + [5940]="nsm", + [5970]="nsm", + [5971]="nsm", + [6002]="nsm", + [6003]="nsm", + [6068]="nsm", + [6069]="nsm", + [6071]="nsm", + [6072]="nsm", + [6073]="nsm", + [6074]="nsm", + [6075]="nsm", + [6076]="nsm", + [6077]="nsm", + [6086]="nsm", + [6089]="nsm", + [6090]="nsm", + [6091]="nsm", + [6092]="nsm", + [6093]="nsm", + [6094]="nsm", + [6095]="nsm", + [6096]="nsm", + [6097]="nsm", + [6098]="nsm", + [6099]="nsm", + [6107]="et", + [6109]="nsm", + [6128]="on", + [6129]="on", + [6130]="on", + [6131]="on", + [6132]="on", + [6133]="on", + [6134]="on", + [6135]="on", + [6136]="on", + [6137]="on", + [6144]="on", + [6145]="on", + [6146]="on", + [6147]="on", + [6148]="on", + [6149]="on", + [6150]="on", + [6151]="on", + [6152]="on", + [6153]="on", + [6154]="on", + [6155]="nsm", + [6156]="nsm", + [6157]="nsm", + [6158]="bn", + [6277]="nsm", + [6278]="nsm", + [6313]="nsm", + [6432]="nsm", + [6433]="nsm", + [6434]="nsm", + [6439]="nsm", + [6440]="nsm", + [6450]="nsm", + [6457]="nsm", + [6458]="nsm", + [6459]="nsm", + [6464]="on", + [6468]="on", + [6469]="on", + [6622]="on", + [6623]="on", + [6624]="on", + [6625]="on", + [6626]="on", + [6627]="on", + [6628]="on", + [6629]="on", + [6630]="on", + [6631]="on", + [6632]="on", + [6633]="on", + [6634]="on", + [6635]="on", + [6636]="on", + [6637]="on", + [6638]="on", + [6639]="on", + [6640]="on", + [6641]="on", + [6642]="on", + [6643]="on", + [6644]="on", + [6645]="on", + [6646]="on", + [6647]="on", + [6648]="on", + [6649]="on", + [6650]="on", + [6651]="on", + [6652]="on", + [6653]="on", + [6654]="on", + [6655]="on", + [6679]="nsm", + [6680]="nsm", + [6683]="nsm", + [6742]="nsm", + [6744]="nsm", + [6745]="nsm", + [6746]="nsm", + [6747]="nsm", + [6748]="nsm", + [6749]="nsm", + [6750]="nsm", + [6752]="nsm", + [6754]="nsm", + [6757]="nsm", + [6758]="nsm", + [6759]="nsm", + [6760]="nsm", + [6761]="nsm", + [6762]="nsm", + [6763]="nsm", + [6764]="nsm", + [6771]="nsm", + [6772]="nsm", + [6773]="nsm", + [6774]="nsm", + [6775]="nsm", + [6776]="nsm", + [6777]="nsm", + [6778]="nsm", + [6779]="nsm", + [6780]="nsm", + [6783]="nsm", + [6832]="nsm", + [6833]="nsm", + [6834]="nsm", + [6835]="nsm", + [6836]="nsm", + [6837]="nsm", + [6838]="nsm", + [6839]="nsm", + [6840]="nsm", + [6841]="nsm", + [6842]="nsm", + [6843]="nsm", + [6844]="nsm", + [6845]="nsm", + [6846]="nsm", + [6912]="nsm", + [6913]="nsm", + [6914]="nsm", + [6915]="nsm", + [6964]="nsm", + [6966]="nsm", + [6967]="nsm", + [6968]="nsm", + [6969]="nsm", + [6970]="nsm", + [6972]="nsm", + [6978]="nsm", + [7019]="nsm", + [7020]="nsm", + [7021]="nsm", + [7022]="nsm", + [7023]="nsm", + [7024]="nsm", + [7025]="nsm", + [7026]="nsm", + [7027]="nsm", + [7040]="nsm", + [7041]="nsm", + [7074]="nsm", + [7075]="nsm", + [7076]="nsm", + [7077]="nsm", + [7080]="nsm", + [7081]="nsm", + [7083]="nsm", + [7084]="nsm", + [7085]="nsm", + [7142]="nsm", + [7144]="nsm", + [7145]="nsm", + [7149]="nsm", + [7151]="nsm", + [7152]="nsm", + [7153]="nsm", + [7212]="nsm", + [7213]="nsm", + [7214]="nsm", + [7215]="nsm", + [7216]="nsm", + [7217]="nsm", + [7218]="nsm", + [7219]="nsm", + [7222]="nsm", + [7223]="nsm", + [7376]="nsm", + [7377]="nsm", + [7378]="nsm", + [7380]="nsm", + [7381]="nsm", + [7382]="nsm", + [7383]="nsm", + [7384]="nsm", + [7385]="nsm", + [7386]="nsm", + [7387]="nsm", + [7388]="nsm", + [7389]="nsm", + [7390]="nsm", + [7391]="nsm", + [7392]="nsm", + [7394]="nsm", + [7395]="nsm", + [7396]="nsm", + [7397]="nsm", + [7398]="nsm", + [7399]="nsm", + [7400]="nsm", + [7405]="nsm", + [7412]="nsm", + [7416]="nsm", + [7417]="nsm", + [7616]="nsm", + [7617]="nsm", + [7618]="nsm", + [7619]="nsm", + [7620]="nsm", + [7621]="nsm", + [7622]="nsm", + [7623]="nsm", + [7624]="nsm", + [7625]="nsm", + [7626]="nsm", + [7627]="nsm", + [7628]="nsm", + [7629]="nsm", + [7630]="nsm", + [7631]="nsm", + [7632]="nsm", + [7633]="nsm", + [7634]="nsm", + [7635]="nsm", + [7636]="nsm", + [7637]="nsm", + [7638]="nsm", + [7639]="nsm", + [7640]="nsm", + [7641]="nsm", + [7642]="nsm", + [7643]="nsm", + [7644]="nsm", + [7645]="nsm", + [7646]="nsm", + [7647]="nsm", + [7648]="nsm", + [7649]="nsm", + [7650]="nsm", + [7651]="nsm", + [7652]="nsm", + [7653]="nsm", + [7654]="nsm", + [7655]="nsm", + [7656]="nsm", + [7657]="nsm", + [7658]="nsm", + [7659]="nsm", + [7660]="nsm", + [7661]="nsm", + [7662]="nsm", + [7663]="nsm", + [7664]="nsm", + [7665]="nsm", + [7666]="nsm", + [7667]="nsm", + [7668]="nsm", + [7669]="nsm", + [7670]="nsm", + [7671]="nsm", + [7672]="nsm", + [7673]="nsm", + [7675]="nsm", + [7676]="nsm", + [7677]="nsm", + [7678]="nsm", + [7679]="nsm", + [8125]="on", + [8127]="on", + [8128]="on", + [8129]="on", + [8141]="on", + [8142]="on", + [8143]="on", + [8157]="on", + [8158]="on", + [8159]="on", + [8173]="on", + [8174]="on", + [8175]="on", + [8189]="on", + [8190]="on", + [8192]="ws", + [8193]="ws", + [8194]="ws", + [8195]="ws", + [8196]="ws", + [8197]="ws", + [8198]="ws", + [8199]="ws", + [8200]="ws", + [8201]="ws", + [8202]="ws", + [8203]="bn", + [8204]="bn", + [8205]="bn", + [8207]="r", + [8208]="on", + [8209]="on", + [8210]="on", + [8211]="on", + [8212]="on", + [8213]="on", + [8214]="on", + [8215]="on", + [8216]="on", + [8217]="on", + [8218]="on", + [8219]="on", + [8220]="on", + [8221]="on", + [8222]="on", + [8223]="on", + [8224]="on", + [8225]="on", + [8226]="on", + [8227]="on", + [8228]="on", + [8229]="on", + [8230]="on", + [8231]="on", + [8232]="ws", + [8233]="b", + [8234]="lre", + [8235]="rle", + [8236]="pdf", + [8237]="lro", + [8238]="rlo", + [8239]="cs", + [8240]="et", + [8241]="et", + [8242]="et", + [8243]="et", + [8244]="et", + [8245]="on", + [8246]="on", + [8247]="on", + [8248]="on", + [8249]="on", + [8250]="on", + [8251]="on", + [8252]="on", + [8253]="on", + [8254]="on", + [8255]="on", + [8256]="on", + [8257]="on", + [8258]="on", + [8259]="on", + [8260]="cs", + [8261]="on", + [8262]="on", + [8263]="on", + [8264]="on", + [8265]="on", + [8266]="on", + [8267]="on", + [8268]="on", + [8269]="on", + [8270]="on", + [8271]="on", + [8272]="on", + [8273]="on", + [8274]="on", + [8275]="on", + [8276]="on", + [8277]="on", + [8278]="on", + [8279]="on", + [8280]="on", + [8281]="on", + [8282]="on", + [8283]="on", + [8284]="on", + [8285]="on", + [8286]="on", + [8287]="ws", + [8288]="bn", + [8289]="bn", + [8290]="bn", + [8291]="bn", + [8292]="bn", + [8294]="lri", + [8295]="rli", + [8296]="fsi", + [8297]="pdi", + [8298]="bn", + [8299]="bn", + [8300]="bn", + [8301]="bn", + [8302]="bn", + [8303]="bn", + [8304]="en", + [8308]="en", + [8309]="en", + [8310]="en", + [8311]="en", + [8312]="en", + [8313]="en", + [8314]="es", + [8315]="es", + [8316]="on", + [8317]="on", + [8318]="on", + [8320]="en", + [8321]="en", + [8322]="en", + [8323]="en", + [8324]="en", + [8325]="en", + [8326]="en", + [8327]="en", + [8328]="en", + [8329]="en", + [8330]="es", + [8331]="es", + [8332]="on", + [8333]="on", + [8334]="on", + [8352]="et", + [8353]="et", + [8354]="et", + [8355]="et", + [8356]="et", + [8357]="et", + [8358]="et", + [8359]="et", + [8360]="et", + [8361]="et", + [8362]="et", + [8363]="et", + [8364]="et", + [8365]="et", + [8366]="et", + [8367]="et", + [8368]="et", + [8369]="et", + [8370]="et", + [8371]="et", + [8372]="et", + [8373]="et", + [8374]="et", + [8375]="et", + [8376]="et", + [8377]="et", + [8378]="et", + [8379]="et", + [8380]="et", + [8381]="et", + [8382]="et", + [8383]="et", + [8400]="nsm", + [8401]="nsm", + [8402]="nsm", + [8403]="nsm", + [8404]="nsm", + [8405]="nsm", + [8406]="nsm", + [8407]="nsm", + [8408]="nsm", + [8409]="nsm", + [8410]="nsm", + [8411]="nsm", + [8412]="nsm", + [8413]="nsm", + [8414]="nsm", + [8415]="nsm", + [8416]="nsm", + [8417]="nsm", + [8418]="nsm", + [8419]="nsm", + [8420]="nsm", + [8421]="nsm", + [8422]="nsm", + [8423]="nsm", + [8424]="nsm", + [8425]="nsm", + [8426]="nsm", + [8427]="nsm", + [8428]="nsm", + [8429]="nsm", + [8430]="nsm", + [8431]="nsm", + [8432]="nsm", + [8448]="on", + [8449]="on", + [8451]="on", + [8452]="on", + [8453]="on", + [8454]="on", + [8456]="on", + [8457]="on", + [8468]="on", + [8470]="on", + [8471]="on", + [8472]="on", + [8478]="on", + [8479]="on", + [8480]="on", + [8481]="on", + [8482]="on", + [8483]="on", + [8485]="on", + [8487]="on", + [8489]="on", + [8494]="et", + [8506]="on", + [8507]="on", + [8512]="on", + [8513]="on", + [8514]="on", + [8515]="on", + [8516]="on", + [8522]="on", + [8523]="on", + [8524]="on", + [8525]="on", + [8528]="on", + [8529]="on", + [8530]="on", + [8531]="on", + [8532]="on", + [8533]="on", + [8534]="on", + [8535]="on", + [8536]="on", + [8537]="on", + [8538]="on", + [8539]="on", + [8540]="on", + [8541]="on", + [8542]="on", + [8543]="on", + [8585]="on", + [8586]="on", + [8587]="on", + [8592]="on", + [8593]="on", + [8594]="on", + [8595]="on", + [8596]="on", + [8597]="on", + [8598]="on", + [8599]="on", + [8600]="on", + [8601]="on", + [8602]="on", + [8603]="on", + [8604]="on", + [8605]="on", + [8606]="on", + [8607]="on", + [8608]="on", + [8609]="on", + [8610]="on", + [8611]="on", + [8612]="on", + [8613]="on", + [8614]="on", + [8615]="on", + [8616]="on", + [8617]="on", + [8618]="on", + [8619]="on", + [8620]="on", + [8621]="on", + [8622]="on", + [8623]="on", + [8624]="on", + [8625]="on", + [8626]="on", + [8627]="on", + [8628]="on", + [8629]="on", + [8630]="on", + [8631]="on", + [8632]="on", + [8633]="on", + [8634]="on", + [8635]="on", + [8636]="on", + [8637]="on", + [8638]="on", + [8639]="on", + [8640]="on", + [8641]="on", + [8642]="on", + [8643]="on", + [8644]="on", + [8645]="on", + [8646]="on", + [8647]="on", + [8648]="on", + [8649]="on", + [8650]="on", + [8651]="on", + [8652]="on", + [8653]="on", + [8654]="on", + [8655]="on", + [8656]="on", + [8657]="on", + [8658]="on", + [8659]="on", + [8660]="on", + [8661]="on", + [8662]="on", + [8663]="on", + [8664]="on", + [8665]="on", + [8666]="on", + [8667]="on", + [8668]="on", + [8669]="on", + [8670]="on", + [8671]="on", + [8672]="on", + [8673]="on", + [8674]="on", + [8675]="on", + [8676]="on", + [8677]="on", + [8678]="on", + [8679]="on", + [8680]="on", + [8681]="on", + [8682]="on", + [8683]="on", + [8684]="on", + [8685]="on", + [8686]="on", + [8687]="on", + [8688]="on", + [8689]="on", + [8690]="on", + [8691]="on", + [8692]="on", + [8693]="on", + [8694]="on", + [8695]="on", + [8696]="on", + [8697]="on", + [8698]="on", + [8699]="on", + [8700]="on", + [8701]="on", + [8702]="on", + [8703]="on", + [8704]="on", + [8705]="on", + [8706]="on", + [8707]="on", + [8708]="on", + [8709]="on", + [8710]="on", + [8711]="on", + [8712]="on", + [8713]="on", + [8714]="on", + [8715]="on", + [8716]="on", + [8717]="on", + [8718]="on", + [8719]="on", + [8720]="on", + [8721]="on", + [8722]="es", + [8723]="et", + [8724]="on", + [8725]="on", + [8726]="on", + [8727]="on", + [8728]="on", + [8729]="on", + [8730]="on", + [8731]="on", + [8732]="on", + [8733]="on", + [8734]="on", + [8735]="on", + [8736]="on", + [8737]="on", + [8738]="on", + [8739]="on", + [8740]="on", + [8741]="on", + [8742]="on", + [8743]="on", + [8744]="on", + [8745]="on", + [8746]="on", + [8747]="on", + [8748]="on", + [8749]="on", + [8750]="on", + [8751]="on", + [8752]="on", + [8753]="on", + [8754]="on", + [8755]="on", + [8756]="on", + [8757]="on", + [8758]="on", + [8759]="on", + [8760]="on", + [8761]="on", + [8762]="on", + [8763]="on", + [8764]="on", + [8765]="on", + [8766]="on", + [8767]="on", + [8768]="on", + [8769]="on", + [8770]="on", + [8771]="on", + [8772]="on", + [8773]="on", + [8774]="on", + [8775]="on", + [8776]="on", + [8777]="on", + [8778]="on", + [8779]="on", + [8780]="on", + [8781]="on", + [8782]="on", + [8783]="on", + [8784]="on", + [8785]="on", + [8786]="on", + [8787]="on", + [8788]="on", + [8789]="on", + [8790]="on", + [8791]="on", + [8792]="on", + [8793]="on", + [8794]="on", + [8795]="on", + [8796]="on", + [8797]="on", + [8798]="on", + [8799]="on", + [8800]="on", + [8801]="on", + [8802]="on", + [8803]="on", + [8804]="on", + [8805]="on", + [8806]="on", + [8807]="on", + [8808]="on", + [8809]="on", + [8810]="on", + [8811]="on", + [8812]="on", + [8813]="on", + [8814]="on", + [8815]="on", + [8816]="on", + [8817]="on", + [8818]="on", + [8819]="on", + [8820]="on", + [8821]="on", + [8822]="on", + [8823]="on", + [8824]="on", + [8825]="on", + [8826]="on", + [8827]="on", + [8828]="on", + [8829]="on", + [8830]="on", + [8831]="on", + [8832]="on", + [8833]="on", + [8834]="on", + [8835]="on", + [8836]="on", + [8837]="on", + [8838]="on", + [8839]="on", + [8840]="on", + [8841]="on", + [8842]="on", + [8843]="on", + [8844]="on", + [8845]="on", + [8846]="on", + [8847]="on", + [8848]="on", + [8849]="on", + [8850]="on", + [8851]="on", + [8852]="on", + [8853]="on", + [8854]="on", + [8855]="on", + [8856]="on", + [8857]="on", + [8858]="on", + [8859]="on", + [8860]="on", + [8861]="on", + [8862]="on", + [8863]="on", + [8864]="on", + [8865]="on", + [8866]="on", + [8867]="on", + [8868]="on", + [8869]="on", + [8870]="on", + [8871]="on", + [8872]="on", + [8873]="on", + [8874]="on", + [8875]="on", + [8876]="on", + [8877]="on", + [8878]="on", + [8879]="on", + [8880]="on", + [8881]="on", + [8882]="on", + [8883]="on", + [8884]="on", + [8885]="on", + [8886]="on", + [8887]="on", + [8888]="on", + [8889]="on", + [8890]="on", + [8891]="on", + [8892]="on", + [8893]="on", + [8894]="on", + [8895]="on", + [8896]="on", + [8897]="on", + [8898]="on", + [8899]="on", + [8900]="on", + [8901]="on", + [8902]="on", + [8903]="on", + [8904]="on", + [8905]="on", + [8906]="on", + [8907]="on", + [8908]="on", + [8909]="on", + [8910]="on", + [8911]="on", + [8912]="on", + [8913]="on", + [8914]="on", + [8915]="on", + [8916]="on", + [8917]="on", + [8918]="on", + [8919]="on", + [8920]="on", + [8921]="on", + [8922]="on", + [8923]="on", + [8924]="on", + [8925]="on", + [8926]="on", + [8927]="on", + [8928]="on", + [8929]="on", + [8930]="on", + [8931]="on", + [8932]="on", + [8933]="on", + [8934]="on", + [8935]="on", + [8936]="on", + [8937]="on", + [8938]="on", + [8939]="on", + [8940]="on", + [8941]="on", + [8942]="on", + [8943]="on", + [8944]="on", + [8945]="on", + [8946]="on", + [8947]="on", + [8948]="on", + [8949]="on", + [8950]="on", + [8951]="on", + [8952]="on", + [8953]="on", + [8954]="on", + [8955]="on", + [8956]="on", + [8957]="on", + [8958]="on", + [8959]="on", + [8960]="on", + [8961]="on", + [8962]="on", + [8963]="on", + [8964]="on", + [8965]="on", + [8966]="on", + [8967]="on", + [8968]="on", + [8969]="on", + [8970]="on", + [8971]="on", + [8972]="on", + [8973]="on", + [8974]="on", + [8975]="on", + [8976]="on", + [8977]="on", + [8978]="on", + [8979]="on", + [8980]="on", + [8981]="on", + [8982]="on", + [8983]="on", + [8984]="on", + [8985]="on", + [8986]="on", + [8987]="on", + [8988]="on", + [8989]="on", + [8990]="on", + [8991]="on", + [8992]="on", + [8993]="on", + [8994]="on", + [8995]="on", + [8996]="on", + [8997]="on", + [8998]="on", + [8999]="on", + [9000]="on", + [9001]="on", + [9002]="on", + [9003]="on", + [9004]="on", + [9005]="on", + [9006]="on", + [9007]="on", + [9008]="on", + [9009]="on", + [9010]="on", + [9011]="on", + [9012]="on", + [9013]="on", + [9083]="on", + [9084]="on", + [9085]="on", + [9086]="on", + [9087]="on", + [9088]="on", + [9089]="on", + [9090]="on", + [9091]="on", + [9092]="on", + [9093]="on", + [9094]="on", + [9095]="on", + [9096]="on", + [9097]="on", + [9098]="on", + [9099]="on", + [9100]="on", + [9101]="on", + [9102]="on", + [9103]="on", + [9104]="on", + [9105]="on", + [9106]="on", + [9107]="on", + [9108]="on", + [9110]="on", + [9111]="on", + [9112]="on", + [9113]="on", + [9114]="on", + [9115]="on", + [9116]="on", + [9117]="on", + [9118]="on", + [9119]="on", + [9120]="on", + [9121]="on", + [9122]="on", + [9123]="on", + [9124]="on", + [9125]="on", + [9126]="on", + [9127]="on", + [9128]="on", + [9129]="on", + [9130]="on", + [9131]="on", + [9132]="on", + [9133]="on", + [9134]="on", + [9135]="on", + [9136]="on", + [9137]="on", + [9138]="on", + [9139]="on", + [9140]="on", + [9141]="on", + [9142]="on", + [9143]="on", + [9144]="on", + [9145]="on", + [9146]="on", + [9147]="on", + [9148]="on", + [9149]="on", + [9150]="on", + [9151]="on", + [9152]="on", + [9153]="on", + [9154]="on", + [9155]="on", + [9156]="on", + [9157]="on", + [9158]="on", + [9159]="on", + [9160]="on", + [9161]="on", + [9162]="on", + [9163]="on", + [9164]="on", + [9165]="on", + [9166]="on", + [9167]="on", + [9168]="on", + [9169]="on", + [9170]="on", + [9171]="on", + [9172]="on", + [9173]="on", + [9174]="on", + [9175]="on", + [9176]="on", + [9177]="on", + [9178]="on", + [9179]="on", + [9180]="on", + [9181]="on", + [9182]="on", + [9183]="on", + [9184]="on", + [9185]="on", + [9186]="on", + [9187]="on", + [9188]="on", + [9189]="on", + [9190]="on", + [9191]="on", + [9192]="on", + [9193]="on", + [9194]="on", + [9195]="on", + [9196]="on", + [9197]="on", + [9198]="on", + [9199]="on", + [9200]="on", + [9201]="on", + [9202]="on", + [9203]="on", + [9204]="on", + [9205]="on", + [9206]="on", + [9207]="on", + [9208]="on", + [9209]="on", + [9210]="on", + [9211]="on", + [9212]="on", + [9213]="on", + [9214]="on", + [9215]="on", + [9216]="on", + [9217]="on", + [9218]="on", + [9219]="on", + [9220]="on", + [9221]="on", + [9222]="on", + [9223]="on", + [9224]="on", + [9225]="on", + [9226]="on", + [9227]="on", + [9228]="on", + [9229]="on", + [9230]="on", + [9231]="on", + [9232]="on", + [9233]="on", + [9234]="on", + [9235]="on", + [9236]="on", + [9237]="on", + [9238]="on", + [9239]="on", + [9240]="on", + [9241]="on", + [9242]="on", + [9243]="on", + [9244]="on", + [9245]="on", + [9246]="on", + [9247]="on", + [9248]="on", + [9249]="on", + [9250]="on", + [9251]="on", + [9252]="on", + [9253]="on", + [9254]="on", + [9280]="on", + [9281]="on", + [9282]="on", + [9283]="on", + [9284]="on", + [9285]="on", + [9286]="on", + [9287]="on", + [9288]="on", + [9289]="on", + [9290]="on", + [9312]="on", + [9313]="on", + [9314]="on", + [9315]="on", + [9316]="on", + [9317]="on", + [9318]="on", + [9319]="on", + [9320]="on", + [9321]="on", + [9322]="on", + [9323]="on", + [9324]="on", + [9325]="on", + [9326]="on", + [9327]="on", + [9328]="on", + [9329]="on", + [9330]="on", + [9331]="on", + [9332]="on", + [9333]="on", + [9334]="on", + [9335]="on", + [9336]="on", + [9337]="on", + [9338]="on", + [9339]="on", + [9340]="on", + [9341]="on", + [9342]="on", + [9343]="on", + [9344]="on", + [9345]="on", + [9346]="on", + [9347]="on", + [9348]="on", + [9349]="on", + [9350]="on", + [9351]="on", + [9352]="en", + [9353]="en", + [9354]="en", + [9355]="en", + [9356]="en", + [9357]="en", + [9358]="en", + [9359]="en", + [9360]="en", + [9361]="en", + [9362]="en", + [9363]="en", + [9364]="en", + [9365]="en", + [9366]="en", + [9367]="en", + [9368]="en", + [9369]="en", + [9370]="en", + [9371]="en", + [9450]="on", + [9451]="on", + [9452]="on", + [9453]="on", + [9454]="on", + [9455]="on", + [9456]="on", + [9457]="on", + [9458]="on", + [9459]="on", + [9460]="on", + [9461]="on", + [9462]="on", + [9463]="on", + [9464]="on", + [9465]="on", + [9466]="on", + [9467]="on", + [9468]="on", + [9469]="on", + [9470]="on", + [9471]="on", + [9472]="on", + [9473]="on", + [9474]="on", + [9475]="on", + [9476]="on", + [9477]="on", + [9478]="on", + [9479]="on", + [9480]="on", + [9481]="on", + [9482]="on", + [9483]="on", + [9484]="on", + [9485]="on", + [9486]="on", + [9487]="on", + [9488]="on", + [9489]="on", + [9490]="on", + [9491]="on", + [9492]="on", + [9493]="on", + [9494]="on", + [9495]="on", + [9496]="on", + [9497]="on", + [9498]="on", + [9499]="on", + [9500]="on", + [9501]="on", + [9502]="on", + [9503]="on", + [9504]="on", + [9505]="on", + [9506]="on", + [9507]="on", + [9508]="on", + [9509]="on", + [9510]="on", + [9511]="on", + [9512]="on", + [9513]="on", + [9514]="on", + [9515]="on", + [9516]="on", + [9517]="on", + [9518]="on", + [9519]="on", + [9520]="on", + [9521]="on", + [9522]="on", + [9523]="on", + [9524]="on", + [9525]="on", + [9526]="on", + [9527]="on", + [9528]="on", + [9529]="on", + [9530]="on", + [9531]="on", + [9532]="on", + [9533]="on", + [9534]="on", + [9535]="on", + [9536]="on", + [9537]="on", + [9538]="on", + [9539]="on", + [9540]="on", + [9541]="on", + [9542]="on", + [9543]="on", + [9544]="on", + [9545]="on", + [9546]="on", + [9547]="on", + [9548]="on", + [9549]="on", + [9550]="on", + [9551]="on", + [9552]="on", + [9553]="on", + [9554]="on", + [9555]="on", + [9556]="on", + [9557]="on", + [9558]="on", + [9559]="on", + [9560]="on", + [9561]="on", + [9562]="on", + [9563]="on", + [9564]="on", + [9565]="on", + [9566]="on", + [9567]="on", + [9568]="on", + [9569]="on", + [9570]="on", + [9571]="on", + [9572]="on", + [9573]="on", + [9574]="on", + [9575]="on", + [9576]="on", + [9577]="on", + [9578]="on", + [9579]="on", + [9580]="on", + [9581]="on", + [9582]="on", + [9583]="on", + [9584]="on", + [9585]="on", + [9586]="on", + [9587]="on", + [9588]="on", + [9589]="on", + [9590]="on", + [9591]="on", + [9592]="on", + [9593]="on", + [9594]="on", + [9595]="on", + [9596]="on", + [9597]="on", + [9598]="on", + [9599]="on", + [9600]="on", + [9601]="on", + [9602]="on", + [9603]="on", + [9604]="on", + [9605]="on", + [9606]="on", + [9607]="on", + [9608]="on", + [9609]="on", + [9610]="on", + [9611]="on", + [9612]="on", + [9613]="on", + [9614]="on", + [9615]="on", + [9616]="on", + [9617]="on", + [9618]="on", + [9619]="on", + [9620]="on", + [9621]="on", + [9622]="on", + [9623]="on", + [9624]="on", + [9625]="on", + [9626]="on", + [9627]="on", + [9628]="on", + [9629]="on", + [9630]="on", + [9631]="on", + [9632]="on", + [9633]="on", + [9634]="on", + [9635]="on", + [9636]="on", + [9637]="on", + [9638]="on", + [9639]="on", + [9640]="on", + [9641]="on", + [9642]="on", + [9643]="on", + [9644]="on", + [9645]="on", + [9646]="on", + [9647]="on", + [9648]="on", + [9649]="on", + [9650]="on", + [9651]="on", + [9652]="on", + [9653]="on", + [9654]="on", + [9655]="on", + [9656]="on", + [9657]="on", + [9658]="on", + [9659]="on", + [9660]="on", + [9661]="on", + [9662]="on", + [9663]="on", + [9664]="on", + [9665]="on", + [9666]="on", + [9667]="on", + [9668]="on", + [9669]="on", + [9670]="on", + [9671]="on", + [9672]="on", + [9673]="on", + [9674]="on", + [9675]="on", + [9676]="on", + [9677]="on", + [9678]="on", + [9679]="on", + [9680]="on", + [9681]="on", + [9682]="on", + [9683]="on", + [9684]="on", + [9685]="on", + [9686]="on", + [9687]="on", + [9688]="on", + [9689]="on", + [9690]="on", + [9691]="on", + [9692]="on", + [9693]="on", + [9694]="on", + [9695]="on", + [9696]="on", + [9697]="on", + [9698]="on", + [9699]="on", + [9700]="on", + [9701]="on", + [9702]="on", + [9703]="on", + [9704]="on", + [9705]="on", + [9706]="on", + [9707]="on", + [9708]="on", + [9709]="on", + [9710]="on", + [9711]="on", + [9712]="on", + [9713]="on", + [9714]="on", + [9715]="on", + [9716]="on", + [9717]="on", + [9718]="on", + [9719]="on", + [9720]="on", + [9721]="on", + [9722]="on", + [9723]="on", + [9724]="on", + [9725]="on", + [9726]="on", + [9727]="on", + [9728]="on", + [9729]="on", + [9730]="on", + [9731]="on", + [9732]="on", + [9733]="on", + [9734]="on", + [9735]="on", + [9736]="on", + [9737]="on", + [9738]="on", + [9739]="on", + [9740]="on", + [9741]="on", + [9742]="on", + [9743]="on", + [9744]="on", + [9745]="on", + [9746]="on", + [9747]="on", + [9748]="on", + [9749]="on", + [9750]="on", + [9751]="on", + [9752]="on", + [9753]="on", + [9754]="on", + [9755]="on", + [9756]="on", + [9757]="on", + [9758]="on", + [9759]="on", + [9760]="on", + [9761]="on", + [9762]="on", + [9763]="on", + [9764]="on", + [9765]="on", + [9766]="on", + [9767]="on", + [9768]="on", + [9769]="on", + [9770]="on", + [9771]="on", + [9772]="on", + [9773]="on", + [9774]="on", + [9775]="on", + [9776]="on", + [9777]="on", + [9778]="on", + [9779]="on", + [9780]="on", + [9781]="on", + [9782]="on", + [9783]="on", + [9784]="on", + [9785]="on", + [9786]="on", + [9787]="on", + [9788]="on", + [9789]="on", + [9790]="on", + [9791]="on", + [9792]="on", + [9793]="on", + [9794]="on", + [9795]="on", + [9796]="on", + [9797]="on", + [9798]="on", + [9799]="on", + [9800]="on", + [9801]="on", + [9802]="on", + [9803]="on", + [9804]="on", + [9805]="on", + [9806]="on", + [9807]="on", + [9808]="on", + [9809]="on", + [9810]="on", + [9811]="on", + [9812]="on", + [9813]="on", + [9814]="on", + [9815]="on", + [9816]="on", + [9817]="on", + [9818]="on", + [9819]="on", + [9820]="on", + [9821]="on", + [9822]="on", + [9823]="on", + [9824]="on", + [9825]="on", + [9826]="on", + [9827]="on", + [9828]="on", + [9829]="on", + [9830]="on", + [9831]="on", + [9832]="on", + [9833]="on", + [9834]="on", + [9835]="on", + [9836]="on", + [9837]="on", + [9838]="on", + [9839]="on", + [9840]="on", + [9841]="on", + [9842]="on", + [9843]="on", + [9844]="on", + [9845]="on", + [9846]="on", + [9847]="on", + [9848]="on", + [9849]="on", + [9850]="on", + [9851]="on", + [9852]="on", + [9853]="on", + [9854]="on", + [9855]="on", + [9856]="on", + [9857]="on", + [9858]="on", + [9859]="on", + [9860]="on", + [9861]="on", + [9862]="on", + [9863]="on", + [9864]="on", + [9865]="on", + [9866]="on", + [9867]="on", + [9868]="on", + [9869]="on", + [9870]="on", + [9871]="on", + [9872]="on", + [9873]="on", + [9874]="on", + [9875]="on", + [9876]="on", + [9877]="on", + [9878]="on", + [9879]="on", + [9880]="on", + [9881]="on", + [9882]="on", + [9883]="on", + [9884]="on", + [9885]="on", + [9886]="on", + [9887]="on", + [9888]="on", + [9889]="on", + [9890]="on", + [9891]="on", + [9892]="on", + [9893]="on", + [9894]="on", + [9895]="on", + [9896]="on", + [9897]="on", + [9898]="on", + [9899]="on", + [9901]="on", + [9902]="on", + [9903]="on", + [9904]="on", + [9905]="on", + [9906]="on", + [9907]="on", + [9908]="on", + [9909]="on", + [9910]="on", + [9911]="on", + [9912]="on", + [9913]="on", + [9914]="on", + [9915]="on", + [9916]="on", + [9917]="on", + [9918]="on", + [9919]="on", + [9920]="on", + [9921]="on", + [9922]="on", + [9923]="on", + [9924]="on", + [9925]="on", + [9926]="on", + [9927]="on", + [9928]="on", + [9929]="on", + [9930]="on", + [9931]="on", + [9932]="on", + [9933]="on", + [9934]="on", + [9935]="on", + [9936]="on", + [9937]="on", + [9938]="on", + [9939]="on", + [9940]="on", + [9941]="on", + [9942]="on", + [9943]="on", + [9944]="on", + [9945]="on", + [9946]="on", + [9947]="on", + [9948]="on", + [9949]="on", + [9950]="on", + [9951]="on", + [9952]="on", + [9953]="on", + [9954]="on", + [9955]="on", + [9956]="on", + [9957]="on", + [9958]="on", + [9959]="on", + [9960]="on", + [9961]="on", + [9962]="on", + [9963]="on", + [9964]="on", + [9965]="on", + [9966]="on", + [9967]="on", + [9968]="on", + [9969]="on", + [9970]="on", + [9971]="on", + [9972]="on", + [9973]="on", + [9974]="on", + [9975]="on", + [9976]="on", + [9977]="on", + [9978]="on", + [9979]="on", + [9980]="on", + [9981]="on", + [9982]="on", + [9983]="on", + [9984]="on", + [9985]="on", + [9986]="on", + [9987]="on", + [9988]="on", + [9989]="on", + [9990]="on", + [9991]="on", + [9992]="on", + [9993]="on", + [9994]="on", + [9995]="on", + [9996]="on", + [9997]="on", + [9998]="on", + [9999]="on", + [10000]="on", + [10001]="on", + [10002]="on", + [10003]="on", + [10004]="on", + [10005]="on", + [10006]="on", + [10007]="on", + [10008]="on", + [10009]="on", + [10010]="on", + [10011]="on", + [10012]="on", + [10013]="on", + [10014]="on", + [10015]="on", + [10016]="on", + [10017]="on", + [10018]="on", + [10019]="on", + [10020]="on", + [10021]="on", + [10022]="on", + [10023]="on", + [10024]="on", + [10025]="on", + [10026]="on", + [10027]="on", + [10028]="on", + [10029]="on", + [10030]="on", + [10031]="on", + [10032]="on", + [10033]="on", + [10034]="on", + [10035]="on", + [10036]="on", + [10037]="on", + [10038]="on", + [10039]="on", + [10040]="on", + [10041]="on", + [10042]="on", + [10043]="on", + [10044]="on", + [10045]="on", + [10046]="on", + [10047]="on", + [10048]="on", + [10049]="on", + [10050]="on", + [10051]="on", + [10052]="on", + [10053]="on", + [10054]="on", + [10055]="on", + [10056]="on", + [10057]="on", + [10058]="on", + [10059]="on", + [10060]="on", + [10061]="on", + [10062]="on", + [10063]="on", + [10064]="on", + [10065]="on", + [10066]="on", + [10067]="on", + [10068]="on", + [10069]="on", + [10070]="on", + [10071]="on", + [10072]="on", + [10073]="on", + [10074]="on", + [10075]="on", + [10076]="on", + [10077]="on", + [10078]="on", + [10079]="on", + [10080]="on", + [10081]="on", + [10082]="on", + [10083]="on", + [10084]="on", + [10085]="on", + [10086]="on", + [10087]="on", + [10088]="on", + [10089]="on", + [10090]="on", + [10091]="on", + [10092]="on", + [10093]="on", + [10094]="on", + [10095]="on", + [10096]="on", + [10097]="on", + [10098]="on", + [10099]="on", + [10100]="on", + [10101]="on", + [10102]="on", + [10103]="on", + [10104]="on", + [10105]="on", + [10106]="on", + [10107]="on", + [10108]="on", + [10109]="on", + [10110]="on", + [10111]="on", + [10112]="on", + [10113]="on", + [10114]="on", + [10115]="on", + [10116]="on", + [10117]="on", + [10118]="on", + [10119]="on", + [10120]="on", + [10121]="on", + [10122]="on", + [10123]="on", + [10124]="on", + [10125]="on", + [10126]="on", + [10127]="on", + [10128]="on", + [10129]="on", + [10130]="on", + [10131]="on", + [10132]="on", + [10133]="on", + [10134]="on", + [10135]="on", + [10136]="on", + [10137]="on", + [10138]="on", + [10139]="on", + [10140]="on", + [10141]="on", + [10142]="on", + [10143]="on", + [10144]="on", + [10145]="on", + [10146]="on", + [10147]="on", + [10148]="on", + [10149]="on", + [10150]="on", + [10151]="on", + [10152]="on", + [10153]="on", + [10154]="on", + [10155]="on", + [10156]="on", + [10157]="on", + [10158]="on", + [10159]="on", + [10160]="on", + [10161]="on", + [10162]="on", + [10163]="on", + [10164]="on", + [10165]="on", + [10166]="on", + [10167]="on", + [10168]="on", + [10169]="on", + [10170]="on", + [10171]="on", + [10172]="on", + [10173]="on", + [10174]="on", + [10175]="on", + [10176]="on", + [10177]="on", + [10178]="on", + [10179]="on", + [10180]="on", + [10181]="on", + [10182]="on", + [10183]="on", + [10184]="on", + [10185]="on", + [10186]="on", + [10187]="on", + [10188]="on", + [10189]="on", + [10190]="on", + [10191]="on", + [10192]="on", + [10193]="on", + [10194]="on", + [10195]="on", + [10196]="on", + [10197]="on", + [10198]="on", + [10199]="on", + [10200]="on", + [10201]="on", + [10202]="on", + [10203]="on", + [10204]="on", + [10205]="on", + [10206]="on", + [10207]="on", + [10208]="on", + [10209]="on", + [10210]="on", + [10211]="on", + [10212]="on", + [10213]="on", + [10214]="on", + [10215]="on", + [10216]="on", + [10217]="on", + [10218]="on", + [10219]="on", + [10220]="on", + [10221]="on", + [10222]="on", + [10223]="on", + [10224]="on", + [10225]="on", + [10226]="on", + [10227]="on", + [10228]="on", + [10229]="on", + [10230]="on", + [10231]="on", + [10232]="on", + [10233]="on", + [10234]="on", + [10235]="on", + [10236]="on", + [10237]="on", + [10238]="on", + [10239]="on", + [10496]="on", + [10497]="on", + [10498]="on", + [10499]="on", + [10500]="on", + [10501]="on", + [10502]="on", + [10503]="on", + [10504]="on", + [10505]="on", + [10506]="on", + [10507]="on", + [10508]="on", + [10509]="on", + [10510]="on", + [10511]="on", + [10512]="on", + [10513]="on", + [10514]="on", + [10515]="on", + [10516]="on", + [10517]="on", + [10518]="on", + [10519]="on", + [10520]="on", + [10521]="on", + [10522]="on", + [10523]="on", + [10524]="on", + [10525]="on", + [10526]="on", + [10527]="on", + [10528]="on", + [10529]="on", + [10530]="on", + [10531]="on", + [10532]="on", + [10533]="on", + [10534]="on", + [10535]="on", + [10536]="on", + [10537]="on", + [10538]="on", + [10539]="on", + [10540]="on", + [10541]="on", + [10542]="on", + [10543]="on", + [10544]="on", + [10545]="on", + [10546]="on", + [10547]="on", + [10548]="on", + [10549]="on", + [10550]="on", + [10551]="on", + [10552]="on", + [10553]="on", + [10554]="on", + [10555]="on", + [10556]="on", + [10557]="on", + [10558]="on", + [10559]="on", + [10560]="on", + [10561]="on", + [10562]="on", + [10563]="on", + [10564]="on", + [10565]="on", + [10566]="on", + [10567]="on", + [10568]="on", + [10569]="on", + [10570]="on", + [10571]="on", + [10572]="on", + [10573]="on", + [10574]="on", + [10575]="on", + [10576]="on", + [10577]="on", + [10578]="on", + [10579]="on", + [10580]="on", + [10581]="on", + [10582]="on", + [10583]="on", + [10584]="on", + [10585]="on", + [10586]="on", + [10587]="on", + [10588]="on", + [10589]="on", + [10590]="on", + [10591]="on", + [10592]="on", + [10593]="on", + [10594]="on", + [10595]="on", + [10596]="on", + [10597]="on", + [10598]="on", + [10599]="on", + [10600]="on", + [10601]="on", + [10602]="on", + [10603]="on", + [10604]="on", + [10605]="on", + [10606]="on", + [10607]="on", + [10608]="on", + [10609]="on", + [10610]="on", + [10611]="on", + [10612]="on", + [10613]="on", + [10614]="on", + [10615]="on", + [10616]="on", + [10617]="on", + [10618]="on", + [10619]="on", + [10620]="on", + [10621]="on", + [10622]="on", + [10623]="on", + [10624]="on", + [10625]="on", + [10626]="on", + [10627]="on", + [10628]="on", + [10629]="on", + [10630]="on", + [10631]="on", + [10632]="on", + [10633]="on", + [10634]="on", + [10635]="on", + [10636]="on", + [10637]="on", + [10638]="on", + [10639]="on", + [10640]="on", + [10641]="on", + [10642]="on", + [10643]="on", + [10644]="on", + [10645]="on", + [10646]="on", + [10647]="on", + [10648]="on", + [10649]="on", + [10650]="on", + [10651]="on", + [10652]="on", + [10653]="on", + [10654]="on", + [10655]="on", + [10656]="on", + [10657]="on", + [10658]="on", + [10659]="on", + [10660]="on", + [10661]="on", + [10662]="on", + [10663]="on", + [10664]="on", + [10665]="on", + [10666]="on", + [10667]="on", + [10668]="on", + [10669]="on", + [10670]="on", + [10671]="on", + [10672]="on", + [10673]="on", + [10674]="on", + [10675]="on", + [10676]="on", + [10677]="on", + [10678]="on", + [10679]="on", + [10680]="on", + [10681]="on", + [10682]="on", + [10683]="on", + [10684]="on", + [10685]="on", + [10686]="on", + [10687]="on", + [10688]="on", + [10689]="on", + [10690]="on", + [10691]="on", + [10692]="on", + [10693]="on", + [10694]="on", + [10695]="on", + [10696]="on", + [10697]="on", + [10698]="on", + [10699]="on", + [10700]="on", + [10701]="on", + [10702]="on", + [10703]="on", + [10704]="on", + [10705]="on", + [10706]="on", + [10707]="on", + [10708]="on", + [10709]="on", + [10710]="on", + [10711]="on", + [10712]="on", + [10713]="on", + [10714]="on", + [10715]="on", + [10716]="on", + [10717]="on", + [10718]="on", + [10719]="on", + [10720]="on", + [10721]="on", + [10722]="on", + [10723]="on", + [10724]="on", + [10725]="on", + [10726]="on", + [10727]="on", + [10728]="on", + [10729]="on", + [10730]="on", + [10731]="on", + [10732]="on", + [10733]="on", + [10734]="on", + [10735]="on", + [10736]="on", + [10737]="on", + [10738]="on", + [10739]="on", + [10740]="on", + [10741]="on", + [10742]="on", + [10743]="on", + [10744]="on", + [10745]="on", + [10746]="on", + [10747]="on", + [10748]="on", + [10749]="on", + [10750]="on", + [10751]="on", + [10752]="on", + [10753]="on", + [10754]="on", + [10755]="on", + [10756]="on", + [10757]="on", + [10758]="on", + [10759]="on", + [10760]="on", + [10761]="on", + [10762]="on", + [10763]="on", + [10764]="on", + [10765]="on", + [10766]="on", + [10767]="on", + [10768]="on", + [10769]="on", + [10770]="on", + [10771]="on", + [10772]="on", + [10773]="on", + [10774]="on", + [10775]="on", + [10776]="on", + [10777]="on", + [10778]="on", + [10779]="on", + [10780]="on", + [10781]="on", + [10782]="on", + [10783]="on", + [10784]="on", + [10785]="on", + [10786]="on", + [10787]="on", + [10788]="on", + [10789]="on", + [10790]="on", + [10791]="on", + [10792]="on", + [10793]="on", + [10794]="on", + [10795]="on", + [10796]="on", + [10797]="on", + [10798]="on", + [10799]="on", + [10800]="on", + [10801]="on", + [10802]="on", + [10803]="on", + [10804]="on", + [10805]="on", + [10806]="on", + [10807]="on", + [10808]="on", + [10809]="on", + [10810]="on", + [10811]="on", + [10812]="on", + [10813]="on", + [10814]="on", + [10815]="on", + [10816]="on", + [10817]="on", + [10818]="on", + [10819]="on", + [10820]="on", + [10821]="on", + [10822]="on", + [10823]="on", + [10824]="on", + [10825]="on", + [10826]="on", + [10827]="on", + [10828]="on", + [10829]="on", + [10830]="on", + [10831]="on", + [10832]="on", + [10833]="on", + [10834]="on", + [10835]="on", + [10836]="on", + [10837]="on", + [10838]="on", + [10839]="on", + [10840]="on", + [10841]="on", + [10842]="on", + [10843]="on", + [10844]="on", + [10845]="on", + [10846]="on", + [10847]="on", + [10848]="on", + [10849]="on", + [10850]="on", + [10851]="on", + [10852]="on", + [10853]="on", + [10854]="on", + [10855]="on", + [10856]="on", + [10857]="on", + [10858]="on", + [10859]="on", + [10860]="on", + [10861]="on", + [10862]="on", + [10863]="on", + [10864]="on", + [10865]="on", + [10866]="on", + [10867]="on", + [10868]="on", + [10869]="on", + [10870]="on", + [10871]="on", + [10872]="on", + [10873]="on", + [10874]="on", + [10875]="on", + [10876]="on", + [10877]="on", + [10878]="on", + [10879]="on", + [10880]="on", + [10881]="on", + [10882]="on", + [10883]="on", + [10884]="on", + [10885]="on", + [10886]="on", + [10887]="on", + [10888]="on", + [10889]="on", + [10890]="on", + [10891]="on", + [10892]="on", + [10893]="on", + [10894]="on", + [10895]="on", + [10896]="on", + [10897]="on", + [10898]="on", + [10899]="on", + [10900]="on", + [10901]="on", + [10902]="on", + [10903]="on", + [10904]="on", + [10905]="on", + [10906]="on", + [10907]="on", + [10908]="on", + [10909]="on", + [10910]="on", + [10911]="on", + [10912]="on", + [10913]="on", + [10914]="on", + [10915]="on", + [10916]="on", + [10917]="on", + [10918]="on", + [10919]="on", + [10920]="on", + [10921]="on", + [10922]="on", + [10923]="on", + [10924]="on", + [10925]="on", + [10926]="on", + [10927]="on", + [10928]="on", + [10929]="on", + [10930]="on", + [10931]="on", + [10932]="on", + [10933]="on", + [10934]="on", + [10935]="on", + [10936]="on", + [10937]="on", + [10938]="on", + [10939]="on", + [10940]="on", + [10941]="on", + [10942]="on", + [10943]="on", + [10944]="on", + [10945]="on", + [10946]="on", + [10947]="on", + [10948]="on", + [10949]="on", + [10950]="on", + [10951]="on", + [10952]="on", + [10953]="on", + [10954]="on", + [10955]="on", + [10956]="on", + [10957]="on", + [10958]="on", + [10959]="on", + [10960]="on", + [10961]="on", + [10962]="on", + [10963]="on", + [10964]="on", + [10965]="on", + [10966]="on", + [10967]="on", + [10968]="on", + [10969]="on", + [10970]="on", + [10971]="on", + [10972]="on", + [10973]="on", + [10974]="on", + [10975]="on", + [10976]="on", + [10977]="on", + [10978]="on", + [10979]="on", + [10980]="on", + [10981]="on", + [10982]="on", + [10983]="on", + [10984]="on", + [10985]="on", + [10986]="on", + [10987]="on", + [10988]="on", + [10989]="on", + [10990]="on", + [10991]="on", + [10992]="on", + [10993]="on", + [10994]="on", + [10995]="on", + [10996]="on", + [10997]="on", + [10998]="on", + [10999]="on", + [11000]="on", + [11001]="on", + [11002]="on", + [11003]="on", + [11004]="on", + [11005]="on", + [11006]="on", + [11007]="on", + [11008]="on", + [11009]="on", + [11010]="on", + [11011]="on", + [11012]="on", + [11013]="on", + [11014]="on", + [11015]="on", + [11016]="on", + [11017]="on", + [11018]="on", + [11019]="on", + [11020]="on", + [11021]="on", + [11022]="on", + [11023]="on", + [11024]="on", + [11025]="on", + [11026]="on", + [11027]="on", + [11028]="on", + [11029]="on", + [11030]="on", + [11031]="on", + [11032]="on", + [11033]="on", + [11034]="on", + [11035]="on", + [11036]="on", + [11037]="on", + [11038]="on", + [11039]="on", + [11040]="on", + [11041]="on", + [11042]="on", + [11043]="on", + [11044]="on", + [11045]="on", + [11046]="on", + [11047]="on", + [11048]="on", + [11049]="on", + [11050]="on", + [11051]="on", + [11052]="on", + [11053]="on", + [11054]="on", + [11055]="on", + [11056]="on", + [11057]="on", + [11058]="on", + [11059]="on", + [11060]="on", + [11061]="on", + [11062]="on", + [11063]="on", + [11064]="on", + [11065]="on", + [11066]="on", + [11067]="on", + [11068]="on", + [11069]="on", + [11070]="on", + [11071]="on", + [11072]="on", + [11073]="on", + [11074]="on", + [11075]="on", + [11076]="on", + [11077]="on", + [11078]="on", + [11079]="on", + [11080]="on", + [11081]="on", + [11082]="on", + [11083]="on", + [11084]="on", + [11085]="on", + [11086]="on", + [11087]="on", + [11088]="on", + [11089]="on", + [11090]="on", + [11091]="on", + [11092]="on", + [11093]="on", + [11094]="on", + [11095]="on", + [11096]="on", + [11097]="on", + [11098]="on", + [11099]="on", + [11100]="on", + [11101]="on", + [11102]="on", + [11103]="on", + [11104]="on", + [11105]="on", + [11106]="on", + [11107]="on", + [11108]="on", + [11109]="on", + [11110]="on", + [11111]="on", + [11112]="on", + [11113]="on", + [11114]="on", + [11115]="on", + [11116]="on", + [11117]="on", + [11118]="on", + [11119]="on", + [11120]="on", + [11121]="on", + [11122]="on", + [11123]="on", + [11126]="on", + [11127]="on", + [11128]="on", + [11129]="on", + [11130]="on", + [11131]="on", + [11132]="on", + [11133]="on", + [11134]="on", + [11135]="on", + [11136]="on", + [11137]="on", + [11138]="on", + [11139]="on", + [11140]="on", + [11141]="on", + [11142]="on", + [11143]="on", + [11144]="on", + [11145]="on", + [11146]="on", + [11147]="on", + [11148]="on", + [11149]="on", + [11150]="on", + [11151]="on", + [11152]="on", + [11153]="on", + [11154]="on", + [11155]="on", + [11156]="on", + [11157]="on", + [11160]="on", + [11161]="on", + [11162]="on", + [11163]="on", + [11164]="on", + [11165]="on", + [11166]="on", + [11167]="on", + [11168]="on", + [11169]="on", + [11170]="on", + [11171]="on", + [11172]="on", + [11173]="on", + [11174]="on", + [11175]="on", + [11176]="on", + [11177]="on", + [11178]="on", + [11179]="on", + [11180]="on", + [11181]="on", + [11182]="on", + [11183]="on", + [11184]="on", + [11185]="on", + [11186]="on", + [11187]="on", + [11188]="on", + [11189]="on", + [11190]="on", + [11191]="on", + [11192]="on", + [11193]="on", + [11197]="on", + [11198]="on", + [11199]="on", + [11200]="on", + [11201]="on", + [11202]="on", + [11203]="on", + [11204]="on", + [11205]="on", + [11206]="on", + [11207]="on", + [11208]="on", + [11210]="on", + [11211]="on", + [11212]="on", + [11213]="on", + [11214]="on", + [11215]="on", + [11216]="on", + [11217]="on", + [11218]="on", + [11244]="on", + [11245]="on", + [11246]="on", + [11247]="on", + [11493]="on", + [11494]="on", + [11495]="on", + [11496]="on", + [11497]="on", + [11498]="on", + [11503]="nsm", + [11504]="nsm", + [11505]="nsm", + [11513]="on", + [11514]="on", + [11515]="on", + [11516]="on", + [11517]="on", + [11518]="on", + [11519]="on", + [11647]="nsm", + [11744]="nsm", + [11745]="nsm", + [11746]="nsm", + [11747]="nsm", + [11748]="nsm", + [11749]="nsm", + [11750]="nsm", + [11751]="nsm", + [11752]="nsm", + [11753]="nsm", + [11754]="nsm", + [11755]="nsm", + [11756]="nsm", + [11757]="nsm", + [11758]="nsm", + [11759]="nsm", + [11760]="nsm", + [11761]="nsm", + [11762]="nsm", + [11763]="nsm", + [11764]="nsm", + [11765]="nsm", + [11766]="nsm", + [11767]="nsm", + [11768]="nsm", + [11769]="nsm", + [11770]="nsm", + [11771]="nsm", + [11772]="nsm", + [11773]="nsm", + [11774]="nsm", + [11775]="nsm", + [11776]="on", + [11777]="on", + [11778]="on", + [11779]="on", + [11780]="on", + [11781]="on", + [11782]="on", + [11783]="on", + [11784]="on", + [11785]="on", + [11786]="on", + [11787]="on", + [11788]="on", + [11789]="on", + [11790]="on", + [11791]="on", + [11792]="on", + [11793]="on", + [11794]="on", + [11795]="on", + [11796]="on", + [11797]="on", + [11798]="on", + [11799]="on", + [11800]="on", + [11801]="on", + [11802]="on", + [11803]="on", + [11804]="on", + [11805]="on", + [11806]="on", + [11807]="on", + [11808]="on", + [11809]="on", + [11810]="on", + [11811]="on", + [11812]="on", + [11813]="on", + [11814]="on", + [11815]="on", + [11816]="on", + [11817]="on", + [11818]="on", + [11819]="on", + [11820]="on", + [11821]="on", + [11822]="on", + [11823]="on", + [11824]="on", + [11825]="on", + [11826]="on", + [11827]="on", + [11828]="on", + [11829]="on", + [11830]="on", + [11831]="on", + [11832]="on", + [11833]="on", + [11834]="on", + [11835]="on", + [11836]="on", + [11837]="on", + [11838]="on", + [11839]="on", + [11840]="on", + [11841]="on", + [11842]="on", + [11843]="on", + [11844]="on", + [11845]="on", + [11846]="on", + [11847]="on", + [11848]="on", + [11849]="on", + [11904]="on", + [11905]="on", + [11906]="on", + [11907]="on", + [11908]="on", + [11909]="on", + [11910]="on", + [11911]="on", + [11912]="on", + [11913]="on", + [11914]="on", + [11915]="on", + [11916]="on", + [11917]="on", + [11918]="on", + [11919]="on", + [11920]="on", + [11921]="on", + [11922]="on", + [11923]="on", + [11924]="on", + [11925]="on", + [11926]="on", + [11927]="on", + [11928]="on", + [11929]="on", + [11931]="on", + [11932]="on", + [11933]="on", + [11934]="on", + [11935]="on", + [11936]="on", + [11937]="on", + [11938]="on", + [11939]="on", + [11940]="on", + [11941]="on", + [11942]="on", + [11943]="on", + [11944]="on", + [11945]="on", + [11946]="on", + [11947]="on", + [11948]="on", + [11949]="on", + [11950]="on", + [11951]="on", + [11952]="on", + [11953]="on", + [11954]="on", + [11955]="on", + [11956]="on", + [11957]="on", + [11958]="on", + [11959]="on", + [11960]="on", + [11961]="on", + [11962]="on", + [11963]="on", + [11964]="on", + [11965]="on", + [11966]="on", + [11967]="on", + [11968]="on", + [11969]="on", + [11970]="on", + [11971]="on", + [11972]="on", + [11973]="on", + [11974]="on", + [11975]="on", + [11976]="on", + [11977]="on", + [11978]="on", + [11979]="on", + [11980]="on", + [11981]="on", + [11982]="on", + [11983]="on", + [11984]="on", + [11985]="on", + [11986]="on", + [11987]="on", + [11988]="on", + [11989]="on", + [11990]="on", + [11991]="on", + [11992]="on", + [11993]="on", + [11994]="on", + [11995]="on", + [11996]="on", + [11997]="on", + [11998]="on", + [11999]="on", + [12000]="on", + [12001]="on", + [12002]="on", + [12003]="on", + [12004]="on", + [12005]="on", + [12006]="on", + [12007]="on", + [12008]="on", + [12009]="on", + [12010]="on", + [12011]="on", + [12012]="on", + [12013]="on", + [12014]="on", + [12015]="on", + [12016]="on", + [12017]="on", + [12018]="on", + [12019]="on", + [12032]="on", + [12033]="on", + [12034]="on", + [12035]="on", + [12036]="on", + [12037]="on", + [12038]="on", + [12039]="on", + [12040]="on", + [12041]="on", + [12042]="on", + [12043]="on", + [12044]="on", + [12045]="on", + [12046]="on", + [12047]="on", + [12048]="on", + [12049]="on", + [12050]="on", + [12051]="on", + [12052]="on", + [12053]="on", + [12054]="on", + [12055]="on", + [12056]="on", + [12057]="on", + [12058]="on", + [12059]="on", + [12060]="on", + [12061]="on", + [12062]="on", + [12063]="on", + [12064]="on", + [12065]="on", + [12066]="on", + [12067]="on", + [12068]="on", + [12069]="on", + [12070]="on", + [12071]="on", + [12072]="on", + [12073]="on", + [12074]="on", + [12075]="on", + [12076]="on", + [12077]="on", + [12078]="on", + [12079]="on", + [12080]="on", + [12081]="on", + [12082]="on", + [12083]="on", + [12084]="on", + [12085]="on", + [12086]="on", + [12087]="on", + [12088]="on", + [12089]="on", + [12090]="on", + [12091]="on", + [12092]="on", + [12093]="on", + [12094]="on", + [12095]="on", + [12096]="on", + [12097]="on", + [12098]="on", + [12099]="on", + [12100]="on", + [12101]="on", + [12102]="on", + [12103]="on", + [12104]="on", + [12105]="on", + [12106]="on", + [12107]="on", + [12108]="on", + [12109]="on", + [12110]="on", + [12111]="on", + [12112]="on", + [12113]="on", + [12114]="on", + [12115]="on", + [12116]="on", + [12117]="on", + [12118]="on", + [12119]="on", + [12120]="on", + [12121]="on", + [12122]="on", + [12123]="on", + [12124]="on", + [12125]="on", + [12126]="on", + [12127]="on", + [12128]="on", + [12129]="on", + [12130]="on", + [12131]="on", + [12132]="on", + [12133]="on", + [12134]="on", + [12135]="on", + [12136]="on", + [12137]="on", + [12138]="on", + [12139]="on", + [12140]="on", + [12141]="on", + [12142]="on", + [12143]="on", + [12144]="on", + [12145]="on", + [12146]="on", + [12147]="on", + [12148]="on", + [12149]="on", + [12150]="on", + [12151]="on", + [12152]="on", + [12153]="on", + [12154]="on", + [12155]="on", + [12156]="on", + [12157]="on", + [12158]="on", + [12159]="on", + [12160]="on", + [12161]="on", + [12162]="on", + [12163]="on", + [12164]="on", + [12165]="on", + [12166]="on", + [12167]="on", + [12168]="on", + [12169]="on", + [12170]="on", + [12171]="on", + [12172]="on", + [12173]="on", + [12174]="on", + [12175]="on", + [12176]="on", + [12177]="on", + [12178]="on", + [12179]="on", + [12180]="on", + [12181]="on", + [12182]="on", + [12183]="on", + [12184]="on", + [12185]="on", + [12186]="on", + [12187]="on", + [12188]="on", + [12189]="on", + [12190]="on", + [12191]="on", + [12192]="on", + [12193]="on", + [12194]="on", + [12195]="on", + [12196]="on", + [12197]="on", + [12198]="on", + [12199]="on", + [12200]="on", + [12201]="on", + [12202]="on", + [12203]="on", + [12204]="on", + [12205]="on", + [12206]="on", + [12207]="on", + [12208]="on", + [12209]="on", + [12210]="on", + [12211]="on", + [12212]="on", + [12213]="on", + [12214]="on", + [12215]="on", + [12216]="on", + [12217]="on", + [12218]="on", + [12219]="on", + [12220]="on", + [12221]="on", + [12222]="on", + [12223]="on", + [12224]="on", + [12225]="on", + [12226]="on", + [12227]="on", + [12228]="on", + [12229]="on", + [12230]="on", + [12231]="on", + [12232]="on", + [12233]="on", + [12234]="on", + [12235]="on", + [12236]="on", + [12237]="on", + [12238]="on", + [12239]="on", + [12240]="on", + [12241]="on", + [12242]="on", + [12243]="on", + [12244]="on", + [12245]="on", + [12272]="on", + [12273]="on", + [12274]="on", + [12275]="on", + [12276]="on", + [12277]="on", + [12278]="on", + [12279]="on", + [12280]="on", + [12281]="on", + [12282]="on", + [12283]="on", + [12288]="ws", + [12289]="on", + [12290]="on", + [12291]="on", + [12292]="on", + [12296]="on", + [12297]="on", + [12298]="on", + [12299]="on", + [12300]="on", + [12301]="on", + [12302]="on", + [12303]="on", + [12304]="on", + [12305]="on", + [12306]="on", + [12307]="on", + [12308]="on", + [12309]="on", + [12310]="on", + [12311]="on", + [12312]="on", + [12313]="on", + [12314]="on", + [12315]="on", + [12316]="on", + [12317]="on", + [12318]="on", + [12319]="on", + [12320]="on", + [12330]="nsm", + [12331]="nsm", + [12332]="nsm", + [12333]="nsm", + [12336]="on", + [12342]="on", + [12343]="on", + [12349]="on", + [12350]="on", + [12351]="on", + [12441]="nsm", + [12442]="nsm", + [12443]="on", + [12444]="on", + [12448]="on", + [12539]="on", + [12736]="on", + [12737]="on", + [12738]="on", + [12739]="on", + [12740]="on", + [12741]="on", + [12742]="on", + [12743]="on", + [12744]="on", + [12745]="on", + [12746]="on", + [12747]="on", + [12748]="on", + [12749]="on", + [12750]="on", + [12751]="on", + [12752]="on", + [12753]="on", + [12754]="on", + [12755]="on", + [12756]="on", + [12757]="on", + [12758]="on", + [12759]="on", + [12760]="on", + [12761]="on", + [12762]="on", + [12763]="on", + [12764]="on", + [12765]="on", + [12766]="on", + [12767]="on", + [12768]="on", + [12769]="on", + [12770]="on", + [12771]="on", + [12829]="on", + [12830]="on", + [12880]="on", + [12881]="on", + [12882]="on", + [12883]="on", + [12884]="on", + [12885]="on", + [12886]="on", + [12887]="on", + [12888]="on", + [12889]="on", + [12890]="on", + [12891]="on", + [12892]="on", + [12893]="on", + [12894]="on", + [12895]="on", + [12924]="on", + [12925]="on", + [12926]="on", + [12977]="on", + [12978]="on", + [12979]="on", + [12980]="on", + [12981]="on", + [12982]="on", + [12983]="on", + [12984]="on", + [12985]="on", + [12986]="on", + [12987]="on", + [12988]="on", + [12989]="on", + [12990]="on", + [12991]="on", + [13004]="on", + [13005]="on", + [13006]="on", + [13007]="on", + [13175]="on", + [13176]="on", + [13177]="on", + [13178]="on", + [13278]="on", + [13279]="on", + [13311]="on", + [19904]="on", + [19905]="on", + [19906]="on", + [19907]="on", + [19908]="on", + [19909]="on", + [19910]="on", + [19911]="on", + [19912]="on", + [19913]="on", + [19914]="on", + [19915]="on", + [19916]="on", + [19917]="on", + [19918]="on", + [19919]="on", + [19920]="on", + [19921]="on", + [19922]="on", + [19923]="on", + [19924]="on", + [19925]="on", + [19926]="on", + [19927]="on", + [19928]="on", + [19929]="on", + [19930]="on", + [19931]="on", + [19932]="on", + [19933]="on", + [19934]="on", + [19935]="on", + [19936]="on", + [19937]="on", + [19938]="on", + [19939]="on", + [19940]="on", + [19941]="on", + [19942]="on", + [19943]="on", + [19944]="on", + [19945]="on", + [19946]="on", + [19947]="on", + [19948]="on", + [19949]="on", + [19950]="on", + [19951]="on", + [19952]="on", + [19953]="on", + [19954]="on", + [19955]="on", + [19956]="on", + [19957]="on", + [19958]="on", + [19959]="on", + [19960]="on", + [19961]="on", + [19962]="on", + [19963]="on", + [19964]="on", + [19965]="on", + [19966]="on", + [19967]="on", + [42128]="on", + [42129]="on", + [42130]="on", + [42131]="on", + [42132]="on", + [42133]="on", + [42134]="on", + [42135]="on", + [42136]="on", + [42137]="on", + [42138]="on", + [42139]="on", + [42140]="on", + [42141]="on", + [42142]="on", + [42143]="on", + [42144]="on", + [42145]="on", + [42146]="on", + [42147]="on", + [42148]="on", + [42149]="on", + [42150]="on", + [42151]="on", + [42152]="on", + [42153]="on", + [42154]="on", + [42155]="on", + [42156]="on", + [42157]="on", + [42158]="on", + [42159]="on", + [42160]="on", + [42161]="on", + [42162]="on", + [42163]="on", + [42164]="on", + [42165]="on", + [42166]="on", + [42167]="on", + [42168]="on", + [42169]="on", + [42170]="on", + [42171]="on", + [42172]="on", + [42173]="on", + [42174]="on", + [42175]="on", + [42176]="on", + [42177]="on", + [42178]="on", + [42179]="on", + [42180]="on", + [42181]="on", + [42182]="on", + [42509]="on", + [42510]="on", + [42511]="on", + [42607]="nsm", + [42608]="nsm", + [42609]="nsm", + [42610]="nsm", + [42611]="on", + [42612]="nsm", + [42613]="nsm", + [42614]="nsm", + [42615]="nsm", + [42616]="nsm", + [42617]="nsm", + [42618]="nsm", + [42619]="nsm", + [42620]="nsm", + [42621]="nsm", + [42622]="on", + [42623]="on", + [42654]="nsm", + [42655]="nsm", + [42736]="nsm", + [42737]="nsm", + [42752]="on", + [42753]="on", + [42754]="on", + [42755]="on", + [42756]="on", + [42757]="on", + [42758]="on", + [42759]="on", + [42760]="on", + [42761]="on", + [42762]="on", + [42763]="on", + [42764]="on", + [42765]="on", + [42766]="on", + [42767]="on", + [42768]="on", + [42769]="on", + [42770]="on", + [42771]="on", + [42772]="on", + [42773]="on", + [42774]="on", + [42775]="on", + [42776]="on", + [42777]="on", + [42778]="on", + [42779]="on", + [42780]="on", + [42781]="on", + [42782]="on", + [42783]="on", + [42784]="on", + [42785]="on", + [42888]="on", + [43010]="nsm", + [43014]="nsm", + [43019]="nsm", + [43045]="nsm", + [43046]="nsm", + [43048]="on", + [43049]="on", + [43050]="on", + [43051]="on", + [43064]="et", + [43065]="et", + [43124]="on", + [43125]="on", + [43126]="on", + [43127]="on", + [43204]="nsm", + [43205]="nsm", + [43232]="nsm", + [43233]="nsm", + [43234]="nsm", + [43235]="nsm", + [43236]="nsm", + [43237]="nsm", + [43238]="nsm", + [43239]="nsm", + [43240]="nsm", + [43241]="nsm", + [43242]="nsm", + [43243]="nsm", + [43244]="nsm", + [43245]="nsm", + [43246]="nsm", + [43247]="nsm", + [43248]="nsm", + [43249]="nsm", + [43302]="nsm", + [43303]="nsm", + [43304]="nsm", + [43305]="nsm", + [43306]="nsm", + [43307]="nsm", + [43308]="nsm", + [43309]="nsm", + [43335]="nsm", + [43336]="nsm", + [43337]="nsm", + [43338]="nsm", + [43339]="nsm", + [43340]="nsm", + [43341]="nsm", + [43342]="nsm", + [43343]="nsm", + [43344]="nsm", + [43345]="nsm", + [43392]="nsm", + [43393]="nsm", + [43394]="nsm", + [43443]="nsm", + [43446]="nsm", + [43447]="nsm", + [43448]="nsm", + [43449]="nsm", + [43452]="nsm", + [43493]="nsm", + [43561]="nsm", + [43562]="nsm", + [43563]="nsm", + [43564]="nsm", + [43565]="nsm", + [43566]="nsm", + [43569]="nsm", + [43570]="nsm", + [43573]="nsm", + [43574]="nsm", + [43587]="nsm", + [43596]="nsm", + [43644]="nsm", + [43696]="nsm", + [43698]="nsm", + [43699]="nsm", + [43700]="nsm", + [43703]="nsm", + [43704]="nsm", + [43710]="nsm", + [43711]="nsm", + [43713]="nsm", + [43756]="nsm", + [43757]="nsm", + [43766]="nsm", + [44005]="nsm", + [44008]="nsm", + [44013]="nsm", + [64285]="r", + [64286]="nsm", + [64287]="r", + [64288]="r", + [64289]="r", + [64290]="r", + [64291]="r", + [64292]="r", + [64293]="r", + [64294]="r", + [64295]="r", + [64296]="r", + [64297]="es", + [64298]="r", + [64299]="r", + [64300]="r", + [64301]="r", + [64302]="r", + [64303]="r", + [64304]="r", + [64305]="r", + [64306]="r", + [64307]="r", + [64308]="r", + [64309]="r", + [64310]="r", + [64312]="r", + [64313]="r", + [64314]="r", + [64315]="r", + [64316]="r", + [64318]="r", + [64320]="r", + [64321]="r", + [64323]="r", + [64324]="r", + [64326]="r", + [64327]="r", + [64328]="r", + [64329]="r", + [64330]="r", + [64331]="r", + [64332]="r", + [64333]="r", + [64334]="r", + [64335]="r", + [64336]="al", + [64337]="al", + [64338]="al", + [64339]="al", + [64340]="al", + [64341]="al", + [64342]="al", + [64343]="al", + [64344]="al", + [64345]="al", + [64346]="al", + [64347]="al", + [64348]="al", + [64349]="al", + [64350]="al", + [64351]="al", + [64352]="al", + [64353]="al", + [64354]="al", + [64355]="al", + [64356]="al", + [64357]="al", + [64358]="al", + [64359]="al", + [64360]="al", + [64361]="al", + [64362]="al", + [64363]="al", + [64364]="al", + [64365]="al", + [64366]="al", + [64367]="al", + [64368]="al", + [64369]="al", + [64370]="al", + [64371]="al", + [64372]="al", + [64373]="al", + [64374]="al", + [64375]="al", + [64376]="al", + [64377]="al", + [64378]="al", + [64379]="al", + [64380]="al", + [64381]="al", + [64382]="al", + [64383]="al", + [64384]="al", + [64385]="al", + [64386]="al", + [64387]="al", + [64388]="al", + [64389]="al", + [64390]="al", + [64391]="al", + [64392]="al", + [64393]="al", + [64394]="al", + [64395]="al", + [64396]="al", + [64397]="al", + [64398]="al", + [64399]="al", + [64400]="al", + [64401]="al", + [64402]="al", + [64403]="al", + [64404]="al", + [64405]="al", + [64406]="al", + [64407]="al", + [64408]="al", + [64409]="al", + [64410]="al", + [64411]="al", + [64412]="al", + [64413]="al", + [64414]="al", + [64415]="al", + [64416]="al", + [64417]="al", + [64418]="al", + [64419]="al", + [64420]="al", + [64421]="al", + [64422]="al", + [64423]="al", + [64424]="al", + [64425]="al", + [64426]="al", + [64427]="al", + [64428]="al", + [64429]="al", + [64430]="al", + [64431]="al", + [64432]="al", + [64433]="al", + [64434]="al", + [64435]="al", + [64436]="al", + [64437]="al", + [64438]="al", + [64439]="al", + [64440]="al", + [64441]="al", + [64442]="al", + [64443]="al", + [64444]="al", + [64445]="al", + [64446]="al", + [64447]="al", + [64448]="al", + [64449]="al", + [64467]="al", + [64468]="al", + [64469]="al", + [64470]="al", + [64471]="al", + [64472]="al", + [64473]="al", + [64474]="al", + [64475]="al", + [64476]="al", + [64477]="al", + [64478]="al", + [64479]="al", + [64480]="al", + [64481]="al", + [64482]="al", + [64483]="al", + [64484]="al", + [64485]="al", + [64486]="al", + [64487]="al", + [64488]="al", + [64489]="al", + [64490]="al", + [64491]="al", + [64492]="al", + [64493]="al", + [64494]="al", + [64495]="al", + [64496]="al", + [64497]="al", + [64498]="al", + [64499]="al", + [64500]="al", + [64501]="al", + [64502]="al", + [64503]="al", + [64504]="al", + [64505]="al", + [64506]="al", + [64507]="al", + [64508]="al", + [64509]="al", + [64510]="al", + [64511]="al", + [64512]="al", + [64513]="al", + [64514]="al", + [64515]="al", + [64516]="al", + [64517]="al", + [64518]="al", + [64519]="al", + [64520]="al", + [64521]="al", + [64522]="al", + [64523]="al", + [64524]="al", + [64525]="al", + [64526]="al", + [64527]="al", + [64528]="al", + [64529]="al", + [64530]="al", + [64531]="al", + [64532]="al", + [64533]="al", + [64534]="al", + [64535]="al", + [64536]="al", + [64537]="al", + [64538]="al", + [64539]="al", + [64540]="al", + [64541]="al", + [64542]="al", + [64543]="al", + [64544]="al", + [64545]="al", + [64546]="al", + [64547]="al", + [64548]="al", + [64549]="al", + [64550]="al", + [64551]="al", + [64552]="al", + [64553]="al", + [64554]="al", + [64555]="al", + [64556]="al", + [64557]="al", + [64558]="al", + [64559]="al", + [64560]="al", + [64561]="al", + [64562]="al", + [64563]="al", + [64564]="al", + [64565]="al", + [64566]="al", + [64567]="al", + [64568]="al", + [64569]="al", + [64570]="al", + [64571]="al", + [64572]="al", + [64573]="al", + [64574]="al", + [64575]="al", + [64576]="al", + [64577]="al", + [64578]="al", + [64579]="al", + [64580]="al", + [64581]="al", + [64582]="al", + [64583]="al", + [64584]="al", + [64585]="al", + [64586]="al", + [64587]="al", + [64588]="al", + [64589]="al", + [64590]="al", + [64591]="al", + [64592]="al", + [64593]="al", + [64594]="al", + [64595]="al", + [64596]="al", + [64597]="al", + [64598]="al", + [64599]="al", + [64600]="al", + [64601]="al", + [64602]="al", + [64603]="al", + [64604]="al", + [64605]="al", + [64606]="al", + [64607]="al", + [64608]="al", + [64609]="al", + [64610]="al", + [64611]="al", + [64612]="al", + [64613]="al", + [64614]="al", + [64615]="al", + [64616]="al", + [64617]="al", + [64618]="al", + [64619]="al", + [64620]="al", + [64621]="al", + [64622]="al", + [64623]="al", + [64624]="al", + [64625]="al", + [64626]="al", + [64627]="al", + [64628]="al", + [64629]="al", + [64630]="al", + [64631]="al", + [64632]="al", + [64633]="al", + [64634]="al", + [64635]="al", + [64636]="al", + [64637]="al", + [64638]="al", + [64639]="al", + [64640]="al", + [64641]="al", + [64642]="al", + [64643]="al", + [64644]="al", + [64645]="al", + [64646]="al", + [64647]="al", + [64648]="al", + [64649]="al", + [64650]="al", + [64651]="al", + [64652]="al", + [64653]="al", + [64654]="al", + [64655]="al", + [64656]="al", + [64657]="al", + [64658]="al", + [64659]="al", + [64660]="al", + [64661]="al", + [64662]="al", + [64663]="al", + [64664]="al", + [64665]="al", + [64666]="al", + [64667]="al", + [64668]="al", + [64669]="al", + [64670]="al", + [64671]="al", + [64672]="al", + [64673]="al", + [64674]="al", + [64675]="al", + [64676]="al", + [64677]="al", + [64678]="al", + [64679]="al", + [64680]="al", + [64681]="al", + [64682]="al", + [64683]="al", + [64684]="al", + [64685]="al", + [64686]="al", + [64687]="al", + [64688]="al", + [64689]="al", + [64690]="al", + [64691]="al", + [64692]="al", + [64693]="al", + [64694]="al", + [64695]="al", + [64696]="al", + [64697]="al", + [64698]="al", + [64699]="al", + [64700]="al", + [64701]="al", + [64702]="al", + [64703]="al", + [64704]="al", + [64705]="al", + [64706]="al", + [64707]="al", + [64708]="al", + [64709]="al", + [64710]="al", + [64711]="al", + [64712]="al", + [64713]="al", + [64714]="al", + [64715]="al", + [64716]="al", + [64717]="al", + [64718]="al", + [64719]="al", + [64720]="al", + [64721]="al", + [64722]="al", + [64723]="al", + [64724]="al", + [64725]="al", + [64726]="al", + [64727]="al", + [64728]="al", + [64729]="al", + [64730]="al", + [64731]="al", + [64732]="al", + [64733]="al", + [64734]="al", + [64735]="al", + [64736]="al", + [64737]="al", + [64738]="al", + [64739]="al", + [64740]="al", + [64741]="al", + [64742]="al", + [64743]="al", + [64744]="al", + [64745]="al", + [64746]="al", + [64747]="al", + [64748]="al", + [64749]="al", + [64750]="al", + [64751]="al", + [64752]="al", + [64753]="al", + [64754]="al", + [64755]="al", + [64756]="al", + [64757]="al", + [64758]="al", + [64759]="al", + [64760]="al", + [64761]="al", + [64762]="al", + [64763]="al", + [64764]="al", + [64765]="al", + [64766]="al", + [64767]="al", + [64768]="al", + [64769]="al", + [64770]="al", + [64771]="al", + [64772]="al", + [64773]="al", + [64774]="al", + [64775]="al", + [64776]="al", + [64777]="al", + [64778]="al", + [64779]="al", + [64780]="al", + [64781]="al", + [64782]="al", + [64783]="al", + [64784]="al", + [64785]="al", + [64786]="al", + [64787]="al", + [64788]="al", + [64789]="al", + [64790]="al", + [64791]="al", + [64792]="al", + [64793]="al", + [64794]="al", + [64795]="al", + [64796]="al", + [64797]="al", + [64798]="al", + [64799]="al", + [64800]="al", + [64801]="al", + [64802]="al", + [64803]="al", + [64804]="al", + [64805]="al", + [64806]="al", + [64807]="al", + [64808]="al", + [64809]="al", + [64810]="al", + [64811]="al", + [64812]="al", + [64813]="al", + [64814]="al", + [64815]="al", + [64816]="al", + [64817]="al", + [64818]="al", + [64819]="al", + [64820]="al", + [64821]="al", + [64822]="al", + [64823]="al", + [64824]="al", + [64825]="al", + [64826]="al", + [64827]="al", + [64828]="al", + [64829]="al", + [64830]="on", + [64831]="on", + [64848]="al", + [64849]="al", + [64850]="al", + [64851]="al", + [64852]="al", + [64853]="al", + [64854]="al", + [64855]="al", + [64856]="al", + [64857]="al", + [64858]="al", + [64859]="al", + [64860]="al", + [64861]="al", + [64862]="al", + [64863]="al", + [64864]="al", + [64865]="al", + [64866]="al", + [64867]="al", + [64868]="al", + [64869]="al", + [64870]="al", + [64871]="al", + [64872]="al", + [64873]="al", + [64874]="al", + [64875]="al", + [64876]="al", + [64877]="al", + [64878]="al", + [64879]="al", + [64880]="al", + [64881]="al", + [64882]="al", + [64883]="al", + [64884]="al", + [64885]="al", + [64886]="al", + [64887]="al", + [64888]="al", + [64889]="al", + [64890]="al", + [64891]="al", + [64892]="al", + [64893]="al", + [64894]="al", + [64895]="al", + [64896]="al", + [64897]="al", + [64898]="al", + [64899]="al", + [64900]="al", + [64901]="al", + [64902]="al", + [64903]="al", + [64904]="al", + [64905]="al", + [64906]="al", + [64907]="al", + [64908]="al", + [64909]="al", + [64910]="al", + [64911]="al", + [64914]="al", + [64915]="al", + [64916]="al", + [64917]="al", + [64918]="al", + [64919]="al", + [64920]="al", + [64921]="al", + [64922]="al", + [64923]="al", + [64924]="al", + [64925]="al", + [64926]="al", + [64927]="al", + [64928]="al", + [64929]="al", + [64930]="al", + [64931]="al", + [64932]="al", + [64933]="al", + [64934]="al", + [64935]="al", + [64936]="al", + [64937]="al", + [64938]="al", + [64939]="al", + [64940]="al", + [64941]="al", + [64942]="al", + [64943]="al", + [64944]="al", + [64945]="al", + [64946]="al", + [64947]="al", + [64948]="al", + [64949]="al", + [64950]="al", + [64951]="al", + [64952]="al", + [64953]="al", + [64954]="al", + [64955]="al", + [64956]="al", + [64957]="al", + [64958]="al", + [64959]="al", + [64960]="al", + [64961]="al", + [64962]="al", + [64963]="al", + [64964]="al", + [64965]="al", + [64966]="al", + [64967]="al", + [65008]="al", + [65009]="al", + [65010]="al", + [65011]="al", + [65012]="al", + [65013]="al", + [65014]="al", + [65015]="al", + [65016]="al", + [65017]="al", + [65018]="al", + [65019]="al", + [65020]="al", + [65021]="on", + [65040]="on", + [65041]="on", + [65042]="on", + [65043]="on", + [65044]="on", + [65045]="on", + [65046]="on", + [65047]="on", + [65048]="on", + [65049]="on", + [65056]="nsm", + [65057]="nsm", + [65058]="nsm", + [65059]="nsm", + [65060]="nsm", + [65061]="nsm", + [65062]="nsm", + [65063]="nsm", + [65064]="nsm", + [65065]="nsm", + [65066]="nsm", + [65067]="nsm", + [65068]="nsm", + [65069]="nsm", + [65070]="nsm", + [65071]="nsm", + [65072]="on", + [65073]="on", + [65074]="on", + [65075]="on", + [65076]="on", + [65077]="on", + [65078]="on", + [65079]="on", + [65080]="on", + [65081]="on", + [65082]="on", + [65083]="on", + [65084]="on", + [65085]="on", + [65086]="on", + [65087]="on", + [65088]="on", + [65089]="on", + [65090]="on", + [65091]="on", + [65092]="on", + [65093]="on", + [65094]="on", + [65095]="on", + [65096]="on", + [65097]="on", + [65098]="on", + [65099]="on", + [65100]="on", + [65101]="on", + [65102]="on", + [65103]="on", + [65104]="cs", + [65105]="on", + [65106]="cs", + [65108]="on", + [65109]="cs", + [65110]="on", + [65111]="on", + [65112]="on", + [65113]="on", + [65114]="on", + [65115]="on", + [65116]="on", + [65117]="on", + [65118]="on", + [65119]="et", + [65120]="on", + [65121]="on", + [65122]="es", + [65123]="es", + [65124]="on", + [65125]="on", + [65126]="on", + [65128]="on", + [65129]="et", + [65130]="et", + [65131]="on", + [65136]="al", + [65137]="al", + [65138]="al", + [65139]="al", + [65140]="al", + [65142]="al", + [65143]="al", + [65144]="al", + [65145]="al", + [65146]="al", + [65147]="al", + [65148]="al", + [65149]="al", + [65150]="al", + [65151]="al", + [65152]="al", + [65153]="al", + [65154]="al", + [65155]="al", + [65156]="al", + [65157]="al", + [65158]="al", + [65159]="al", + [65160]="al", + [65161]="al", + [65162]="al", + [65163]="al", + [65164]="al", + [65165]="al", + [65166]="al", + [65167]="al", + [65168]="al", + [65169]="al", + [65170]="al", + [65171]="al", + [65172]="al", + [65173]="al", + [65174]="al", + [65175]="al", + [65176]="al", + [65177]="al", + [65178]="al", + [65179]="al", + [65180]="al", + [65181]="al", + [65182]="al", + [65183]="al", + [65184]="al", + [65185]="al", + [65186]="al", + [65187]="al", + [65188]="al", + [65189]="al", + [65190]="al", + [65191]="al", + [65192]="al", + [65193]="al", + [65194]="al", + [65195]="al", + [65196]="al", + [65197]="al", + [65198]="al", + [65199]="al", + [65200]="al", + [65201]="al", + [65202]="al", + [65203]="al", + [65204]="al", + [65205]="al", + [65206]="al", + [65207]="al", + [65208]="al", + [65209]="al", + [65210]="al", + [65211]="al", + [65212]="al", + [65213]="al", + [65214]="al", + [65215]="al", + [65216]="al", + [65217]="al", + [65218]="al", + [65219]="al", + [65220]="al", + [65221]="al", + [65222]="al", + [65223]="al", + [65224]="al", + [65225]="al", + [65226]="al", + [65227]="al", + [65228]="al", + [65229]="al", + [65230]="al", + [65231]="al", + [65232]="al", + [65233]="al", + [65234]="al", + [65235]="al", + [65236]="al", + [65237]="al", + [65238]="al", + [65239]="al", + [65240]="al", + [65241]="al", + [65242]="al", + [65243]="al", + [65244]="al", + [65245]="al", + [65246]="al", + [65247]="al", + [65248]="al", + [65249]="al", + [65250]="al", + [65251]="al", + [65252]="al", + [65253]="al", + [65254]="al", + [65255]="al", + [65256]="al", + [65257]="al", + [65258]="al", + [65259]="al", + [65260]="al", + [65261]="al", + [65262]="al", + [65263]="al", + [65264]="al", + [65265]="al", + [65266]="al", + [65267]="al", + [65268]="al", + [65269]="al", + [65270]="al", + [65271]="al", + [65272]="al", + [65273]="al", + [65274]="al", + [65275]="al", + [65276]="al", + [65279]="bn", + [65281]="on", + [65282]="on", + [65283]="et", + [65284]="et", + [65285]="et", + [65286]="on", + [65287]="on", + [65288]="on", + [65289]="on", + [65290]="on", + [65291]="es", + [65292]="cs", + [65293]="es", + [65294]="cs", + [65295]="cs", + [65296]="en", + [65297]="en", + [65298]="en", + [65299]="en", + [65300]="en", + [65301]="en", + [65302]="en", + [65303]="en", + [65304]="en", + [65305]="en", + [65306]="cs", + [65307]="on", + [65308]="on", + [65309]="on", + [65310]="on", + [65311]="on", + [65312]="on", + [65339]="on", + [65340]="on", + [65341]="on", + [65342]="on", + [65343]="on", + [65344]="on", + [65371]="on", + [65372]="on", + [65373]="on", + [65374]="on", + [65375]="on", + [65376]="on", + [65377]="on", + [65378]="on", + [65379]="on", + [65380]="on", + [65381]="on", + [65504]="et", + [65505]="et", + [65506]="on", + [65507]="on", + [65508]="on", + [65509]="et", + [65510]="et", + [65512]="on", + [65513]="on", + [65514]="on", + [65515]="on", + [65516]="on", + [65517]="on", + [65518]="on", + [65529]="on", + [65530]="on", + [65531]="on", + [65532]="on", + [65533]="on", + [65793]="on", + [65856]="on", + [65857]="on", + [65858]="on", + [65859]="on", + [65860]="on", + [65861]="on", + [65862]="on", + [65863]="on", + [65864]="on", + [65865]="on", + [65866]="on", + [65867]="on", + [65868]="on", + [65869]="on", + [65870]="on", + [65871]="on", + [65872]="on", + [65873]="on", + [65874]="on", + [65875]="on", + [65876]="on", + [65877]="on", + [65878]="on", + [65879]="on", + [65880]="on", + [65881]="on", + [65882]="on", + [65883]="on", + [65884]="on", + [65885]="on", + [65886]="on", + [65887]="on", + [65888]="on", + [65889]="on", + [65890]="on", + [65891]="on", + [65892]="on", + [65893]="on", + [65894]="on", + [65895]="on", + [65896]="on", + [65897]="on", + [65898]="on", + [65899]="on", + [65900]="on", + [65901]="on", + [65902]="on", + [65903]="on", + [65904]="on", + [65905]="on", + [65906]="on", + [65907]="on", + [65908]="on", + [65909]="on", + [65910]="on", + [65911]="on", + [65912]="on", + [65913]="on", + [65914]="on", + [65915]="on", + [65916]="on", + [65917]="on", + [65918]="on", + [65919]="on", + [65920]="on", + [65921]="on", + [65922]="on", + [65923]="on", + [65924]="on", + [65925]="on", + [65926]="on", + [65927]="on", + [65928]="on", + [65929]="on", + [65930]="on", + [65931]="on", + [65932]="on", + [65936]="on", + [65937]="on", + [65938]="on", + [65939]="on", + [65940]="on", + [65941]="on", + [65942]="on", + [65943]="on", + [65944]="on", + [65945]="on", + [65946]="on", + [65947]="on", + [65952]="on", + [66045]="nsm", + [66272]="nsm", + [66273]="en", + [66274]="en", + [66275]="en", + [66276]="en", + [66277]="en", + [66278]="en", + [66279]="en", + [66280]="en", + [66281]="en", + [66282]="en", + [66283]="en", + [66284]="en", + [66285]="en", + [66286]="en", + [66287]="en", + [66288]="en", + [66289]="en", + [66290]="en", + [66291]="en", + [66292]="en", + [66293]="en", + [66294]="en", + [66295]="en", + [66296]="en", + [66297]="en", + [66298]="en", + [66299]="en", + [66422]="nsm", + [66423]="nsm", + [66424]="nsm", + [66425]="nsm", + [66426]="nsm", + [67584]="r", + [67585]="r", + [67586]="r", + [67587]="r", + [67588]="r", + [67589]="r", + [67592]="r", + [67594]="r", + [67595]="r", + [67596]="r", + [67597]="r", + [67598]="r", + [67599]="r", + [67600]="r", + [67601]="r", + [67602]="r", + [67603]="r", + [67604]="r", + [67605]="r", + [67606]="r", + [67607]="r", + [67608]="r", + [67609]="r", + [67610]="r", + [67611]="r", + [67612]="r", + [67613]="r", + [67614]="r", + [67615]="r", + [67616]="r", + [67617]="r", + [67618]="r", + [67619]="r", + [67620]="r", + [67621]="r", + [67622]="r", + [67623]="r", + [67624]="r", + [67625]="r", + [67626]="r", + [67627]="r", + [67628]="r", + [67629]="r", + [67630]="r", + [67631]="r", + [67632]="r", + [67633]="r", + [67634]="r", + [67635]="r", + [67636]="r", + [67637]="r", + [67639]="r", + [67640]="r", + [67644]="r", + [67647]="r", + [67648]="r", + [67649]="r", + [67650]="r", + [67651]="r", + [67652]="r", + [67653]="r", + [67654]="r", + [67655]="r", + [67656]="r", + [67657]="r", + [67658]="r", + [67659]="r", + [67660]="r", + [67661]="r", + [67662]="r", + [67663]="r", + [67664]="r", + [67665]="r", + [67666]="r", + [67667]="r", + [67668]="r", + [67669]="r", + [67671]="r", + [67672]="r", + [67673]="r", + [67674]="r", + [67675]="r", + [67676]="r", + [67677]="r", + [67678]="r", + [67679]="r", + [67680]="r", + [67681]="r", + [67682]="r", + [67683]="r", + [67684]="r", + [67685]="r", + [67686]="r", + [67687]="r", + [67688]="r", + [67689]="r", + [67690]="r", + [67691]="r", + [67692]="r", + [67693]="r", + [67694]="r", + [67695]="r", + [67696]="r", + [67697]="r", + [67698]="r", + [67699]="r", + [67700]="r", + [67701]="r", + [67702]="r", + [67703]="r", + [67704]="r", + [67705]="r", + [67706]="r", + [67707]="r", + [67708]="r", + [67709]="r", + [67710]="r", + [67711]="r", + [67712]="r", + [67713]="r", + [67714]="r", + [67715]="r", + [67716]="r", + [67717]="r", + [67718]="r", + [67719]="r", + [67720]="r", + [67721]="r", + [67722]="r", + [67723]="r", + [67724]="r", + [67725]="r", + [67726]="r", + [67727]="r", + [67728]="r", + [67729]="r", + [67730]="r", + [67731]="r", + [67732]="r", + [67733]="r", + [67734]="r", + [67735]="r", + [67736]="r", + [67737]="r", + [67738]="r", + [67739]="r", + [67740]="r", + [67741]="r", + [67742]="r", + [67751]="r", + [67752]="r", + [67753]="r", + [67754]="r", + [67755]="r", + [67756]="r", + [67757]="r", + [67758]="r", + [67759]="r", + [67808]="r", + [67809]="r", + [67810]="r", + [67811]="r", + [67812]="r", + [67813]="r", + [67814]="r", + [67815]="r", + [67816]="r", + [67817]="r", + [67818]="r", + [67819]="r", + [67820]="r", + [67821]="r", + [67822]="r", + [67823]="r", + [67824]="r", + [67825]="r", + [67826]="r", + [67828]="r", + [67829]="r", + [67835]="r", + [67836]="r", + [67837]="r", + [67838]="r", + [67839]="r", + [67840]="r", + [67841]="r", + [67842]="r", + [67843]="r", + [67844]="r", + [67845]="r", + [67846]="r", + [67847]="r", + [67848]="r", + [67849]="r", + [67850]="r", + [67851]="r", + [67852]="r", + [67853]="r", + [67854]="r", + [67855]="r", + [67856]="r", + [67857]="r", + [67858]="r", + [67859]="r", + [67860]="r", + [67861]="r", + [67862]="r", + [67863]="r", + [67864]="r", + [67865]="r", + [67866]="r", + [67867]="r", + [67871]="on", + [67872]="r", + [67873]="r", + [67874]="r", + [67875]="r", + [67876]="r", + [67877]="r", + [67878]="r", + [67879]="r", + [67880]="r", + [67881]="r", + [67882]="r", + [67883]="r", + [67884]="r", + [67885]="r", + [67886]="r", + [67887]="r", + [67888]="r", + [67889]="r", + [67890]="r", + [67891]="r", + [67892]="r", + [67893]="r", + [67894]="r", + [67895]="r", + [67896]="r", + [67897]="r", + [67903]="r", + [67968]="r", + [67969]="r", + [67970]="r", + [67971]="r", + [67972]="r", + [67973]="r", + [67974]="r", + [67975]="r", + [67976]="r", + [67977]="r", + [67978]="r", + [67979]="r", + [67980]="r", + [67981]="r", + [67982]="r", + [67983]="r", + [67984]="r", + [67985]="r", + [67986]="r", + [67987]="r", + [67988]="r", + [67989]="r", + [67990]="r", + [67991]="r", + [67992]="r", + [67993]="r", + [67994]="r", + [67995]="r", + [67996]="r", + [67997]="r", + [67998]="r", + [67999]="r", + [68000]="r", + [68001]="r", + [68002]="r", + [68003]="r", + [68004]="r", + [68005]="r", + [68006]="r", + [68007]="r", + [68008]="r", + [68009]="r", + [68010]="r", + [68011]="r", + [68012]="r", + [68013]="r", + [68014]="r", + [68015]="r", + [68016]="r", + [68017]="r", + [68018]="r", + [68019]="r", + [68020]="r", + [68021]="r", + [68022]="r", + [68023]="r", + [68028]="r", + [68029]="r", + [68030]="r", + [68031]="r", + [68032]="r", + [68033]="r", + [68034]="r", + [68035]="r", + [68036]="r", + [68037]="r", + [68038]="r", + [68039]="r", + [68040]="r", + [68041]="r", + [68042]="r", + [68043]="r", + [68044]="r", + [68045]="r", + [68046]="r", + [68047]="r", + [68050]="r", + [68051]="r", + [68052]="r", + [68053]="r", + [68054]="r", + [68055]="r", + [68056]="r", + [68057]="r", + [68058]="r", + [68059]="r", + [68060]="r", + [68061]="r", + [68062]="r", + [68063]="r", + [68064]="r", + [68065]="r", + [68066]="r", + [68067]="r", + [68068]="r", + [68069]="r", + [68070]="r", + [68071]="r", + [68072]="r", + [68073]="r", + [68074]="r", + [68075]="r", + [68076]="r", + [68077]="r", + [68078]="r", + [68079]="r", + [68080]="r", + [68081]="r", + [68082]="r", + [68083]="r", + [68084]="r", + [68085]="r", + [68086]="r", + [68087]="r", + [68088]="r", + [68089]="r", + [68090]="r", + [68091]="r", + [68092]="r", + [68093]="r", + [68094]="r", + [68095]="r", + [68096]="r", + [68097]="nsm", + [68098]="nsm", + [68099]="nsm", + [68101]="nsm", + [68102]="nsm", + [68108]="nsm", + [68109]="nsm", + [68110]="nsm", + [68111]="nsm", + [68112]="r", + [68113]="r", + [68114]="r", + [68115]="r", + [68117]="r", + [68118]="r", + [68119]="r", + [68121]="r", + [68122]="r", + [68123]="r", + [68124]="r", + [68125]="r", + [68126]="r", + [68127]="r", + [68128]="r", + [68129]="r", + [68130]="r", + [68131]="r", + [68132]="r", + [68133]="r", + [68134]="r", + [68135]="r", + [68136]="r", + [68137]="r", + [68138]="r", + [68139]="r", + [68140]="r", + [68141]="r", + [68142]="r", + [68143]="r", + [68144]="r", + [68145]="r", + [68146]="r", + [68147]="r", + [68152]="nsm", + [68153]="nsm", + [68154]="nsm", + [68159]="nsm", + [68160]="r", + [68161]="r", + [68162]="r", + [68163]="r", + [68164]="r", + [68165]="r", + [68166]="r", + [68167]="r", + [68176]="r", + [68177]="r", + [68178]="r", + [68179]="r", + [68180]="r", + [68181]="r", + [68182]="r", + [68183]="r", + [68184]="r", + [68192]="r", + [68193]="r", + [68194]="r", + [68195]="r", + [68196]="r", + [68197]="r", + [68198]="r", + [68199]="r", + [68200]="r", + [68201]="r", + [68202]="r", + [68203]="r", + [68204]="r", + [68205]="r", + [68206]="r", + [68207]="r", + [68208]="r", + [68209]="r", + [68210]="r", + [68211]="r", + [68212]="r", + [68213]="r", + [68214]="r", + [68215]="r", + [68216]="r", + [68217]="r", + [68218]="r", + [68219]="r", + [68220]="r", + [68221]="r", + [68222]="r", + [68223]="r", + [68224]="r", + [68225]="r", + [68226]="r", + [68227]="r", + [68228]="r", + [68229]="r", + [68230]="r", + [68231]="r", + [68232]="r", + [68233]="r", + [68234]="r", + [68235]="r", + [68236]="r", + [68237]="r", + [68238]="r", + [68239]="r", + [68240]="r", + [68241]="r", + [68242]="r", + [68243]="r", + [68244]="r", + [68245]="r", + [68246]="r", + [68247]="r", + [68248]="r", + [68249]="r", + [68250]="r", + [68251]="r", + [68252]="r", + [68253]="r", + [68254]="r", + [68255]="r", + [68288]="r", + [68289]="r", + [68290]="r", + [68291]="r", + [68292]="r", + [68293]="r", + [68294]="r", + [68295]="r", + [68296]="r", + [68297]="r", + [68298]="r", + [68299]="r", + [68300]="r", + [68301]="r", + [68302]="r", + [68303]="r", + [68304]="r", + [68305]="r", + [68306]="r", + [68307]="r", + [68308]="r", + [68309]="r", + [68310]="r", + [68311]="r", + [68312]="r", + [68313]="r", + [68314]="r", + [68315]="r", + [68316]="r", + [68317]="r", + [68318]="r", + [68319]="r", + [68320]="r", + [68321]="r", + [68322]="r", + [68323]="r", + [68324]="r", + [68325]="nsm", + [68326]="nsm", + [68331]="r", + [68332]="r", + [68333]="r", + [68334]="r", + [68335]="r", + [68336]="r", + [68337]="r", + [68338]="r", + [68339]="r", + [68340]="r", + [68341]="r", + [68342]="r", + [68352]="r", + [68353]="r", + [68354]="r", + [68355]="r", + [68356]="r", + [68357]="r", + [68358]="r", + [68359]="r", + [68360]="r", + [68361]="r", + [68362]="r", + [68363]="r", + [68364]="r", + [68365]="r", + [68366]="r", + [68367]="r", + [68368]="r", + [68369]="r", + [68370]="r", + [68371]="r", + [68372]="r", + [68373]="r", + [68374]="r", + [68375]="r", + [68376]="r", + [68377]="r", + [68378]="r", + [68379]="r", + [68380]="r", + [68381]="r", + [68382]="r", + [68383]="r", + [68384]="r", + [68385]="r", + [68386]="r", + [68387]="r", + [68388]="r", + [68389]="r", + [68390]="r", + [68391]="r", + [68392]="r", + [68393]="r", + [68394]="r", + [68395]="r", + [68396]="r", + [68397]="r", + [68398]="r", + [68399]="r", + [68400]="r", + [68401]="r", + [68402]="r", + [68403]="r", + [68404]="r", + [68405]="r", + [68409]="on", + [68410]="on", + [68411]="on", + [68412]="on", + [68413]="on", + [68414]="on", + [68415]="on", + [68416]="r", + [68417]="r", + [68418]="r", + [68419]="r", + [68420]="r", + [68421]="r", + [68422]="r", + [68423]="r", + [68424]="r", + [68425]="r", + [68426]="r", + [68427]="r", + [68428]="r", + [68429]="r", + [68430]="r", + [68431]="r", + [68432]="r", + [68433]="r", + [68434]="r", + [68435]="r", + [68436]="r", + [68437]="r", + [68440]="r", + [68441]="r", + [68442]="r", + [68443]="r", + [68444]="r", + [68445]="r", + [68446]="r", + [68447]="r", + [68448]="r", + [68449]="r", + [68450]="r", + [68451]="r", + [68452]="r", + [68453]="r", + [68454]="r", + [68455]="r", + [68456]="r", + [68457]="r", + [68458]="r", + [68459]="r", + [68460]="r", + [68461]="r", + [68462]="r", + [68463]="r", + [68464]="r", + [68465]="r", + [68466]="r", + [68472]="r", + [68473]="r", + [68474]="r", + [68475]="r", + [68476]="r", + [68477]="r", + [68478]="r", + [68479]="r", + [68480]="r", + [68481]="r", + [68482]="r", + [68483]="r", + [68484]="r", + [68485]="r", + [68486]="r", + [68487]="r", + [68488]="r", + [68489]="r", + [68490]="r", + [68491]="r", + [68492]="r", + [68493]="r", + [68494]="r", + [68495]="r", + [68496]="r", + [68497]="r", + [68505]="r", + [68506]="r", + [68507]="r", + [68508]="r", + [68521]="r", + [68522]="r", + [68523]="r", + [68524]="r", + [68525]="r", + [68526]="r", + [68527]="r", + [68608]="r", + [68609]="r", + [68610]="r", + [68611]="r", + [68612]="r", + [68613]="r", + [68614]="r", + [68615]="r", + [68616]="r", + [68617]="r", + [68618]="r", + [68619]="r", + [68620]="r", + [68621]="r", + [68622]="r", + [68623]="r", + [68624]="r", + [68625]="r", + [68626]="r", + [68627]="r", + [68628]="r", + [68629]="r", + [68630]="r", + [68631]="r", + [68632]="r", + [68633]="r", + [68634]="r", + [68635]="r", + [68636]="r", + [68637]="r", + [68638]="r", + [68639]="r", + [68640]="r", + [68641]="r", + [68642]="r", + [68643]="r", + [68644]="r", + [68645]="r", + [68646]="r", + [68647]="r", + [68648]="r", + [68649]="r", + [68650]="r", + [68651]="r", + [68652]="r", + [68653]="r", + [68654]="r", + [68655]="r", + [68656]="r", + [68657]="r", + [68658]="r", + [68659]="r", + [68660]="r", + [68661]="r", + [68662]="r", + [68663]="r", + [68664]="r", + [68665]="r", + [68666]="r", + [68667]="r", + [68668]="r", + [68669]="r", + [68670]="r", + [68671]="r", + [68672]="r", + [68673]="r", + [68674]="r", + [68675]="r", + [68676]="r", + [68677]="r", + [68678]="r", + [68679]="r", + [68680]="r", + [68736]="r", + [68737]="r", + [68738]="r", + [68739]="r", + [68740]="r", + [68741]="r", + [68742]="r", + [68743]="r", + [68744]="r", + [68745]="r", + [68746]="r", + [68747]="r", + [68748]="r", + [68749]="r", + [68750]="r", + [68751]="r", + [68752]="r", + [68753]="r", + [68754]="r", + [68755]="r", + [68756]="r", + [68757]="r", + [68758]="r", + [68759]="r", + [68760]="r", + [68761]="r", + [68762]="r", + [68763]="r", + [68764]="r", + [68765]="r", + [68766]="r", + [68767]="r", + [68768]="r", + [68769]="r", + [68770]="r", + [68771]="r", + [68772]="r", + [68773]="r", + [68774]="r", + [68775]="r", + [68776]="r", + [68777]="r", + [68778]="r", + [68779]="r", + [68780]="r", + [68781]="r", + [68782]="r", + [68783]="r", + [68784]="r", + [68785]="r", + [68786]="r", + [68800]="r", + [68801]="r", + [68802]="r", + [68803]="r", + [68804]="r", + [68805]="r", + [68806]="r", + [68807]="r", + [68808]="r", + [68809]="r", + [68810]="r", + [68811]="r", + [68812]="r", + [68813]="r", + [68814]="r", + [68815]="r", + [68816]="r", + [68817]="r", + [68818]="r", + [68819]="r", + [68820]="r", + [68821]="r", + [68822]="r", + [68823]="r", + [68824]="r", + [68825]="r", + [68826]="r", + [68827]="r", + [68828]="r", + [68829]="r", + [68830]="r", + [68831]="r", + [68832]="r", + [68833]="r", + [68834]="r", + [68835]="r", + [68836]="r", + [68837]="r", + [68838]="r", + [68839]="r", + [68840]="r", + [68841]="r", + [68842]="r", + [68843]="r", + [68844]="r", + [68845]="r", + [68846]="r", + [68847]="r", + [68848]="r", + [68849]="r", + [68850]="r", + [68858]="r", + [68859]="r", + [68860]="r", + [68861]="r", + [68862]="r", + [68863]="r", + [69216]="an", + [69217]="an", + [69218]="an", + [69219]="an", + [69220]="an", + [69221]="an", + [69222]="an", + [69223]="an", + [69224]="an", + [69225]="an", + [69226]="an", + [69227]="an", + [69228]="an", + [69229]="an", + [69230]="an", + [69231]="an", + [69232]="an", + [69233]="an", + [69234]="an", + [69235]="an", + [69236]="an", + [69237]="an", + [69238]="an", + [69239]="an", + [69240]="an", + [69241]="an", + [69242]="an", + [69243]="an", + [69244]="an", + [69245]="an", + [69246]="an", + [69633]="nsm", + [69688]="nsm", + [69689]="nsm", + [69690]="nsm", + [69691]="nsm", + [69692]="nsm", + [69693]="nsm", + [69694]="nsm", + [69695]="nsm", + [69696]="nsm", + [69697]="nsm", + [69698]="nsm", + [69699]="nsm", + [69700]="nsm", + [69701]="nsm", + [69702]="nsm", + [69714]="on", + [69715]="on", + [69716]="on", + [69717]="on", + [69718]="on", + [69719]="on", + [69720]="on", + [69721]="on", + [69722]="on", + [69723]="on", + [69724]="on", + [69725]="on", + [69726]="on", + [69727]="on", + [69728]="on", + [69729]="on", + [69730]="on", + [69731]="on", + [69732]="on", + [69733]="on", + [69759]="nsm", + [69760]="nsm", + [69761]="nsm", + [69811]="nsm", + [69812]="nsm", + [69813]="nsm", + [69814]="nsm", + [69817]="nsm", + [69818]="nsm", + [69888]="nsm", + [69889]="nsm", + [69890]="nsm", + [69927]="nsm", + [69928]="nsm", + [69929]="nsm", + [69930]="nsm", + [69931]="nsm", + [69933]="nsm", + [69934]="nsm", + [69935]="nsm", + [69936]="nsm", + [69937]="nsm", + [69938]="nsm", + [69939]="nsm", + [69940]="nsm", + [70003]="nsm", + [70016]="nsm", + [70017]="nsm", + [70070]="nsm", + [70071]="nsm", + [70072]="nsm", + [70073]="nsm", + [70074]="nsm", + [70075]="nsm", + [70076]="nsm", + [70077]="nsm", + [70078]="nsm", + [70090]="nsm", + [70091]="nsm", + [70092]="nsm", + [70191]="nsm", + [70192]="nsm", + [70193]="nsm", + [70196]="nsm", + [70198]="nsm", + [70199]="nsm", + [70206]="nsm", + [70367]="nsm", + [70371]="nsm", + [70372]="nsm", + [70373]="nsm", + [70374]="nsm", + [70375]="nsm", + [70376]="nsm", + [70377]="nsm", + [70378]="nsm", + [70400]="nsm", + [70401]="nsm", + [70460]="nsm", + [70464]="nsm", + [70502]="nsm", + [70503]="nsm", + [70504]="nsm", + [70505]="nsm", + [70506]="nsm", + [70507]="nsm", + [70508]="nsm", + [70512]="nsm", + [70513]="nsm", + [70514]="nsm", + [70515]="nsm", + [70516]="nsm", + [70712]="nsm", + [70713]="nsm", + [70714]="nsm", + [70715]="nsm", + [70716]="nsm", + [70717]="nsm", + [70718]="nsm", + [70719]="nsm", + [70722]="nsm", + [70723]="nsm", + [70724]="nsm", + [70726]="nsm", + [70835]="nsm", + [70836]="nsm", + [70837]="nsm", + [70838]="nsm", + [70839]="nsm", + [70840]="nsm", + [70842]="nsm", + [70847]="nsm", + [70848]="nsm", + [70850]="nsm", + [70851]="nsm", + [71090]="nsm", + [71091]="nsm", + [71092]="nsm", + [71093]="nsm", + [71100]="nsm", + [71101]="nsm", + [71103]="nsm", + [71104]="nsm", + [71132]="nsm", + [71133]="nsm", + [71219]="nsm", + [71220]="nsm", + [71221]="nsm", + [71222]="nsm", + [71223]="nsm", + [71224]="nsm", + [71225]="nsm", + [71226]="nsm", + [71229]="nsm", + [71231]="nsm", + [71232]="nsm", + [71264]="on", + [71265]="on", + [71266]="on", + [71267]="on", + [71268]="on", + [71269]="on", + [71270]="on", + [71271]="on", + [71272]="on", + [71273]="on", + [71274]="on", + [71275]="on", + [71276]="on", + [71339]="nsm", + [71341]="nsm", + [71344]="nsm", + [71345]="nsm", + [71346]="nsm", + [71347]="nsm", + [71348]="nsm", + [71349]="nsm", + [71351]="nsm", + [71453]="nsm", + [71454]="nsm", + [71455]="nsm", + [71458]="nsm", + [71459]="nsm", + [71460]="nsm", + [71461]="nsm", + [71463]="nsm", + [71464]="nsm", + [71465]="nsm", + [71466]="nsm", + [71467]="nsm", + [72193]="nsm", + [72194]="nsm", + [72195]="nsm", + [72196]="nsm", + [72197]="nsm", + [72198]="nsm", + [72201]="nsm", + [72202]="nsm", + [72243]="nsm", + [72244]="nsm", + [72245]="nsm", + [72246]="nsm", + [72247]="nsm", + [72248]="nsm", + [72251]="nsm", + [72252]="nsm", + [72253]="nsm", + [72254]="nsm", + [72263]="nsm", + [72273]="nsm", + [72274]="nsm", + [72275]="nsm", + [72276]="nsm", + [72277]="nsm", + [72278]="nsm", + [72281]="nsm", + [72282]="nsm", + [72283]="nsm", + [72330]="nsm", + [72331]="nsm", + [72332]="nsm", + [72333]="nsm", + [72334]="nsm", + [72335]="nsm", + [72336]="nsm", + [72337]="nsm", + [72338]="nsm", + [72339]="nsm", + [72340]="nsm", + [72341]="nsm", + [72342]="nsm", + [72344]="nsm", + [72345]="nsm", + [72752]="nsm", + [72753]="nsm", + [72754]="nsm", + [72755]="nsm", + [72756]="nsm", + [72757]="nsm", + [72758]="nsm", + [72760]="nsm", + [72761]="nsm", + [72762]="nsm", + [72763]="nsm", + [72764]="nsm", + [72765]="nsm", + [72850]="nsm", + [72851]="nsm", + [72852]="nsm", + [72853]="nsm", + [72854]="nsm", + [72855]="nsm", + [72856]="nsm", + [72857]="nsm", + [72858]="nsm", + [72859]="nsm", + [72860]="nsm", + [72861]="nsm", + [72862]="nsm", + [72863]="nsm", + [72864]="nsm", + [72865]="nsm", + [72866]="nsm", + [72867]="nsm", + [72868]="nsm", + [72869]="nsm", + [72870]="nsm", + [72871]="nsm", + [72874]="nsm", + [72875]="nsm", + [72876]="nsm", + [72877]="nsm", + [72878]="nsm", + [72879]="nsm", + [72880]="nsm", + [72882]="nsm", + [72883]="nsm", + [72885]="nsm", + [72886]="nsm", + [73009]="nsm", + [73010]="nsm", + [73011]="nsm", + [73012]="nsm", + [73013]="nsm", + [73014]="nsm", + [73018]="nsm", + [73020]="nsm", + [73021]="nsm", + [73023]="nsm", + [73024]="nsm", + [73025]="nsm", + [73026]="nsm", + [73027]="nsm", + [73028]="nsm", + [73029]="nsm", + [73031]="nsm", + [92912]="nsm", + [92913]="nsm", + [92914]="nsm", + [92915]="nsm", + [92916]="nsm", + [92976]="nsm", + [92977]="nsm", + [92978]="nsm", + [92979]="nsm", + [92980]="nsm", + [92981]="nsm", + [92982]="nsm", + [94095]="nsm", + [94096]="nsm", + [94097]="nsm", + [94098]="nsm", + [113821]="nsm", + [113822]="nsm", + [113824]="bn", + [113825]="bn", + [113826]="bn", + [113827]="bn", + [119143]="nsm", + [119144]="nsm", + [119145]="nsm", + [119155]="bn", + [119156]="bn", + [119157]="bn", + [119158]="bn", + [119159]="bn", + [119160]="bn", + [119161]="bn", + [119162]="bn", + [119163]="nsm", + [119164]="nsm", + [119165]="nsm", + [119166]="nsm", + [119167]="nsm", + [119168]="nsm", + [119169]="nsm", + [119170]="nsm", + [119173]="nsm", + [119174]="nsm", + [119175]="nsm", + [119176]="nsm", + [119177]="nsm", + [119178]="nsm", + [119179]="nsm", + [119210]="nsm", + [119211]="nsm", + [119212]="nsm", + [119213]="nsm", + [119296]="on", + [119297]="on", + [119298]="on", + [119299]="on", + [119300]="on", + [119301]="on", + [119302]="on", + [119303]="on", + [119304]="on", + [119305]="on", + [119306]="on", + [119307]="on", + [119308]="on", + [119309]="on", + [119310]="on", + [119311]="on", + [119312]="on", + [119313]="on", + [119314]="on", + [119315]="on", + [119316]="on", + [119317]="on", + [119318]="on", + [119319]="on", + [119320]="on", + [119321]="on", + [119322]="on", + [119323]="on", + [119324]="on", + [119325]="on", + [119326]="on", + [119327]="on", + [119328]="on", + [119329]="on", + [119330]="on", + [119331]="on", + [119332]="on", + [119333]="on", + [119334]="on", + [119335]="on", + [119336]="on", + [119337]="on", + [119338]="on", + [119339]="on", + [119340]="on", + [119341]="on", + [119342]="on", + [119343]="on", + [119344]="on", + [119345]="on", + [119346]="on", + [119347]="on", + [119348]="on", + [119349]="on", + [119350]="on", + [119351]="on", + [119352]="on", + [119353]="on", + [119354]="on", + [119355]="on", + [119356]="on", + [119357]="on", + [119358]="on", + [119359]="on", + [119360]="on", + [119361]="on", + [119362]="nsm", + [119363]="nsm", + [119364]="nsm", + [119365]="on", + [119552]="on", + [119553]="on", + [119554]="on", + [119555]="on", + [119556]="on", + [119557]="on", + [119558]="on", + [119559]="on", + [119560]="on", + [119561]="on", + [119562]="on", + [119563]="on", + [119564]="on", + [119565]="on", + [119566]="on", + [119567]="on", + [119568]="on", + [119569]="on", + [119570]="on", + [119571]="on", + [119572]="on", + [119573]="on", + [119574]="on", + [119575]="on", + [119576]="on", + [119577]="on", + [119578]="on", + [119579]="on", + [119580]="on", + [119581]="on", + [119582]="on", + [119583]="on", + [119584]="on", + [119585]="on", + [119586]="on", + [119587]="on", + [119588]="on", + [119589]="on", + [119590]="on", + [119591]="on", + [119592]="on", + [119593]="on", + [119594]="on", + [119595]="on", + [119596]="on", + [119597]="on", + [119598]="on", + [119599]="on", + [119600]="on", + [119601]="on", + [119602]="on", + [119603]="on", + [119604]="on", + [119605]="on", + [119606]="on", + [119607]="on", + [119608]="on", + [119609]="on", + [119610]="on", + [119611]="on", + [119612]="on", + [119613]="on", + [119614]="on", + [119615]="on", + [119616]="on", + [119617]="on", + [119618]="on", + [119619]="on", + [119620]="on", + [119621]="on", + [119622]="on", + [119623]="on", + [119624]="on", + [119625]="on", + [119626]="on", + [119627]="on", + [119628]="on", + [119629]="on", + [119630]="on", + [119631]="on", + [119632]="on", + [119633]="on", + [119634]="on", + [119635]="on", + [119636]="on", + [119637]="on", + [119638]="on", + [120539]="on", + [120597]="on", + [120655]="on", + [120713]="on", + [120771]="on", + [120782]="en", + [120783]="en", + [120784]="en", + [120785]="en", + [120786]="en", + [120787]="en", + [120788]="en", + [120789]="en", + [120790]="en", + [120791]="en", + [120792]="en", + [120793]="en", + [120794]="en", + [120795]="en", + [120796]="en", + [120797]="en", + [120798]="en", + [120799]="en", + [120800]="en", + [120801]="en", + [120802]="en", + [120803]="en", + [120804]="en", + [120805]="en", + [120806]="en", + [120807]="en", + [120808]="en", + [120809]="en", + [120810]="en", + [120811]="en", + [120812]="en", + [120813]="en", + [120814]="en", + [120815]="en", + [120816]="en", + [120817]="en", + [120818]="en", + [120819]="en", + [120820]="en", + [120821]="en", + [120822]="en", + [120823]="en", + [120824]="en", + [120825]="en", + [120826]="en", + [120827]="en", + [120828]="en", + [120829]="en", + [120830]="en", + [120831]="en", + [121344]="nsm", + [121345]="nsm", + [121346]="nsm", + [121347]="nsm", + [121348]="nsm", + [121349]="nsm", + [121350]="nsm", + [121351]="nsm", + [121352]="nsm", + [121353]="nsm", + [121354]="nsm", + [121355]="nsm", + [121356]="nsm", + [121357]="nsm", + [121358]="nsm", + [121359]="nsm", + [121360]="nsm", + [121361]="nsm", + [121362]="nsm", + [121363]="nsm", + [121364]="nsm", + [121365]="nsm", + [121366]="nsm", + [121367]="nsm", + [121368]="nsm", + [121369]="nsm", + [121370]="nsm", + [121371]="nsm", + [121372]="nsm", + [121373]="nsm", + [121374]="nsm", + [121375]="nsm", + [121376]="nsm", + [121377]="nsm", + [121378]="nsm", + [121379]="nsm", + [121380]="nsm", + [121381]="nsm", + [121382]="nsm", + [121383]="nsm", + [121384]="nsm", + [121385]="nsm", + [121386]="nsm", + [121387]="nsm", + [121388]="nsm", + [121389]="nsm", + [121390]="nsm", + [121391]="nsm", + [121392]="nsm", + [121393]="nsm", + [121394]="nsm", + [121395]="nsm", + [121396]="nsm", + [121397]="nsm", + [121398]="nsm", + [121403]="nsm", + [121404]="nsm", + [121405]="nsm", + [121406]="nsm", + [121407]="nsm", + [121408]="nsm", + [121409]="nsm", + [121410]="nsm", + [121411]="nsm", + [121412]="nsm", + [121413]="nsm", + [121414]="nsm", + [121415]="nsm", + [121416]="nsm", + [121417]="nsm", + [121418]="nsm", + [121419]="nsm", + [121420]="nsm", + [121421]="nsm", + [121422]="nsm", + [121423]="nsm", + [121424]="nsm", + [121425]="nsm", + [121426]="nsm", + [121427]="nsm", + [121428]="nsm", + [121429]="nsm", + [121430]="nsm", + [121431]="nsm", + [121432]="nsm", + [121433]="nsm", + [121434]="nsm", + [121435]="nsm", + [121436]="nsm", + [121437]="nsm", + [121438]="nsm", + [121439]="nsm", + [121440]="nsm", + [121441]="nsm", + [121442]="nsm", + [121443]="nsm", + [121444]="nsm", + [121445]="nsm", + [121446]="nsm", + [121447]="nsm", + [121448]="nsm", + [121449]="nsm", + [121450]="nsm", + [121451]="nsm", + [121452]="nsm", + [121461]="nsm", + [121476]="nsm", + [121499]="nsm", + [121500]="nsm", + [121501]="nsm", + [121502]="nsm", + [121503]="nsm", + [121505]="nsm", + [121506]="nsm", + [121507]="nsm", + [121508]="nsm", + [121509]="nsm", + [121510]="nsm", + [121511]="nsm", + [121512]="nsm", + [121513]="nsm", + [121514]="nsm", + [121515]="nsm", + [121516]="nsm", + [121517]="nsm", + [121518]="nsm", + [121519]="nsm", + [122880]="nsm", + [122881]="nsm", + [122882]="nsm", + [122883]="nsm", + [122884]="nsm", + [122885]="nsm", + [122886]="nsm", + [122888]="nsm", + [122889]="nsm", + [122890]="nsm", + [122891]="nsm", + [122892]="nsm", + [122893]="nsm", + [122894]="nsm", + [122895]="nsm", + [122896]="nsm", + [122897]="nsm", + [122898]="nsm", + [122899]="nsm", + [122900]="nsm", + [122901]="nsm", + [122902]="nsm", + [122903]="nsm", + [122904]="nsm", + [122907]="nsm", + [122908]="nsm", + [122909]="nsm", + [122910]="nsm", + [122911]="nsm", + [122912]="nsm", + [122913]="nsm", + [122915]="nsm", + [122916]="nsm", + [122918]="nsm", + [122919]="nsm", + [122920]="nsm", + [122921]="nsm", + [122922]="nsm", + [124928]="r", + [124929]="r", + [124930]="r", + [124931]="r", + [124932]="r", + [124933]="r", + [124934]="r", + [124935]="r", + [124936]="r", + [124937]="r", + [124938]="r", + [124939]="r", + [124940]="r", + [124941]="r", + [124942]="r", + [124943]="r", + [124944]="r", + [124945]="r", + [124946]="r", + [124947]="r", + [124948]="r", + [124949]="r", + [124950]="r", + [124951]="r", + [124952]="r", + [124953]="r", + [124954]="r", + [124955]="r", + [124956]="r", + [124957]="r", + [124958]="r", + [124959]="r", + [124960]="r", + [124961]="r", + [124962]="r", + [124963]="r", + [124964]="r", + [124965]="r", + [124966]="r", + [124967]="r", + [124968]="r", + [124969]="r", + [124970]="r", + [124971]="r", + [124972]="r", + [124973]="r", + [124974]="r", + [124975]="r", + [124976]="r", + [124977]="r", + [124978]="r", + [124979]="r", + [124980]="r", + [124981]="r", + [124982]="r", + [124983]="r", + [124984]="r", + [124985]="r", + [124986]="r", + [124987]="r", + [124988]="r", + [124989]="r", + [124990]="r", + [124991]="r", + [124992]="r", + [124993]="r", + [124994]="r", + [124995]="r", + [124996]="r", + [124997]="r", + [124998]="r", + [124999]="r", + [125000]="r", + [125001]="r", + [125002]="r", + [125003]="r", + [125004]="r", + [125005]="r", + [125006]="r", + [125007]="r", + [125008]="r", + [125009]="r", + [125010]="r", + [125011]="r", + [125012]="r", + [125013]="r", + [125014]="r", + [125015]="r", + [125016]="r", + [125017]="r", + [125018]="r", + [125019]="r", + [125020]="r", + [125021]="r", + [125022]="r", + [125023]="r", + [125024]="r", + [125025]="r", + [125026]="r", + [125027]="r", + [125028]="r", + [125029]="r", + [125030]="r", + [125031]="r", + [125032]="r", + [125033]="r", + [125034]="r", + [125035]="r", + [125036]="r", + [125037]="r", + [125038]="r", + [125039]="r", + [125040]="r", + [125041]="r", + [125042]="r", + [125043]="r", + [125044]="r", + [125045]="r", + [125046]="r", + [125047]="r", + [125048]="r", + [125049]="r", + [125050]="r", + [125051]="r", + [125052]="r", + [125053]="r", + [125054]="r", + [125055]="r", + [125056]="r", + [125057]="r", + [125058]="r", + [125059]="r", + [125060]="r", + [125061]="r", + [125062]="r", + [125063]="r", + [125064]="r", + [125065]="r", + [125066]="r", + [125067]="r", + [125068]="r", + [125069]="r", + [125070]="r", + [125071]="r", + [125072]="r", + [125073]="r", + [125074]="r", + [125075]="r", + [125076]="r", + [125077]="r", + [125078]="r", + [125079]="r", + [125080]="r", + [125081]="r", + [125082]="r", + [125083]="r", + [125084]="r", + [125085]="r", + [125086]="r", + [125087]="r", + [125088]="r", + [125089]="r", + [125090]="r", + [125091]="r", + [125092]="r", + [125093]="r", + [125094]="r", + [125095]="r", + [125096]="r", + [125097]="r", + [125098]="r", + [125099]="r", + [125100]="r", + [125101]="r", + [125102]="r", + [125103]="r", + [125104]="r", + [125105]="r", + [125106]="r", + [125107]="r", + [125108]="r", + [125109]="r", + [125110]="r", + [125111]="r", + [125112]="r", + [125113]="r", + [125114]="r", + [125115]="r", + [125116]="r", + [125117]="r", + [125118]="r", + [125119]="r", + [125120]="r", + [125121]="r", + [125122]="r", + [125123]="r", + [125124]="r", + [125127]="r", + [125128]="r", + [125129]="r", + [125130]="r", + [125131]="r", + [125132]="r", + [125133]="r", + [125134]="r", + [125135]="r", + [125136]="nsm", + [125137]="nsm", + [125138]="nsm", + [125139]="nsm", + [125140]="nsm", + [125141]="nsm", + [125142]="nsm", + [125184]="r", + [125185]="r", + [125186]="r", + [125187]="r", + [125188]="r", + [125189]="r", + [125190]="r", + [125191]="r", + [125192]="r", + [125193]="r", + [125194]="r", + [125195]="r", + [125196]="r", + [125197]="r", + [125198]="r", + [125199]="r", + [125200]="r", + [125201]="r", + [125202]="r", + [125203]="r", + [125204]="r", + [125205]="r", + [125206]="r", + [125207]="r", + [125208]="r", + [125209]="r", + [125210]="r", + [125211]="r", + [125212]="r", + [125213]="r", + [125214]="r", + [125215]="r", + [125216]="r", + [125217]="r", + [125218]="r", + [125219]="r", + [125220]="r", + [125221]="r", + [125222]="r", + [125223]="r", + [125224]="r", + [125225]="r", + [125226]="r", + [125227]="r", + [125228]="r", + [125229]="r", + [125230]="r", + [125231]="r", + [125232]="r", + [125233]="r", + [125234]="r", + [125235]="r", + [125236]="r", + [125237]="r", + [125238]="r", + [125239]="r", + [125240]="r", + [125241]="r", + [125242]="r", + [125243]="r", + [125244]="r", + [125245]="r", + [125246]="r", + [125247]="r", + [125248]="r", + [125249]="r", + [125250]="r", + [125251]="r", + [125252]="nsm", + [125253]="nsm", + [125254]="nsm", + [125255]="nsm", + [125256]="nsm", + [125257]="nsm", + [125258]="nsm", + [125264]="r", + [125265]="r", + [125266]="r", + [125267]="r", + [125268]="r", + [125269]="r", + [125270]="r", + [125271]="r", + [125272]="r", + [125273]="r", + [125278]="r", + [125279]="r", + [126464]="al", + [126465]="al", + [126466]="al", + [126467]="al", + [126469]="al", + [126470]="al", + [126471]="al", + [126472]="al", + [126473]="al", + [126474]="al", + [126475]="al", + [126476]="al", + [126477]="al", + [126478]="al", + [126479]="al", + [126480]="al", + [126481]="al", + [126482]="al", + [126483]="al", + [126484]="al", + [126485]="al", + [126486]="al", + [126487]="al", + [126488]="al", + [126489]="al", + [126490]="al", + [126491]="al", + [126492]="al", + [126493]="al", + [126494]="al", + [126495]="al", + [126497]="al", + [126498]="al", + [126500]="al", + [126503]="al", + [126505]="al", + [126506]="al", + [126507]="al", + [126508]="al", + [126509]="al", + [126510]="al", + [126511]="al", + [126512]="al", + [126513]="al", + [126514]="al", + [126516]="al", + [126517]="al", + [126518]="al", + [126519]="al", + [126521]="al", + [126523]="al", + [126530]="al", + [126535]="al", + [126537]="al", + [126539]="al", + [126541]="al", + [126542]="al", + [126543]="al", + [126545]="al", + [126546]="al", + [126548]="al", + [126551]="al", + [126553]="al", + [126555]="al", + [126557]="al", + [126559]="al", + [126561]="al", + [126562]="al", + [126564]="al", + [126567]="al", + [126568]="al", + [126569]="al", + [126570]="al", + [126572]="al", + [126573]="al", + [126574]="al", + [126575]="al", + [126576]="al", + [126577]="al", + [126578]="al", + [126580]="al", + [126581]="al", + [126582]="al", + [126583]="al", + [126585]="al", + [126586]="al", + [126587]="al", + [126588]="al", + [126590]="al", + [126592]="al", + [126593]="al", + [126594]="al", + [126595]="al", + [126596]="al", + [126597]="al", + [126598]="al", + [126599]="al", + [126600]="al", + [126601]="al", + [126603]="al", + [126604]="al", + [126605]="al", + [126606]="al", + [126607]="al", + [126608]="al", + [126609]="al", + [126610]="al", + [126611]="al", + [126612]="al", + [126613]="al", + [126614]="al", + [126615]="al", + [126616]="al", + [126617]="al", + [126618]="al", + [126619]="al", + [126625]="al", + [126626]="al", + [126627]="al", + [126629]="al", + [126630]="al", + [126631]="al", + [126632]="al", + [126633]="al", + [126635]="al", + [126636]="al", + [126637]="al", + [126638]="al", + [126639]="al", + [126640]="al", + [126641]="al", + [126642]="al", + [126643]="al", + [126644]="al", + [126645]="al", + [126646]="al", + [126647]="al", + [126648]="al", + [126649]="al", + [126650]="al", + [126651]="al", + [126704]="on", + [126705]="on", + [126976]="on", + [126977]="on", + [126978]="on", + [126979]="on", + [126980]="on", + [126981]="on", + [126982]="on", + [126983]="on", + [126984]="on", + [126985]="on", + [126986]="on", + [126987]="on", + [126988]="on", + [126989]="on", + [126990]="on", + [126991]="on", + [126992]="on", + [126993]="on", + [126994]="on", + [126995]="on", + [126996]="on", + [126997]="on", + [126998]="on", + [126999]="on", + [127000]="on", + [127001]="on", + [127002]="on", + [127003]="on", + [127004]="on", + [127005]="on", + [127006]="on", + [127007]="on", + [127008]="on", + [127009]="on", + [127010]="on", + [127011]="on", + [127012]="on", + [127013]="on", + [127014]="on", + [127015]="on", + [127016]="on", + [127017]="on", + [127018]="on", + [127019]="on", + [127024]="on", + [127025]="on", + [127026]="on", + [127027]="on", + [127028]="on", + [127029]="on", + [127030]="on", + [127031]="on", + [127032]="on", + [127033]="on", + [127034]="on", + [127035]="on", + [127036]="on", + [127037]="on", + [127038]="on", + [127039]="on", + [127040]="on", + [127041]="on", + [127042]="on", + [127043]="on", + [127044]="on", + [127045]="on", + [127046]="on", + [127047]="on", + [127048]="on", + [127049]="on", + [127050]="on", + [127051]="on", + [127052]="on", + [127053]="on", + [127054]="on", + [127055]="on", + [127056]="on", + [127057]="on", + [127058]="on", + [127059]="on", + [127060]="on", + [127061]="on", + [127062]="on", + [127063]="on", + [127064]="on", + [127065]="on", + [127066]="on", + [127067]="on", + [127068]="on", + [127069]="on", + [127070]="on", + [127071]="on", + [127072]="on", + [127073]="on", + [127074]="on", + [127075]="on", + [127076]="on", + [127077]="on", + [127078]="on", + [127079]="on", + [127080]="on", + [127081]="on", + [127082]="on", + [127083]="on", + [127084]="on", + [127085]="on", + [127086]="on", + [127087]="on", + [127088]="on", + [127089]="on", + [127090]="on", + [127091]="on", + [127092]="on", + [127093]="on", + [127094]="on", + [127095]="on", + [127096]="on", + [127097]="on", + [127098]="on", + [127099]="on", + [127100]="on", + [127101]="on", + [127102]="on", + [127103]="on", + [127104]="on", + [127105]="on", + [127106]="on", + [127107]="on", + [127108]="on", + [127109]="on", + [127110]="on", + [127111]="on", + [127112]="on", + [127113]="on", + [127114]="on", + [127115]="on", + [127116]="on", + [127117]="on", + [127118]="on", + [127119]="on", + [127120]="on", + [127121]="on", + [127122]="on", + [127123]="on", + [127136]="on", + [127137]="on", + [127138]="on", + [127139]="on", + [127140]="on", + [127141]="on", + [127142]="on", + [127143]="on", + [127144]="on", + [127145]="on", + [127146]="on", + [127147]="on", + [127148]="on", + [127149]="on", + [127150]="on", + [127153]="on", + [127154]="on", + [127155]="on", + [127156]="on", + [127157]="on", + [127158]="on", + [127159]="on", + [127160]="on", + [127161]="on", + [127162]="on", + [127163]="on", + [127164]="on", + [127165]="on", + [127166]="on", + [127167]="on", + [127169]="on", + [127170]="on", + [127171]="on", + [127172]="on", + [127173]="on", + [127174]="on", + [127175]="on", + [127176]="on", + [127177]="on", + [127178]="on", + [127179]="on", + [127180]="on", + [127181]="on", + [127182]="on", + [127183]="on", + [127185]="on", + [127186]="on", + [127187]="on", + [127188]="on", + [127189]="on", + [127190]="on", + [127191]="on", + [127192]="on", + [127193]="on", + [127194]="on", + [127195]="on", + [127196]="on", + [127197]="on", + [127198]="on", + [127199]="on", + [127200]="on", + [127201]="on", + [127202]="on", + [127203]="on", + [127204]="on", + [127205]="on", + [127206]="on", + [127207]="on", + [127208]="on", + [127209]="on", + [127210]="on", + [127211]="on", + [127212]="on", + [127213]="on", + [127214]="on", + [127215]="on", + [127216]="on", + [127217]="on", + [127218]="on", + [127219]="on", + [127220]="on", + [127221]="on", + [127232]="en", + [127233]="en", + [127234]="en", + [127235]="en", + [127236]="en", + [127237]="en", + [127238]="en", + [127239]="en", + [127240]="en", + [127241]="en", + [127242]="en", + [127243]="on", + [127244]="on", + [127338]="on", + [127339]="on", + [127584]="on", + [127585]="on", + [127586]="on", + [127587]="on", + [127588]="on", + [127589]="on", + [127744]="on", + [127745]="on", + [127746]="on", + [127747]="on", + [127748]="on", + [127749]="on", + [127750]="on", + [127751]="on", + [127752]="on", + [127753]="on", + [127754]="on", + [127755]="on", + [127756]="on", + [127757]="on", + [127758]="on", + [127759]="on", + [127760]="on", + [127761]="on", + [127762]="on", + [127763]="on", + [127764]="on", + [127765]="on", + [127766]="on", + [127767]="on", + [127768]="on", + [127769]="on", + [127770]="on", + [127771]="on", + [127772]="on", + [127773]="on", + [127774]="on", + [127775]="on", + [127776]="on", + [127777]="on", + [127778]="on", + [127779]="on", + [127780]="on", + [127781]="on", + [127782]="on", + [127783]="on", + [127784]="on", + [127785]="on", + [127786]="on", + [127787]="on", + [127788]="on", + [127789]="on", + [127790]="on", + [127791]="on", + [127792]="on", + [127793]="on", + [127794]="on", + [127795]="on", + [127796]="on", + [127797]="on", + [127798]="on", + [127799]="on", + [127800]="on", + [127801]="on", + [127802]="on", + [127803]="on", + [127804]="on", + [127805]="on", + [127806]="on", + [127807]="on", + [127808]="on", + [127809]="on", + [127810]="on", + [127811]="on", + [127812]="on", + [127813]="on", + [127814]="on", + [127815]="on", + [127816]="on", + [127817]="on", + [127818]="on", + [127819]="on", + [127820]="on", + [127821]="on", + [127822]="on", + [127823]="on", + [127824]="on", + [127825]="on", + [127826]="on", + [127827]="on", + [127828]="on", + [127829]="on", + [127830]="on", + [127831]="on", + [127832]="on", + [127833]="on", + [127834]="on", + [127835]="on", + [127836]="on", + [127837]="on", + [127838]="on", + [127839]="on", + [127840]="on", + [127841]="on", + [127842]="on", + [127843]="on", + [127844]="on", + [127845]="on", + [127846]="on", + [127847]="on", + [127848]="on", + [127849]="on", + [127850]="on", + [127851]="on", + [127852]="on", + [127853]="on", + [127854]="on", + [127855]="on", + [127856]="on", + [127857]="on", + [127858]="on", + [127859]="on", + [127860]="on", + [127861]="on", + [127862]="on", + [127863]="on", + [127864]="on", + [127865]="on", + [127866]="on", + [127867]="on", + [127868]="on", + [127869]="on", + [127870]="on", + [127871]="on", + [127872]="on", + [127873]="on", + [127874]="on", + [127875]="on", + [127876]="on", + [127877]="on", + [127878]="on", + [127879]="on", + [127880]="on", + [127881]="on", + [127882]="on", + [127883]="on", + [127884]="on", + [127885]="on", + [127886]="on", + [127887]="on", + [127888]="on", + [127889]="on", + [127890]="on", + [127891]="on", + [127892]="on", + [127893]="on", + [127894]="on", + [127895]="on", + [127896]="on", + [127897]="on", + [127898]="on", + [127899]="on", + [127900]="on", + [127901]="on", + [127902]="on", + [127903]="on", + [127904]="on", + [127905]="on", + [127906]="on", + [127907]="on", + [127908]="on", + [127909]="on", + [127910]="on", + [127911]="on", + [127912]="on", + [127913]="on", + [127914]="on", + [127915]="on", + [127916]="on", + [127917]="on", + [127918]="on", + [127919]="on", + [127920]="on", + [127921]="on", + [127922]="on", + [127923]="on", + [127924]="on", + [127925]="on", + [127926]="on", + [127927]="on", + [127928]="on", + [127929]="on", + [127930]="on", + [127931]="on", + [127932]="on", + [127933]="on", + [127934]="on", + [127935]="on", + [127936]="on", + [127937]="on", + [127938]="on", + [127939]="on", + [127940]="on", + [127941]="on", + [127942]="on", + [127943]="on", + [127944]="on", + [127945]="on", + [127946]="on", + [127947]="on", + [127948]="on", + [127949]="on", + [127950]="on", + [127951]="on", + [127952]="on", + [127953]="on", + [127954]="on", + [127955]="on", + [127956]="on", + [127957]="on", + [127958]="on", + [127959]="on", + [127960]="on", + [127961]="on", + [127962]="on", + [127963]="on", + [127964]="on", + [127965]="on", + [127966]="on", + [127967]="on", + [127968]="on", + [127969]="on", + [127970]="on", + [127971]="on", + [127972]="on", + [127973]="on", + [127974]="on", + [127975]="on", + [127976]="on", + [127977]="on", + [127978]="on", + [127979]="on", + [127980]="on", + [127981]="on", + [127982]="on", + [127983]="on", + [127984]="on", + [127985]="on", + [127986]="on", + [127987]="on", + [127988]="on", + [127989]="on", + [127990]="on", + [127991]="on", + [127992]="on", + [127993]="on", + [127994]="on", + [127995]="on", + [127996]="on", + [127997]="on", + [127998]="on", + [127999]="on", + [128000]="on", + [128001]="on", + [128002]="on", + [128003]="on", + [128004]="on", + [128005]="on", + [128006]="on", + [128007]="on", + [128008]="on", + [128009]="on", + [128010]="on", + [128011]="on", + [128012]="on", + [128013]="on", + [128014]="on", + [128015]="on", + [128016]="on", + [128017]="on", + [128018]="on", + [128019]="on", + [128020]="on", + [128021]="on", + [128022]="on", + [128023]="on", + [128024]="on", + [128025]="on", + [128026]="on", + [128027]="on", + [128028]="on", + [128029]="on", + [128030]="on", + [128031]="on", + [128032]="on", + [128033]="on", + [128034]="on", + [128035]="on", + [128036]="on", + [128037]="on", + [128038]="on", + [128039]="on", + [128040]="on", + [128041]="on", + [128042]="on", + [128043]="on", + [128044]="on", + [128045]="on", + [128046]="on", + [128047]="on", + [128048]="on", + [128049]="on", + [128050]="on", + [128051]="on", + [128052]="on", + [128053]="on", + [128054]="on", + [128055]="on", + [128056]="on", + [128057]="on", + [128058]="on", + [128059]="on", + [128060]="on", + [128061]="on", + [128062]="on", + [128063]="on", + [128064]="on", + [128065]="on", + [128066]="on", + [128067]="on", + [128068]="on", + [128069]="on", + [128070]="on", + [128071]="on", + [128072]="on", + [128073]="on", + [128074]="on", + [128075]="on", + [128076]="on", + [128077]="on", + [128078]="on", + [128079]="on", + [128080]="on", + [128081]="on", + [128082]="on", + [128083]="on", + [128084]="on", + [128085]="on", + [128086]="on", + [128087]="on", + [128088]="on", + [128089]="on", + [128090]="on", + [128091]="on", + [128092]="on", + [128093]="on", + [128094]="on", + [128095]="on", + [128096]="on", + [128097]="on", + [128098]="on", + [128099]="on", + [128100]="on", + [128101]="on", + [128102]="on", + [128103]="on", + [128104]="on", + [128105]="on", + [128106]="on", + [128107]="on", + [128108]="on", + [128109]="on", + [128110]="on", + [128111]="on", + [128112]="on", + [128113]="on", + [128114]="on", + [128115]="on", + [128116]="on", + [128117]="on", + [128118]="on", + [128119]="on", + [128120]="on", + [128121]="on", + [128122]="on", + [128123]="on", + [128124]="on", + [128125]="on", + [128126]="on", + [128127]="on", + [128128]="on", + [128129]="on", + [128130]="on", + [128131]="on", + [128132]="on", + [128133]="on", + [128134]="on", + [128135]="on", + [128136]="on", + [128137]="on", + [128138]="on", + [128139]="on", + [128140]="on", + [128141]="on", + [128142]="on", + [128143]="on", + [128144]="on", + [128145]="on", + [128146]="on", + [128147]="on", + [128148]="on", + [128149]="on", + [128150]="on", + [128151]="on", + [128152]="on", + [128153]="on", + [128154]="on", + [128155]="on", + [128156]="on", + [128157]="on", + [128158]="on", + [128159]="on", + [128160]="on", + [128161]="on", + [128162]="on", + [128163]="on", + [128164]="on", + [128165]="on", + [128166]="on", + [128167]="on", + [128168]="on", + [128169]="on", + [128170]="on", + [128171]="on", + [128172]="on", + [128173]="on", + [128174]="on", + [128175]="on", + [128176]="on", + [128177]="on", + [128178]="on", + [128179]="on", + [128180]="on", + [128181]="on", + [128182]="on", + [128183]="on", + [128184]="on", + [128185]="on", + [128186]="on", + [128187]="on", + [128188]="on", + [128189]="on", + [128190]="on", + [128191]="on", + [128192]="on", + [128193]="on", + [128194]="on", + [128195]="on", + [128196]="on", + [128197]="on", + [128198]="on", + [128199]="on", + [128200]="on", + [128201]="on", + [128202]="on", + [128203]="on", + [128204]="on", + [128205]="on", + [128206]="on", + [128207]="on", + [128208]="on", + [128209]="on", + [128210]="on", + [128211]="on", + [128212]="on", + [128213]="on", + [128214]="on", + [128215]="on", + [128216]="on", + [128217]="on", + [128218]="on", + [128219]="on", + [128220]="on", + [128221]="on", + [128222]="on", + [128223]="on", + [128224]="on", + [128225]="on", + [128226]="on", + [128227]="on", + [128228]="on", + [128229]="on", + [128230]="on", + [128231]="on", + [128232]="on", + [128233]="on", + [128234]="on", + [128235]="on", + [128236]="on", + [128237]="on", + [128238]="on", + [128239]="on", + [128240]="on", + [128241]="on", + [128242]="on", + [128243]="on", + [128244]="on", + [128245]="on", + [128246]="on", + [128247]="on", + [128248]="on", + [128249]="on", + [128250]="on", + [128251]="on", + [128252]="on", + [128253]="on", + [128254]="on", + [128255]="on", + [128256]="on", + [128257]="on", + [128258]="on", + [128259]="on", + [128260]="on", + [128261]="on", + [128262]="on", + [128263]="on", + [128264]="on", + [128265]="on", + [128266]="on", + [128267]="on", + [128268]="on", + [128269]="on", + [128270]="on", + [128271]="on", + [128272]="on", + [128273]="on", + [128274]="on", + [128275]="on", + [128276]="on", + [128277]="on", + [128278]="on", + [128279]="on", + [128280]="on", + [128281]="on", + [128282]="on", + [128283]="on", + [128284]="on", + [128285]="on", + [128286]="on", + [128287]="on", + [128288]="on", + [128289]="on", + [128290]="on", + [128291]="on", + [128292]="on", + [128293]="on", + [128294]="on", + [128295]="on", + [128296]="on", + [128297]="on", + [128298]="on", + [128299]="on", + [128300]="on", + [128301]="on", + [128302]="on", + [128303]="on", + [128304]="on", + [128305]="on", + [128306]="on", + [128307]="on", + [128308]="on", + [128309]="on", + [128310]="on", + [128311]="on", + [128312]="on", + [128313]="on", + [128314]="on", + [128315]="on", + [128316]="on", + [128317]="on", + [128318]="on", + [128319]="on", + [128320]="on", + [128321]="on", + [128322]="on", + [128323]="on", + [128324]="on", + [128325]="on", + [128326]="on", + [128327]="on", + [128328]="on", + [128329]="on", + [128330]="on", + [128331]="on", + [128332]="on", + [128333]="on", + [128334]="on", + [128335]="on", + [128336]="on", + [128337]="on", + [128338]="on", + [128339]="on", + [128340]="on", + [128341]="on", + [128342]="on", + [128343]="on", + [128344]="on", + [128345]="on", + [128346]="on", + [128347]="on", + [128348]="on", + [128349]="on", + [128350]="on", + [128351]="on", + [128352]="on", + [128353]="on", + [128354]="on", + [128355]="on", + [128356]="on", + [128357]="on", + [128358]="on", + [128359]="on", + [128360]="on", + [128361]="on", + [128362]="on", + [128363]="on", + [128364]="on", + [128365]="on", + [128366]="on", + [128367]="on", + [128368]="on", + [128369]="on", + [128370]="on", + [128371]="on", + [128372]="on", + [128373]="on", + [128374]="on", + [128375]="on", + [128376]="on", + [128377]="on", + [128378]="on", + [128379]="on", + [128380]="on", + [128381]="on", + [128382]="on", + [128383]="on", + [128384]="on", + [128385]="on", + [128386]="on", + [128387]="on", + [128388]="on", + [128389]="on", + [128390]="on", + [128391]="on", + [128392]="on", + [128393]="on", + [128394]="on", + [128395]="on", + [128396]="on", + [128397]="on", + [128398]="on", + [128399]="on", + [128400]="on", + [128401]="on", + [128402]="on", + [128403]="on", + [128404]="on", + [128405]="on", + [128406]="on", + [128407]="on", + [128408]="on", + [128409]="on", + [128410]="on", + [128411]="on", + [128412]="on", + [128413]="on", + [128414]="on", + [128415]="on", + [128416]="on", + [128417]="on", + [128418]="on", + [128419]="on", + [128420]="on", + [128421]="on", + [128422]="on", + [128423]="on", + [128424]="on", + [128425]="on", + [128426]="on", + [128427]="on", + [128428]="on", + [128429]="on", + [128430]="on", + [128431]="on", + [128432]="on", + [128433]="on", + [128434]="on", + [128435]="on", + [128436]="on", + [128437]="on", + [128438]="on", + [128439]="on", + [128440]="on", + [128441]="on", + [128442]="on", + [128443]="on", + [128444]="on", + [128445]="on", + [128446]="on", + [128447]="on", + [128448]="on", + [128449]="on", + [128450]="on", + [128451]="on", + [128452]="on", + [128453]="on", + [128454]="on", + [128455]="on", + [128456]="on", + [128457]="on", + [128458]="on", + [128459]="on", + [128460]="on", + [128461]="on", + [128462]="on", + [128463]="on", + [128464]="on", + [128465]="on", + [128466]="on", + [128467]="on", + [128468]="on", + [128469]="on", + [128470]="on", + [128471]="on", + [128472]="on", + [128473]="on", + [128474]="on", + [128475]="on", + [128476]="on", + [128477]="on", + [128478]="on", + [128479]="on", + [128480]="on", + [128481]="on", + [128482]="on", + [128483]="on", + [128484]="on", + [128485]="on", + [128486]="on", + [128487]="on", + [128488]="on", + [128489]="on", + [128490]="on", + [128491]="on", + [128492]="on", + [128493]="on", + [128494]="on", + [128495]="on", + [128496]="on", + [128497]="on", + [128498]="on", + [128499]="on", + [128500]="on", + [128501]="on", + [128502]="on", + [128503]="on", + [128504]="on", + [128505]="on", + [128506]="on", + [128507]="on", + [128508]="on", + [128509]="on", + [128510]="on", + [128511]="on", + [128512]="on", + [128513]="on", + [128514]="on", + [128515]="on", + [128516]="on", + [128517]="on", + [128518]="on", + [128519]="on", + [128520]="on", + [128521]="on", + [128522]="on", + [128523]="on", + [128524]="on", + [128525]="on", + [128526]="on", + [128527]="on", + [128528]="on", + [128529]="on", + [128530]="on", + [128531]="on", + [128532]="on", + [128533]="on", + [128534]="on", + [128535]="on", + [128536]="on", + [128537]="on", + [128538]="on", + [128539]="on", + [128540]="on", + [128541]="on", + [128542]="on", + [128543]="on", + [128544]="on", + [128545]="on", + [128546]="on", + [128547]="on", + [128548]="on", + [128549]="on", + [128550]="on", + [128551]="on", + [128552]="on", + [128553]="on", + [128554]="on", + [128555]="on", + [128556]="on", + [128557]="on", + [128558]="on", + [128559]="on", + [128560]="on", + [128561]="on", + [128562]="on", + [128563]="on", + [128564]="on", + [128565]="on", + [128566]="on", + [128567]="on", + [128568]="on", + [128569]="on", + [128570]="on", + [128571]="on", + [128572]="on", + [128573]="on", + [128574]="on", + [128575]="on", + [128576]="on", + [128577]="on", + [128578]="on", + [128579]="on", + [128580]="on", + [128581]="on", + [128582]="on", + [128583]="on", + [128584]="on", + [128585]="on", + [128586]="on", + [128587]="on", + [128588]="on", + [128589]="on", + [128590]="on", + [128591]="on", + [128592]="on", + [128593]="on", + [128594]="on", + [128595]="on", + [128596]="on", + [128597]="on", + [128598]="on", + [128599]="on", + [128600]="on", + [128601]="on", + [128602]="on", + [128603]="on", + [128604]="on", + [128605]="on", + [128606]="on", + [128607]="on", + [128608]="on", + [128609]="on", + [128610]="on", + [128611]="on", + [128612]="on", + [128613]="on", + [128614]="on", + [128615]="on", + [128616]="on", + [128617]="on", + [128618]="on", + [128619]="on", + [128620]="on", + [128621]="on", + [128622]="on", + [128623]="on", + [128624]="on", + [128625]="on", + [128626]="on", + [128627]="on", + [128628]="on", + [128629]="on", + [128630]="on", + [128631]="on", + [128632]="on", + [128633]="on", + [128634]="on", + [128635]="on", + [128636]="on", + [128637]="on", + [128638]="on", + [128639]="on", + [128640]="on", + [128641]="on", + [128642]="on", + [128643]="on", + [128644]="on", + [128645]="on", + [128646]="on", + [128647]="on", + [128648]="on", + [128649]="on", + [128650]="on", + [128651]="on", + [128652]="on", + [128653]="on", + [128654]="on", + [128655]="on", + [128656]="on", + [128657]="on", + [128658]="on", + [128659]="on", + [128660]="on", + [128661]="on", + [128662]="on", + [128663]="on", + [128664]="on", + [128665]="on", + [128666]="on", + [128667]="on", + [128668]="on", + [128669]="on", + [128670]="on", + [128671]="on", + [128672]="on", + [128673]="on", + [128674]="on", + [128675]="on", + [128676]="on", + [128677]="on", + [128678]="on", + [128679]="on", + [128680]="on", + [128681]="on", + [128682]="on", + [128683]="on", + [128684]="on", + [128685]="on", + [128686]="on", + [128687]="on", + [128688]="on", + [128689]="on", + [128690]="on", + [128691]="on", + [128692]="on", + [128693]="on", + [128694]="on", + [128695]="on", + [128696]="on", + [128697]="on", + [128698]="on", + [128699]="on", + [128700]="on", + [128701]="on", + [128702]="on", + [128703]="on", + [128704]="on", + [128705]="on", + [128706]="on", + [128707]="on", + [128708]="on", + [128709]="on", + [128710]="on", + [128711]="on", + [128712]="on", + [128713]="on", + [128714]="on", + [128715]="on", + [128716]="on", + [128717]="on", + [128718]="on", + [128719]="on", + [128720]="on", + [128721]="on", + [128722]="on", + [128723]="on", + [128724]="on", + [128736]="on", + [128737]="on", + [128738]="on", + [128739]="on", + [128740]="on", + [128741]="on", + [128742]="on", + [128743]="on", + [128744]="on", + [128745]="on", + [128746]="on", + [128747]="on", + [128748]="on", + [128752]="on", + [128753]="on", + [128754]="on", + [128755]="on", + [128756]="on", + [128757]="on", + [128758]="on", + [128759]="on", + [128760]="on", + [128768]="on", + [128769]="on", + [128770]="on", + [128771]="on", + [128772]="on", + [128773]="on", + [128774]="on", + [128775]="on", + [128776]="on", + [128777]="on", + [128778]="on", + [128779]="on", + [128780]="on", + [128781]="on", + [128782]="on", + [128783]="on", + [128784]="on", + [128785]="on", + [128786]="on", + [128787]="on", + [128788]="on", + [128789]="on", + [128790]="on", + [128791]="on", + [128792]="on", + [128793]="on", + [128794]="on", + [128795]="on", + [128796]="on", + [128797]="on", + [128798]="on", + [128799]="on", + [128800]="on", + [128801]="on", + [128802]="on", + [128803]="on", + [128804]="on", + [128805]="on", + [128806]="on", + [128807]="on", + [128808]="on", + [128809]="on", + [128810]="on", + [128811]="on", + [128812]="on", + [128813]="on", + [128814]="on", + [128815]="on", + [128816]="on", + [128817]="on", + [128818]="on", + [128819]="on", + [128820]="on", + [128821]="on", + [128822]="on", + [128823]="on", + [128824]="on", + [128825]="on", + [128826]="on", + [128827]="on", + [128828]="on", + [128829]="on", + [128830]="on", + [128831]="on", + [128832]="on", + [128833]="on", + [128834]="on", + [128835]="on", + [128836]="on", + [128837]="on", + [128838]="on", + [128839]="on", + [128840]="on", + [128841]="on", + [128842]="on", + [128843]="on", + [128844]="on", + [128845]="on", + [128846]="on", + [128847]="on", + [128848]="on", + [128849]="on", + [128850]="on", + [128851]="on", + [128852]="on", + [128853]="on", + [128854]="on", + [128855]="on", + [128856]="on", + [128857]="on", + [128858]="on", + [128859]="on", + [128860]="on", + [128861]="on", + [128862]="on", + [128863]="on", + [128864]="on", + [128865]="on", + [128866]="on", + [128867]="on", + [128868]="on", + [128869]="on", + [128870]="on", + [128871]="on", + [128872]="on", + [128873]="on", + [128874]="on", + [128875]="on", + [128876]="on", + [128877]="on", + [128878]="on", + [128879]="on", + [128880]="on", + [128881]="on", + [128882]="on", + [128883]="on", + [128896]="on", + [128897]="on", + [128898]="on", + [128899]="on", + [128900]="on", + [128901]="on", + [128902]="on", + [128903]="on", + [128904]="on", + [128905]="on", + [128906]="on", + [128907]="on", + [128908]="on", + [128909]="on", + [128910]="on", + [128911]="on", + [128912]="on", + [128913]="on", + [128914]="on", + [128915]="on", + [128916]="on", + [128917]="on", + [128918]="on", + [128919]="on", + [128920]="on", + [128921]="on", + [128922]="on", + [128923]="on", + [128924]="on", + [128925]="on", + [128926]="on", + [128927]="on", + [128928]="on", + [128929]="on", + [128930]="on", + [128931]="on", + [128932]="on", + [128933]="on", + [128934]="on", + [128935]="on", + [128936]="on", + [128937]="on", + [128938]="on", + [128939]="on", + [128940]="on", + [128941]="on", + [128942]="on", + [128943]="on", + [128944]="on", + [128945]="on", + [128946]="on", + [128947]="on", + [128948]="on", + [128949]="on", + [128950]="on", + [128951]="on", + [128952]="on", + [128953]="on", + [128954]="on", + [128955]="on", + [128956]="on", + [128957]="on", + [128958]="on", + [128959]="on", + [128960]="on", + [128961]="on", + [128962]="on", + [128963]="on", + [128964]="on", + [128965]="on", + [128966]="on", + [128967]="on", + [128968]="on", + [128969]="on", + [128970]="on", + [128971]="on", + [128972]="on", + [128973]="on", + [128974]="on", + [128975]="on", + [128976]="on", + [128977]="on", + [128978]="on", + [128979]="on", + [128980]="on", + [129024]="on", + [129025]="on", + [129026]="on", + [129027]="on", + [129028]="on", + [129029]="on", + [129030]="on", + [129031]="on", + [129032]="on", + [129033]="on", + [129034]="on", + [129035]="on", + [129040]="on", + [129041]="on", + [129042]="on", + [129043]="on", + [129044]="on", + [129045]="on", + [129046]="on", + [129047]="on", + [129048]="on", + [129049]="on", + [129050]="on", + [129051]="on", + [129052]="on", + [129053]="on", + [129054]="on", + [129055]="on", + [129056]="on", + [129057]="on", + [129058]="on", + [129059]="on", + [129060]="on", + [129061]="on", + [129062]="on", + [129063]="on", + [129064]="on", + [129065]="on", + [129066]="on", + [129067]="on", + [129068]="on", + [129069]="on", + [129070]="on", + [129071]="on", + [129072]="on", + [129073]="on", + [129074]="on", + [129075]="on", + [129076]="on", + [129077]="on", + [129078]="on", + [129079]="on", + [129080]="on", + [129081]="on", + [129082]="on", + [129083]="on", + [129084]="on", + [129085]="on", + [129086]="on", + [129087]="on", + [129088]="on", + [129089]="on", + [129090]="on", + [129091]="on", + [129092]="on", + [129093]="on", + [129094]="on", + [129095]="on", + [129104]="on", + [129105]="on", + [129106]="on", + [129107]="on", + [129108]="on", + [129109]="on", + [129110]="on", + [129111]="on", + [129112]="on", + [129113]="on", + [129120]="on", + [129121]="on", + [129122]="on", + [129123]="on", + [129124]="on", + [129125]="on", + [129126]="on", + [129127]="on", + [129128]="on", + [129129]="on", + [129130]="on", + [129131]="on", + [129132]="on", + [129133]="on", + [129134]="on", + [129135]="on", + [129136]="on", + [129137]="on", + [129138]="on", + [129139]="on", + [129140]="on", + [129141]="on", + [129142]="on", + [129143]="on", + [129144]="on", + [129145]="on", + [129146]="on", + [129147]="on", + [129148]="on", + [129149]="on", + [129150]="on", + [129151]="on", + [129152]="on", + [129153]="on", + [129154]="on", + [129155]="on", + [129156]="on", + [129157]="on", + [129158]="on", + [129159]="on", + [129168]="on", + [129169]="on", + [129170]="on", + [129171]="on", + [129172]="on", + [129173]="on", + [129174]="on", + [129175]="on", + [129176]="on", + [129177]="on", + [129178]="on", + [129179]="on", + [129180]="on", + [129181]="on", + [129182]="on", + [129183]="on", + [129184]="on", + [129185]="on", + [129186]="on", + [129187]="on", + [129188]="on", + [129189]="on", + [129190]="on", + [129191]="on", + [129192]="on", + [129193]="on", + [129194]="on", + [129195]="on", + [129196]="on", + [129197]="on", + [129280]="on", + [129281]="on", + [129282]="on", + [129283]="on", + [129284]="on", + [129285]="on", + [129286]="on", + [129287]="on", + [129288]="on", + [129289]="on", + [129290]="on", + [129291]="on", + [129296]="on", + [129297]="on", + [129298]="on", + [129299]="on", + [129300]="on", + [129301]="on", + [129302]="on", + [129303]="on", + [129304]="on", + [129305]="on", + [129306]="on", + [129307]="on", + [129308]="on", + [129309]="on", + [129310]="on", + [129311]="on", + [129312]="on", + [129313]="on", + [129314]="on", + [129315]="on", + [129316]="on", + [129317]="on", + [129318]="on", + [129319]="on", + [129320]="on", + [129321]="on", + [129322]="on", + [129323]="on", + [129324]="on", + [129325]="on", + [129326]="on", + [129327]="on", + [129328]="on", + [129329]="on", + [129330]="on", + [129331]="on", + [129332]="on", + [129333]="on", + [129334]="on", + [129335]="on", + [129336]="on", + [129337]="on", + [129338]="on", + [129339]="on", + [129340]="on", + [129341]="on", + [129342]="on", + [129344]="on", + [129345]="on", + [129346]="on", + [129347]="on", + [129348]="on", + [129349]="on", + [129350]="on", + [129351]="on", + [129352]="on", + [129353]="on", + [129354]="on", + [129355]="on", + [129356]="on", + [129360]="on", + [129361]="on", + [129362]="on", + [129363]="on", + [129364]="on", + [129365]="on", + [129366]="on", + [129367]="on", + [129368]="on", + [129369]="on", + [129370]="on", + [129371]="on", + [129372]="on", + [129373]="on", + [129374]="on", + [129375]="on", + [129376]="on", + [129377]="on", + [129378]="on", + [129379]="on", + [129380]="on", + [129381]="on", + [129382]="on", + [129383]="on", + [129384]="on", + [129385]="on", + [129386]="on", + [129387]="on", + [129408]="on", + [129409]="on", + [129410]="on", + [129411]="on", + [129412]="on", + [129413]="on", + [129414]="on", + [129415]="on", + [129416]="on", + [129417]="on", + [129418]="on", + [129419]="on", + [129420]="on", + [129421]="on", + [129422]="on", + [129423]="on", + [129424]="on", + [129425]="on", + [129426]="on", + [129427]="on", + [129428]="on", + [129429]="on", + [129430]="on", + [129431]="on", + [129472]="on", + [129488]="on", + [129489]="on", + [129490]="on", + [129491]="on", + [129492]="on", + [129493]="on", + [129494]="on", + [129495]="on", + [129496]="on", + [129497]="on", + [129498]="on", + [129499]="on", + [129500]="on", + [129501]="on", + [129502]="on", + [129503]="on", + [129504]="on", + [129505]="on", + [129506]="on", + [129507]="on", + [129508]="on", + [129509]="on", + [129510]="on", + [917505]="bn", + [917536]="bn", + [917537]="bn", + [917538]="bn", + [917539]="bn", + [917540]="bn", + [917541]="bn", + [917542]="bn", + [917543]="bn", + [917544]="bn", + [917545]="bn", + [917546]="bn", + [917547]="bn", + [917548]="bn", + [917549]="bn", + [917550]="bn", + [917551]="bn", + [917552]="bn", + [917553]="bn", + [917554]="bn", + [917555]="bn", + [917556]="bn", + [917557]="bn", + [917558]="bn", + [917559]="bn", + [917560]="bn", + [917561]="bn", + [917562]="bn", + [917563]="bn", + [917564]="bn", + [917565]="bn", + [917566]="bn", + [917567]="bn", + [917568]="bn", + [917569]="bn", + [917570]="bn", + [917571]="bn", + [917572]="bn", + [917573]="bn", + [917574]="bn", + [917575]="bn", + [917576]="bn", + [917577]="bn", + [917578]="bn", + [917579]="bn", + [917580]="bn", + [917581]="bn", + [917582]="bn", + [917583]="bn", + [917584]="bn", + [917585]="bn", + [917586]="bn", + [917587]="bn", + [917588]="bn", + [917589]="bn", + [917590]="bn", + [917591]="bn", + [917592]="bn", + [917593]="bn", + [917594]="bn", + [917595]="bn", + [917596]="bn", + [917597]="bn", + [917598]="bn", + [917599]="bn", + [917600]="bn", + [917601]="bn", + [917602]="bn", + [917603]="bn", + [917604]="bn", + [917605]="bn", + [917606]="bn", + [917607]="bn", + [917608]="bn", + [917609]="bn", + [917610]="bn", + [917611]="bn", + [917612]="bn", + [917613]="bn", + [917614]="bn", + [917615]="bn", + [917616]="bn", + [917617]="bn", + [917618]="bn", + [917619]="bn", + [917620]="bn", + [917621]="bn", + [917622]="bn", + [917623]="bn", + [917624]="bn", + [917625]="bn", + [917626]="bn", + [917627]="bn", + [917628]="bn", + [917629]="bn", + [917630]="bn", + [917631]="bn", + }, + ["mirrors"]={ + [40]=41, + [41]=40, + [60]=62, + [62]=60, + [91]=93, + [93]=91, + [123]=125, + [125]=123, + [171]=187, + [187]=171, + [3898]=3899, + [3899]=3898, + [3900]=3901, + [3901]=3900, + [5787]=5788, + [5788]=5787, + [8249]=8250, + [8250]=8249, + [8261]=8262, + [8262]=8261, + [8317]=8318, + [8318]=8317, + [8333]=8334, + [8334]=8333, + [8712]=8715, + [8713]=8716, + [8714]=8717, + [8715]=8712, + [8716]=8713, + [8717]=8714, + [8725]=10741, + [8764]=8765, + [8765]=8764, + [8771]=8909, + [8786]=8787, + [8787]=8786, + [8788]=8789, + [8789]=8788, + [8804]=8805, + [8805]=8804, + [8806]=8807, + [8807]=8806, + [8808]=8809, + [8809]=8808, + [8810]=8811, + [8811]=8810, + [8814]=8815, + [8815]=8814, + [8816]=8817, + [8817]=8816, + [8818]=8819, + [8819]=8818, + [8820]=8821, + [8821]=8820, + [8822]=8823, + [8823]=8822, + [8824]=8825, + [8825]=8824, + [8826]=8827, + [8827]=8826, + [8828]=8829, + [8829]=8828, + [8830]=8831, + [8831]=8830, + [8832]=8833, + [8833]=8832, + [8834]=8835, + [8835]=8834, + [8836]=8837, + [8837]=8836, + [8838]=8839, + [8839]=8838, + [8840]=8841, + [8841]=8840, + [8842]=8843, + [8843]=8842, + [8847]=8848, + [8848]=8847, + [8849]=8850, + [8850]=8849, + [8856]=10680, + [8866]=8867, + [8867]=8866, + [8870]=10974, + [8872]=10980, + [8873]=10979, + [8875]=10981, + [8880]=8881, + [8881]=8880, + [8882]=8883, + [8883]=8882, + [8884]=8885, + [8885]=8884, + [8886]=8887, + [8887]=8886, + [8905]=8906, + [8906]=8905, + [8907]=8908, + [8908]=8907, + [8909]=8771, + [8912]=8913, + [8913]=8912, + [8918]=8919, + [8919]=8918, + [8920]=8921, + [8921]=8920, + [8922]=8923, + [8923]=8922, + [8924]=8925, + [8925]=8924, + [8926]=8927, + [8927]=8926, + [8928]=8929, + [8929]=8928, + [8930]=8931, + [8931]=8930, + [8932]=8933, + [8933]=8932, + [8934]=8935, + [8935]=8934, + [8936]=8937, + [8937]=8936, + [8938]=8939, + [8939]=8938, + [8940]=8941, + [8941]=8940, + [8944]=8945, + [8945]=8944, + [8946]=8954, + [8947]=8955, + [8948]=8956, + [8950]=8957, + [8951]=8958, + [8954]=8946, + [8955]=8947, + [8956]=8948, + [8957]=8950, + [8958]=8951, + [8968]=8969, + [8969]=8968, + [8970]=8971, + [8971]=8970, + [9001]=9002, + [9002]=9001, + [10088]=10089, + [10089]=10088, + [10090]=10091, + [10091]=10090, + [10092]=10093, + [10093]=10092, + [10094]=10095, + [10095]=10094, + [10096]=10097, + [10097]=10096, + [10098]=10099, + [10099]=10098, + [10100]=10101, + [10101]=10100, + [10179]=10180, + [10180]=10179, + [10181]=10182, + [10182]=10181, + [10184]=10185, + [10185]=10184, + [10187]=10189, + [10189]=10187, + [10197]=10198, + [10198]=10197, + [10205]=10206, + [10206]=10205, + [10210]=10211, + [10211]=10210, + [10212]=10213, + [10213]=10212, + [10214]=10215, + [10215]=10214, + [10216]=10217, + [10217]=10216, + [10218]=10219, + [10219]=10218, + [10220]=10221, + [10221]=10220, + [10222]=10223, + [10223]=10222, + [10627]=10628, + [10628]=10627, + [10629]=10630, + [10630]=10629, + [10631]=10632, + [10632]=10631, + [10633]=10634, + [10634]=10633, + [10635]=10636, + [10636]=10635, + [10637]=10640, + [10638]=10639, + [10639]=10638, + [10640]=10637, + [10641]=10642, + [10642]=10641, + [10643]=10644, + [10644]=10643, + [10645]=10646, + [10646]=10645, + [10647]=10648, + [10648]=10647, + [10680]=8856, + [10688]=10689, + [10689]=10688, + [10692]=10693, + [10693]=10692, + [10703]=10704, + [10704]=10703, + [10705]=10706, + [10706]=10705, + [10708]=10709, + [10709]=10708, + [10712]=10713, + [10713]=10712, + [10714]=10715, + [10715]=10714, + [10741]=8725, + [10744]=10745, + [10745]=10744, + [10748]=10749, + [10749]=10748, + [10795]=10796, + [10796]=10795, + [10797]=10798, + [10798]=10797, + [10804]=10805, + [10805]=10804, + [10812]=10813, + [10813]=10812, + [10852]=10853, + [10853]=10852, + [10873]=10874, + [10874]=10873, + [10877]=10878, + [10878]=10877, + [10879]=10880, + [10880]=10879, + [10881]=10882, + [10882]=10881, + [10883]=10884, + [10884]=10883, + [10891]=10892, + [10892]=10891, + [10897]=10898, + [10898]=10897, + [10899]=10900, + [10900]=10899, + [10901]=10902, + [10902]=10901, + [10903]=10904, + [10904]=10903, + [10905]=10906, + [10906]=10905, + [10907]=10908, + [10908]=10907, + [10913]=10914, + [10914]=10913, + [10918]=10919, + [10919]=10918, + [10920]=10921, + [10921]=10920, + [10922]=10923, + [10923]=10922, + [10924]=10925, + [10925]=10924, + [10927]=10928, + [10928]=10927, + [10931]=10932, + [10932]=10931, + [10939]=10940, + [10940]=10939, + [10941]=10942, + [10942]=10941, + [10943]=10944, + [10944]=10943, + [10945]=10946, + [10946]=10945, + [10947]=10948, + [10948]=10947, + [10949]=10950, + [10950]=10949, + [10957]=10958, + [10958]=10957, + [10959]=10960, + [10960]=10959, + [10961]=10962, + [10962]=10961, + [10963]=10964, + [10964]=10963, + [10965]=10966, + [10966]=10965, + [10974]=8870, + [10979]=8873, + [10980]=8872, + [10981]=8875, + [10988]=10989, + [10989]=10988, + [10999]=11000, + [11000]=10999, + [11001]=11002, + [11002]=11001, + [11778]=11779, + [11779]=11778, + [11780]=11781, + [11781]=11780, + [11785]=11786, + [11786]=11785, + [11788]=11789, + [11789]=11788, + [11804]=11805, + [11805]=11804, + [11808]=11809, + [11809]=11808, + [11810]=11811, + [11811]=11810, + [11812]=11813, + [11813]=11812, + [11814]=11815, + [11815]=11814, + [11816]=11817, + [11817]=11816, + [12296]=12297, + [12297]=12296, + [12298]=12299, + [12299]=12298, + [12300]=12301, + [12301]=12300, + [12302]=12303, + [12303]=12302, + [12304]=12305, + [12305]=12304, + [12308]=12309, + [12309]=12308, + [12310]=12311, + [12311]=12310, + [12312]=12313, + [12313]=12312, + [12314]=12315, + [12315]=12314, + [65113]=65114, + [65114]=65113, + [65115]=65116, + [65116]=65115, + [65117]=65118, + [65118]=65117, + [65124]=65125, + [65125]=65124, + [65288]=65289, + [65289]=65288, + [65308]=65310, + [65310]=65308, + [65339]=65341, + [65341]=65339, + [65371]=65373, + [65373]=65371, + [65375]=65376, + [65376]=65375, + [65378]=65379, + [65379]=65378, + }, + ["textclasses"]={ + [40]="open", + [41]="close", + [60]="open", + [62]="close", + [91]="open", + [93]="close", + [123]="open", + [125]="close", + [171]="open", + [187]="close", + [8249]="open", + [8250]="close", + [8317]="open", + [8318]="close", + [8333]="open", + [8334]="close", + [10647]="open", + [10648]="close", + [65113]="open", + [65114]="close", + [65115]="open", + [65116]="close", + [65117]="open", + [65118]="close", + [65124]="open", + [65125]="close", + [65288]="open", + [65289]="close", + [65308]="open", + [65310]="close", + [65339]="open", + [65341]="close", + [65371]="open", + [65373]="close", + [65375]="open", + [65376]="close", + [65378]="open", + [65379]="close", + }, +} diff --git a/context/data/textadept/context/init.lua b/context/data/textadept/context/init.lua index 2aefb970f..9d89d2c0a 100644 --- a/context/data/textadept/context/init.lua +++ b/context/data/textadept/context/init.lua @@ -66,4 +66,78 @@ require("textadept-context-types") -- This prevents other themes to spoil our settings. -ui.set_theme("scite-context-theme") +-- ui.set_theme("scite-context-theme") +buffer:set_theme("scite-context-theme") + +-- Since version 10 there is some settings stuff in the main init file but that +-- crashes on load_settings. It has to do with the replacement of properties +-- but we already had that replaced for a while. There is some blob made that +-- gets loaded but it's not robust (should be done different I think). Anyway, +-- intercepting the two event handlers is easiest. Maybe some day I will +-- replace that init anyway (if these fundamentals keep changing between +-- versions.) +-- +-- I admit that it's not a beautiful solution but it works ok and I already +-- spent too much time figuring things out anyway. + +local events_connect = events.connect + +local function events_newbuffer() + local buffer = _G.buffer + local SETDIRECTFUNCTION = _SCINTILLA.properties.direct_function[1] + local SETDIRECTPOINTER = _SCINTILLA.properties.doc_pointer[2] + local SETLUASTATE = _SCINTILLA.functions.change_lexer_state[1] + local SETLEXERLANGUAGE = _SCINTILLA.properties.lexer_language[2] + buffer.lexer_language = 'lpeg' + buffer:private_lexer_call(SETDIRECTFUNCTION, buffer.direct_function) + buffer:private_lexer_call(SETDIRECTPOINTER, buffer.direct_pointer) + buffer:private_lexer_call(SETLUASTATE, _LUA) + buffer.property['lexer.lpeg.home'] = _USERHOME..'/lexers/?.lua;'.. _HOME..'/lexers' + -- load_settings() + buffer:private_lexer_call(SETLEXERLANGUAGE, 'text') + if buffer == ui.command_entry then + buffer.caret_line_visible = false + end +end + +-- Why these resets: + +local ctrl_keys = { + '[', ']', '/', '\\', 'Z', 'Y', 'X', 'C', 'V', 'A', 'L', 'T', 'D', 'U' +} + +local ctrl_shift_keys = { + 'L', 'T', 'U', 'Z' +} + +local function events_newview() + local buffer = _G.buffer + for i=1, #ctrl_keys do + buffer:clear_cmd_key(string.byte(ctrl_keys[i]) | buffer.MOD_CTRL << 16) + end + for i=1, #ctrl_shift_keys do + buffer:clear_cmd_key(string.byte(ctrl_shift_keys[i]) | (buffer.MOD_CTRL | buffer.MOD_SHIFT) << 16) + end + if #_VIEWS > 1 then + -- load_settings() + local SETLEXERLANGUAGE = _SCINTILLA.properties.lexer_language[2] + buffer:private_lexer_call(SETLEXERLANGUAGE, buffer._lexer or 'text') + end +end + +events.connect = function(where,what,location) + if location == 1 then + if where == events.BUFFER_NEW then + return events_connect(where,events_newbuffer,location) + elseif where == events.VIEW_NEW then + return events_connect(where,events_newview,location) + end + end + return events_connect(where,what,location) +end + +local savedrequire = require + +require = function(name,...) + return savedrequire(name == "lexer" and "scite-context-lexer" or name,...) +end diff --git a/context/data/textadept/context/lexers/lexer.lua b/context/data/textadept/context/lexers/lexer.lua new file mode 100644 index 000000000..0a752e412 --- /dev/null +++ b/context/data/textadept/context/lexers/lexer.lua @@ -0,0 +1,2662 @@ +local info = { + version = 1.400, + comment = "basics for scintilla lpeg lexer for context/metafun", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files", + comment = "contains copyrighted code from mitchell.att.foicica.com", + +} + +-- We need a copy of this file to lexer.lua in the same path. This was not needed +-- before version 10 but I can't figure out what else to do. It looks like there +-- is some loading of lexer.lua but I can't see where. + +if lpeg.setmaxstack then lpeg.setmaxstack(1000) end + +local log = false +local trace = false +local detail = false +local show = false -- nice for tracing (also for later) +local collapse = false -- can save some 15% (maybe easier on scintilla) +local inspect = false -- can save some 15% (maybe easier on scintilla) + +-- local log = true +-- local trace = true + +-- GET GOING +-- +-- You need to copy this file over lexer.lua. In principle other lexers could work +-- too but not now. Maybe some day. All patterns will move into the patterns name +-- space. I might do the same with styles. If you run an older version of SciTE you +-- can take one of the archives. Pre 3.41 versions can just be copied to the right +-- path, as there we still use part of the normal lexer. Below we mention some +-- issues with different versions of SciTE. We try to keep up with changes but best +-- check careful if the version that yuou install works as expected because SciTE +-- and the scintillua dll need to be in sync. +-- +-- REMARK +-- +-- We started using lpeg lexing as soon as it came available. Because we had rather +-- demanding files and also wanted to use nested lexers, we ended up with our own +-- variant. At least at that time this was more robust and also much faster (as we +-- have some pretty large Lua data files and also work with large xml files). As a +-- consequence successive versions had to be adapted to changes in the (at that time +-- still unstable) api. In addition to lexing we also have spell checking and such. +-- Around version 3.60 things became more stable so I don't expect to change much. +-- +-- LEXING +-- +-- When pc's showed up we wrote our own editor (texedit) in MODULA 2. It was fast, +-- had multiple overlapping (text) windows, could run in the at most 1M memory at +-- that time, etc. The realtime file browsing with lexing that we had at that time +-- is still on my current wish list. The color scheme and logic that we used related +-- to the logic behind the ConTeXt user interface that evolved. +-- +-- Later I rewrote the editor in perl/tk. I don't like the perl syntax but tk +-- widgets are very powerful and hard to beat. In fact, TextAdept reminds me of +-- that: wrap your own interface around a framework (tk had an edit control that one +-- could control completely not that different from scintilla). Last time I checked +-- it still ran fine so I might try to implement something like its file handling in +-- TextAdept. +-- +-- In the end I settled for SciTE for which I wrote TeX and MetaPost lexers that +-- could handle keyword sets. With respect to lexing (syntax highlighting) ConTeXt +-- has a long history, if only because we need it for manuals. Anyway, in the end we +-- arrived at lpeg based lexing (which is quite natural as we have lots of lpeg +-- usage in ConTeXt). The basic color schemes haven't changed much. The most +-- prominent differences are the nested lexers. +-- +-- In the meantime I made the lexer suitable for typesetting sources which was no +-- big deal as we already had that in place (ConTeXt used lpeg from the day it +-- showed up so we have several lexing options there too). +-- +-- Keep in mind that in ConTeXt (typesetting) lexing can follow several approached: +-- line based (which is handy for verbatim mode), syntax mode (which is nice for +-- tutorials), and tolerant mode (so that one can also show bad examples or errors). +-- These demands can clash. +-- +-- HISTORY +-- +-- The remarks below are more for myself so that I keep track of changes in the +-- way we adapt to the changes in the scintillua and scite. +-- +-- The fold and lex functions are copied and patched from original code by Mitchell +-- (see lexer.lua) in the scintillua distribution. So whatever I say below, assume +-- that all errors are mine. The ability to use lpeg in scintilla is a real nice +-- addition and a brilliant move. The code is a byproduct of the (mainly Lua based) +-- TextAdept which at the time I ran into it was a rapidly moving target so I +-- decided to stick ot SciTE. When I played with it, it had no realtime output pane +-- although that seems to be dealt with now (2017). I need to have a look at it in +-- more detail but a first test again made the output hang and it was a bit slow too +-- (and I also want the log pane as SciTE has it, on the right, in view). So, for +-- now I stick to SciTE even when it's somewhat crippled by the fact that we cannot +-- hook our own (language dependent) lexer into the output pane (somehow the +-- errorlist lexer is hard coded into the editor). Hopefully that will change some +-- day. The ConTeXt distribution has cmd runner for textdept that will plug in the +-- lexers discussed here as well as a dedicated runner. Considere it an experiment. +-- +-- The basic code hasn't changed much but we had to adapt a few times to changes in +-- the api and/or work around bugs. Starting with SciTE version 3.20 there was an +-- issue with coloring. We still lacked a connection with SciTE itself (properties +-- as well as printing to the log pane) and we could not trace this (on windows). +-- However on unix we can see messages! As far as I can see, there are no +-- fundamental changes in lexer.lua or LexLPeg.cxx so it must be/have been in +-- Scintilla itself. So we went back to 3.10. Indicators of issues are: no lexing of +-- 'next' and 'goto <label>' in the Lua lexer and no brace highlighting either. +-- Interesting is that it does work ok in the cld lexer (so the Lua code is okay). +-- All seems to be ok again in later versions, so, when you update best check first +-- and just switch back to an older version as normally a SciTE update is not +-- critital. When char-def.lua lexes real fast this is a signal that the lexer quits +-- somewhere halfway. Maybe there are some hard coded limitations on the amount of +-- styles and/or length of names. +-- +-- Anyway, after checking 3.24 and adapting to the new lexer tables things are okay +-- again. So, this version assumes 3.24 or higher. In 3.24 we have a different token +-- result, i.e. no longer a { tag, pattern } but just two return values. I didn't +-- check other changes but will do that when I run into issues. I had already +-- optimized these small tables by hashing which was much more efficient (and maybe +-- even more efficient than the current approach) but this is no longer needed. For +-- the moment we keep some of that code around as I don't know what happens in +-- future versions. I'm anyway still happy with this kind of lexing. +-- +-- In 3.31 another major change took place: some helper constants (maybe they're no +-- longer constants) and functions were moved into the lexer modules namespace but +-- the functions are assigned to the Lua module afterward so we cannot alias them +-- beforehand. We're probably getting close to a stable interface now. At that time +-- for the first time I considered making a whole copy and patch the other functions +-- too as we need an extra nesting model. However, I don't want to maintain too +-- much. An unfortunate change in 3.03 is that no longer a script can be specified. +-- This means that instead of loading the extensions via the properties file, we now +-- need to load them in our own lexers, unless of course we replace lexer.lua +-- completely (which adds another installation issue). +-- +-- Another change has been that _LEXERHOME is no longer available. It looks like +-- more and more functionality gets dropped so maybe at some point we need to ship +-- our own dll/so files. For instance, I'd like to have access to the current +-- filename and other SciTE properties. We could then cache some info with each +-- file, if only we had knowledge of what file we're dealing with. This all makes a +-- nice installation more complex and (worse) makes it hard to share files between +-- different editors usign s similar directory structure. +-- +-- For huge files folding can be pretty slow and I do have some large ones that I +-- keep open all the time. Loading is normally no ussue, unless one has remembered +-- the status and the cursor is at the last line of a 200K line file. Optimizing the +-- fold function brought down loading of char-def.lua from 14 sec => 8 sec. +-- Replacing the word_match function and optimizing the lex function gained another +-- 2+ seconds. A 6 second load is quite ok for me. The changed lexer table structure +-- (no subtables) brings loading down to a few seconds. +-- +-- When the lexer path is copied to the TextAdept lexer path, and the theme +-- definition to theme path (as lexer.lua), the lexer works there as well. Although +-- ... when I decided to check the state of TextAdept I had to adapt some loader +-- code. The solution is not pretty but works and also permits overloading. When I +-- have time and motive I will make a proper setup file to tune the look and feel a +-- bit more than we do now. The TextAdept editor nwo has tabs and a console so it +-- has become more useable for me (it's still somewhat slower than SciTE). +-- Interesting is that the jit version of TextAdept crashes on lexing large files +-- (and does not feel faster either; maybe a side effect of known limitations as we +-- know that Luajit is more limited than stock Lua). +-- +-- Function load(lexer_name) starts with _lexers.WHITESPACE = lexer_name .. +-- '_whitespace' which means that we need to have it frozen at the moment we load +-- another lexer. Because spacing is used to revert to a parent lexer we need to +-- make sure that we load children as late as possible in order not to get the wrong +-- whitespace trigger. This took me quite a while to figure out (not being that +-- familiar with the internals). The lex and fold functions have been optimized. It +-- is a pitty that there is no proper print available. Another thing needed is a +-- default style in our own theme style definition, as otherwise we get wrong nested +-- lexers, especially if they are larger than a view. This is the hardest part of +-- getting things right. +-- +-- It's a pitty that there is no scintillua library for the OSX version of SciTE. +-- Even better would be to have the scintillua library as integral part of SciTE as +-- that way I could use OSX alongside windows and linux (depending on needs). Also +-- nice would be to have a proper interface to SciTE then because currently the +-- lexer is rather isolated and the Lua version does not provide all standard +-- libraries. It would also be good to have lpeg support in the regular SciTE Lua +-- extension (currently you need to pick it up from someplace else). I keep hoping. +-- +-- With 3.41 the interface changed again so it became time to look into the C++ code +-- and consider compiling and patching myself, something that I like to avoid. +-- Loading is more complicated now as the lexer gets loaded automatically so we have +-- little control over extending the code now. After a few days trying all kind of +-- solutions I decided to follow a different approach: drop in a complete +-- replacement. This of course means that I need to keep track of even more changes +-- (which for sure will happen) but at least I get rid of interferences. Till 3.60 +-- the api (lexing and configuration) was simply too unstable across versions which +-- is a pitty because we expect authors to install SciTE without hassle. Maybe in a +-- few years things will have stabelized. Maybe it's also not really expected that +-- one writes lexers at all. A side effect is that I now no longer will use shipped +-- lexers for languages that I made no lexer for, but just the built-in ones in +-- addition to the ConTeXt lpeg lexers. Not that it matters much as the ConTeXt +-- lexers cover what I need (and I can always write more). For editing TeX files one +-- only needs a limited set of lexers (TeX, MetaPost, Lua, BibTeX, C/W, PDF, SQL, +-- etc). I can add more when I want. +-- +-- In fact, the transition to 3.41 was triggered by an unfateful update of Ubuntu +-- which left me with an incompatible SciTE and lexer library and updating was not +-- possible due to the lack of 64 bit libraries. We'll see what the future brings. +-- For now I can use SciTE under wine on linux. The fact that scintillua ships +-- independently is a showstopper. +-- +-- Promissing is that the library now can use another Lua instance so maybe some day +-- it will get properly in SciTE and we can use more clever scripting. +-- +-- In some lexers we use embedded ones even if we could do it directly, The reason +-- is that when the end token is edited (e.g. -->), backtracking to the space before +-- the begin token (e.g. <!--) results in applying the surrounding whitespace which +-- in turn means that when the end token is edited right, backtracking doesn't go +-- back. One solution (in the dll) would be to backtrack several space categories. +-- After all, lexing is quite fast (applying the result is much slower). +-- +-- For some reason the first blob of text tends to go wrong (pdf and web). It would +-- be nice to have 'whole doc' initial lexing. Quite fishy as it makes it impossible +-- to lex the first part well (for already opened documents) because only a partial +-- text is passed. +-- +-- So, maybe I should just write this from scratch (assuming more generic usage) +-- because after all, the dll expects just tables, based on a string. I can then +-- also do some more aggressive resource sharing (needed when used generic). +-- +-- I think that nested lexers are still bugged (esp over longer ranges). It never +-- was robust or maybe it's simply not meant for too complex cases (well, it +-- probably *is* tricky material). The 3.24 version was probably the best so far. +-- The fact that styles bleed between lexers even if their states are isolated is an +-- issue. Another issus is that zero characters in the text passed to the lexer can +-- mess things up (pdf files have them in streams). +-- +-- For more complex 'languages', like web or xml, we need to make sure that we use +-- e.g. 'default' for spacing that makes up some construct. Ok, we then still have a +-- backtracking issue but less. +-- +-- Good news for some ConTeXt users: there is now a scintillua plugin for notepad++ +-- and we ship an ini file for that editor with some installation instructions +-- embedded. Also, TextAdept has a console so that we can run realtime. The spawner +-- is still not perfect (sometimes hangs) but it was enough reason to spend time on +-- making our lexer work with TextAdept and create a setup. +-- +-- Some bad news. The interface changed (again) in textadept 10, some for the better +-- (but a bit different from what happens here) and some for the worse, especially +-- moving some code to the init file so we now need some bad hacks. I decided to +-- stay with the old method of defining lexers and because the lexer cannot be run +-- in parallel any more (some change in the binary?) I will probably also cleanup +-- code below as we no longer need to be compatible. Unfortunately textadept is too +-- much a moving target to simply kick in some (tex related) production flow (apart +-- from the fact that it doesn't yet have the scite like realtime console). I'll +-- keep an eye on it. Because we don't need many added features I might as well decide +-- to make a lean and mean instance (after all the license permits forking). + +-- TRACING +-- +-- The advantage is that we now can check more easily with regular Lua(TeX). We can +-- also use wine and print to the console (somehow stdout is intercepted there.) So, +-- I've added a bit of tracing. Interesting is to notice that each document gets its +-- own instance which has advantages but also means that when we are spellchecking +-- we reload the word lists each time. (In the past I assumed a shared instance and +-- took some precautions. But I can fix this.) +-- +-- TODO +-- +-- It would be nice if we could loads some ConTeXt Lua modules (the basic set) and +-- then use resolvers and such. But it might not work well with scite. +-- +-- The current lexer basics are still a mix between old and new. Maybe I should redo +-- some more. This is probably easier in TextAdept than in SciTE. +-- +-- We have to make sure we don't overload ConTeXt definitions when this code is used +-- in ConTeXt. I still have to add some of the goodies that we have there in lexers +-- into these. +-- +-- Maybe I should use a special stripped on the one hand and extended version of the +-- dll (stable api) and at least add a bit more interfacing to scintilla. +-- +-- I need to investigate if we can use the already built in Lua instance so that we +-- can combine the power of lexing with extensions. +-- +-- I need to play with hotspot and other properties like indicators (whatever they +-- are). +-- +-- I want to get rid of these lexers.STYLE_XX and lexers.XX things. This is possible +-- when we give up compatibility. Generalize the helpers that I wrote for SciTE so +-- that they also can be used TextAdept. +-- +-- I can make an export to ConTeXt, but first I'll redo the code that makes the +-- grammar, as we only seem to need +-- +-- lexer._TOKENSTYLES : table +-- lexer._CHILDREN : flag +-- lexer._EXTRASTYLES : table +-- lexer._GRAMMAR : flag +-- +-- lexers.load : function +-- lexers.lex : function +-- +-- So, if we drop compatibility with other lex definitions, we can make things +-- simpler. However, in the meantime one can just do this: +-- +-- context --extra=listing --scite [--compact --verycompact] somefile.tex +-- +-- and get a printable document. So, this todo is a bit obsolete. +-- +-- Properties is an ugly mess ... due to chages in the interface we're now left +-- with some hybrid that sort of works ok + +-- textadept: buffer:colourise(0,-1) + +local lpeg = require("lpeg") + +local global = _G +local find, gmatch, match, lower, upper, gsub, sub, format, byte = string.find, string.gmatch, string.match, string.lower, string.upper, string.gsub, string.sub, string.format, string.byte +local concat, sort = table.concat, table.sort +local type, next, setmetatable, rawset, tonumber, tostring = type, next, setmetatable, rawset, tonumber, tostring +local R, P, S, V, C, Cp, Cs, Ct, Cmt, Cc, Cf, Cg, Carg = lpeg.R, lpeg.P, lpeg.S, lpeg.V, lpeg.C, lpeg.Cp, lpeg.Cs, lpeg.Ct, lpeg.Cmt, lpeg.Cc, lpeg.Cf, lpeg.Cg, lpeg.Carg +local lpegmatch = lpeg.match + +local usage = (textadept and "textadept") or (resolvers and "context") or "scite" +local nesting = 0 +local output = nil + +----- print = textadept and ui and ui.print or print -- crashes when ui is not yet defined + +local function print(...) + if not output then + output = io.open("lexer.log","w") + end + output:write(...,"\n") + output:flush() +end + +local function report(fmt,str,...) + if log then + if str then + fmt = format(fmt,str,...) + end + print(format("scite lpeg lexer > %s > %s",nesting == 0 and "-" or nesting,fmt)) + end +end + +local function inform(...) + if log and trace then + report(...) + end +end + +inform("loading context lexer module (global table: %s)",tostring(global)) + +do + + local floor = math and math.floor + local format = format + local tonumber = tonumber + + if not floor then + + if tonumber(string.match(_VERSION,"%d%.%d")) < 5.3 then + floor = function(n) + return tonumber(format("%d",n)) + end + else + -- 5.3 has a mixed number system and format %d doesn't work with + -- floats any longer ... no fun + floor = function(n) + return (n - n % 1) + end + end + + math = math or { } + + math.floor = floor + + end + +end + +local floor = math.floor + +if not package.searchpath then + + -- Unfortunately the io library is only available when we end up + -- in this branch of code. + + inform("using adapted function 'package.searchpath' (if used at all)") + + function package.searchpath(name,path) + local tried = { } + for part in gmatch(path,"[^;]+") do + local filename = gsub(part,"%?",name) + local f = io.open(filename,"r") + if f then + inform("file found on path: %s",filename) + f:close() + return filename + end + tried[#tried + 1] = format("no file '%s'",filename) + end + -- added: local path .. for testing + local f = io.open(filename,"r") + if f then + inform("file found on current path: %s",filename) + f:close() + return filename + end + -- + tried[#tried + 1] = format("no file '%s'",filename) + return nil, concat(tried,"\n") + end + +end + +local lexers = { } +local context = { } +local helpers = { } +lexers.context = context +lexers.helpers = helpers + +local patterns = { } +context.patterns = patterns -- todo: lexers.patterns + +context.report = report +context.inform = inform + +lexers.LEXERPATH = package.path -- can be multiple paths separated by ; + +if resolvers then + -- todo: set LEXERPATH + -- todo: set report +end + +local function sortedkeys(hash) -- simple version, good enough for here + local t, n = { }, 0 + for k, v in next, hash do + t[#t+1] = k + local l = #tostring(k) + if l > n then + n = l + end + end + sort(t) + return t, n +end + +helpers.sortedkeys = sortedkeys + +local usedlexers = { } +local parent_lexer = nil + +-- The problem with styles is that there is some nasty interaction with scintilla +-- and each version of lexer dll/so has a different issue. So, from now on we will +-- just add them here. There is also a limit on some 30 styles. Maybe I should +-- hash them in order to reuse. + +-- todo: work with proper hashes and analyze what styles are really used by a +-- lexer + +local default = { + "nothing", "whitespace", "comment", "string", "number", "keyword", + "identifier", "operator", "error", "preprocessor", "constant", "variable", + "function", "type", "label", "embedded", + "quote", "special", "extra", "reserved", "okay", "warning", + "command", "internal", "preamble", "grouping", "primitive", "plain", + "user", + -- not used (yet) .. we cross the 32 boundary so had to patch the initializer, see (1) + "char", "class", "data", "definition", "invisible", "regex", + "standout", "tag", + "text", +} + +local predefined = { + "default", "linenumber", "bracelight", "bracebad", "controlchar", + "indentguide", "calltip", + -- seems new + "folddisplaytext" +} + +-- Bah ... ugly ... nicer would be a proper hash .. we now have properties +-- as well as STYLE_* and some connection between them ... why .. ok, we +-- could delay things but who cares. Anyway, at this moment the properties +-- are still unknown. + +local function preparestyles(list) + local reverse = { } + for i=1,#list do + local k = list[i] + local K = upper(k) + local s = "style." .. k + lexers[K] = k -- is this used + lexers["STYLE_"..K] = "$(" .. k .. ")" + reverse[k] = true + end + return reverse +end + +local defaultstyles = preparestyles(default) +local predefinedstyles = preparestyles(predefined) + +-- These helpers are set afterwards so we delay their initialization ... there +-- is no need to alias each time again and this way we can more easily adapt +-- to updates. + +-- These keep changing (values, functions, tables ...) so we nee to check these +-- with each update. Some of them are set in the loader (the require 'lexer' is +-- in fact not a real one as the lexer code is loaded in the dll). It's also not +-- getting more efficient. + +-- FOLD_BASE = lexers.FOLD_BASE or SC_FOLDLEVELBASE +-- FOLD_HEADER = lexers.FOLD_HEADER or SC_FOLDLEVELHEADERFLAG +-- FOLD_BLANK = lexers.FOLD_BLANK or SC_FOLDLEVELWHITEFLAG +-- get_style_at = lexers.get_style_at or GetStyleAt +-- get_indent_amount = lexers.get_indent_amount or GetIndentAmount +-- get_property = lexers.get_property or GetProperty +-- get_fold_level = lexers.get_fold_level or GetFoldLevel + +-- It needs checking: do we have access to all properties now? I'll clean +-- this up anyway as I want a simple clean and stable model. + +-- This is somewhat messy. The lexer dll provides some virtual fields: +-- +-- + property +-- + property_int +-- + style_at +-- + fold_level +-- + indent_amount +-- +-- but for some reasons not: +-- +-- + property_expanded +-- +-- As a consequence we need to define it here because otherwise the +-- lexer will crash. The fuzzy thing is that we don't have to define +-- the property and property_int tables but we do have to define the +-- expanded beforehand. The folding properties are no longer interfaced +-- so the interface to scite is now rather weak (only a few hard coded +-- properties). + +local FOLD_BASE = 0 +local FOLD_HEADER = 0 +local FOLD_BLANK = 0 + +local style_at = { } +local indent_amount = { } +local fold_level = { } + +local function check_main_properties() + if not lexers.property then + lexers.property = { } + end + if not lexers.property_int then + lexers.property_int = setmetatable({ }, { + __index = function(t,k) + -- why the tostring .. it relies on lua casting to a number when + -- doing a comparison + return tonumber(lexers.property[k]) or 0 -- tostring removed + end, + -- __newindex = function(t,k,v) + -- report("properties are read-only, '%s' is not changed",k) + -- end, + }) + end +end + +lexers.property_expanded = setmetatable({ }, { + __index = function(t,k) + -- better be safe for future changes .. what if at some point this is + -- made consistent in the dll ... we need to keep an eye on that + local property = lexers.property + if not property then + check_main_properties() + end + -- +-- return gsub(property[k],"[$%%]%b()", function(k) +-- return t[sub(k,3,-2)] +-- end) + local v = property[k] + if v then + v = gsub(v,"[$%%]%b()", function(k) + return t[sub(k,3,-2)] + end) + end + return v + end, + __newindex = function(t,k,v) + report("properties are read-only, '%s' is not changed",k) + end, +}) + +-- A downward compatible feature but obsolete: + +-- local function get_property(tag,default) +-- return lexers.property_int[tag] or lexers.property[tag] or default +-- end + +-- We still want our own properties (as it keeps changing so better play +-- safe from now on). At some point I can freeze them. + +local function check_properties(lexer) + if lexer.properties then + return lexer + end + check_main_properties() + -- we use a proxy + local mainproperties = lexers.property + local properties = { } + local expanded = setmetatable({ }, { + __index = function(t,k) + return gsub(properties[k] or mainproperties[k],"[$%%]%b()", function(k) + return t[sub(k,3,-2)] + end) + end, + }) + lexer.properties = setmetatable(properties, { + __index = mainproperties, + __call = function(t,k,default) -- expands + local v = expanded[k] + local t = type(default) + if t == "number" then + return tonumber(v) or default + elseif t == "boolean" then + return v == nil and default or v + else + return v or default + end + end, + }) + return lexer +end + +-- do +-- lexers.property = { foo = 123, red = "R" } +-- local a = check_properties({}) print("a.foo",a.properties.foo) +-- a.properties.foo = "bar" print("a.foo",a.properties.foo) +-- a.properties.foo = "bar:$(red)" print("a.foo",a.properties.foo) print("a.foo",a.properties("foo")) +-- end + +local function set(value,default) + if value == 0 or value == false or value == "0" then + return false + elseif value == 1 or value == true or value == "1" then + return true + else + return default + end +end + +local function check_context_properties() + local property = lexers.property -- let's hope that this stays + log = set(property["lexer.context.log"], log) + trace = set(property["lexer.context.trace"], trace) + detail = set(property["lexer.context.detail"], detail) + show = set(property["lexer.context.show"], show) + collapse = set(property["lexer.context.collapse"],collapse) + inspect = set(property["lexer.context.inspect"], inspect) +end + +function context.registerproperties(p) -- global + check_main_properties() + local property = lexers.property -- let's hope that this stays + for k, v in next, p do + property[k] = v + end + check_context_properties() +end + +context.properties = setmetatable({ }, { + __index = lexers.property, + __newindex = function(t,k,v) + check_main_properties() + lexers.property[k] = v + check_context_properties() + end, +}) + +-- We want locals to we set them delayed. Once. + +local function initialize() + FOLD_BASE = lexers.FOLD_BASE + FOLD_HEADER = lexers.FOLD_HEADER + FOLD_BLANK = lexers.FOLD_BLANK + -- + style_at = lexers.style_at -- table + indent_amount = lexers.indent_amount -- table + fold_level = lexers.fold_level -- table + -- + check_main_properties() + -- + initialize = nil +end + +-- Style handler. +-- +-- The property table will be set later (after loading) by the library. The +-- styleset is not needed any more as we predefine all styles as defaults +-- anyway (too bug sensitive otherwise). + +local function tocolors(colors) + local colorset = { } + local property_int = lexers.property_int or { } + for k, v in next, colors do + if type(v) == "table" then + local r, g, b = v[1], v[2], v[3] + if r and g and b then + v = tonumber(format("%02X%02X%02X",b,g,r),16) or 0 -- hm + elseif r then + v = tonumber(format("%02X%02X%02X",r,r,r),16) or 0 + else + v = 0 + end + end + colorset[k] = v + property_int["color."..k] = v + end + return colorset +end + +local function toproperty(specification) + local serialized = { } + for key, value in next, specification do + if value == true then + serialized[#serialized+1] = key + elseif type(value) == "table" then + local r, g, b = value[1], value[2], value[3] + if r and g and b then + value = format("#%02X%02X%02X",r,g,b) or "#000000" + elseif r then + value = format("#%02X%02X%02X",r,r,r) or "#000000" + else + value = "#000000" + end + serialized[#serialized+1] = key .. ":" .. value + else + serialized[#serialized+1] = key .. ":" .. tostring(value) + end + end + return concat(serialized,",") +end + +local function tostyles(styles) + local styleset = { } + local property = lexers.property or { } + for k, v in next, styles do + v = toproperty(v) + styleset[k] = v + property["style."..k] = v + end + return styleset +end + +context.toproperty = toproperty +context.tostyles = tostyles +context.tocolors = tocolors + +-- If we had one instance/state of Lua as well as all regular libraries +-- preloaded we could use the context base libraries. So, let's go poor- +-- mans solution now. + +function context.registerstyles(styles) + local styleset = tostyles(styles) + context.styles = styles + context.styleset = styleset + if detail then + local t, n = sortedkeys(styleset) + local template = " %-" .. n .. "s : %s" + report("initializing styleset:") + for i=1,#t do + local k = t[i] + report(template,k,styleset[k]) + end + elseif trace then + report("initializing styleset") + end +end + +function context.registercolors(colors) -- needed for textadept + local colorset = tocolors(colors) + context.colors = colors + context.colorset = colorset + if detail then + local t, n = sortedkeys(colorset) + local template = " %-" .. n .. "s : %i" + report("initializing colorset:") + for i=1,#t do + local k = t[i] + report(template,k,colorset[k]) + end + elseif trace then + report("initializing colorset") + end +end + +-- Some spell checking related stuff. Unfortunately we cannot use a path set +-- by property. This will get a hook for resolvers. + +local locations = { + "context/lexers", -- context lexers + "context/lexers/data", -- context lexers + "../lexers", -- original lexers + "../lexers/data", -- original lexers + ".", -- whatever + "./data", -- whatever +} + +-- local function collect(name) +-- local root = gsub(lexers.LEXERPATH or ".","/.-lua$","") .. "/" -- this is a horrible hack +-- -- report("module '%s' locating '%s'",tostring(lexers),name) +-- for i=1,#locations do +-- local fullname = root .. locations[i] .. "/" .. name .. ".lua" -- so we can also check for .luc +-- if trace then +-- report("attempt to locate '%s'",fullname) +-- end +-- local okay, result = pcall(function () return dofile(fullname) end) +-- if okay then +-- return result, fullname +-- end +-- end +-- end + +local collect + +if usage == "context" then + + collect = function(name) + return require(name), name + end + +else + + collect = function(name) + local rootlist = lexers.LEXERPATH or "." + for root in gmatch(rootlist,"[^;]+") do + local root = gsub(root,"/[^/]-lua$","") + for i=1,#locations do + local fullname = root .. "/" .. locations[i] .. "/" .. name .. ".lua" -- so we can also check for .luc + if trace then + report("attempt to locate '%s'",fullname) + end + local okay, result = pcall(function () return dofile(fullname) end) + if okay then + return result, fullname + end + end + end + -- return require(name), name + end + +end + +function context.loadluafile(name) + local data, fullname = collect(name) + if data then + if trace then + report("lua file '%s' has been loaded",fullname) + end + return data, fullname + end + if not textadept then + report("unable to load lua file '%s'",name) + end +end + +-- in fact we could share more as we probably process the data but then we need +-- to have a more advanced helper + +local cache = { } + +function context.loaddefinitions(name) + local data = cache[name] + if data then + if trace then + report("reusing definitions '%s'",name) + end + return data + elseif trace and data == false then + report("definitions '%s' were not found",name) + end + local data, fullname = collect(name) + if not data then + if not textadept then + report("unable to load definition file '%s'",name) + end + data = false + elseif trace then + report("definition file '%s' has been loaded",fullname) + if detail then + local t, n = sortedkeys(data) + local template = " %-" .. n .. "s : %s" + for i=1,#t do + local k = t[i] + local v = data[k] + if type(v) ~= "table" then + report(template,k,tostring(v)) + elseif #v > 0 then + report(template,k,#v) + else + -- no need to show hash + end + end + end + end + cache[name] = data + return type(data) == "table" and data +end + +-- A bit of regression in textadept > 10 so updated ... done a bit different. +-- We don't use this in the context lexers anyway. + +function context.word_match(words,word_chars,case_insensitive) + -- used to be proper tables ... + if type(words) == "string" then + local clean = gsub(words,"%-%-[^\n]+","") + local split = { } + for s in gmatch(clean,"%S+") do + split[#split+1] = s + end + words = split + end + local list = { } + for i=1,#words do + list[words[i]] = true + end + if case_insensitive then + for i=1,#words do + list[lower(words[i])] = true + end + end + local chars = S(word_chars or "") + for i=1,#words do + chars = chars + S(words[i]) + end + local match = case_insensitive and + function(input,index,word) + -- We can speed mixed case if needed. + return (list[word] or list[lower(word)]) and index or nil + end + or + function(input,index,word) + return list[word] and index or nil + end + return Cmt(chars^1,match) +end + +-- Patterns are grouped in a separate namespace but the regular lexers expect +-- shortcuts to be present in the lexers library. Maybe I'll incorporate some +-- of l-lpeg later. + +do + + local anything = P(1) + local idtoken = R("az","AZ","\127\255","__") + local digit = R("09") + local sign = S("+-") + local period = P(".") + local octdigit = R("07") + local hexdigit = R("09","AF","af") + local lower = R("az") + local upper = R("AZ") + local alpha = upper + lower + local space = S(" \n\r\t\f\v") + local eol = S("\r\n") + local backslash = P("\\") + local decimal = digit^1 + local octal = P("0") + * octdigit^1 + local hexadecimal = P("0") * S("xX") + * (hexdigit^0 * period * hexdigit^1 + hexdigit^1 * period * hexdigit^0 + hexdigit^1) + * (S("pP") * sign^-1 * hexdigit^1)^-1 -- * + local integer = sign^-1 + * (hexadecimal + octal + decimal) + local float = sign^-1 + * (digit^0 * period * digit^1 + digit^1 * period * digit^0 + digit^1) + * S("eE") * sign^-1 * digit^1 -- * + + patterns.idtoken = idtoken + patterns.digit = digit + patterns.sign = sign + patterns.period = period + patterns.octdigit = octdigit + patterns.hexdigit = hexdigit + patterns.ascii = R("\000\127") -- useless + patterns.extend = R("\000\255") -- useless + patterns.control = R("\000\031") + patterns.lower = lower + patterns.upper = upper + patterns.alpha = alpha + patterns.decimal = decimal + patterns.octal = octal + patterns.hexadecimal = hexadecimal + patterns.float = float + patterns.cardinal = decimal + + patterns.signeddecimal = sign^-1 * decimal + patterns.signedoctal = sign^-1 * octal + patterns.signedhexadecimal = sign^-1 * hexadecimal + patterns.integer = integer + patterns.real = + sign^-1 * ( -- at most one + digit^1 * period * digit^0 -- 10.0 10. + + digit^0 * period * digit^1 -- 0.10 .10 + + digit^1 -- 10 + ) + + patterns.anything = anything + patterns.any = anything + patterns.restofline = (1-eol)^1 + patterns.space = space + patterns.spacing = space^1 + patterns.nospacing = (1-space)^1 + patterns.eol = eol + patterns.newline = P("\r\n") + eol + patterns.backslash = backslash + + local endof = S("\n\r\f") + + patterns.startofline = P(function(input,index) + return (index == 1 or lpegmatch(endof,input,index-1)) and index + end) + + -- These are the expected ones for other lexers. Maybe all in own namespace + -- and provide compatibility layer. or should I just remove them? + + lexers.any = anything + lexers.ascii = ascii + lexers.extend = extend + lexers.alpha = alpha + lexers.digit = digit + lexers.alnum = alpha + digit + lexers.lower = lower + lexers.upper = upper + lexers.xdigit = hexdigit + lexers.cntrl = control + lexers.graph = R("!~") + lexers.print = R(" ~") + lexers.punct = R("!/", ":@", "[\'", "{~") + lexers.space = space + lexers.newline = S("\r\n\f")^1 + lexers.nonnewline = 1 - lexers.newline + lexers.nonnewline_esc = 1 - (lexers.newline + '\\') + backslash * anything + lexers.dec_num = decimal + lexers.oct_num = octal + lexers.hex_num = hexadecimal + lexers.integer = integer + lexers.float = float + lexers.word = (alpha + "_") * (alpha + digit + "_")^0 -- weird, why digits + +end + +-- end of patterns + +function context.exact_match(words,word_chars,case_insensitive) + local characters = concat(words) + local pattern -- the concat catches _ etc + if word_chars == true or word_chars == false or word_chars == nil then + word_chars = "" + end + if type(word_chars) == "string" then + pattern = S(characters) + patterns.idtoken + if case_insensitive then + pattern = pattern + S(upper(characters)) + S(lower(characters)) + end + if word_chars ~= "" then + pattern = pattern + S(word_chars) + end + elseif word_chars then + pattern = word_chars + end + if case_insensitive then + local list = { } + if #words == 0 then + for k, v in next, words do + list[lower(k)] = v + end + else + for i=1,#words do + list[lower(words[i])] = true + end + end + return Cmt(pattern^1, function(_,i,s) + return list[lower(s)] -- and i or nil + end) + else + local list = { } + if #words == 0 then + for k, v in next, words do + list[k] = v + end + else + for i=1,#words do + list[words[i]] = true + end + end + return Cmt(pattern^1, function(_,i,s) + return list[s] -- and i or nil + end) + end +end + +function context.just_match(words) + local p = P(words[1]) + for i=2,#words do + p = p + P(words[i]) + end + return p +end + +-- spell checking (we can only load lua files) +-- +-- return { +-- min = 3, +-- max = 40, +-- n = 12345, +-- words = { +-- ["someword"] = "someword", +-- ["anotherword"] = "Anotherword", +-- }, +-- } + +local lists = { } + +function context.setwordlist(tag,limit) -- returns hash (lowercase keys and original values) + if not tag or tag == "" then + return false, 3 + end + local list = lists[tag] + if not list then + list = context.loaddefinitions("spell-" .. tag) + if not list or type(list) ~= "table" then + if not textadept then + report("invalid spell checking list for '%s'",tag) + end + list = { words = false, min = 3 } + else + list.words = list.words or false + list.min = list.min or 3 + end + lists[tag] = list + end + if trace then + report("enabling spell checking for '%s' with minimum '%s'",tag,list.min) + end + return list.words, list.min +end + +patterns.wordtoken = R("az","AZ","\127\255") +patterns.wordpattern = patterns.wordtoken^3 -- todo: if limit and #s < limit then + +function context.checkedword(validwords,validminimum,s,i) -- ,limit + if not validwords then -- or #s < validminimum then + return true, "text", i -- true, "default", i + else + -- keys are lower + local word = validwords[s] + if word == s then + return true, "okay", i -- exact match + elseif word then + return true, "warning", i -- case issue + else + local word = validwords[lower(s)] + if word == s then + return true, "okay", i -- exact match + elseif word then + return true, "warning", i -- case issue + elseif upper(s) == s then + return true, "warning", i -- probably a logo or acronym + else + return true, "error", i + end + end + end +end + +function context.styleofword(validwords,validminimum,s) -- ,limit + if not validwords or #s < validminimum then + return "text" + else + -- keys are lower + local word = validwords[s] + if word == s then + return "okay" -- exact match + elseif word then + return "warning" -- case issue + else + local word = validwords[lower(s)] + if word == s then + return "okay" -- exact match + elseif word then + return "warning" -- case issue + elseif upper(s) == s then + return "warning" -- probably a logo or acronym + else + return "error" + end + end + end +end + +-- overloaded functions + +local h_table, b_table, n_table = { }, { }, { } -- from the time small tables were used (optimization) + +setmetatable(h_table, { __index = function(t,level) local v = { level, FOLD_HEADER } t[level] = v return v end }) +setmetatable(b_table, { __index = function(t,level) local v = { level, FOLD_BLANK } t[level] = v return v end }) +setmetatable(n_table, { __index = function(t,level) local v = { level } t[level] = v return v end }) + +local newline = patterns.newline +local p_yes = Cp() * Cs((1-newline)^1) * newline^-1 +local p_nop = newline + +local folders = { } + +-- Snippets from the > 10 code .. but we do things different so ... + +local function fold_by_parsing(text,start_pos,start_line,start_level,lexer) + local folder = folders[lexer] + if not folder then + -- + local pattern, folds, text, start_pos, line_num, prev_level, current_level + -- + local fold_symbols = lexer._foldsymbols + local fold_pattern = lexer._foldpattern -- use lpeg instead (context extension) + -- + -- textadept >= 10 + -- + -- local zerosumlines = lexer.property_int["fold.on.zero.sum.lines"] > 0 -- not done + -- local compact = lexer.property_int['fold.compact'] > 0 -- not done + -- local lowercase = lexer._CASEINSENSITIVEFOLDPOINTS -- useless (utf will distort) + -- + if fold_pattern then + -- if no functions are found then we could have a faster one + fold_pattern = Cp() * C(fold_pattern) / function(s,match) + local symbols = fold_symbols[style_at[start_pos + s]] + if symbols then + local l = symbols[match] + if l then + current_level = current_level + l + end + end + end + local action_y = function() + folds[line_num] = prev_level + if current_level > prev_level then + folds[line_num] = prev_level + FOLD_HEADER + end + if current_level < FOLD_BASE then + current_level = FOLD_BASE + end + prev_level = current_level + line_num = line_num + 1 + end + local action_n = function() + folds[line_num] = prev_level + FOLD_BLANK + line_num = line_num + 1 + end + pattern = ((fold_pattern + (1-newline))^1 * newline / action_y + newline/action_n)^0 + + else + -- the traditional one but a bit optimized + local fold_symbols_patterns = fold_symbols._patterns + local action_y = function(pos,line) + for j=1, #fold_symbols_patterns do + for s, match in gmatch(line,fold_symbols_patterns[j]) do -- "()(" .. patterns[i] .. ")" + local symbols = fold_symbols[style_at[start_pos + pos + s - 1]] + local l = symbols and symbols[match] + local t = type(l) + if t == "number" then + current_level = current_level + l + elseif t == "function" then + current_level = current_level + l(text, pos, line, s, match) + end + end + end + folds[line_num] = prev_level + if current_level > prev_level then + folds[line_num] = prev_level + FOLD_HEADER + end + if current_level < FOLD_BASE then + current_level = FOLD_BASE + end + prev_level = current_level + line_num = line_num + 1 + end + local action_n = function() + folds[line_num] = prev_level + FOLD_BLANK + line_num = line_num + 1 + end + pattern = (p_yes/action_y + p_nop/action_n)^0 + end + -- + local reset_parser = lexer._reset_parser + -- + folder = function(_text_,_start_pos_,_start_line_,_start_level_) + if reset_parser then + reset_parser() + end + folds = { } + text = _text_ + start_pos = _start_pos_ + line_num = _start_line_ + prev_level = _start_level_ + current_level = prev_level + lpegmatch(pattern,text) + -- make folds collectable + local t = folds + folds = nil + return t + end + folders[lexer] = folder + end + return folder(text,start_pos,start_line,start_level,lexer) +end + +local folds, current_line, prev_level + +local function action_y() + local current_level = FOLD_BASE + indent_amount[current_line] + if current_level > prev_level then -- next level + local i = current_line - 1 + local f + while true do + f = folds[i] + if not f then + break + elseif f[2] == FOLD_BLANK then + i = i - 1 + else + f[2] = FOLD_HEADER -- low indent + break + end + end + folds[current_line] = { current_level } -- high indent + elseif current_level < prev_level then -- prev level + local f = folds[current_line - 1] + if f then + f[1] = prev_level -- high indent + end + folds[current_line] = { current_level } -- low indent + else -- same level + folds[current_line] = { prev_level } + end + prev_level = current_level + current_line = current_line + 1 +end + +local function action_n() + folds[current_line] = { prev_level, FOLD_BLANK } + current_line = current_line + 1 +end + +local pattern = ( S("\t ")^0 * ( (1-patterns.eol)^1 / action_y + P(true) / action_n) * newline )^0 + +local function fold_by_indentation(text,start_pos,start_line,start_level) + -- initialize + folds = { } + current_line = start_line + prev_level = start_level + -- define + -- -- not here .. pattern binds and local functions are not frozen + -- analyze + lpegmatch(pattern,text) + -- flatten + for line, level in next, folds do + folds[line] = level[1] + (level[2] or 0) + end + -- done, make folds collectable + local t = folds + folds = nil + return t +end + +local function fold_by_line(text,start_pos,start_line,start_level) + local folds = { } + -- can also be lpeg'd + for _ in gmatch(text,".-\r?\n") do + folds[start_line] = n_table[start_level] -- { start_level } -- stile tables ? needs checking + start_line = start_line + 1 + end + return folds +end + +local threshold_by_lexer = 512 * 1024 -- we don't know the filesize yet +local threshold_by_parsing = 512 * 1024 -- we don't know the filesize yet +local threshold_by_indentation = 512 * 1024 -- we don't know the filesize yet +local threshold_by_line = 512 * 1024 -- we don't know the filesize yet + +function context.fold(lexer,text,start_pos,start_line,start_level) -- hm, we had size thresholds .. where did they go + if text == "" then + return { } + end + if initialize then + initialize() + end + local fold_by_lexer = lexer._fold + local fold_by_symbols = lexer._foldsymbols + local filesize = 0 -- we don't know that + if fold_by_lexer then + if filesize <= threshold_by_lexer then + return fold_by_lexer(text,start_pos,start_line,start_level,lexer) + end + elseif fold_by_symbols then -- and lexer.properties("fold.by.parsing",1) > 0 then + if filesize <= threshold_by_parsing then + return fold_by_parsing(text,start_pos,start_line,start_level,lexer) + end + elseif lexer._FOLDBYINDENTATION or lexer.properties("fold.by.indentation",1) > 0 then + if filesize <= threshold_by_indentation then + return fold_by_indentation(text,start_pos,start_line,start_level,lexer) + end + elseif lexer._FOLDBYLINE or lexer.properties("fold.by.line",1) > 0 then + if filesize <= threshold_by_line then + return fold_by_line(text,start_pos,start_line,start_level,lexer) + end + end + return { } +end + +-- The following code is mostly unchanged: + +local function add_rule(lexer,id,rule) -- unchanged + if not lexer._RULES then + lexer._RULES = { } + lexer._RULEORDER = { } + end + lexer._RULES[id] = rule + lexer._RULEORDER[#lexer._RULEORDER + 1] = id +end + +local function modify_rule(lexer,id,rule) -- needed for textadept > 10 + if lexer._lexer then + lexer = lexer._lexer + end + lexer._RULES[id] = rule +end + +local function get_rule(lexer,id) -- needed for textadept > 10 + if lexer._lexer then + lexer = lexer._lexer + end + return lexer._RULES[id] +end + +-- I finally figured out that adding more styles was an issue because of several +-- reasons: +-- +-- + in old versions there was a limit in the amount, so we overran the built-in +-- hard coded scintilla range +-- + then, the add_style function didn't check for already known ones, so again +-- we had an overrun (with some magic that could be avoided) +-- + then, when I messed with a new default set I realized that there is no check +-- in initializing _TOKENSTYLES (here the inspect function helps) +-- + of course it was mostly a side effect of passing all the used styles to the +-- _tokenstyles instead of only the not-default ones but such a thing should not +-- matter (read: intercepted) +-- +-- This finally removed a head-ache and was revealed by lots of tracing, which I +-- should have built in way earlier. + +local function add_style(lexer,token_name,style) -- changed a bit around 3.41 + -- We don't add styles that are already defined as this can overflow the + -- amount possible (in old versions of scintilla). + if defaultstyles[token_name] then + if trace and detail then + report("default style '%s' is ignored as extra style",token_name) + end +-- return + elseif predefinedstyles[token_name] then + if trace and detail then + report("predefined style '%s' is ignored as extra style",token_name) + end +-- return + else + if trace and detail then + report("adding extra style '%s' as '%s'",token_name,style) + end + end + -- This is unchanged. We skip the dangerous zone. + local num_styles = lexer._numstyles + if num_styles == 32 then + num_styles = num_styles + 8 + end + if num_styles >= 255 then + report("there can't be more than %s styles",255) + end + lexer._TOKENSTYLES[token_name] = num_styles + lexer._EXTRASTYLES[token_name] = style + lexer._numstyles = num_styles + 1 + -- hm, the original (now) also copies to the parent ._lexer +end + +local function check_styles(lexer) + -- Here we also use a check for the dangerous zone. That way we can have a + -- larger default set. The original code just assumes that #default is less + -- than the dangerous zone's start. + local numstyles = 0 + local tokenstyles = { } + for i=1, #default do + if numstyles == 32 then + numstyles = numstyles + 8 + end + tokenstyles[default[i]] = numstyles + numstyles = numstyles + 1 + end + -- Unchanged. + for i=1, #predefined do + tokenstyles[predefined[i]] = i + 31 + end + lexer._TOKENSTYLES = tokenstyles + lexer._numstyles = numstyles + lexer._EXTRASTYLES = { } + return lexer +end + +-- At some point an 'any' append showed up in the original code ... +-- but I see no need to catch that case ... beter fix the specification. +-- +-- hm, why are many joined twice + +local function join_tokens(lexer) -- slightly different from the original (no 'any' append) + local patterns = lexer._RULES + local order = lexer._RULEORDER + -- report("lexer: %s, tokens: %s",lexer._NAME,table.concat(order," + ")) + if patterns and order then + local token_rule = patterns[order[1]] -- normally whitespace + for i=2,#order do + token_rule = token_rule + patterns[order[i]] + end + if lexer._TYPE ~= "context" then + token_rule = token_rule + lexers.token(lexers.DEFAULT, patterns.any) + end + lexer._TOKENRULE = token_rule + return token_rule + else + return P(1) + end +end + +-- hm, maybe instead of a grammer just a flat one + +local function add_lexer(grammar, lexer) -- mostly the same as the original + local token_rule = join_tokens(lexer) + local lexer_name = lexer._NAME + local children = lexer._CHILDREN + for i=1,#children do + local child = children[i] + if child._CHILDREN then + add_lexer(grammar, child) + end + local child_name = child._NAME + local rules = child._EMBEDDEDRULES[lexer_name] + local rules_token_rule = grammar["__" .. child_name] or rules.token_rule + local pattern = (-rules.end_rule * rules_token_rule)^0 * rules.end_rule^-1 + grammar[child_name] = pattern * V(lexer_name) + local embedded_child = "_" .. child_name + grammar[embedded_child] = rules.start_rule * pattern + token_rule = V(embedded_child) + token_rule + end + if trace then + report("adding lexer '%s' with %s children",lexer_name,#children) + end + grammar["__" .. lexer_name] = token_rule + grammar[lexer_name] = token_rule^0 +end + +local function build_grammar(lexer,initial_rule) -- same as the original + local children = lexer._CHILDREN + local lexer_name = lexer._NAME + local preamble = lexer._preamble + local grammar = lexer._grammar + if grammar then + -- experiment + elseif children then + if not initial_rule then + initial_rule = lexer_name + end + grammar = { initial_rule } + add_lexer(grammar, lexer) + lexer._INITIALRULE = initial_rule + grammar = Ct(P(grammar)) + if trace then + report("building grammar for '%s' with whitespace '%s'and %s children",lexer_name,lexer.whitespace or "?",#children) + end + else + grammar = Ct(join_tokens(lexer)^0) + if trace then + report("building grammar for '%s' with whitespace '%s'",lexer_name,lexer.whitespace or "?") + end + end + if preamble then + grammar = preamble^-1 * grammar + end + lexer._GRAMMAR = grammar +end + +-- So far. We need these local functions in the next one. + +local lineparsers = { } + +local maxmatched = 100 + +local function collapsed(t) + local lasttoken = nil + local lastindex = nil + for i=1,#t,2 do + local token = t[i] + local position = t[i+1] + if token == lasttoken then + t[lastindex] = position + elseif lastindex then + lastindex = lastindex + 1 + t[lastindex] = token + lastindex = lastindex + 1 + t[lastindex] = position + lasttoken = token + else + lastindex = i+1 + lasttoken = token + end + end + for i=#t,lastindex+1,-1 do + t[i] = nil + end + return t +end + +local function matched(lexer,grammar,text) + -- text = string.gsub(text,"\z","!") + local t = lpegmatch(grammar,text) + if trace then + if show then + report("output of lexer: %s (max %s entries)",lexer._NAME,maxmatched) + local s = lexer._TOKENSTYLES + local p = 1 + for i=1,2*maxmatched,2 do + local n = i + 1 + local ti = t[i] + local tn = t[n] + if ti then + local txt = sub(text,p,tn-1) + if txt then + txt = gsub(txt,"[%s]"," ") + else + txt = "!no text!" + end + report("%4i : %s > %s (%s) (%s)",floor(n/2),ti,tn,s[ti] or "!unset!",txt) + p = tn + else + break + end + end + end + report("lexer results: %s, length: %s, ranges: %s",lexer._NAME,#text,floor(#t/2)) + if collapse then + t = collapsed(t) + report("lexer collapsed: %s, length: %s, ranges: %s",lexer._NAME,#text,floor(#t/2)) + end + elseif collapse then + t = collapsed(t) + end + return t +end + +-- Todo: make nice generic lexer (extra argument with start/stop commands) for +-- context itself. +-- +-- In textadept >= 10 grammar building seem to have changed a bit. So, in retrospect +-- I could better have just dropped compatibility and stick to ctx lexers only. + +function context.lex(lexer,text,init_style) + -- local lexer = global._LEXER + local grammar = lexer._GRAMMAR + if initialize then + initialize() + end + if not grammar then + return { } + elseif lexer._LEXBYLINE then -- we could keep token + local tokens = { } + local offset = 0 + local noftokens = 0 + local lineparser = lineparsers[lexer] + if not lineparser then -- probably a cmt is more efficient + lineparser = C((1-newline)^0 * newline) / function(line) + local length = #line + local line_tokens = length > 0 and lpegmatch(grammar,line) + if line_tokens then + for i=1,#line_tokens,2 do + noftokens = noftokens + 1 + tokens[noftokens] = line_tokens[i] + noftokens = noftokens + 1 + tokens[noftokens] = line_tokens[i + 1] + offset + end + end + offset = offset + length + if noftokens > 0 and tokens[noftokens] ~= offset then + noftokens = noftokens + 1 + tokens[noftokens] = "default" + noftokens = noftokens + 1 + tokens[noftokens] = offset + 1 + end + end + lineparser = lineparser^0 + lineparsers[lexer] = lineparser + end + lpegmatch(lineparser,text) + return tokens + elseif lexer._CHILDREN then + local hash = lexer._HASH -- hm, was _hash + if not hash then + hash = { } + lexer._HASH = hash + end + grammar = hash[init_style] + if grammar then + lexer._GRAMMAR = grammar + -- lexer._GRAMMAR = lexer._GRAMMAR or grammar + else + for style, style_num in next, lexer._TOKENSTYLES do + if style_num == init_style then + -- the name of the lexers is filtered from the whitespace + -- specification .. weird code, should be a reverse hash + local lexer_name = match(style,"^(.+)_whitespace") or lexer._NAME + if lexer._INITIALRULE ~= lexer_name then + grammar = hash[lexer_name] + if not grammar then + build_grammar(lexer,lexer_name) + grammar = lexer._GRAMMAR + hash[lexer_name] = grammar + end + end + break + end + end + grammar = grammar or lexer._GRAMMAR + hash[init_style] = grammar + end + if trace then + report("lexing '%s' with initial style '%s' and %s children", lexer._NAME,init_style,#lexer._CHILDREN or 0) + end + return matched(lexer,grammar,text) + else + if trace then + report("lexing '%s' with initial style '%s'",lexer._NAME,init_style) + end + return matched(lexer,grammar,text) + end +end + +-- hm, changed in 3.24 .. no longer small table but one table (so we could remove our +-- agressive optimization which worked quite well) + +function context.token(name, patt) + return patt * Cc(name) * Cp() +end + +-- The next ones were mostly unchanged (till now), we moved it here when 3.41 +-- became close to impossible to combine with cq. overload and a merge was +-- the only solution. It makes later updates more painful but the update to +-- 3.41 was already a bit of a nightmare anyway. + +-- Loading lexers is rather interwoven with what the dll/so sets and +-- it changes over time. So, we need to keep an eye on changes. One +-- problem that we always faced were the limitations in length of +-- lexer names (as they get app/prepended occasionally to strings with +-- a hard coded limit). So, we always used alternative names and now need +-- to make sure this doesn't clash. As I no longer intend to use shipped +-- lexers I could strip away some of the code in the future, but keeping +-- it as reference makes sense. + +-- I spend quite some time figuring out why 3.41 didn't work or crashed which +-- is hard when no stdout is available and when the io library is absent. In +-- the end of of the problems was in the _NAME setting. We set _NAME +-- to e.g. 'tex' but load from a file with a longer name, which we do +-- as we don't want to clash with existing files, we end up in +-- lexers not being found. + +local whitespaces = { } + +local function push_whitespace(name) + table.insert(whitespaces,lexers.WHITESPACE or "whitespace") + lexers.WHITESPACE = name .. "_whitespace" +end + +local function pop_whitespace() + lexers.WHITESPACE = table.remove(whitespaces) or "whitespace" +end + +local function check_whitespace(lexer,name) + if lexer then + lexer.whitespace = (name or lexer.name or lexer._NAME) .. "_whitespace" + end +end + +function context.new(name,filename) + local lexer = { + _TYPE = "context", + -- + _NAME = name, -- used for token building + _FILENAME = filename, -- for diagnostic purposed + -- + name = name, + filename = filename, + -- +-- _tokenstyles = context.styleset, + } + if trace then + report("initializing lexer tagged '%s' from file '%s'",name,filename or name) + end + check_whitespace(lexer) + check_styles(lexer) + check_properties(lexer) + lexer._tokenstyles = context.styleset + return lexer +end + +local function nolexer(name) + local lexer = { + _TYPE = "unset", + _NAME = name, + -- _rules = { }, + } + check_styles(lexer) + check_whitespace(lexer) + check_properties(lexer) + return lexer +end + +local function load_lexer(name,namespace) + if trace then + report("loading lexer file '%s'",name) + end + push_whitespace(namespace or name) -- for traditional lexers .. no alt_name yet + local lexer, fullname = context.loadluafile(name) + pop_whitespace() + if not lexer then + report("invalid lexer file '%s'",name) + elseif trace then + report("lexer file '%s' has been loaded",fullname) + end + if type(lexer) ~= "table" then + if trace then + report("lexer file '%s' gets a dummy lexer",name) + end + return nolexer(name) + end + if lexer._TYPE ~= "context" then + lexer._TYPE = "native" + check_styles(lexer) + check_whitespace(lexer,namespace or name) + check_properties(lexer) + end + if not lexer._NAME then + lexer._NAME = name -- so: filename + end + if name ~= namespace then + lexer._NAME = namespace + end + return lexer +end + +-- tracing ... + +local function inspect_lexer(lexer,level) + -- If we had the regular libs available I could use the usual + -- helpers. + local parent = lexer._lexer + lexer._lexer = nil -- prevent endless recursion + local name = lexer._NAME + local function showstyles_1(tag,styles) + local numbers = { } + for k, v in next, styles do + numbers[v] = k + end + -- sort by number and make number hash too + local keys = sortedkeys(numbers) + for i=1,#keys do + local k = keys[i] + local v = numbers[k] + report("[%s %s] %s %s = %s",level,name,tag,k,v) + end + end + local function showstyles_2(tag,styles) + local keys = sortedkeys(styles) + for i=1,#keys do + local k = keys[i] + local v = styles[k] + report("[%s %s] %s %s = %s",level,name,tag,k,v) + end + end + local keys = sortedkeys(lexer) + for i=1,#keys do + local k = keys[i] + local v = lexer[k] + report("[%s %s] root key : %s = %s",level,name,k,tostring(v)) + end + showstyles_1("token style",lexer._TOKENSTYLES) + showstyles_2("extra style",lexer._EXTRASTYLES) + local children = lexer._CHILDREN + if children then + for i=1,#children do + inspect_lexer(children[i],level+1) + end + end + lexer._lexer = parent +end + +function context.inspect(lexer) + inspect_lexer(lexer,0) +end + +-- An optional second argument has been introduced so that one can embed a lexer +-- more than once ... maybe something to look into (as not it's done by remembering +-- the start sequence ... quite okay but maybe suboptimal ... anyway, never change +-- a working solution). + +-- namespace can be automatic: if parent then use name of parent (chain) + +-- The original lexer framework had a rather messy user uinterface (e.g. moving +-- stuff from _rules to _RULES at some point but I could live with that. Now it uses +-- add_ helpers. But the subsystem is still not clean and pretty. Now, I can move to +-- the add_ but there is no gain in it so we support a mix which gives somewhat ugly +-- code. In fact, there should be proper subtables for this. I might actually do +-- this because we now always overload the normal lexer (parallel usage seems no +-- longer possible). For SciTE we can actually do a conceptual upgrade (more the +-- context way) because there is no further development there. That way we could +-- make even more advanced lexers. + +local savedrequire = require + +local escapes = { + ["%"] = "%%", + ["."] = "%.", + ["+"] = "%+", ["-"] = "%-", ["*"] = "%*", + ["["] = "%[", ["]"] = "%]", + ["("] = "%(", [")"] = "%)", + -- ["{"] = "%{", ["}"] = "%}" + -- ["^"] = "%^", ["$"] = "%$", +} + +function context.loadlexer(filename,namespace) + + if textadept then + require = function(name) + return savedrequire(name == "lexer" and "scite-context-lexer" or name) + end + end + + nesting = nesting + 1 + if not namespace then + namespace = filename + end + local lexer = usedlexers[namespace] -- we load by filename but the internal name can be short + if lexer then + if trace then + report("reusing lexer '%s'",namespace) + end + nesting = nesting - 1 + return lexer + elseif trace then + report("loading lexer '%s'",namespace) + end + -- + if initialize then + initialize() + end + -- + parent_lexer = nil + -- + lexer = load_lexer(filename,namespace) or nolexer(filename,namespace) + usedlexers[filename] = lexer + -- + if not lexer._rules and not lexer._lexer and not lexer_grammar then -- hmm should be lexer._grammar + lexer._lexer = parent_lexer + end + -- + if lexer._lexer then + local _l = lexer._lexer + local _r = lexer._rules + local _s = lexer._tokenstyles + if not _l._tokenstyles then + _l._tokenstyles = { } + end + if _r then + local rules = _l._rules + local name = lexer.name + for i=1,#_r do + local rule = _r[i] + rules[#rules + 1] = { + name .. "_" .. rule[1], + rule[2], + } + end + end + if _s then + local tokenstyles = _l._tokenstyles + for token, style in next, _s do + tokenstyles[token] = style + end + end + lexer = _l + end + -- + local _r = lexer._rules + local _g = lexer._grammar + if _r or _g then + local _s = lexer._tokenstyles + if _s then + for token, style in next, _s do + add_style(lexer, token, style) + end + end + if _r then + for i=1,#_r do + local rule = _r[i] + add_rule(lexer, rule[1], rule[2]) + end + end + build_grammar(lexer) + else + -- other lexers + build_grammar(lexer) + end + -- + add_style(lexer, lexer.whitespace, lexers.STYLE_WHITESPACE) + -- + local foldsymbols = lexer._foldsymbols + if foldsymbols then + local patterns = foldsymbols._patterns + if patterns then + for i = 1, #patterns do + patterns[i] = "()(" .. gsub(patterns[i],".",escapes) .. ")" + end + end + end + -- + lexer.lex = lexers.lex + lexer.fold = lexers.fold + -- + nesting = nesting - 1 + -- + if inspect then + context.inspect(lexer) + end + -- + if textadept then + require = savedrequire + end + -- + return lexer +end + +-- I probably need to check this occasionally with the original as I've messed around a bit +-- in the past to get nesting working well as one can hit the max number of styles, get +-- clashes due to fuzzy inheritance etc. so there is some interplay with the other patched +-- code. + +function context.embed_lexer(parent, child, start_rule, end_rule) -- mostly the same as the original + local embeddedrules = child._EMBEDDEDRULES + if not embeddedrules then + embeddedrules = { } + child._EMBEDDEDRULES = embeddedrules + end + if not child._RULES then + local rules = child._rules + if not rules then + report("child lexer '%s' has no rules",child._NAME or "unknown") + rules = { } + child._rules = rules + end + for i=1,#rules do + local rule = rules[i] + add_rule(child, rule[1], rule[2]) + end + end + embeddedrules[parent._NAME] = { + ["start_rule"] = start_rule, + ["token_rule"] = join_tokens(child), + ["end_rule"] = end_rule + } + local children = parent._CHILDREN + if not children then + children = { } + parent._CHILDREN = children + end + children[#children + 1] = child + local tokenstyles = parent._tokenstyles + if not tokenstyles then + tokenstyles = { } + parent._tokenstyles = tokenstyles + end + local childname = child._NAME + local whitespace = childname .. "_whitespace" + tokenstyles[whitespace] = lexers.STYLE_WHITESPACE -- all these STYLE_THINGS will go .. just a proper hash + if trace then + report("using whitespace '%s' as trigger for '%s' with property '%s'",whitespace,childname,lexers.STYLE_WHITESPACE) + end + local childstyles = child._tokenstyles + if childstyles then + for token, style in next, childstyles do + tokenstyles[token] = style + end + end + -- new, a bit redone, untested, no clue yet what it is for + local parentsymbols = parent._foldsymbols + local childsymbols = child ._foldsymbols + if not parentsymbols then + parentsymbols = { } + parent._foldsymbols = parentsymbols + end + if childsymbols then + for token, symbols in next, childsymbols do + local tokensymbols = parentsymbols[token] + if not tokensymbols then + tokensymbols = { } + parentsymbols[token] = tokensymbols + end + for k, v in next, symbols do + if type(k) == 'number' then + tokensymbols[#tokensymbols + 1] = v + elseif not tokensymbols[k] then + tokensymbols[k] = v + end + end + end + end + -- newer, textadept >= 10, whatever ... + local childsymbols = child._FOLDPOINTS + if childsymbols then + for token, symbols in next, childsymbols do + if token ~= "_SYMBOLS" then + for symbol, v in next, symbols do + lexer:add_fold_point(token_name, symbol, v) + end + end + end + end + -- + child._lexer = parent + parent_lexer = parent +end + +-- we now move the adapted code to the lexers namespace + +lexers.new = context.new +lexers.load = context.loadlexer +------.loadlexer = context.loadlexer +lexers.loadluafile = context.loadluafile +lexers.embed_lexer = context.embed_lexer +lexers.fold = context.fold +lexers.lex = context.lex +lexers.token = context.token +lexers.word_match = context.word_match +lexers.exact_match = context.exact_match +lexers.just_match = context.just_match +lexers.inspect = context.inspect +lexers.report = context.report +lexers.inform = context.inform + +-- helper .. alas ... in scite the lexer's lua instance is rather crippled .. not +-- even math is part of it + +do + + local floor = math and math.floor + local char = string.char + local format = format + local tonumber = tonumber + + local function utfchar(n) + if n < 0x80 then + return char(n) + elseif n < 0x800 then + return char( + 0xC0 + floor(n/0x40), + 0x80 + (n % 0x40) + ) + elseif n < 0x10000 then + return char( + 0xE0 + floor(n/0x1000), + 0x80 + (floor(n/0x40) % 0x40), + 0x80 + (n % 0x40) + ) + elseif n < 0x40000 then + return char( + 0xF0 + floor(n/0x40000), + 0x80 + floor(n/0x1000), + 0x80 + (floor(n/0x40) % 0x40), + 0x80 + (n % 0x40) + ) + else + -- return char( + -- 0xF1 + floor(n/0x1000000), + -- 0x80 + floor(n/0x40000), + -- 0x80 + floor(n/0x1000), + -- 0x80 + (floor(n/0x40) % 0x40), + -- 0x80 + (n % 0x40) + -- ) + return "?" + end + end + + context.utfchar = utfchar + + -- -- the next one is good enough for use here but not perfect (see context for a + -- -- better one) + -- + -- local function make(t) + -- local p + -- for k, v in next, t do + -- if not p then + -- if next(v) then + -- p = P(k) * make(v) + -- else + -- p = P(k) + -- end + -- else + -- if next(v) then + -- p = p + P(k) * make(v) + -- else + -- p = p + P(k) + -- end + -- end + -- end + -- return p + -- end + -- + -- function lpeg.utfchartabletopattern(list) + -- local tree = { } + -- for i=1,#list do + -- local t = tree + -- for c in gmatch(list[i],".") do + -- if not t[c] then + -- t[c] = { } + -- end + -- t = t[c] + -- end + -- end + -- return make(tree) + -- end + + local utf8next = R("\128\191") + local utf8one = R("\000\127") + local utf8two = R("\194\223") * utf8next + local utf8three = R("\224\239") * utf8next * utf8next + local utf8four = R("\240\244") * utf8next * utf8next * utf8next + + helpers.utfcharpattern = P(1) * utf8next^0 -- unchecked but fast + helpers.utfbytepattern = utf8one / byte + + utf8two / function(s) local c1, c2 = byte(s,1,2) return c1 * 64 + c2 - 12416 end + + utf8three / function(s) local c1, c2, c3 = byte(s,1,3) return (c1 * 64 + c2) * 64 + c3 - 925824 end + + utf8four / function(s) local c1, c2, c3, c4 = byte(s,1,4) return ((c1 * 64 + c2) * 64 + c3) * 64 + c4 - 63447168 end + + local p_false = P(false) + local p_true = P(true) + + local function make(t) + local function making(t) + local p = p_false + local keys = sortedkeys(t) + for i=1,#keys do + local k = keys[i] + if k ~= "" then + local v = t[k] + if v == true then + p = p + P(k) * p_true + elseif v == false then + -- can't happen + else + p = p + P(k) * making(v) + end + end + end + if t[""] then + p = p + p_true + end + return p + end + local p = p_false + local keys = sortedkeys(t) + for i=1,#keys do + local k = keys[i] + if k ~= "" then + local v = t[k] + if v == true then + p = p + P(k) * p_true + elseif v == false then + -- can't happen + else + p = p + P(k) * making(v) + end + end + end + return p + end + + local function collapse(t,x) + if type(t) ~= "table" then + return t, x + else + local n = next(t) + if n == nil then + return t, x + elseif next(t,n) == nil then + -- one entry + local k = n + local v = t[k] + if type(v) == "table" then + return collapse(v,x..k) + else + return v, x .. k + end + else + local tt = { } + for k, v in next, t do + local vv, kk = collapse(v,k) + tt[kk] = vv + end + return tt, x + end + end + end + + function helpers.utfchartabletopattern(list) + local tree = { } + local n = #list + if n == 0 then + for s in next, list do + local t = tree + local p, pk + for c in gmatch(s,".") do + if t == true then + t = { [c] = true, [""] = true } + p[pk] = t + p = t + t = false + elseif t == false then + t = { [c] = false } + p[pk] = t + p = t + t = false + else + local tc = t[c] + if not tc then + tc = false + t[c] = false + end + p = t + t = tc + end + pk = c + end + if t == false then + p[pk] = true + elseif t == true then + -- okay + else + t[""] = true + end + end + else + for i=1,n do + local s = list[i] + local t = tree + local p, pk + for c in gmatch(s,".") do + if t == true then + t = { [c] = true, [""] = true } + p[pk] = t + p = t + t = false + elseif t == false then + t = { [c] = false } + p[pk] = t + p = t + t = false + else + local tc = t[c] + if not tc then + tc = false + t[c] = false + end + p = t + t = tc + end + pk = c + end + if t == false then + p[pk] = true + elseif t == true then + -- okay + else + t[""] = true + end + end + end + collapse(tree,"") + -- inspect(tree) + return make(tree) + end + + patterns.invisibles = helpers.utfchartabletopattern { + utfchar(0x00A0), -- nbsp + utfchar(0x2000), -- enquad + utfchar(0x2001), -- emquad + utfchar(0x2002), -- enspace + utfchar(0x2003), -- emspace + utfchar(0x2004), -- threeperemspace + utfchar(0x2005), -- fourperemspace + utfchar(0x2006), -- sixperemspace + utfchar(0x2007), -- figurespace + utfchar(0x2008), -- punctuationspace + utfchar(0x2009), -- breakablethinspace + utfchar(0x200A), -- hairspace + utfchar(0x200B), -- zerowidthspace + utfchar(0x202F), -- narrownobreakspace + utfchar(0x205F), -- math thinspace + } + + -- now we can make: + + patterns.iwordtoken = patterns.wordtoken - patterns.invisibles + patterns.iwordpattern = patterns.iwordtoken^3 + +end + +-- The following helpers are not used, partially replaced by other mechanisms and +-- when needed I'll first optimize them. I only made them somewhat more readable. + +function lexers.delimited_range(chars, single_line, no_escape, balanced) -- unchanged + local s = sub(chars,1,1) + local e = #chars == 2 and sub(chars,2,2) or s + local range + local b = balanced and s or "" + local n = single_line and "\n" or "" + if no_escape then + local invalid = S(e .. n .. b) + range = patterns.any - invalid + else + local invalid = S(e .. n .. b) + patterns.backslash + range = patterns.any - invalid + patterns.backslash * patterns.any + end + if balanced and s ~= e then + return P { + s * (range + V(1))^0 * e + } + else + return s * range^0 * P(e)^-1 + end +end + +function lexers.starts_line(patt) -- unchanged + return P ( function(input, index) + if index == 1 then + return index + end + local char = sub(input,index - 1,index - 1) + if char == "\n" or char == "\r" or char == "\f" then + return index + end + end ) * patt +end + +function lexers.last_char_includes(s) -- unchanged + s = "[" .. gsub(s,"[-%%%[]", "%%%1") .. "]" + return P ( function(input, index) + if index == 1 then + return index + end + local i = index + while match(sub(input,i - 1,i - 1),"[ \t\r\n\f]") do + i = i - 1 + end + if match(sub(input,i - 1,i - 1),s) then + return index + end + end) +end + +function lexers.nested_pair(start_chars, end_chars) -- unchanged + local s = start_chars + local e = P(end_chars)^-1 + return P { + s * (patterns.any - s - end_chars + V(1))^0 * e + } +end + +local function prev_line_is_comment(prefix, text, pos, line, s) -- unchanged + local start = find(line,"%S") + if start < s and not find(line,prefix,start,true) then + return false + end + local p = pos - 1 + if sub(text,p,p) == "\n" then + p = p - 1 + if sub(text,p,p) == "\r" then + p = p - 1 + end + if sub(text,p,p) ~= "\n" then + while p > 1 and sub(text,p - 1,p - 1) ~= "\n" + do p = p - 1 + end + while find(sub(text,p,p),"^[\t ]$") do + p = p + 1 + end + return sub(text,p,p + #prefix - 1) == prefix + end + end + return false +end + +local function next_line_is_comment(prefix, text, pos, line, s) + local p = find(text,"\n",pos + s) + if p then + p = p + 1 + while find(sub(text,p,p),"^[\t ]$") do + p = p + 1 + end + return sub(text,p,p + #prefix - 1) == prefix + end + return false +end + +function lexers.fold_line_comments(prefix) + local property_int = lexers.property_int + return function(text, pos, line, s) + if property_int["fold.line.comments"] == 0 then + return 0 + end + if s > 1 and match(line,"^%s*()") < s then + return 0 + end + local prev_line_comment = prev_line_is_comment(prefix, text, pos, line, s) + local next_line_comment = next_line_is_comment(prefix, text, pos, line, s) + if not prev_line_comment and next_line_comment then + return 1 + end + if prev_line_comment and not next_line_comment then + return -1 + end + return 0 + end +end + +-- There are some fundamental changes in textadept version 10 and I don't want to +-- adapt again so we go the reverse route: map new to old. This is needed because +-- we need to load other lexers which is teh result of not being able to load the +-- lexer framework in parallel. Something happened in 10 that makes the main lexer +-- always enforced so now we need to really replace that one (and even then it loads +-- twice (i can probably sort that out). Maybe there's now some hard coded magic +-- in the binary. + +if textadept then + + -- Folds are still somewhat weak because of the end condition not being + -- bound to a start .. probably to complex and it seems to work anyhow. As + -- we have extended thinsg we just remap. + + local function add_fold_point(lexer,token_name,start_symbol,end_symbol) + if type(start_symbol) == "string" then + local foldsymbols = lexer._foldsymbols + if not foldsymbols then + foldsymbols = { } + lexer._foldsymbols = foldsymbols + end + local patterns = foldsymbols._patterns + if not patterns then + patterns = { } + usedpatt = { } -- > 10 uses a mixed index/hash (we don't use patterns) + foldsymbols._patterns = patterns + foldsymbols._usedpatt = usedpatt + end + local foldsymbol = foldsymbols[token_name] + if not foldsymbol then + foldsymbol = { } + foldsymbols[token_name] = foldsymbol + end + if not usedpatt[start_symbol] then + patterns[#patterns+1] = start_symbol + usedpatt[start_symbol] = true + end + if type(end_symbol) == "string" then + foldsymbol[start_symbol] = 1 + foldsymbol[end_symbol] = -1 + if not usedpatt[end_symbol] then + patterns[#patterns+1] = end_symbol + usedpatt[end_symbol] = true + end + else + foldsymbol[start_symbol] = end_symbol + end + end + end + + local function add_style(lexer,name,style) + local tokenstyles = lexer._tokenstyles + if not tokenstyles then + tokenstyles = { } + lexer._tokenstyles = tokenstyles + end + tokenstyles[name] = style + end + + local function add_rule(lexer,id,rule) + local rules = lexer._rules + if not rules then + rules = { } + lexer._rules = rules + end + rules[#rules+1] = { id, rule } + end + + local function modify_rule(lexer,id,rule) -- needed for textadept > 10 + if lexer._lexer then + lexer = lexer._lexer + end + local RULES = lexer._RULES + if RULES then + RULES[id] = rule + end + end + + local function get_rule(lexer,id) -- needed for textadept > 10 + if lexer._lexer then + lexer = lexer._lexer + end + local RULES = lexer._RULES + if RULES then + return RULES[id] + end + end + + local new = context.new + local lmt = { + __index = { + + add_rule = add_rule, + modify_rule = modify_rule, + get_rule = get_rule, + add_style = add_style, + add_fold_point = add_fold_point, + + join_tokens = join_tokens, + build_grammar = build_grammar, + + embed = lexers.embed, + lex = lexers.lex, + fold = lexers.fold + + } + } + + function lexers.new(name,options) + local lexer = new(name) + if options then + lexer._LEXBYLINE = options['lex_by_line'] + lexer._FOLDBYINDENTATION = options['fold_by_indentation'] + lexer._CASEINSENSITIVEFOLDPOINTS = options['case_insensitive_fold_points'] + lexer._lexer = options['inherit'] + end + setmetatable(lexer,lmt) + return lexer + end + +end + +-- done + +return lexers diff --git a/context/data/textadept/context/lexers/scite-context-lexer-bnf.lua b/context/data/textadept/context/lexers/scite-context-lexer-bnf.lua new file mode 100644 index 000000000..ce57642ba --- /dev/null +++ b/context/data/textadept/context/lexers/scite-context-lexer-bnf.lua @@ -0,0 +1,99 @@ +local info = { + version = 1.001, + comment = "scintilla lpeg lexer for bnf", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files", +} + +-- will replace the one in metafun + +local global, lpeg = _G, lpeg +local P, R, S = lpeg.P, lpeg.R, lpeg.S + +local lexer = require("scite-context-lexer") +local context = lexer.context +local patterns = context.patterns + +local token = lexer.token +local exact_match = lexer.exact_match + +local bnflexer = lexer.new("bnf","scite-context-lexer-bnf") +local whitespace = bnflexer.whitespace + +-- from wikipedia: +-- +-- <syntax> ::= <rule> | <rule> <syntax> +-- <rule> ::= <opt-whitespace> "<" <rule-name> ">" <opt-whitespace> "::=" <opt-whitespace> <expression> <line-end> +-- <opt-whitespace> ::= " " <opt-whitespace> | "" +-- <expression> ::= <list> | <list> <opt-whitespace> "|" <opt-whitespace> <expression> +-- <line-end> ::= <opt-whitespace> <EOL> | <line-end> <line-end> +-- <list> ::= <term> | <term> <opt-whitespace> <list> +-- <term> ::= <literal> | "<" <rule-name> ">" +-- <literal> ::= '"' <text1> '"' | "'" <text2> "'" +-- <text1> ::= "" | <character1> <text1> +-- <text2> ::= "" | <character2> <text2> +-- <character> ::= <letter> | <digit> | <symbol> +-- <letter> ::= "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z" | "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z" +-- <digit> ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" +-- <symbol> ::= "|" | " " | "-" | "!" | "#" | "$" | "%" | "&" | "(" | ")" | "*" | "+" | "," | "-" | "." | "/" | ":" | ";" | ">" | "=" | "<" | "?" | "@" | "[" | "\" | "]" | "^" | "_" | "`" | "{" | "}" | "~" +-- <character1> ::= <character> | "'" +-- <character2> ::= <character> | '"' +-- <rule-name> ::= <letter> | <rule-name> <rule-char> +-- <rule-char> ::= <letter> | <digit> | "-" + +local anything = patterns.anything +local separator = P("|") +local left = P("<") +local right = P(">") +local space = S(" \t\n\r\f") +local spaces = space^1 +local letter = R("AZ","az") +local digit = R("09") +local symbol = S([[| -!#$%&()*+,-./:;>=<?@[\]^_`{}~]]) +local text = (letter + digit + symbol^0) +local name = letter * (letter + digit + P("-"))^0 +local becomes = P("::=") +local extra = P("|") +local single = P("'") +local double = P('"') + +local t_spacing = token(whitespace,space^1) +local t_term = token("command",left) + * token("text",name) + * token("command",right) +local t_text = token("quote",single) + * token("text",text) + * token("quote",single) + + token("quote",double) + * token("text",text) + * token("quote",double) +local t_becomes = token("operator",becomes) +local t_extra = token("extra",extra) +local t_rest = token("default",anything) + +bnflexer._rules = { + { "whitespace", t_spacing }, + { "term", t_term }, + { "text", t_text }, + { "becomes", t_becomes }, + { "extra", t_extra }, + { "rest", t_rest }, +} + +bnflexer._tokenstyles = context.styleset + +bnflexer._foldpattern = left + right + +bnflexer._foldsymbols = { + _patterns = { + "<", + ">", + }, + ["grouping"] = { + ["<"] = 1, + [">"] = -1, + }, +} + +return bnflexer diff --git a/context/data/textadept/context/lexers/scite-context-lexer-json.lua b/context/data/textadept/context/lexers/scite-context-lexer-json.lua new file mode 100644 index 000000000..20a2d1d12 --- /dev/null +++ b/context/data/textadept/context/lexers/scite-context-lexer-json.lua @@ -0,0 +1,100 @@ +local info = { + version = 1.002, + comment = "scintilla lpeg lexer for json", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files", +} + +local global, string, table, lpeg = _G, string, table, lpeg +local P, R, S, V = lpeg.P, lpeg.R, lpeg.S, lpeg.V +local type = type + +local lexer = require("scite-context-lexer") +local context = lexer.context +local patterns = context.patterns + +local token = lexer.token +local exact_match = lexer.exact_match + +local jsonlexer = lexer.new("json","scite-context-lexer-json") +local whitespace = jsonlexer.whitespace + +local anything = patterns.anything +local comma = P(",") +local colon = P(":") +local escape = P("\\") +----- single = P("'") +local double = P('"') +local openarray = P('[') +local closearray = P(']') +local openhash = P('{') +local closehash = P('}') +----- lineending = S("\n\r") +local space = S(" \t\n\r\f") +local spaces = space^1 +local operator = S(':,{}[]') +local fence = openarray + closearray + openhash + closehash + +local escape_un = P("\\u") / "0x" * S("09","AF","af") +local escape_bs = P([[\]]) * P(1) +local content = (escape_un + escape_bs + (1-double))^0 + +local reserved = P("true") + + P("false") + + P("null") + +local integer = P("-")^-1 * (patterns.hexadecimal + patterns.decimal) +local float = patterns.float + +local t_number = token("number", float + integer) + * (token("error",R("AZ","az","__")^1))^0 + +local t_spacing = token(whitespace, space^1) +local t_optionalws = token("default", space^1)^0 + +local t_operator = token("special", operator) + +local t_string = token("operator",double) + * token("string",content) + * token("operator",double) + +local t_key = token("operator",double) + * token("text",content) + * token("operator",double) + * t_optionalws + * token("operator",colon) + +local t_fences = token("operator",fence) -- grouping + +local t_reserved = token("primitive",reserved) + +local t_rest = token("default",anything) + +jsonlexer._rules = { + { "whitespace", t_spacing }, + { "reserved", t_reserved }, + { "key", t_key }, + { "number", t_number }, + { "string", t_string }, + { "fences", t_fences }, + { "operator", t_operator }, + { "rest", t_rest }, +} + +jsonlexer._tokenstyles = context.styleset + +jsonlexer._foldpattern = fence + +jsonlexer._foldsymbols = { + _patterns = { + "{", "}", + "[", "]", + }, + ["grouping"] = { + ["{"] = 1, ["}"] = -1, + ["["] = 1, ["]"] = -1, + }, +} + +return jsonlexer diff --git a/context/data/textadept/context/lexers/scite-context-lexer-mps.lua b/context/data/textadept/context/lexers/scite-context-lexer-mps.lua index 1c87ea6d0..4bbfae03c 100644 --- a/context/data/textadept/context/lexers/scite-context-lexer-mps.lua +++ b/context/data/textadept/context/lexers/scite-context-lexer-mps.lua @@ -91,9 +91,12 @@ local plain = token("plain", exact_match(metapostcommands)) local quoted = token("quote", dquote) * token("string", P(1-dquote)^0) * token("quote", dquote) -local texstuff = token("quote", P("btex ") + P("verbatimtex ")) - * token("string", P(1-P(" etex"))^0) - * token("quote", P(" etex")) +local separator = P(" ") + S("\n\r")^1 +local btex = (P("btex") + P("verbatimtex")) * separator +local etex = separator * P("etex") +local texstuff = token("quote", btex) + * token("string", (1-etex)^0) + * token("quote", etex) local primitive = token("primitive", exact_match(metapostprimitives)) local identifier = token("default", cstoken^1) local number = token("number", number) @@ -130,10 +133,10 @@ metafunlexer._rules = { { "comment", comment }, { "internal", internal }, { "shortcut", shortcut }, + { "luacall", luacall }, { "helper", helper }, { "plain", plain }, { "primitive", primitive }, - { "luacall", luacall }, { "texstuff", texstuff }, { "suffix", suffix }, { "identifier", identifier }, diff --git a/context/data/textadept/context/lexers/scite-context-lexer-pdf.lua b/context/data/textadept/context/lexers/scite-context-lexer-pdf.lua index 0fd238d63..1956071b7 100644 --- a/context/data/textadept/context/lexers/scite-context-lexer-pdf.lua +++ b/context/data/textadept/context/lexers/scite-context-lexer-pdf.lua @@ -90,7 +90,7 @@ local t_number = token("number", real) -- t_reference = token("number", cardinal) -- * t_spacing -- * token("number", cardinal) -local t_reserved = token("number", P("true") + P("false") + P("NULL")) +local t_reserved = token("number", P("true") + P("false") + P("null")) -- t_reference = token("warning", cardinal * spacing * cardinal * spacing) -- * token("keyword", p_reference) local t_reference = token("warning", cardinal) @@ -121,17 +121,31 @@ local t_stream = token("keyword", p_stream) * token("text", (1 - p_endstream)^1) * token("keyword", p_endstream) +local t_other = t_constant + t_reference + t_string + t_unicode + t_number + t_reserved + t_whatsit + local t_dictionary = { "dictionary", - dictionary = t_opendictionary * (t_spaces * t_keyword * t_spaces * V("whatever"))^0 * t_spaces * t_closedictionary, - array = t_openarray * (t_spaces * V("whatever"))^0 * t_spaces * t_closearray, - whatever = V("dictionary") + V("array") + t_constant + t_reference + t_string + t_unicode + t_number + t_reserved + t_whatsit, + dictionary = t_opendictionary + * (t_spaces * t_keyword * t_spaces * V("whatever"))^0 + * t_spaces + * t_closedictionary, + array = t_openarray + * (t_spaces * V("whatever"))^0 + * t_spaces + * t_closearray, + whatever = V("dictionary") + + V("array") + + t_other, } local t_object = { "object", -- weird that we need to catch the end here (probably otherwise an invalid lpeg) dictionary = t_dictionary.dictionary, array = t_dictionary.array, whatever = t_dictionary.whatever, - object = t_openobject * t_spaces * (V("dictionary")^-1 * t_spaces * t_stream^-1 + V("array") + V("number") + t_spaces) * t_spaces * t_closeobject, + object = t_openobject + * t_spaces + * (V("dictionary") * t_spaces * t_stream^-1 + V("array") + t_other) + * t_spaces + * t_closeobject, number = t_number, } diff --git a/context/data/textadept/context/lexers/scite-context-lexer-tex.lua b/context/data/textadept/context/lexers/scite-context-lexer-tex.lua index 1f1246fc0..2c2421d2f 100644 --- a/context/data/textadept/context/lexers/scite-context-lexer-tex.lua +++ b/context/data/textadept/context/lexers/scite-context-lexer-tex.lua @@ -57,24 +57,36 @@ do -- todo: only once, store in global local definitions = context.loaddefinitions("scite-context-data-interfaces") if definitions then - local list = { } + local used = { } for interface, list in next, definitions do - list[#list+1] = interface - local c = { } - for i=1,#list do - c[list[i]] = true - end - if interface ~= "en" then + if interface ~= "common" then + used[#used+1] = interface + local c = { } + -- these are shared + local list = definitions.common + if list then + for i=1,#list do + c[list[i]] = true + end + end + -- normally this one is empty list = definitions.en if list then for i=1,#list do c[list[i]] = true end end + -- these are interface specific + if interface ~= "en" then + for i=1,#list do + c[list[i]] = true + end + end + commands[interface] = c end - commands[interface] = c end - inform("context user interfaces '%s' supported",table.concat(list," ")) + table.sort(used) + inform("context user interfaces '%s' supported",table.concat(used," ")) end local definitions = context.loaddefinitions("scite-context-data-context") @@ -405,7 +417,7 @@ local luaenvironment = P("lua") * (P("setups") + P("code") + P(true)) local inlinelua = P("\\") * ( P("ctx") * (P("lua") + P("command") + P("late") * (P("lua") + P("command")) + P("function")) + P("cld") * (P("command") + P("context")) - + P("luaexpr") + + P("lua") * (P("expr") + P("script") + P("thread")) + (P("direct") + P("late")) * P("lua") ) diff --git a/context/data/textadept/context/lexers/scite-context-lexer.lua b/context/data/textadept/context/lexers/scite-context-lexer.lua index 37f236a89..0a752e412 100644 --- a/context/data/textadept/context/lexers/scite-context-lexer.lua +++ b/context/data/textadept/context/lexers/scite-context-lexer.lua @@ -8,6 +8,10 @@ local info = { } +-- We need a copy of this file to lexer.lua in the same path. This was not needed +-- before version 10 but I can't figure out what else to do. It looks like there +-- is some loading of lexer.lua but I can't see where. + if lpeg.setmaxstack then lpeg.setmaxstack(1000) end local log = false @@ -232,6 +236,17 @@ local inspect = false -- can save some 15% (maybe easier on scintilla) -- is still not perfect (sometimes hangs) but it was enough reason to spend time on -- making our lexer work with TextAdept and create a setup. -- +-- Some bad news. The interface changed (again) in textadept 10, some for the better +-- (but a bit different from what happens here) and some for the worse, especially +-- moving some code to the init file so we now need some bad hacks. I decided to +-- stay with the old method of defining lexers and because the lexer cannot be run +-- in parallel any more (some change in the binary?) I will probably also cleanup +-- code below as we no longer need to be compatible. Unfortunately textadept is too +-- much a moving target to simply kick in some (tex related) production flow (apart +-- from the fact that it doesn't yet have the scite like realtime console). I'll +-- keep an eye on it. Because we don't need many added features I might as well decide +-- to make a lean and mean instance (after all the license permits forking). + -- TRACING -- -- The advantage is that we now can check more easily with regular Lua(TeX). We can @@ -243,8 +258,8 @@ local inspect = false -- can save some 15% (maybe easier on scintilla) -- -- TODO -- --- It would be nice if we could lods some ConTeXt Lua modules (the basic set) and --- then use resolvers and such. +-- It would be nice if we could loads some ConTeXt Lua modules (the basic set) and +-- then use resolvers and such. But it might not work well with scite. -- -- The current lexer basics are still a mix between old and new. Maybe I should redo -- some more. This is probably easier in TextAdept than in SciTE. @@ -300,7 +315,17 @@ local lpegmatch = lpeg.match local usage = (textadept and "textadept") or (resolvers and "context") or "scite" local nesting = 0 -local print = textadept and ui and ui.print or print +local output = nil + +----- print = textadept and ui and ui.print or print -- crashes when ui is not yet defined + +local function print(...) + if not output then + output = io.open("lexer.log","w") + end + output:write(...,"\n") + output:flush() +end local function report(fmt,str,...) if log then @@ -319,6 +344,36 @@ end inform("loading context lexer module (global table: %s)",tostring(global)) +do + + local floor = math and math.floor + local format = format + local tonumber = tonumber + + if not floor then + + if tonumber(string.match(_VERSION,"%d%.%d")) < 5.3 then + floor = function(n) + return tonumber(format("%d",n)) + end + else + -- 5.3 has a mixed number system and format %d doesn't work with + -- floats any longer ... no fun + floor = function(n) + return (n - n % 1) + end + end + + math = math or { } + + math.floor = floor + + end + +end + +local floor = math.floor + if not package.searchpath then -- Unfortunately the io library is only available when we end up @@ -412,7 +467,9 @@ local default = { local predefined = { "default", "linenumber", "bracelight", "bracebad", "controlchar", - "indentguide", "calltip" + "indentguide", "calltip", + -- seems new + "folddisplaytext" } -- Bah ... ugly ... nicer would be a proper hash .. we now have properties @@ -510,9 +567,16 @@ lexers.property_expanded = setmetatable({ }, { check_main_properties() end -- - return gsub(property[k],"[$%%]%b()", function(k) - return t[sub(k,3,-2)] - end) +-- return gsub(property[k],"[$%%]%b()", function(k) +-- return t[sub(k,3,-2)] +-- end) + local v = property[k] + if v then + v = gsub(v,"[$%%]%b()", function(k) + return t[sub(k,3,-2)] + end) + end + return v end, __newindex = function(t,k,v) report("properties are read-only, '%s' is not changed",k) @@ -835,32 +899,42 @@ function context.loaddefinitions(name) return type(data) == "table" and data end +-- A bit of regression in textadept > 10 so updated ... done a bit different. +-- We don't use this in the context lexers anyway. + function context.word_match(words,word_chars,case_insensitive) - local chars = "%w_" -- maybe just "" when word_chars - if word_chars then - chars = "^([" .. chars .. gsub(word_chars,"([%^%]%-])", "%%%1") .."]+)" - else - chars = "^([" .. chars .."]+)" + -- used to be proper tables ... + if type(words) == "string" then + local clean = gsub(words,"%-%-[^\n]+","") + local split = { } + for s in gmatch(clean,"%S+") do + split[#split+1] = s + end + words = split + end + local list = { } + for i=1,#words do + list[words[i]] = true end if case_insensitive then - local word_list = { } - for i=1,#words do - word_list[lower(words[i])] = true - end - return P(function(input, index) - local s, e, word = find(input,chars,index) - return word and word_list[lower(word)] and e + 1 or nil - end) - else - local word_list = { } for i=1,#words do - word_list[words[i]] = true + list[lower(words[i])] = true end - return P(function(input, index) - local s, e, word = find(input,chars,index) - return word and word_list[word] and e + 1 or nil - end) end + local chars = S(word_chars or "") + for i=1,#words do + chars = chars + S(words[i]) + end + local match = case_insensitive and + function(input,index,word) + -- We can speed mixed case if needed. + return (list[word] or list[lower(word)]) and index or nil + end + or + function(input,index,word) + return list[word] and index or nil + end + return Cmt(chars^1,match) end -- Patterns are grouped in a separate namespace but the regular lexers expect @@ -888,6 +962,11 @@ do local hexadecimal = P("0") * S("xX") * (hexdigit^0 * period * hexdigit^1 + hexdigit^1 * period * hexdigit^0 + hexdigit^1) * (S("pP") * sign^-1 * hexdigit^1)^-1 -- * + local integer = sign^-1 + * (hexadecimal + octal + decimal) + local float = sign^-1 + * (digit^0 * period * digit^1 + digit^1 * period * digit^0 + digit^1) + * S("eE") * sign^-1 * digit^1 -- * patterns.idtoken = idtoken patterns.digit = digit @@ -904,15 +983,13 @@ do patterns.decimal = decimal patterns.octal = octal patterns.hexadecimal = hexadecimal - patterns.float = sign^-1 - * (digit^0 * period * digit^1 + digit^1 * period * digit^0 + digit^1) - * S("eE") * sign^-1 * digit^1 -- * + patterns.float = float patterns.cardinal = decimal patterns.signeddecimal = sign^-1 * decimal patterns.signedoctal = sign^-1 * octal patterns.signedhexadecimal = sign^-1 * hexadecimal - patterns.integer = sign^-1 * (hexadecimal + octal + decimal) + patterns.integer = integer patterns.real = sign^-1 * ( -- at most one digit^1 * period * digit^0 -- 10.0 10. @@ -928,6 +1005,7 @@ do patterns.nospacing = (1-space)^1 patterns.eol = eol patterns.newline = P("\r\n") + eol + patterns.backslash = backslash local endof = S("\n\r\f") @@ -943,7 +1021,7 @@ do lexers.extend = extend lexers.alpha = alpha lexers.digit = digit - lexers.alnum = alnum + lexers.alnum = alpha + digit lexers.lower = lower lexers.upper = upper lexers.xdigit = hexdigit @@ -1127,6 +1205,8 @@ local p_nop = newline local folders = { } +-- Snippets from the > 10 code .. but we do things different so ... + local function fold_by_parsing(text,start_pos,start_line,start_level,lexer) local folder = folders[lexer] if not folder then @@ -1136,6 +1216,12 @@ local function fold_by_parsing(text,start_pos,start_line,start_level,lexer) local fold_symbols = lexer._foldsymbols local fold_pattern = lexer._foldpattern -- use lpeg instead (context extension) -- + -- textadept >= 10 + -- + -- local zerosumlines = lexer.property_int["fold.on.zero.sum.lines"] > 0 -- not done + -- local compact = lexer.property_int['fold.compact'] > 0 -- not done + -- local lowercase = lexer._CASEINSENSITIVEFOLDPOINTS -- useless (utf will distort) + -- if fold_pattern then -- if no functions are found then we could have a faster one fold_pattern = Cp() * C(fold_pattern) / function(s,match) @@ -1168,7 +1254,7 @@ local function fold_by_parsing(text,start_pos,start_line,start_level,lexer) -- the traditional one but a bit optimized local fold_symbols_patterns = fold_symbols._patterns local action_y = function(pos,line) - for j = 1, #fold_symbols_patterns do + for j=1, #fold_symbols_patterns do for s, match in gmatch(line,fold_symbols_patterns[j]) do -- "()(" .. patterns[i] .. ")" local symbols = fold_symbols[style_at[start_pos + pos + s - 1]] local l = symbols and symbols[match] @@ -1311,11 +1397,11 @@ function context.fold(lexer,text,start_pos,start_line,start_level) -- hm, we had if filesize <= threshold_by_parsing then return fold_by_parsing(text,start_pos,start_line,start_level,lexer) end - elseif lexer.properties("fold.by.indentation",1) > 0 then + elseif lexer._FOLDBYINDENTATION or lexer.properties("fold.by.indentation",1) > 0 then if filesize <= threshold_by_indentation then return fold_by_indentation(text,start_pos,start_line,start_level,lexer) end - elseif lexer.properties("fold.by.line",1) > 0 then + elseif lexer._FOLDBYLINE or lexer.properties("fold.by.line",1) > 0 then if filesize <= threshold_by_line then return fold_by_line(text,start_pos,start_line,start_level,lexer) end @@ -1334,6 +1420,20 @@ local function add_rule(lexer,id,rule) -- unchanged lexer._RULEORDER[#lexer._RULEORDER + 1] = id end +local function modify_rule(lexer,id,rule) -- needed for textadept > 10 + if lexer._lexer then + lexer = lexer._lexer + end + lexer._RULES[id] = rule +end + +local function get_rule(lexer,id) -- needed for textadept > 10 + if lexer._lexer then + lexer = lexer._lexer + end + return lexer._RULES[id] +end + -- I finally figured out that adding more styles was an issue because of several -- reasons: -- @@ -1357,12 +1457,12 @@ local function add_style(lexer,token_name,style) -- changed a bit around 3.41 if trace and detail then report("default style '%s' is ignored as extra style",token_name) end - return +-- return elseif predefinedstyles[token_name] then if trace and detail then report("predefined style '%s' is ignored as extra style",token_name) end - return +-- return else if trace and detail then report("adding extra style '%s' as '%s'",token_name,style) @@ -1379,6 +1479,7 @@ local function add_style(lexer,token_name,style) -- changed a bit around 3.41 lexer._TOKENSTYLES[token_name] = num_styles lexer._EXTRASTYLES[token_name] = style lexer._numstyles = num_styles + 1 + -- hm, the original (now) also copies to the parent ._lexer end local function check_styles(lexer) @@ -1428,6 +1529,8 @@ local function join_tokens(lexer) -- slightly different from the original (no 'a end end +-- hm, maybe instead of a grammer just a flat one + local function add_lexer(grammar, lexer) -- mostly the same as the original local token_rule = join_tokens(lexer) local lexer_name = lexer._NAME @@ -1533,17 +1636,17 @@ local function matched(lexer,grammar,text) else txt = "!no text!" end - report("%4i : %s > %s (%s) (%s)",n/2,ti,tn,s[ti] or "!unset!",txt) + report("%4i : %s > %s (%s) (%s)",floor(n/2),ti,tn,s[ti] or "!unset!",txt) p = tn else break end end end - report("lexer results: %s, length: %s, ranges: %s",lexer._NAME,#text,#t/2) + report("lexer results: %s, length: %s, ranges: %s",lexer._NAME,#text,floor(#t/2)) if collapse then t = collapsed(t) - report("lexer collapsed: %s, length: %s, ranges: %s",lexer._NAME,#text,#t/2) + report("lexer collapsed: %s, length: %s, ranges: %s",lexer._NAME,#text,floor(#t/2)) end elseif collapse then t = collapsed(t) @@ -1553,6 +1656,9 @@ end -- Todo: make nice generic lexer (extra argument with start/stop commands) for -- context itself. +-- +-- In textadept >= 10 grammar building seem to have changed a bit. So, in retrospect +-- I could better have just dropped compatibility and stick to ctx lexers only. function context.lex(lexer,text,init_style) -- local lexer = global._LEXER @@ -1623,9 +1729,9 @@ function context.lex(lexer,text,init_style) hash[init_style] = grammar end if trace then - report("lexing '%s' with initial style '%s' and %s children",lexer._NAME,#lexer._CHILDREN or 0,init_style) + report("lexing '%s' with initial style '%s' and %s children", lexer._NAME,init_style,#lexer._CHILDREN or 0) end - return result + return matched(lexer,grammar,text) else if trace then report("lexing '%s' with initial style '%s'",lexer._NAME,init_style) @@ -1634,7 +1740,8 @@ function context.lex(lexer,text,init_style) end end --- hm, changed in 3.24 .. no longer small table but one table: +-- hm, changed in 3.24 .. no longer small table but one table (so we could remove our +-- agressive optimization which worked quite well) function context.token(name, patt) return patt * Cc(name) * Cp() @@ -1687,6 +1794,8 @@ function context.new(name,filename) -- name = name, filename = filename, + -- +-- _tokenstyles = context.styleset, } if trace then report("initializing lexer tagged '%s' from file '%s'",name,filename or name) @@ -1694,6 +1803,7 @@ function context.new(name,filename) check_whitespace(lexer) check_styles(lexer) check_properties(lexer) + lexer._tokenstyles = context.styleset return lexer end @@ -1799,7 +1909,36 @@ end -- namespace can be automatic: if parent then use name of parent (chain) +-- The original lexer framework had a rather messy user uinterface (e.g. moving +-- stuff from _rules to _RULES at some point but I could live with that. Now it uses +-- add_ helpers. But the subsystem is still not clean and pretty. Now, I can move to +-- the add_ but there is no gain in it so we support a mix which gives somewhat ugly +-- code. In fact, there should be proper subtables for this. I might actually do +-- this because we now always overload the normal lexer (parallel usage seems no +-- longer possible). For SciTE we can actually do a conceptual upgrade (more the +-- context way) because there is no further development there. That way we could +-- make even more advanced lexers. + +local savedrequire = require + +local escapes = { + ["%"] = "%%", + ["."] = "%.", + ["+"] = "%+", ["-"] = "%-", ["*"] = "%*", + ["["] = "%[", ["]"] = "%]", + ["("] = "%(", [")"] = "%)", + -- ["{"] = "%{", ["}"] = "%}" + -- ["^"] = "%^", ["$"] = "%$", +} + function context.loadlexer(filename,namespace) + + if textadept then + require = function(name) + return savedrequire(name == "lexer" and "scite-context-lexer" or name) + end + end + nesting = nesting + 1 if not namespace then namespace = filename @@ -1824,7 +1963,7 @@ function context.loadlexer(filename,namespace) lexer = load_lexer(filename,namespace) or nolexer(filename,namespace) usedlexers[filename] = lexer -- - if not lexer._rules and not lexer._lexer and not lexer_grammar then + if not lexer._rules and not lexer._lexer and not lexer_grammar then -- hmm should be lexer._grammar lexer._lexer = parent_lexer end -- @@ -1871,6 +2010,9 @@ function context.loadlexer(filename,namespace) end end build_grammar(lexer) + else + -- other lexers + build_grammar(lexer) end -- add_style(lexer, lexer.whitespace, lexers.STYLE_WHITESPACE) @@ -1880,7 +2022,7 @@ function context.loadlexer(filename,namespace) local patterns = foldsymbols._patterns if patterns then for i = 1, #patterns do - patterns[i] = "()(" .. patterns[i] .. ")" + patterns[i] = "()(" .. gsub(patterns[i],".",escapes) .. ")" end end end @@ -1894,6 +2036,10 @@ function context.loadlexer(filename,namespace) context.inspect(lexer) end -- + if textadept then + require = savedrequire + end + -- return lexer end @@ -1971,6 +2117,17 @@ function context.embed_lexer(parent, child, start_rule, end_rule) -- mostly the end end end + -- newer, textadept >= 10, whatever ... + local childsymbols = child._FOLDPOINTS + if childsymbols then + for token, symbols in next, childsymbols do + if token ~= "_SYMBOLS" then + for symbol, v in next, symbols do + lexer:add_fold_point(token_name, symbol, v) + end + end + end + end -- child._lexer = parent parent_lexer = parent @@ -1993,8 +2150,8 @@ lexers.inspect = context.inspect lexers.report = context.report lexers.inform = context.inform --- helper .. alas ... the lexer's lua instance is rather crippled .. not even --- math is part of it +-- helper .. alas ... in scite the lexer's lua instance is rather crippled .. not +-- even math is part of it do @@ -2003,26 +2160,6 @@ do local format = format local tonumber = tonumber - if not floor then - - if tonumber(string.match(_VERSION,"%d%.%d")) < 5.3 then - floor = function(n) - return tonumber(format("%d",n)) - end - else - -- 5.3 has a mixed number system and format %d doesn't work with - -- floats any longer ... no fun - floor = function(n) - return (n - n % 1) - end - end - - math = math or { } - - math.floor = floor - - end - local function utfchar(n) if n < 0x80 then return char(n) @@ -2398,6 +2535,128 @@ function lexers.fold_line_comments(prefix) end end +-- There are some fundamental changes in textadept version 10 and I don't want to +-- adapt again so we go the reverse route: map new to old. This is needed because +-- we need to load other lexers which is teh result of not being able to load the +-- lexer framework in parallel. Something happened in 10 that makes the main lexer +-- always enforced so now we need to really replace that one (and even then it loads +-- twice (i can probably sort that out). Maybe there's now some hard coded magic +-- in the binary. + +if textadept then + + -- Folds are still somewhat weak because of the end condition not being + -- bound to a start .. probably to complex and it seems to work anyhow. As + -- we have extended thinsg we just remap. + + local function add_fold_point(lexer,token_name,start_symbol,end_symbol) + if type(start_symbol) == "string" then + local foldsymbols = lexer._foldsymbols + if not foldsymbols then + foldsymbols = { } + lexer._foldsymbols = foldsymbols + end + local patterns = foldsymbols._patterns + if not patterns then + patterns = { } + usedpatt = { } -- > 10 uses a mixed index/hash (we don't use patterns) + foldsymbols._patterns = patterns + foldsymbols._usedpatt = usedpatt + end + local foldsymbol = foldsymbols[token_name] + if not foldsymbol then + foldsymbol = { } + foldsymbols[token_name] = foldsymbol + end + if not usedpatt[start_symbol] then + patterns[#patterns+1] = start_symbol + usedpatt[start_symbol] = true + end + if type(end_symbol) == "string" then + foldsymbol[start_symbol] = 1 + foldsymbol[end_symbol] = -1 + if not usedpatt[end_symbol] then + patterns[#patterns+1] = end_symbol + usedpatt[end_symbol] = true + end + else + foldsymbol[start_symbol] = end_symbol + end + end + end + + local function add_style(lexer,name,style) + local tokenstyles = lexer._tokenstyles + if not tokenstyles then + tokenstyles = { } + lexer._tokenstyles = tokenstyles + end + tokenstyles[name] = style + end + + local function add_rule(lexer,id,rule) + local rules = lexer._rules + if not rules then + rules = { } + lexer._rules = rules + end + rules[#rules+1] = { id, rule } + end + + local function modify_rule(lexer,id,rule) -- needed for textadept > 10 + if lexer._lexer then + lexer = lexer._lexer + end + local RULES = lexer._RULES + if RULES then + RULES[id] = rule + end + end + + local function get_rule(lexer,id) -- needed for textadept > 10 + if lexer._lexer then + lexer = lexer._lexer + end + local RULES = lexer._RULES + if RULES then + return RULES[id] + end + end + + local new = context.new + local lmt = { + __index = { + + add_rule = add_rule, + modify_rule = modify_rule, + get_rule = get_rule, + add_style = add_style, + add_fold_point = add_fold_point, + + join_tokens = join_tokens, + build_grammar = build_grammar, + + embed = lexers.embed, + lex = lexers.lex, + fold = lexers.fold + + } + } + + function lexers.new(name,options) + local lexer = new(name) + if options then + lexer._LEXBYLINE = options['lex_by_line'] + lexer._FOLDBYINDENTATION = options['fold_by_indentation'] + lexer._CASEINSENSITIVEFOLDPOINTS = options['case_insensitive_fold_points'] + lexer._lexer = options['inherit'] + end + setmetatable(lexer,lmt) + return lexer + end + +end + -- done return lexers diff --git a/context/data/textadept/context/lexers/text.lua b/context/data/textadept/context/lexers/text.lua new file mode 100644 index 000000000..5d3096b7d --- /dev/null +++ b/context/data/textadept/context/lexers/text.lua @@ -0,0 +1,35 @@ +local info = { + version = 1.002, + comment = "scintilla lpeg lexer that triggers whitespace backtracking", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files", +} + +-- the lexer dll doesn't backtrack when there is no embedded lexer so +-- we need to trigger that, for instance in the bibtex lexer, but still +-- we get failed lexing + +local lexer = require("scite-context-lexer") +local context = lexer.context +local patterns = context.patterns + +local token = lexer.token + +local dummylexer = lexer.new("dummy","scite-context-lexer-dummy") +local whitespace = dummylexer.whitespace + +local space = patterns.space +local nospace = (1-space) + +local t_spacing = token(whitespace, space ^1) +local t_rest = token("default", nospace^1) + +dummylexer._rules = { + { "whitespace", t_spacing }, + { "rest", t_rest }, +} + +dummylexer._tokenstyles = context.styleset + +return dummylexer diff --git a/context/data/textadept/context/modules/textadept-context-files.lua b/context/data/textadept/context/modules/textadept-context-files.lua index d3412edc1..28cc794cb 100644 --- a/context/data/textadept/context/modules/textadept-context-files.lua +++ b/context/data/textadept/context/modules/textadept-context-files.lua @@ -366,7 +366,7 @@ do } - newkeys[OSX and 'mc' or 'cc'] = runner.check + -- newkeys[OSX and 'mc' or 'cc'] = runner.check newkeys[OSX and 'mr' or 'cr'] = runner.process newkeys[OSX and 'mp' or 'cp'] = runner.preview -- newkeys[OSX and 'mx' or 'cx'] = runner.quit -- makes no sense @@ -529,7 +529,7 @@ end do - -- It's a pity that we can't have a proper monospaced font here so we try to make the best of it: + -- It's a pitt y that we can't have a proper monospaced font here so we try to make the best of it: local template = "\n\trelease info: %s\t\n\n\tcopyright: %s\t\n\n\tvariant: ConTeXt related editing\t\n\n\tadapted by: Hans Hagen\t" @@ -697,7 +697,7 @@ local function synchronize(lexer) end events.connect(events.FILE_OPENED,function(filename) - synchronize(buffer.get_lexer(buffer)) + synchronize(buffer:get_lexer()) end) events.connect(events.LEXER_LOADED,function(lexer) @@ -707,23 +707,23 @@ end) -- obsolete -- events.connect(events.BUFFER_AFTER_SWITCH,function() --- synchronize(buffer.get_lexer(buffer)) +-- synchronize(buffer:get_lexer()) -- end) -- events.connect(events.VIEW_AFTER_SWITCH,function() --- synchronize(buffer.get_lexer(buffer)) +-- synchronize(buffer:get_lexer()) -- end) -- events.connect(events.BUFFER_NEW,function() --- synchronize(buffer.get_lexer(buffer)) +-- synchronize(buffer:get_lexer()) -- end) -- events.connect(events.VIEW_NEW,function() --- synchronize(buffer.get_lexer(buffer)) +-- synchronize(buffer:get_lexer()) -- end) -- events.connect(events.RESET_AFTER,function() --- synchronize(buffer.get_lexer(buffer)) +-- synchronize(buffer:get_lexer()) -- end) -- local oldtools = { } diff --git a/context/data/textadept/context/modules/textadept-context-settings.lua b/context/data/textadept/context/modules/textadept-context-settings.lua index 53b5c896f..4a5be38da 100644 --- a/context/data/textadept/context/modules/textadept-context-settings.lua +++ b/context/data/textadept/context/modules/textadept-context-settings.lua @@ -95,21 +95,41 @@ if context then buffer.annotation_visible = buffer.ANNOTATION_BOXED - -- local NUMBER_MARGIN = 0 - -- local MARKER_MARGIN = 1 - -- local FOLD_MARGIN = 2 -- there are more - -- - -- buffer.margin_type_n [NUMBER_MARGIN] = buffer.MARGIN_NUMBER - -- buffer.margin_width_n[NUMBER_MARGIN] = (CURSES and 0 or 4) - -- + 4 * buffer:text_width(buffer.STYLE_LINENUMBER,'9') -- magic - -- buffer.margin_width_n[MARKER_MARGIN] = CURSES and 1 or 4 - -- buffer.margin_width_n[FOLD_MARGIN] = CURSES and 1 or 12 - -- - -- buffer.margin_mask_n[FOLD_MARGIN] = buffer.MASK_FOLDERS + local NUMBER_MARGIN = 0 + local MARKER_MARGIN = 1 + local FOLD_MARGIN = 2 -- there are more + + buffer.margin_type_n [NUMBER_MARGIN] = buffer.MARGIN_NUMBER + buffer.margin_width_n[NUMBER_MARGIN] = (CURSES and 0 or 6) + 4 * buffer:text_width(buffer.STYLE_LINENUMBER,'9') -- magic + buffer.margin_width_n[MARKER_MARGIN] = CURSES and 1 or 18 + buffer.margin_width_n[FOLD_MARGIN] = CURSES and 1 or 18 + + buffer.margin_mask_n[FOLD_MARGIN] = buffer.MASK_FOLDERS -- does something weird: bullets + + buffer:marker_define(buffer.MARKNUM_FOLDEROPEN, buffer.MARK_BOXMINUS) + buffer:marker_define(buffer.MARKNUM_FOLDER, buffer.MARK_BOXPLUS) + buffer:marker_define(buffer.MARKNUM_FOLDERSUB, buffer.MARK_VLINE) + buffer:marker_define(buffer.MARKNUM_FOLDERTAIL, buffer.MARK_LCORNER) + buffer:marker_define(buffer.MARKNUM_FOLDEREND, buffer.MARK_BOXPLUSCONNECTED) + buffer:marker_define(buffer.MARKNUM_FOLDEROPENMID, buffer.MARK_BOXMINUSCONNECTED) + buffer:marker_define(buffer.MARKNUM_FOLDERMIDTAIL, buffer.MARK_TCORNER) + + -- buffer.fold_all = buffer.FOLDACTION_CONTRACT + buffer.FOLDACTION_EXPAND + buffer.FOLDACTION_TOGGLE + + -- somehow the foldeing sumbol sin th emargin cannot be clicked on ... there seems to be some + -- interface .. if this needs to be implemented via events i'll then probably make a copy and + -- start doing all + + -- buffer.margin_sensitive_n[2] = true + + -- buffer.property['fold'] = "1" + -- buffer.automatic_fold = buffer.AUTOMATICFOLD_SHOW + buffer.AUTOMATICFOLD_CLICK + buffer.AUTOMATICFOLD_CHANGE + -- buffer.fold_flags = not CURSES and buffer.FOLDFLAG_LINEAFTER_CONTRACTED or 0 + -- buffer.fold_display_text_style = buffer.FOLDDISPLAYTEXT_BOXED buffer.wrap_mode = buffer.WRAP_NONE - buffer.margin_back_n[0] = property_int["color.linenumber"] -- doesn't work + buffer.margin_back_n[NUMBER_MARGIN] = property_int["color.linenumber"] -- doesn't work buffer.property = { -- ["style.linenumber"] = property["style.linenumber"], -- somehow it fails diff --git a/doc/context/documents/general/qrcs/setup-cs.pdf b/doc/context/documents/general/qrcs/setup-cs.pdf Binary files differindex 1d77b7e07..a051aa83b 100644 --- a/doc/context/documents/general/qrcs/setup-cs.pdf +++ b/doc/context/documents/general/qrcs/setup-cs.pdf diff --git a/doc/context/documents/general/qrcs/setup-de.pdf b/doc/context/documents/general/qrcs/setup-de.pdf Binary files differindex 32375b2d4..582e2e714 100644 --- a/doc/context/documents/general/qrcs/setup-de.pdf +++ b/doc/context/documents/general/qrcs/setup-de.pdf diff --git a/doc/context/documents/general/qrcs/setup-en.pdf b/doc/context/documents/general/qrcs/setup-en.pdf Binary files differindex 481f716ed..41053bae2 100644 --- a/doc/context/documents/general/qrcs/setup-en.pdf +++ b/doc/context/documents/general/qrcs/setup-en.pdf diff --git a/doc/context/documents/general/qrcs/setup-fr.pdf b/doc/context/documents/general/qrcs/setup-fr.pdf Binary files differindex e71d908ba..eb079f479 100644 --- a/doc/context/documents/general/qrcs/setup-fr.pdf +++ b/doc/context/documents/general/qrcs/setup-fr.pdf diff --git a/doc/context/documents/general/qrcs/setup-it.pdf b/doc/context/documents/general/qrcs/setup-it.pdf Binary files differindex d935e0da8..1a6b25443 100644 --- a/doc/context/documents/general/qrcs/setup-it.pdf +++ b/doc/context/documents/general/qrcs/setup-it.pdf diff --git a/doc/context/documents/general/qrcs/setup-mapping-cs.pdf b/doc/context/documents/general/qrcs/setup-mapping-cs.pdf Binary files differindex df65fc44c..b2a031201 100644 --- a/doc/context/documents/general/qrcs/setup-mapping-cs.pdf +++ b/doc/context/documents/general/qrcs/setup-mapping-cs.pdf diff --git a/doc/context/documents/general/qrcs/setup-mapping-de.pdf b/doc/context/documents/general/qrcs/setup-mapping-de.pdf Binary files differindex fdbfd33a0..bfb7b7fd9 100644 --- a/doc/context/documents/general/qrcs/setup-mapping-de.pdf +++ b/doc/context/documents/general/qrcs/setup-mapping-de.pdf diff --git a/doc/context/documents/general/qrcs/setup-mapping-en.pdf b/doc/context/documents/general/qrcs/setup-mapping-en.pdf Binary files differindex 9f077ab20..e9dd9a6a2 100644 --- a/doc/context/documents/general/qrcs/setup-mapping-en.pdf +++ b/doc/context/documents/general/qrcs/setup-mapping-en.pdf diff --git a/doc/context/documents/general/qrcs/setup-mapping-fr.pdf b/doc/context/documents/general/qrcs/setup-mapping-fr.pdf Binary files differindex 2d7fadadc..98ee1af19 100644 --- a/doc/context/documents/general/qrcs/setup-mapping-fr.pdf +++ b/doc/context/documents/general/qrcs/setup-mapping-fr.pdf diff --git a/doc/context/documents/general/qrcs/setup-mapping-it.pdf b/doc/context/documents/general/qrcs/setup-mapping-it.pdf Binary files differindex 414574e20..1d7fe71e0 100644 --- a/doc/context/documents/general/qrcs/setup-mapping-it.pdf +++ b/doc/context/documents/general/qrcs/setup-mapping-it.pdf diff --git a/doc/context/documents/general/qrcs/setup-mapping-nl.pdf b/doc/context/documents/general/qrcs/setup-mapping-nl.pdf Binary files differindex 263ff5bd5..8a8b818d0 100644 --- a/doc/context/documents/general/qrcs/setup-mapping-nl.pdf +++ b/doc/context/documents/general/qrcs/setup-mapping-nl.pdf diff --git a/doc/context/documents/general/qrcs/setup-mapping-ro.pdf b/doc/context/documents/general/qrcs/setup-mapping-ro.pdf Binary files differindex 4155630dc..53767e457 100644 --- a/doc/context/documents/general/qrcs/setup-mapping-ro.pdf +++ b/doc/context/documents/general/qrcs/setup-mapping-ro.pdf diff --git a/doc/context/documents/general/qrcs/setup-nl.pdf b/doc/context/documents/general/qrcs/setup-nl.pdf Binary files differindex 139d612e7..ba0cf20d2 100644 --- a/doc/context/documents/general/qrcs/setup-nl.pdf +++ b/doc/context/documents/general/qrcs/setup-nl.pdf diff --git a/doc/context/documents/general/qrcs/setup-ro.pdf b/doc/context/documents/general/qrcs/setup-ro.pdf Binary files differindex ee7ffc260..022fe5f3f 100644 --- a/doc/context/documents/general/qrcs/setup-ro.pdf +++ b/doc/context/documents/general/qrcs/setup-ro.pdf diff --git a/metapost/context/base/mpiv/mp-mlib.mpiv b/metapost/context/base/mpiv/mp-mlib.mpiv index abef3d52c..b80d2b564 100644 --- a/metapost/context/base/mpiv/mp-mlib.mpiv +++ b/metapost/context/base/mpiv/mp-mlib.mpiv @@ -74,16 +74,16 @@ def namedcolor expr n = withprescript "sp_name=" & n enddef ; -% def spotcolor(expr n, v) = +% def mfun_spotcolor(expr n, v) = % 1 -% withprescript "sp_type=spot" +% withprescript "sp_type=xspot" % withprescript "sp_name=" & n % withprescript "sp_value=" & (if numeric v : decimal v else : v fi) % enddef ; -% -% def multitonecolor(expr name, fractions, components, value) = + +% def mfun_multispotcolor(expr name, fractions, components, value) = % 1 -% withprescript "sp_type=multitone" +% withprescript "sp_type=multispot" % withprescript "sp_name=" & name % withprescript "sp_fractions=" & decimal fractions % withprescript "sp_components=" & components @@ -97,6 +97,8 @@ def spotcolor(expr name, v) = withprescript "sp_value=" & colordecimals v enddef ; +% In this case a mixed color will be calculated: + def multitonecolor(expr name)(text t) = (1) withprescript "sp_type=multitone" diff --git a/metapost/context/base/mpiv/mp-tool.mpiv b/metapost/context/base/mpiv/mp-tool.mpiv index 281767522..8a11d8fda 100644 --- a/metapost/context/base/mpiv/mp-tool.mpiv +++ b/metapost/context/base/mpiv/mp-tool.mpiv @@ -2883,13 +2883,15 @@ enddef ; % This could be standard mplib 2 behaviour: +% vardef rcomponent expr p = if rgbcolor p : redpart elseif cmykcolor p : 1 - cyanpart fi p enddef ; + vardef rcomponent expr p = if rgbcolor p : redpart p elseif cmykcolor p : 1 - cyanpart p else : p fi enddef ; vardef gcomponent expr p = if rgbcolor p : greenpart p elseif cmykcolor p : 1 - magentapart p else : p fi enddef ; vardef bcomponent expr p = if rgbcolor p : bluepart p elseif cmykcolor p : 1 - yellowpart p else : p fi enddef ; vardef ccomponent expr p = if cmykcolor p : cyanpart p elseif rgbcolor p : 1 - redpart p else : p fi enddef ; vardef mcomponent expr p = if cmykcolor p : magentapart p elseif rgbcolor p : 1 - greenpart p else : p fi enddef ; vardef ycomponent expr p = if cmykcolor p : yellowpart p elseif rgbcolor p : 1 - bluepart p else : p fi enddef ; -vardef bcomponent expr p = if cmykcolor p : blackpart p elseif rgbcolor p : 0 else : p fi enddef ; +vardef kcomponent expr p = if cmykcolor p : blackpart p elseif rgbcolor p : 0 else : p fi enddef ; % draw image (...) ... ; % prescripts prepended to first, postscripts appended to last % draw decorated (...) ... ; % prescripts prepended to each, postscripts appended to each diff --git a/scripts/context/lua/mtxrun.lua b/scripts/context/lua/mtxrun.lua index 99c9fd3f2..555e662e3 100644 --- a/scripts/context/lua/mtxrun.lua +++ b/scripts/context/lua/mtxrun.lua @@ -9213,6 +9213,2827 @@ end -- of closure do -- create closure to overcome 200 locals limit +package.loaded["util-soc-imp-reset"] = package.loaded["util-soc-imp-reset"] or true + +-- original size: 374, stripped down to: 282 + +local loaded=package.loaded +loaded["socket"]=nil +loaded["copas"]=nil +loaded["ltn12"]=nil +loaded["mbox"]=nil +loaded["mime"]=nil +loaded["socket.url"]=nil +loaded["socket.headers"]=nil +loaded["socket.tp"]=nil +loaded["socket.http"]=nil +loaded["socket.ftp"]=nil +loaded["socket.smtp"]=nil + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +package.loaded["util-soc-imp-socket"] = package.loaded["util-soc-imp-socket"] or true + +-- original size: 4867, stripped down to: 3858 + + +local type,tostring,setmetatable=type,tostring,setmetatable +local min=math.min +local format=string.format +local socket=require("socket.core") +local connect=socket.connect +local tcp4=socket.tcp4 +local tcp6=socket.tcp6 +local getaddrinfo=socket.dns.getaddrinfo +local defaulthost="0.0.0.0" +local function report(fmt,first,...) + if logs then + report=logs and logs.reporter("socket") + report(fmt,first,...) + elseif fmt then + fmt="socket: "..fmt + if first then + print(format(fmt,first,...)) + else + print(fmt) + end + end +end +socket.report=report +function socket.connect4(address,port,laddress,lport) + return connect(address,port,laddress,lport,"inet") +end +function socket.connect6(address,port,laddress,lport) + return connect(address,port,laddress,lport,"inet6") +end +function socket.bind(host,port,backlog) + if host=="*" or host=="" then + host=defaulthost + end + local addrinfo,err=getaddrinfo(host) + if not addrinfo then + return nil,err + end + for i=1,#addrinfo do + local alt=addrinfo[i] + local sock,err=(alt.family=="inet" and tcp4 or tcp6)() + if not sock then + return nil,err or "unknown error" + end + sock:setoption("reuseaddr",true) + local res,err=sock:bind(alt.addr,port) + if res then + res,err=sock:listen(backlog) + if res then + return sock + else + sock:close() + end + else + sock:close() + end + end + return nil,"invalid address" +end +socket.try=socket.newtry() +function socket.choose(list) + return function(name,opt1,opt2) + if type(name)~="string" then + name,opt1,opt2="default",name,opt1 + end + local f=list[name or "nil"] + if f then + return f(opt1,opt2) + else + report("error: unknown key '%s'",tostring(name)) + end + end +end +local sourcet={} +local sinkt={} +socket.sourcet=sourcet +socket.sinkt=sinkt +socket.BLOCKSIZE=2048 +sinkt["close-when-done"]=function(sock) + return setmetatable ( + { + getfd=function() return sock:getfd() end, + dirty=function() return sock:dirty() end, + }, + { + __call=function(self,chunk,err) + if chunk then + return sock:send(chunk) + else + sock:close() + return 1 + end + end + } + ) +end +sinkt["keep-open"]=function(sock) + return setmetatable ( + { + getfd=function() return sock:getfd() end, + dirty=function() return sock:dirty() end, + },{ + __call=function(self,chunk,err) + if chunk then + return sock:send(chunk) + else + return 1 + end + end + } + ) +end +sinkt["default"]=sinkt["keep-open"] +socket.sink=socket.choose(sinkt) +sourcet["by-length"]=function(sock,length) + local blocksize=socket.BLOCKSIZE + return setmetatable ( + { + getfd=function() return sock:getfd() end, + dirty=function() return sock:dirty() end, + }, + { + __call=function() + if length<=0 then + return nil + end + local chunk,err=sock:receive(min(blocksize,length)) + if err then + return nil,err + end + length=length-#chunk + return chunk + end + } + ) +end +sourcet["until-closed"]=function(sock) + local blocksize=socket.BLOCKSIZE + local done=false + return setmetatable ( + { + getfd=function() return sock:getfd() end, + dirty=function() return sock:dirty() end, + },{ + __call=function() + if done then + return nil + end + local chunk,status,partial=sock:receive(blocksize) + if not status then + return chunk + elseif status=="closed" then + sock:close() + done=true + return partial + else + return nil,status + end + end + } + ) +end +sourcet["default"]=sourcet["until-closed"] +socket.source=socket.choose(sourcet) +_G.socket=socket +package.loaded.socket=socket + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +package.loaded["util-soc-imp-copas"] = package.loaded["util-soc-imp-copas"] or true + +-- original size: 25841, stripped down to: 16063 + + +local socket=socket or require("socket") +local ssl=ssl or nil +local WATCH_DOG_TIMEOUT=120 +local UDP_DATAGRAM_MAX=8192 +local type,next,pcall,getmetatable,tostring=type,next,pcall,getmetatable,tostring +local min,max,random=math.min,math.max,math.random +local find=string.find +local insert,remove=table.insert,table.remove +local gettime=socket.gettime +local selectsocket=socket.select +local createcoroutine=coroutine.create +local resumecoroutine=coroutine.resume +local yieldcoroutine=coroutine.yield +local runningcoroutine=coroutine.running +local function report(fmt,first,...) + if logs then + report=logs and logs.reporter("copas") + report(fmt,first,...) + elseif fmt then + fmt="copas: "..fmt + if first then + print(format(fmt,first,...)) + else + print(fmt) + end + end +end +local copas={ + _COPYRIGHT="Copyright (C) 2005-2016 Kepler Project", + _DESCRIPTION="Coroutine Oriented Portable Asynchronous Services", + _VERSION="Copas 2.0.1", + autoclose=true, + running=false, + report=report, +} +local function statushandler(status,...) + if status then + return... + end + local err=(...) + if type(err)=="table" then + err=err[1] + end + report("error: %s",tostring(err)) + return nil,err +end +function socket.protect(func) + return function(...) + return statushandler(pcall(func,...)) + end +end +function socket.newtry(finalizer) + return function (...) + local status=(...) + if not status then + local detail=select(2,...) + pcall(finalizer,detail) + report("error: %s",tostring(detail)) + return + end + return... + end +end +local function newset() + local reverse={} + local set={} + local queue={} + setmetatable(set,{ + __index={ + insert=function(set,value) + if not reverse[value] then + local n=#set+1 + set[n]=value + reverse[value]=n + end + end, + remove=function(set,value) + local index=reverse[value] + if index then + reverse[value]=nil + local n=#set + local top=set[n] + set[n]=nil + if top~=value then + reverse[top]=index + set[index]=top + end + end + end, + push=function (set,key,itm) + local entry=queue[key] + if entry==nil then + queue[key]={ itm } + else + entry[#entry+1]=itm + end + end, + pop=function (set,key) + local top=queue[key] + if top~=nil then + local ret=remove(top,1) + if top[1]==nil then + queue[key]=nil + end + return ret + end + end + } + } ) + return set +end +local _sleeping={ + times={}, + cos={}, + lethargy={}, + insert=function() + end, + remove=function() + end, + push=function(self,sleeptime,co) + if not co then + return + end + if sleeptime<0 then + self.lethargy[co]=true + return + else + sleeptime=gettime()+sleeptime + end + local t=self.times + local c=self.cos + local i=1 + local n=#t + while i<=n and t[i]<=sleeptime do + i=i+1 + end + insert(t,i,sleeptime) + insert(c,i,co) + end, + getnext= + function(self) + local t=self.times + local delay=t[1] and t[1]-gettime() or nil + return delay and max(delay,0) or nil + end, + pop= + function(self,time) + local t=self.times + local c=self.cos + if #t==0 or time<t[1] then + return + end + local co=c[1] + remove(t,1) + remove(c,1) + return co + end, + wakeup=function(self,co) + local let=self.lethargy + if let[co] then + self:push(0,co) + let[co]=nil + else + local c=self.cos + local t=self.times + for i=1,#c do + if c[i]==co then + remove(c,i) + remove(t,i) + self:push(0,co) + return + end + end + end + end +} +local _servers=newset() +local _reading=newset() +local _writing=newset() +local _reading_log={} +local _writing_log={} +local _is_timeout={ + timeout=true, + wantread=true, + wantwrite=true, +} +local function isTCP(socket) + return not find(tostring(socket),"^udp") +end +local function copasreceive(client,pattern,part) + if not pattern or pattern=="" then + pattern="*l" + end + local current_log=_reading_log + local s,err + repeat + s,err,part=client:receive(pattern,part) + if s or (not _is_timeout[err]) then + current_log[client]=nil + return s,err,part + end + if err=="wantwrite" then + current_log=_writing_log + current_log[client]=gettime() + yieldcoroutine(client,_writing) + else + current_log=_reading_log + current_log[client]=gettime() + yieldcoroutine(client,_reading) + end + until false +end +local function copasreceivefrom(client,size) + local s,err,port + if not size or size==0 then + size=UDP_DATAGRAM_MAX + end + repeat + s,err,port=client:receivefrom(size) + if s or err~="timeout" then + _reading_log[client]=nil + return s,err,port + end + _reading_log[client]=gettime() + yieldcoroutine(client,_reading) + until false +end +local function copasreceivepartial(client,pattern,part) + if not pattern or pattern=="" then + pattern="*l" + end + local logger=_reading_log + local queue=_reading + local s,err + repeat + s,err,part=client:receive(pattern,part) + if s or (type(pattern)=="number" and part~="" and part) or not _is_timeout[err] then + logger[client]=nil + return s,err,part + end + if err=="wantwrite" then + logger=_writing_log + queue=_writing + else + logger=_reading_log + queue=_reading + end + logger[client]=gettime() + yieldcoroutine(client,queue) + until false +end +local function copassend(client,data,from,to) + if not from then + from=1 + end + local lastIndex=from-1 + local logger=_writing_log + local queue=_writing + local s,err + repeat + s,err,lastIndex=client:send(data,lastIndex+1,to) + if random(100)>90 then + logger[client]=gettime() + yieldcoroutine(client,queue) + end + if s or not _is_timeout[err] then + logger[client]=nil + return s,err,lastIndex + end + if err=="wantread" then + logger=_reading_log + queue=_reading + else + logger=_writing_log + queue=_writing + end + logger[client]=gettime() + yieldcoroutine(client,queue) + until false +end +local function copassendto(client,data,ip,port) + repeat + local s,err=client:sendto(data,ip,port) + if random(100)>90 then + _writing_log[client]=gettime() + yieldcoroutine(client,_writing) + end + if s or err~="timeout" then + _writing_log[client]=nil + return s,err + end + _writing_log[client]=gettime() + yieldcoroutine(client,_writing) + until false +end +local function copasconnect(skt,host,port) + skt:settimeout(0) + local ret,err,tried_more_than_once + repeat + ret,err=skt:connect (host,port) + if ret or (err~="timeout" and err~="Operation already in progress") then + if not ret and err=="already connected" and tried_more_than_once then + ret=1 + err=nil + end + _writing_log[skt]=nil + return ret,err + end + tried_more_than_once=tried_more_than_once or true + _writing_log[skt]=gettime() + yieldcoroutine(skt,_writing) + until false +end +local function copasdohandshake(skt,sslt) + if not ssl then + ssl=require("ssl") + end + if not ssl then + report("error: no ssl library") + return + end + local nskt,err=ssl.wrap(skt,sslt) + if not nskt then + report("error: %s",tostring(err)) + return + end + nskt:settimeout(0) + local queue + repeat + local success,err=nskt:dohandshake() + if success then + return nskt + elseif err=="wantwrite" then + queue=_writing + elseif err=="wantread" then + queue=_reading + else + report("error: %s",tostring(err)) + return + end + yieldcoroutine(nskt,queue) + until false +end +local function copasflush(client) +end +copas.connect=copassconnect +copas.send=copassend +copas.sendto=copassendto +copas.receive=copasreceive +copas.receivefrom=copasreceivefrom +copas.copasreceivepartial=copasreceivepartial +copas.copasreceivePartial=copasreceivepartial +copas.dohandshake=copasdohandshake +copas.flush=copasflush +local function _skt_mt_tostring(self) + return tostring(self.socket).." (copas wrapped)" +end +local _skt_mt_tcp_index={ + send=function(self,data,from,to) + return copassend (self.socket,data,from,to) + end, + receive=function (self,pattern,prefix) + if self.timeout==0 then + return copasreceivePartial(self.socket,pattern,prefix) + else + return copasreceive(self.socket,pattern,prefix) + end + end, + flush=function (self) + return copasflush(self.socket) + end, + settimeout=function (self,time) + self.timeout=time + return true + end, + connect=function(self,...) + local res,err=copasconnect(self.socket,...) + if res and self.ssl_params then + res,err=self:dohandshake() + end + return res,err + end, + close=function(self,...) + return self.socket:close(...) + end, + bind=function(self,...) + return self.socket:bind(...) + end, + getsockname=function(self,...) + return self.socket:getsockname(...) + end, + getstats=function(self,...) + return self.socket:getstats(...) + end, + setstats=function(self,...) + return self.socket:setstats(...) + end, + listen=function(self,...) + return self.socket:listen(...) + end, + accept=function(self,...) + return self.socket:accept(...) + end, + setoption=function(self,...) + return self.socket:setoption(...) + end, + getpeername=function(self,...) + return self.socket:getpeername(...) + end, + shutdown=function(self,...) + return self.socket:shutdown(...) + end, + dohandshake=function(self,sslt) + self.ssl_params=sslt or self.ssl_params + local nskt,err=copasdohandshake(self.socket,self.ssl_params) + if not nskt then + return nskt,err + end + self.socket=nskt + return self + end, +} +local _skt_mt_tcp={ + __tostring=_skt_mt_tostring, + __index=_skt_mt_tcp_index, +} +local _skt_mt_udp_index={ + sendto=function (self,...) + return copassendto(self.socket,...) + end, + receive=function (self,size) + return copasreceive(self.socket,size or UDP_DATAGRAM_MAX) + end, + receivefrom=function (self,size) + return copasreceivefrom(self.socket,size or UDP_DATAGRAM_MAX) + end, + setpeername=function(self,...) + return self.socket:getpeername(...) + end, + setsockname=function(self,...) + return self.socket:setsockname(...) + end, + close=function(self,...) + return true + end +} +local _skt_mt_udp={ + __tostring=_skt_mt_tostring, + __index=_skt_mt_udp_index, +} +for k,v in next,_skt_mt_tcp_index do + if not _skt_mt_udp_index[k] then + _skt_mt_udp_index[k]=v + end +end +local function wrap(skt,sslt) + if getmetatable(skt)==_skt_mt_tcp or getmetatable(skt)==_skt_mt_udp then + return skt + end + skt:settimeout(0) + if isTCP(skt) then + return setmetatable ({ socket=skt,ssl_params=sslt },_skt_mt_tcp) + else + return setmetatable ({ socket=skt },_skt_mt_udp) + end +end +copas.wrap=wrap +function copas.handler(handler,sslparams) + return function (skt,...) + skt=wrap(skt) + if sslparams then + skt:dohandshake(sslparams) + end + return handler(skt,...) + end +end +local _errhandlers={} +function copas.setErrorHandler(err) + local co=runningcoroutine() + if co then + _errhandlers[co]=err + end +end +local function _deferror (msg,co,skt) + report("%s (%s) (%s)",msg,tostring(co),tostring(skt)) +end +local function _doTick (co,skt,...) + if not co then + return + end + local ok,res,new_q=resumecoroutine(co,skt,...) + if ok and res and new_q then + new_q:insert(res) + new_q:push(res,co) + else + if not ok then + pcall(_errhandlers[co] or _deferror,res,co,skt) + end + if skt and copas.autoclose and isTCP(skt) then + skt:close() + end + _errhandlers[co]=nil + end +end +local function _accept(input,handler) + local client=input:accept() + if client then + client:settimeout(0) + local co=createcoroutine(handler) + _doTick (co,client) + end + return client +end +local function _tickRead(skt) + _doTick(_reading:pop(skt),skt) +end +local function _tickWrite(skt) + _doTick(_writing:pop(skt),skt) +end +local function addTCPserver(server,handler,timeout) + server:settimeout(timeout or 0) + _servers[server]=handler + _reading:insert(server) +end +local function addUDPserver(server,handler,timeout) + server:settimeout(timeout or 0) + local co=createcoroutine(handler) + _reading:insert(server) + _doTick(co,server) +end +function copas.addserver(server,handler,timeout) + if isTCP(server) then + addTCPserver(server,handler,timeout) + else + addUDPserver(server,handler,timeout) + end +end +function copas.removeserver(server,keep_open) + local s=server + local mt=getmetatable(server) + if mt==_skt_mt_tcp or mt==_skt_mt_udp then + s=server.socket + end + _servers[s]=nil + _reading:remove(s) + if keep_open then + return true + end + return server:close() +end +function copas.addthread(handler,...) + local thread=createcoroutine(function(_,...) return handler(...) end) + _doTick(thread,nil,...) + return thread +end +local _tasks={} +local function addtaskRead(task) + task.def_tick=_tickRead + _tasks[task]=true +end +local function addtaskWrite(task) + task.def_tick=_tickWrite + _tasks[task]=true +end +local function tasks() + return next,_tasks +end +local _readable_t={ + events=function(self) + local i=0 + return function () + i=i+1 + return self._evs[i] + end + end, + tick=function(self,input) + local handler=_servers[input] + if handler then + input=_accept(input,handler) + else + _reading:remove(input) + self.def_tick(input) + end + end +} +addtaskRead(_readable_t) +local _writable_t={ + events=function(self) + local i=0 + return function() + i=i+1 + return self._evs[i] + end + end, + tick=function(self,output) + _writing:remove(output) + self.def_tick(output) + end +} +addtaskWrite(_writable_t) +local _sleeping_t={ + tick=function(self,time,...) + _doTick(_sleeping:pop(time),...) + end +} +function copas.sleep(sleeptime) + yieldcoroutine((sleeptime or 0),_sleeping) +end +function copas.wakeup(co) + _sleeping:wakeup(co) +end +local last_cleansing=0 +local function _select(timeout) + local now=gettime() + local r_evs,w_evs,err=selectsocket(_reading,_writing,timeout) + _readable_t._evs=r_evs + _writable_t._evs=w_evs + if (last_cleansing-now)>WATCH_DOG_TIMEOUT then + last_cleansing=now + for skt,time in next,_reading_log do + if not r_evs[skt] and (time-now)>WATCH_DOG_TIMEOUT then + local n=#r_evs+1 + _reading_log[skt]=nil + r_evs[n]=skt + r_evs[skt]=n + end + end + for skt,time in next,_writing_log do + if not w_evs[skt] and (time-now)>WATCH_DOG_TIMEOUT then + local n=#w_evs+1 + _writing_log[skt]=nil + w_evs[n]=skt + w_evs[skt]=n + end + end + end + if err=="timeout" and #r_evs+#w_evs>0 then + return nil + else + return err + end +end +local function copasfinished() + return not (next(_reading) or next(_writing) or _sleeping:getnext()) +end +local function copasstep(timeout) + _sleeping_t:tick(gettime()) + local nextwait=_sleeping:getnext() + if nextwait then + timeout=timeout and min(nextwait,timeout) or nextwait + elseif copasfinished() then + return false + end + local err=_select(timeout) + if err then + if err=="timeout" then + return false + end + return nil,err + end + for task in tasks() do + for event in task:events() do + task:tick(event) + end + end + return true +end +copas.finished=copasfinished +copas.step=copasstep +function copas.loop(timeout) + copas.running=true + while not copasfinished() do + copasstep(timeout) + end + copas.running=false +end +package.loaded.copas=copas + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +package.loaded["util-soc-imp-ltn12"] = package.loaded["util-soc-imp-ltn12"] or true + +-- original size: 8706, stripped down to: 6102 + + +local select,unpack=select,unpack +local insert,remove=table.insert,table.remove +local sub=string.sub +local function report(fmt,first,...) + if logs then + report=logs and logs.reporter("ltn12") + report(fmt,first,...) + elseif fmt then + fmt="ltn12: "..fmt + if first then + print(format(fmt,first,...)) + else + print(fmt) + end + end +end +local filter={} +local source={} +local sink={} +local pump={} +local ltn12={ + _VERSION="LTN12 1.0.3", + BLOCKSIZE=2048, + filter=filter, + source=source, + sink=sink, + pump=pump, + report=report, +} +function filter.cycle(low,ctx,extra) + if low then + return function(chunk) + return (low(ctx,chunk,extra)) + end + end +end +function filter.chain(...) + local arg={... } + local n=select('#',...) + local top=1 + local index=1 + local retry="" + return function(chunk) + retry=chunk and retry + while true do + local action=arg[index] + if index==top then + chunk=action(chunk) + if chunk=="" or top==n then + return chunk + elseif chunk then + index=index+1 + else + top=top+1 + index=top + end + else + chunk=action(chunk or "") + if chunk=="" then + index=index-1 + chunk=retry + elseif chunk then + if index==n then + return chunk + else + index=index+1 + end + else + report("error: filter returned inappropriate 'nil'") + return + end + end + end + end +end +local function empty() + return nil +end +function source.empty() + return empty +end +local function sourceerror(err) + return function() + return nil,err + end +end +source.error=sourceerror +function source.file(handle,io_err) + if handle then + local blocksize=ltn12.BLOCKSIZE + return function() + local chunk=handle:read(blocksize) + if not chunk then + handle:close() + end + return chunk + end + else + return sourceerror(io_err or "unable to open file") + end +end +function source.simplify(src) + return function() + local chunk,err_or_new=src() + if err_or_new then + src=err_or_new + end + if chunk then + return chunk + else + return nil,err_or_new + end + end +end +function source.string(s) + if s then + local blocksize=ltn12.BLOCKSIZE + local i=1 + return function() + local nexti=i+blocksize + local chunk=sub(s,i,nexti-1) + i=nexti + if chunk~="" then + return chunk + else + return nil + end + end + else return source.empty() end +end +function source.rewind(src) + local t={} + return function(chunk) + if chunk then + insert(t,chunk) + else + chunk=remove(t) + if chunk then + return chunk + else + return src() + end + end + end +end +function source.chain(src,f,...) + if... then + f=filter.chain(f,...) + end + local last_in="" + local last_out="" + local state="feeding" + local err + return function() + if not last_out then + report("error: source is empty") + return + end + while true do + if state=="feeding" then + last_in,err=src() + if err then + return nil,err + end + last_out=f(last_in) + if not last_out then + if last_in then + report("error: filter returned inappropriate 'nil'") + end + return nil + elseif last_out~="" then + state="eating" + if last_in then + last_in="" + end + return last_out + end + else + last_out=f(last_in) + if last_out=="" then + if last_in=="" then + state="feeding" + else + report("error: filter returned nothing") + return + end + elseif not last_out then + if last_in then + report("filter returned inappropriate 'nil'") + end + return nil + else + return last_out + end + end + end + end +end +function source.cat(...) + local arg={... } + local src=remove(arg,1) + return function() + while src do + local chunk,err=src() + if chunk then + return chunk + end + if err then + return nil,err + end + src=remove(arg,1) + end + end +end +function sink.table(t) + if not t then + t={} + end + local f=function(chunk,err) + if chunk then + insert(t,chunk) + end + return 1 + end + return f,t +end +function sink.simplify(snk) + return function(chunk,err) + local ret,err_or_new=snk(chunk,err) + if not ret then + return nil,err_or_new + end + if err_or_new then + snk=err_or_new + end + return 1 + end +end +local function null() + return 1 +end +function sink.null() + return null +end +local function sinkerror(err) + return function() + return nil,err + end +end +sink.error=sinkerror +function sink.file(handle,io_err) + if handle then + return function(chunk,err) + if not chunk then + handle:close() + return 1 + else + return handle:write(chunk) + end + end + else + return sinkerror(io_err or "unable to open file") + end +end +function sink.chain(f,snk,...) + if... then + local args={ f,snk,... } + snk=remove(args,#args) + f=filter.chain(unpack(args)) + end + return function(chunk,err) + if chunk~="" then + local filtered=f(chunk) + local done=chunk and "" + while true do + local ret,snkerr=snk(filtered,err) + if not ret then + return nil,snkerr + end + if filtered==done then + return 1 + end + filtered=f(done) + end + else + return 1 + end + end +end +function pump.step(src,snk) + local chunk,src_err=src() + local ret,snk_err=snk(chunk,src_err) + if chunk and ret then + return 1 + else + return nil,src_err or snk_err + end +end +function pump.all(src,snk,step) + if not step then + step=pump.step + end + while true do + local ret,err=step(src,snk) + if not ret then + if err then + return nil,err + else + return 1 + end + end + end +end +package.loaded.ltn12=ltn12 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +package.loaded["util-soc-imp-mime"] = package.loaded["util-soc-imp-mime"] or true + +-- original size: 2325, stripped down to: 1927 + + +local type,tostring=type,tostring +local mime=require("mime.core") +local ltn12=ltn12 or require("ltn12") +local filtercycle=ltn12.filter.cycle +local function report(fmt,first,...) + if logs then + report=logs and logs.reporter("mime") + report(fmt,first,...) + elseif fmt then + fmt="mime: "..fmt + if first then + print(format(fmt,first,...)) + else + print(fmt) + end + end +end +mime.report=report +local encodet={} +local decodet={} +local wrapt={} +mime.encodet=encodet +mime.decodet=decodet +mime.wrapt=wrapt +local mime_b64=mime.b64 +local mime_qp=mime.qp +local mime_unb64=mime.unb64 +local mime_unqp=mime.unqp +local mime_wrp=mime.wrp +local mime_qpwrp=mime.qpwrp +local mime_eol=mime_eol +local mime_dot=mime_dot +encodet['base64']=function() + return filtercycle(mime_b64,"") +end +encodet['quoted-printable']=function(mode) + return filtercycle(mime_qp,"",mode=="binary" and "=0D=0A" or "\r\n") +end +decodet['base64']=function() + return filtercycle(mime_unb64,"") +end +decodet['quoted-printable']=function() + return filtercycle(mime_unqp,"") +end +local wraptext=function(length) + if not length then + length=76 + end + return filtercycle(mime_wrp,length,length) +end +local wrapquoted=function() + return filtercycle(mime_qpwrp,76,76) +end +wrapt['text']=wraptext +wrapt['base64']=wraptext +wrapt['default']=wraptext +wrapt['quoted-printable']=wrapquoted +function mime.normalize(marker) + return filtercycle(mime_eol,0,marker) +end +function mime.stuff() + return filtercycle(mime_dot,2) +end +local function choose(list) + return function(name,opt1,opt2) + if type(name)~="string" then + name,opt1,opt2="default",name,opt1 + end + local filter=list[name or "nil"] + if filter then + return filter(opt1,opt2) + else + report("error: unknown key '%s'",tostring(name)) + end + end +end +mime.encode=choose(encodet) +mime.decode=choose(decodet) +mime.wrap=choose(wrapt) +package.loaded.mime=mime + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +package.loaded["util-soc-imp-url"] = package.loaded["util-soc-imp-url"] or true + +-- original size: 6827, stripped down to: 5624 + + +local tonumber,tostring,type=tonumber,tostring,type +local gsub,sub,match,find,format,byte,char=string.gsub,string.sub,string.match,string.find,string.format,string.byte,string.char +local insert=table.insert +local socket=socket or require("socket") +local url={ + _VERSION="URL 1.0.3", +} +socket.url=url +function url.escape(s) + return (gsub(s,"([^A-Za-z0-9_])",function(c) + return format("%%%02x",byte(c)) + end)) +end +local function make_set(t) + local s={} + for i=1,#t do + s[t[i]]=true + end + return s +end +local segment_set=make_set { + "-","_",".","!","~","*","'","(", + ")",":","@","&","=","+","$",",", +} +local function protect_segment(s) + return gsub(s,"([^A-Za-z0-9_])",function(c) + if segment_set[c] then + return c + else + return format("%%%02X",byte(c)) + end + end) +end +function url.unescape(s) + return (gsub(s,"%%(%x%x)",function(hex) + return char(tonumber(hex,16)) + end)) +end +local function absolute_path(base_path,relative_path) + if find(relative_path,"^/") then + return relative_path + end + local path=gsub(base_path,"[^/]*$","") + path=path..relative_path + path=gsub(path,"([^/]*%./)",function (s) + if s~="./" then + return s + else + return "" + end + end) + path=gsub(path,"/%.$","/") + local reduced + while reduced~=path do + reduced=path + path=gsub(reduced,"([^/]*/%.%./)",function (s) + if s~="../../" then + return "" + else + return s + end + end) + end + path=gsub(reduced,"([^/]*/%.%.)$",function (s) + if s~="../.." then + return "" + else + return s + end + end) + return path +end +function url.parse(url,default) + local parsed={} + for k,v in next,default or parsed do + parsed[k]=v + end + if not url or url=="" then + return nil,"invalid url" + end + url=gsub(url,"#(.*)$",function(f) + parsed.fragment=f + return "" + end) + url=gsub(url,"^([%w][%w%+%-%.]*)%:",function(s) + parsed.scheme=s + return "" + end) + url=gsub(url,"^//([^/]*)",function(n) + parsed.authority=n + return "" + end) + url=gsub(url,"%?(.*)",function(q) + parsed.query=q + return "" + end) + url=gsub(url,"%;(.*)",function(p) + parsed.params=p + return "" + end) + if url~="" then + parsed.path=url + end + local authority=parsed.authority + if not authority then + return parsed + end + authority=gsub(authority,"^([^@]*)@",function(u) + parsed.userinfo=u + return "" + end) + authority=gsub(authority,":([^:%]]*)$",function(p) + parsed.port=p + return "" + end) + if authority~="" then + parsed.host=match(authority,"^%[(.+)%]$") or authority + end + local userinfo=parsed.userinfo + if not userinfo then + return parsed + end + userinfo=gsub(userinfo,":([^:]*)$",function(p) + parsed.password=p + return "" + end) + parsed.user=userinfo + return parsed +end +function url.build(parsed) + local url=parsed.path or "" + if parsed.params then + url=url..";"..parsed.params + end + if parsed.query then + url=url.."?"..parsed.query + end + local authority=parsed.authority + if parsed.host then + authority=parsed.host + if find(authority,":") then + authority="["..authority.."]" + end + if parsed.port then + authority=authority..":"..tostring(parsed.port) + end + local userinfo=parsed.userinfo + if parsed.user then + userinfo=parsed.user + if parsed.password then + userinfo=userinfo..":"..parsed.password + end + end + if userinfo then authority=userinfo.."@"..authority end + end + if authority then + url="//"..authority..url + end + if parsed.scheme then + url=parsed.scheme..":"..url + end + if parsed.fragment then + url=url.."#"..parsed.fragment + end + return url +end +function url.absolute(base_url,relative_url) + local base_parsed + if type(base_url)=="table" then + base_parsed=base_url + base_url=url.build(base_parsed) + else + base_parsed=url.parse(base_url) + end + local relative_parsed=url.parse(relative_url) + if not base_parsed then + return relative_url + elseif not relative_parsed then + return base_url + elseif relative_parsed.scheme then + return relative_url + else + relative_parsed.scheme=base_parsed.scheme + if not relative_parsed.authority then + relative_parsed.authority=base_parsed.authority + if not relative_parsed.path then + relative_parsed.path=base_parsed.path + if not relative_parsed.params then + relative_parsed.params=base_parsed.params + if not relative_parsed.query then + relative_parsed.query=base_parsed.query + end + end + else + relative_parsed.path=absolute_path(base_parsed.path or "",relative_parsed.path) + end + end + return url.build(relative_parsed) + end +end +function url.parse_path(path) + local parsed={} + path=path or "" + gsub(path,"([^/]+)",function (s) + insert(parsed,s) + end) + for i=1,#parsed do + parsed[i]=url.unescape(parsed[i]) + end + if sub(path,1,1)=="/" then + parsed.is_absolute=1 + end + if sub(path,-1,-1)=="/" then + parsed.is_directory=1 + end + return parsed +end +function url.build_path(parsed,unsafe) + local path="" + local n=#parsed + if unsafe then + for i=1,n-1 do + path=path..parsed[i].."/" + end + if n>0 then + path=path..parsed[n] + if parsed.is_directory then + path=path.."/" + end + end + else + for i=1,n-1 do + path=path..protect_segment(parsed[i]).."/" + end + if n>0 then + path=path..protect_segment(parsed[n]) + if parsed.is_directory then + path=path.."/" + end + end + end + if parsed.is_absolute then + path="/"..path + end + return path +end + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +package.loaded["util-soc-imp-headers"] = package.loaded["util-soc-imp-headers"] or true + +-- original size: 5712, stripped down to: 3865 + + +local next=next +local lower=string.lower +local concat=table.concat +local socket=socket or require("socket") +local canonic={ + ["accept"]="Accept", + ["accept-charset"]="Accept-Charset", + ["accept-encoding"]="Accept-Encoding", + ["accept-language"]="Accept-Language", + ["accept-ranges"]="Accept-Ranges", + ["action"]="Action", + ["alternate-recipient"]="Alternate-Recipient", + ["age"]="Age", + ["allow"]="Allow", + ["arrival-date"]="Arrival-Date", + ["authorization"]="Authorization", + ["bcc"]="Bcc", + ["cache-control"]="Cache-Control", + ["cc"]="Cc", + ["comments"]="Comments", + ["connection"]="Connection", + ["content-description"]="Content-Description", + ["content-disposition"]="Content-Disposition", + ["content-encoding"]="Content-Encoding", + ["content-id"]="Content-ID", + ["content-language"]="Content-Language", + ["content-length"]="Content-Length", + ["content-location"]="Content-Location", + ["content-md5"]="Content-MD5", + ["content-range"]="Content-Range", + ["content-transfer-encoding"]="Content-Transfer-Encoding", + ["content-type"]="Content-Type", + ["cookie"]="Cookie", + ["date"]="Date", + ["diagnostic-code"]="Diagnostic-Code", + ["dsn-gateway"]="DSN-Gateway", + ["etag"]="ETag", + ["expect"]="Expect", + ["expires"]="Expires", + ["final-log-id"]="Final-Log-ID", + ["final-recipient"]="Final-Recipient", + ["from"]="From", + ["host"]="Host", + ["if-match"]="If-Match", + ["if-modified-since"]="If-Modified-Since", + ["if-none-match"]="If-None-Match", + ["if-range"]="If-Range", + ["if-unmodified-since"]="If-Unmodified-Since", + ["in-reply-to"]="In-Reply-To", + ["keywords"]="Keywords", + ["last-attempt-date"]="Last-Attempt-Date", + ["last-modified"]="Last-Modified", + ["location"]="Location", + ["max-forwards"]="Max-Forwards", + ["message-id"]="Message-ID", + ["mime-version"]="MIME-Version", + ["original-envelope-id"]="Original-Envelope-ID", + ["original-recipient"]="Original-Recipient", + ["pragma"]="Pragma", + ["proxy-authenticate"]="Proxy-Authenticate", + ["proxy-authorization"]="Proxy-Authorization", + ["range"]="Range", + ["received"]="Received", + ["received-from-mta"]="Received-From-MTA", + ["references"]="References", + ["referer"]="Referer", + ["remote-mta"]="Remote-MTA", + ["reply-to"]="Reply-To", + ["reporting-mta"]="Reporting-MTA", + ["resent-bcc"]="Resent-Bcc", + ["resent-cc"]="Resent-Cc", + ["resent-date"]="Resent-Date", + ["resent-from"]="Resent-From", + ["resent-message-id"]="Resent-Message-ID", + ["resent-reply-to"]="Resent-Reply-To", + ["resent-sender"]="Resent-Sender", + ["resent-to"]="Resent-To", + ["retry-after"]="Retry-After", + ["return-path"]="Return-Path", + ["sender"]="Sender", + ["server"]="Server", + ["smtp-remote-recipient"]="SMTP-Remote-Recipient", + ["status"]="Status", + ["subject"]="Subject", + ["te"]="TE", + ["to"]="To", + ["trailer"]="Trailer", + ["transfer-encoding"]="Transfer-Encoding", + ["upgrade"]="Upgrade", + ["user-agent"]="User-Agent", + ["vary"]="Vary", + ["via"]="Via", + ["warning"]="Warning", + ["will-retry-until"]="Will-Retry-Until", + ["www-authenticate"]="WWW-Authenticate", + ["x-mailer"]="X-Mailer", +} +setmetatable(canonic,{ + __index=function(t,k) + socket.report("invalid header: %s",k) + t[k]=k + return k + end +}) +local function normalizeheaders(headers) + if not headers then + return {} + end + local normalized={} + for k,v in next,headers do + normalized[#normalized+1]=canonic[k]..": "..v + end + normalized[#normalized+1]="" + normalized[#normalized+1]="" + return concat(normalized,"\r\n") +end +local function lowerheaders(lowered,headers) + if not lowered then + return {} + end + if not headers then + lowered,headers={},lowered + end + for k,v in next,headers do + lowered[lower(k)]=v + end + return lowered +end +socket.headers={ + canonic=canonic, + normalize=normalizeheaders, + lower=lowerheaders, +} + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +package.loaded["util-soc-imp-tp"] = package.loaded["util-soc-imp-tp"] or true + +-- original size: 3082, stripped down to: 2612 + + +local setmetatable,next,type,tonumber=setmetatable,next,type,tonumber +local find,upper=string.find,string,upper +local socket=socket or require("socket") +local ltn12=ltn12 or require("ltn12") +local skipsocket=socket.skip +local sinksocket=socket.sink +local tcpsocket=socket.tcp +local ltn12pump=ltn12.pump +local pumpall=ltn12pump.all +local pumpstep=ltn12pump.step +local tp={ + TIMEOUT=60, +} +socket.tp=tp +local function get_reply(c) + local line,err=c:receive() + local reply=line + if err then return + nil,err + end + local code,sep=skipsocket(2,find(line,"^(%d%d%d)(.?)")) + if not code then + return nil,"invalid server reply" + end + if sep=="-" then + local current + repeat + line,err=c:receive() + if err then + return nil,err + end + current,sep=skipsocket(2,find(line,"^(%d%d%d)(.?)")) + reply=reply.."\n"..line + until code==current and sep==" " + end + return code,reply +end +local methods={} +local mt={ __index=methods } +function methods.getpeername(self) + return self.c:getpeername() +end +function methods.getsockname(self) + return self.c:getpeername() +end +function methods.check(self,ok) + local code,reply=get_reply(self.c) + if not code then + return nil,reply + end + local c=tonumber(code) + local t=type(ok) + if t=="function" then + return ok(c,reply) + elseif t=="table" then + for i=1,#ok do + if find(code,ok[i]) then + return c,reply + end + end + return nil,reply + elseif find(code,ok) then + return c,reply + else + return nil,reply + end +end +function methods.command(self,cmd,arg) + cmd=upper(cmd) + if arg then + cmd=cmd.." "..arg.."\r\n" + else + cmd=cmd.."\r\n" + end + return self.c:send(cmd) +end +function methods.sink(self,snk,pat) + local chunk,err=self.c:receive(pat) + return snk(chunk,err) +end +function methods.send(self,data) + return self.c:send(data) +end +function methods.receive(self,pat) + return self.c:receive(pat) +end +function methods.getfd(self) + return self.c:getfd() +end +function methods.dirty(self) + return self.c:dirty() +end +function methods.getcontrol(self) + return self.c +end +function methods.source(self,source,step) + local sink=sinksocket("keep-open",self.c) + local ret,err=pumpall(source,sink,step or pumpstep) + return ret,err +end +function methods.close(self) + self.c:close() + return 1 +end +function tp.connect(host,port,timeout,create) + local c,e=(create or tcpsocket)() + if not c then + return nil,e + end + c:settimeout(timeout or tp.TIMEOUT) + local r,e=c:connect(host,port) + if not r then + c:close() + return nil,e + end + return setmetatable({ c=c },mt) +end + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +package.loaded["util-soc-imp-http"] = package.loaded["util-soc-imp-http"] or true + +-- original size: 12499, stripped down to: 10001 + + +local tostring,tonumber,setmetatable,next,type=tostring,tonumber,setmetatable,next,type +local find,lower,format,gsub,match=string.find,string.lower,string.format,string.gsub,string.match +local concat=table.concat +local socket=socket or require("socket") +local url=socket.url or require("socket.url") +local ltn12=ltn12 or require("ltn12") +local mime=mime or require("mime") +local headers=socket.headers or require("socket.headers") +local normalizeheaders=headers.normalize +local parseurl=url.parse +local buildurl=url.build +local absoluteurl=url.absolute +local unescapeurl=url.unescape +local skipsocket=socket.skip +local sinksocket=socket.sink +local sourcesocket=socket.source +local trysocket=socket.try +local tcpsocket=socket.tcp +local newtrysocket=socket.newtry +local protectsocket=socket.protect +local emptysource=ltn12.source.empty +local stringsource=ltn12.source.string +local rewindsource=ltn12.source.rewind +local pumpstep=ltn12.pump.step +local pumpall=ltn12.pump.all +local sinknull=ltn12.sink.null +local sinktable=ltn12.sink.table +local mimeb64=mime.b64 +local http={ + TIMEOUT=60, + USERAGENT=socket._VERSION, +} +socket.http=http +local PORT=80 +local SCHEMES={ + http=true, +} +local function receiveheaders(sock,headers) + if not headers then + headers={} + end + local line,err=sock:receive() + if err then + return nil,err + end + while line~="" do + local name,value=skipsocket(2,find(line,"^(.-):%s*(.*)")) + if not (name and value) then + return nil,"malformed reponse headers" + end + name=lower(name) + line,err=sock:receive() + if err then + return nil,err + end + while find(line,"^%s") do + value=value..line + line=sock:receive() + if err then + return nil,err + end + end + local found=headers[name] + if found then + value=found..", "..value + end + headers[name]=value + end + return headers +end +socket.sourcet["http-chunked"]=function(sock,headers) + return setmetatable ( + { + getfd=function() return sock:getfd() end, + dirty=function() return sock:dirty() end, + },{ + __call=function() + local line,err=sock:receive() + if err then + return nil,err + end + local size=tonumber(gsub(line,";.*",""),16) + if not size then + return nil,"invalid chunk size" + end + if size>0 then + local chunk,err,part=sock:receive(size) + if chunk then + sock:receive() + end + return chunk,err + else + headers,err=receiveheaders(sock,headers) + if not headers then + return nil,err + end + end + end + } + ) +end +socket.sinkt["http-chunked"]=function(sock) + return setmetatable( + { + getfd=function() return sock:getfd() end, + dirty=function() return sock:dirty() end, + }, + { + __call=function(self,chunk,err) + if not chunk then + chunk="" + end + return sock:send(format("%X\r\n%s\r\n",#chunk,chunk)) + end + }) +end +local methods={} +local mt={ __index=methods } +local function openhttp(host,port,create) + local c=trysocket((create or tcpsocket)()) + local h=setmetatable({ c=c },mt) + local try=newtrysocket(function() h:close() end) + h.try=try + try(c:settimeout(http.TIMEOUT)) + try(c:connect(host,port or PORT)) + return h +end +http.open=openhttp +function methods.sendrequestline(self,method,uri) + local requestline=format("%s %s HTTP/1.1\r\n",method or "GET",uri) + return self.try(self.c:send(requestline)) +end +function methods.sendheaders(self,headers) + self.try(self.c:send(normalizeheaders(headers))) + return 1 +end +function methods.sendbody(self,headers,source,step) + if not source then + source=emptysource() + end + if not step then + step=pumpstep + end + local mode="http-chunked" + if headers["content-length"] then + mode="keep-open" + end + return self.try(pumpall(source,sinksocket(mode,self.c),step)) +end +function methods.receivestatusline(self) + local try=self.try + local status=try(self.c:receive(5)) + if status~="HTTP/" then + return nil,status + end + status=try(self.c:receive("*l",status)) + local code=skipsocket(2,find(status,"HTTP/%d*%.%d* (%d%d%d)")) + return try(tonumber(code),status) +end +function methods.receiveheaders(self) + return self.try(receiveheaders(self.c)) +end +function methods.receivebody(self,headers,sink,step) + if not sink then + sink=sinknull() + end + if not step then + step=pumpstep + end + local length=tonumber(headers["content-length"]) + local encoding=headers["transfer-encoding"] + local mode="default" + if encoding and encoding~="identity" then + mode="http-chunked" + elseif length then + mode="by-length" + end + return self.try(pumpall(sourcesocket(mode,self.c,length),sink,step)) +end +function methods.receive09body(self,status,sink,step) + local source=rewindsource(sourcesocket("until-closed",self.c)) + source(status) + return self.try(pumpall(source,sink,step)) +end +function methods.close(self) + return self.c:close() +end +local function adjusturi(request) + if not request.proxy and not http.PROXY then + request={ + path=trysocket(request.path,"invalid path 'nil'"), + params=request.params, + query=request.query, + fragment=request.fragment, + } + end + return buildurl(request) +end +local function adjustheaders(request) + local headers={ + ["user-agent"]=http.USERAGENT, + ["host"]=gsub(request.authority,"^.-@",""), + ["connection"]="close, TE", + ["te"]="trailers" + } + local username=request.user + local password=request.password + if username and password then + headers["authorization"]="Basic "..(mimeb64(username..":"..unescapeurl(password))) + end + local proxy=request.proxy or http.PROXY + if proxy then + proxy=parseurl(proxy) + local username=proxy.user + local password=proxy.password + if username and password then + headers["proxy-authorization"]="Basic "..(mimeb64(username..":"..password)) + end + end + local requestheaders=request.headers + if requestheaders then + headers=lowerheaders(headers,requestheaders) + end + return headers +end +local default={ + host="", + port=PORT, + path="/", + scheme="http" +} +local function adjustrequest(originalrequest) + local url=originalrequest.url + local request=url and parseurl(url,default) or {} + for k,v in next,originalrequest do + request[k]=v + end + local host=request.host + local port=request.port + local uri=request.uri + if not host or host=="" then + trysocket(nil,"invalid host '"..tostring(host).."'") + end + if port=="" then + request.port=PORT + end + if not uri or uri=="" then + request.uri=adjusturi(request) + end + request.headers=adjustheaders(request) + local proxy=request.proxy or http.PROXY + if proxy then + proxy=parseurl(proxy) + request.host=proxy.host + request.port=proxy.port or 3128 + end + return request +end +local maxredericts=4 +local validredirects={ [301]=true,[302]=true,[303]=true,[307]=true } +local validmethods={ [false]=true,GET=true,HEAD=true } +local function shouldredirect(request,code,headers) + local location=headers.location + if not location then + return false + end + location=gsub(location,"%s","") + if location=="" then + return false + end + local scheme=match(location,"^([%w][%w%+%-%.]*)%:") + if scheme and not SCHEMES[scheme] then + return false + end + local method=request.method + local redirect=request.redirect + local redirects=request.nredirects or 0 + return redirect and validredirects[code] and validmethods[method] and redirects<=maxredericts +end +local function shouldreceivebody(request,code) + if request.method=="HEAD" then + return nil + end + if code==204 or code==304 then + return nil + end + if code>=100 and code<200 then + return nil + end + return 1 +end +local tredirect,trequest,srequest +tredirect=function(request,location) + local result,code,headers,status=trequest { + url=absoluteurl(request.url,location), + source=request.source, + sink=request.sink, + headers=request.headers, + proxy=request.proxy, + nredirects=(request.nredirects or 0)+1, + create=request.create, + } + if not headers then + headers={} + end + if not headers.location then + headers.location=location + end + return result,code,headers,status +end +trequest=function(originalrequest) + local request=adjustrequest(originalrequest) + local connection=openhttp(request.host,request.port,request.create) + local headers=request.headers + connection:sendrequestline(request.method,request.uri) + connection:sendheaders(headers) + if request.source then + connection:sendbody(headers,request.source,request.step) + end + local code,status=connection:receivestatusline() + if not code then + connection:receive09body(status,request.sink,request.step) + return 1,200 + end + while code==100 do + headers=connection:receiveheaders() + code,status=connection:receivestatusline() + end + headers=connection:receiveheaders() + if shouldredirect(request,code,headers) and not request.source then + connection:close() + return tredirect(originalrequest,headers.location) + end + if shouldreceivebody(request,code) then + connection:receivebody(headers,request.sink,request.step) + end + connection:close() + return 1,code,headers,status +end +local function genericform(url,body) + local buffer={} + local request={ + url=url, + sink=sinktable(buffer), + target=buffer, + } + if body then + request.source=stringsource(body) + request.method="POST" + request.headers={ + ["content-length"]=#body, + ["content-type"]="application/x-www-form-urlencoded" + } + end + return request +end +http.genericform=genericform +srequest=function(url,body) + local request=genericform(url,body) + local _,code,headers,status=trequest(request) + return concat(request.target),code,headers,status +end +http.request=protectsocket(function(request,body) + if type(request)=="string" then + return srequest(request,body) + else + return trequest(request) + end +end) + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +package.loaded["util-soc-imp-ftp"] = package.loaded["util-soc-imp-ftp"] or true + +-- original size: 10321, stripped down to: 8867 + + +local setmetatable,type,next=setmetatable,type,next +local find,format,gsub,match=string.find,string.format,string.gsub,string.match +local concat=table.concat +local mod=math.mod +local socket=socket or require("socket") +local url=socket.url or require("socket.url") +local tp=socket.tp or require("socket.tp") +local ltn12=ltn12 or require("ltn12") +local tcpsocket=socket.tcp +local trysocket=socket.try +local skipsocket=socket.skip +local sinksocket=socket.sink +local selectsocket=socket.select +local bindsocket=socket.bind +local newtrysocket=socket.newtry +local sourcesocket=socket.source +local protectsocket=socket.protect +local parseurl=url.parse +local unescapeurl=url.unescape +local pumpall=ltn12.pump.all +local pumpstep=ltn12.pump.step +local sourcestring=ltn12.source.string +local sinktable=ltn12.sink.table +local ftp={ + TIMEOUT=60, + USER="ftp", + PASSWORD="anonymous@anonymous.org", +} +socket.ftp=ftp +local PORT=21 +local methods={} +local mt={ __index=methods } +function ftp.open(server,port,create) + local tp=trysocket(tp.connect(server,port or PORT,ftp.TIMEOUT,create)) + local f=setmetatable({ tp=tp },metat) + f.try=newtrysocket(function() f:close() end) + return f +end +function methods.portconnect(self) + local try=self.try + local server=self.server + try(server:settimeout(ftp.TIMEOUT)) + self.data=try(server:accept()) + try(self.data:settimeout(ftp.TIMEOUT)) +end +function methods.pasvconnect(self) + local try=self.try + self.data=try(tcpsocket()) + self(self.data:settimeout(ftp.TIMEOUT)) + self(self.data:connect(self.pasvt.address,self.pasvt.port)) +end +function methods.login(self,user,password) + local try=self.try + local tp=self.tp + try(tp:command("user",user or ftp.USER)) + local code,reply=try(tp:check{"2..",331}) + if code==331 then + try(tp:command("pass",password or ftp.PASSWORD)) + try(tp:check("2..")) + end + return 1 +end +function methods.pasv(self) + local try=self.try + local tp=self.tp + try(tp:command("pasv")) + local code,reply=try(self.tp:check("2..")) + local pattern="(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)" + local a,b,c,d,p1,p2=skipsocket(2,find(reply,pattern)) + try(a and b and c and d and p1 and p2,reply) + local address=format("%d.%d.%d.%d",a,b,c,d) + local port=p1*256+p2 + local server=self.server + self.pasvt={ + address=address, + port=port, + } + if server then + server:close() + self.server=nil + end + return address,port +end +function methods.epsv(self) + local try=self.try + local tp=self.tp + try(tp:command("epsv")) + local code,reply=try(tp:check("229")) + local pattern="%((.)(.-)%1(.-)%1(.-)%1%)" + local d,prt,address,port=match(reply,pattern) + try(port,"invalid epsv response") + local address=tp:getpeername() + local server=self.server + self.pasvt={ + address=address, + port=port, + } + if self.server then + server:close() + self.server=nil + end + return address,port +end +function methods.port(self,address,port) + local try=self.try + local tp=self.tp + self.pasvt=nil + if not address then + address,port=try(tp:getsockname()) + self.server=try(bindsocket(address,0)) + address,port=try(self.server:getsockname()) + try(self.server:settimeout(ftp.TIMEOUT)) + end + local pl=mod(port,256) + local ph=(port-pl)/256 + local arg=gsub(format("%s,%d,%d",address,ph,pl),"%.",",") + try(tp:command("port",arg)) + try(tp:check("2..")) + return 1 +end +function methods.eprt(self,family,address,port) + local try=self.try + local tp=self.tp + self.pasvt=nil + if not address then + address,port=try(tp:getsockname()) + self.server=try(bindsocket(address,0)) + address,port=try(self.server:getsockname()) + try(self.server:settimeout(ftp.TIMEOUT)) + end + local arg=format("|%s|%s|%d|",family,address,port) + try(tp:command("eprt",arg)) + try(tp:check("2..")) + return 1 +end +function methods.send(self,sendt) + local try=self.try + local tp=self.tp + try(self.pasvt or self.server,"need port or pasv first") + if self.pasvt then + self:pasvconnect() + end + local argument=sendt.argument or unescapeurl(gsub(sendt.path or "","^[/\\]","")) + if argument=="" then + argument=nil + end + local command=sendt.command or "stor" + try(tp:command(command,argument)) + local code,reply=try(tp:check{"2..","1.."}) + if not self.pasvt then + self:portconnect() + end + local step=sendt.step or pumpstep + local readt={ tp } + local checkstep=function(src,snk) + local readyt=selectsocket(readt,nil,0) + if readyt[tp] then + code=try(tp:check("2..")) + end + return step(src,snk) + end + local sink=sinksocket("close-when-done",self.data) + try(pumpall(sendt.source,sink,checkstep)) + if find(code,"1..") then + try(tp:check("2..")) + end + self.data:close() + local sent=skipsocket(1,self.data:getstats()) + self.data=nil + return sent +end +function methods.receive(self,recvt) + local try=self.try + local tp=self.tp + try(self.pasvt or self.server,"need port or pasv first") + if self.pasvt then self:pasvconnect() end + local argument=recvt.argument or unescapeurl(gsub(recvt.path or "","^[/\\]","")) + if argument=="" then + argument=nil + end + local command=recvt.command or "retr" + try(tp:command(command,argument)) + local code,reply=try(tp:check{"1..","2.."}) + if code>=200 and code<=299 then + recvt.sink(reply) + return 1 + end + if not self.pasvt then + self:portconnect() + end + local source=sourcesocket("until-closed",self.data) + local step=recvt.step or pumpstep + try(pumpall(source,recvt.sink,step)) + if find(code,"1..") then + try(tp:check("2..")) + end + self.data:close() + self.data=nil + return 1 +end +function methods.cwd(self,dir) + local try=self.try + local tp=self.tp + try(tp:command("cwd",dir)) + try(tp:check(250)) + return 1 +end +function methods.type(self,typ) + local try=self.try + local tp=self.tp + try(tp:command("type",typ)) + try(tp:check(200)) + return 1 +end +function methods.greet(self) + local try=self.try + local tp=self.tp + local code=try(tp:check{"1..","2.."}) + if find(code,"1..") then + try(tp:check("2..")) + end + return 1 +end +function methods.quit(self) + local try=self.try + try(self.tp:command("quit")) + try(self.tp:check("2..")) + return 1 +end +function methods.close(self) + local data=self.data + if data then + data:close() + end + local server=self.server + if server then + server:close() + end + local tp=self.tp + if tp then + tp:close() + end +end +local function override(t) + if t.url then + local u=parseurl(t.url) + for k,v in next,t do + u[k]=v + end + return u + else + return t + end +end +local function tput(putt) + putt=override(putt) + local host=putt.host + trysocket(host,"missing hostname") + local f=ftp.open(host,putt.port,putt.create) + f:greet() + f:login(putt.user,putt.password) + local typ=putt.type + if typ then + f:type(typ) + end + f:epsv() + local sent=f:send(putt) + f:quit() + f:close() + return sent +end +local default={ + path="/", + scheme="ftp", +} +local function genericform(u) + local t=trysocket(parseurl(u,default)) + trysocket(t.scheme=="ftp","wrong scheme '"..t.scheme.."'") + trysocket(t.host,"missing hostname") + local pat="^type=(.)$" + if t.params then + local typ=skipsocket(2,find(t.params,pat)) + t.type=typ + trysocket(typ=="a" or typ=="i","invalid type '"..typ.."'") + end + return t +end +ftp.genericform=genericform +local function sput(u,body) + local putt=genericform(u) + putt.source=sourcestring(body) + return tput(putt) +end +ftp.put=protectsocket(function(putt,body) + if type(putt)=="string" then + return sput(putt,body) + else + return tput(putt) + end +end) +local function tget(gett) + gett=override(gett) + local host=gett.host + trysocket(host,"missing hostname") + local f=ftp.open(host,gett.port,gett.create) + f:greet() + f:login(gett.user,gett.password) + if gett.type then + f:type(gett.type) + end + f:epsv() + f:receive(gett) + f:quit() + return f:close() +end +local function sget(u) + local gett=genericform(u) + local t={} + gett.sink=sinktable(t) + tget(gett) + return concat(t) +end +ftp.command=protectsocket(function(cmdt) + cmdt=override(cmdt) + local command=cmdt.command + local argument=cmdt.argument + local check=cmdt.check + local host=cmdt.host + trysocket(host,"missing hostname") + trysocket(command,"missing command") + local f=ftp.open(host,cmdt.port,cmdt.create) + local try=f.try + local tp=f.tp + f:greet() + f:login(cmdt.user,cmdt.password) + if type(command)=="table" then + local argument=argument or {} + for i=1,#command do + local cmd=command[i] + try(tp:command(cmd,argument[i])) + if check and check[i] then + try(tp:check(check[i])) + end + end + else + try(tp:command(command,argument)) + if check then + try(tp:check(check)) + end + end + f:quit() + return f:close() +end) +ftp.get=protectsocket(function(gett) + if type(gett)=="string" then + return sget(gett) + else + return tget(gett) + end +end) + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +package.loaded["util-soc-imp-smtp"] = package.loaded["util-soc-imp-smtp"] or true + +-- original size: 6975, stripped down to: 6055 + + +local type,setmetatable,next=type,setmetatable,next +local find,lower,format=string.find,string.lower,string.format +local osdate,osgetenv=os.data,os.getenv +local random=math.random +local socket=socket or require("socket") +local headers=socket.headers or require("socket.headers") +local ltn12=ltn12 or require("ltn12") +local tp=socket.tp or require("socket.tp") +local mime=mime or require("mime") +local mimeb64=mime.b64 +local mimestuff=mime.stuff +local skipsocket=socket.skip +local trysocket=socket.try +local newtrysocket=socket.newtry +local protectsocket=socket.protect +local normalizeheaders=headers.normalize +local lowerheaders=headers.lower +local createcoroutine=coroutine.create +local resumecoroutine=coroutine.resume +local yieldcoroutine=coroutine.resume +local smtp={ + TIMEOUT=60, + SERVER="localhost", + PORT=25, + DOMAIN=osgetenv("SERVER_NAME") or "localhost", + ZONE="-0000", +} +socket.smtp=smtp +local methods={} +local mt={ __index=methods } +function methods.greet(self,domain) + local try=self.try + local tp=self.tp + try(tp:check("2..")) + try(tp:command("EHLO",domain or _M.DOMAIN)) + return skipsocket(1,try(tp:check("2.."))) +end +function methods.mail(self,from) + local try=self.try + local tp=self.tp + try(tp:command("MAIL","FROM:"..from)) + return try(tp:check("2..")) +end +function methods.rcpt(self,to) + local try=self.try + local tp=self.tp + try(tp:command("RCPT","TO:"..to)) + return try(tp:check("2..")) +end +function methods.data(self,src,step) + local try=self.try + local tp=self.tp + try(tp:command("DATA")) + try(tp:check("3..")) + try(tp:source(src,step)) + try(tp:send("\r\n.\r\n")) + return try(tp:check("2..")) +end +function methods.quit(self) + local try=self.try + local tp=self.tp + try(tp:command("QUIT")) + return try(tp:check("2..")) +end +function methods.close(self) + return self.tp:close() +end +function methods.login(self,user,password) + local try=self.try + local tp=self.tp + try(tp:command("AUTH","LOGIN")) + try(tp:check("3..")) + try(tp:send(mimeb64(user).."\r\n")) + try(tp:check("3..")) + try(tp:send(mimeb64(password).."\r\n")) + return try(tp:check("2..")) +end +function methods.plain(self,user,password) + local try=self.try + local tp=self.tp + local auth="PLAIN "..mimeb64("\0"..user.."\0"..password) + try(tp:command("AUTH",auth)) + return try(tp:check("2..")) +end +function methods.auth(self,user,password,ext) + if not user or not password then + return 1 + end + local try=self.try + if find(ext,"AUTH[^\n]+LOGIN") then + return self:login(user,password) + elseif find(ext,"AUTH[^\n]+PLAIN") then + return self:plain(user,password) + else + try(nil,"authentication not supported") + end +end +function methods.send(self,mail) + self:mail(mail.from) + local receipt=mail.rcpt + if type(receipt)=="table" then + for i=1,#receipt do + self:rcpt(receipt[i]) + end + elseif receipt then + self:rcpt(receipt) + end + self:data(ltn12.source.chain(mail.source,mimestuff()),mail.step) +end +local function opensmtp(self,server,port,create) + if not server or server=="" then + server=smtp.SERVER + end + if not port or port=="" then + port=smtp.PORT + end + local s={ + tp=trysocket(tp.connect(server,port,smtp.TIMEOUT,create)), + try=newtrysocket(function() + s:close() + end), + } + setmetatable(s,mt) + return s +end +smtp.open=opensmtp +local nofboundaries=0 +local function newboundary() + nofboundaries=nofboundaries+1 + return format('%s%05d==%05u',osdate('%d%m%Y%H%M%S'),random(0,99999),nofboundaries) +end +local send_message +local function send_headers(headers) + yieldcoroutine(normalizeheaders(headers)) +end +local function send_multipart(message) + local boundary=newboundary() + local headers=lowerheaders(message.headers) + local body=message.body + local preamble=body.preamble + local epilogue=body.epilogue + local content=headers['content-type'] or 'multipart/mixed' + headers['content-type']=content..'; boundary="'..boundary..'"' + send_headers(headers) + if preamble then + yieldcoroutine(preamble) + yieldcoroutine("\r\n") + end + for i=1,#body do + yieldcoroutine("\r\n--"..boundary.."\r\n") + send_message(body[i]) + end + yieldcoroutine("\r\n--"..boundary.."--\r\n\r\n") + if epilogue then + yieldcoroutine(epilogue) + yieldcoroutine("\r\n") + end +end +local default_content_type='text/plain; charset="UTF-8"' +local function send_source(message) + local headers=lowerheaders(message.headers) + if not headers['content-type'] then + headers['content-type']=default_content_type + end + send_headers(headers) + local getchunk=message.body + while true do + local chunk,err=getchunk() + if err then + yieldcoroutine(nil,err) + elseif chunk then + yieldcoroutine(chunk) + else + break + end + end +end +local function send_string(message) + local headers=lowerheaders(message.headers) + if not headers['content-type'] then + headers['content-type']=default_content_type + end + send_headers(headers) + yieldcoroutine(message.body) +end +function send_message(message) + local body=message.body + if type(body)=="table" then + send_multipart(message) + elseif type(body)=="function" then + send_source(message) + else + send_string(message) + end +end +local function adjust_headers(message) + local headers=lowerheaders(message.headers) + if not headers["date"] then + headers["date"]=osdate("!%a, %d %b %Y %H:%M:%S ")..(message.zone or smtp.ZONE) + end + if not headers["x-mailer"] then + headers["x-mailer"]=socket._VERSION + end + headers["mime-version"]="1.0" + return headers +end +function smtp.message(message) + message.headers=adjust_headers(message) + local action=createcoroutine(function() + send_message(message) + end) + return function() + local ret,a,b=resumecoroutine(action) + if ret then + return a,b + else + return nil,a + end + end +end +smtp.send=protectsocket(function(mail) + local snd=opensmtp(mail.server,mail.port,mail.create) + local ext=snd:greet(mail.domain) + snd:auth(mail.user,mail.password,ext) + snd:send(mail) + snd:quit() + return snd:close() +end) + + +end -- of closure + +do -- create closure to overcome 200 locals limit + package.loaded["trac-set"] = package.loaded["trac-set"] or true -- original size: 13340, stripped down to: 9459 @@ -21733,10 +24554,10 @@ end end -- of closure --- used libraries : l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua --- skipped libraries : util-soc-imp-reset util-soc-imp-socket util-soc-imp-copas util-soc-imp-ltn12 util-soc-imp-mime util-soc-imp-url util-soc-imp-headers util-soc-imp-tp util-soc-imp-http util-soc-imp-ftp util-soc-imp-smtp --- original bytes : 893485 --- stripped bytes : 323975 +-- used libraries : l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua util-soc-imp-reset.lua util-soc-imp-socket.lua util-soc-imp-copas.lua util-soc-imp-ltn12.lua util-soc-imp-mime.lua util-soc-imp-url.lua util-soc-imp-headers.lua util-soc-imp-tp.lua util-soc-imp-http.lua util-soc-imp-ftp.lua util-soc-imp-smtp.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua +-- skipped libraries : - +-- original bytes : 981014 +-- stripped bytes : 346248 -- end library merge @@ -21788,18 +24609,18 @@ local ownlibs = { -- order can be made better 'util-prs.lua', 'util-fmt.lua', - 'util-soc-imp-reset', - 'util-soc-imp-socket', - 'util-soc-imp-copas', - 'util-soc-imp-ltn12', - -- 'util-soc-imp-mbox', - 'util-soc-imp-mime', - 'util-soc-imp-url', - 'util-soc-imp-headers', - 'util-soc-imp-tp', - 'util-soc-imp-http', - 'util-soc-imp-ftp', - 'util-soc-imp-smtp', + 'util-soc-imp-reset.lua', + 'util-soc-imp-socket.lua', + 'util-soc-imp-copas.lua', + 'util-soc-imp-ltn12.lua', + -- 'util-soc-imp-mbox.lua', + 'util-soc-imp-mime.lua', + 'util-soc-imp-url.lua', + 'util-soc-imp-headers.lua', + 'util-soc-imp-tp.lua', + 'util-soc-imp-http.lua', + 'util-soc-imp-ftp.lua', + 'util-soc-imp-smtp.lua', 'trac-set.lua', 'trac-log.lua', diff --git a/scripts/context/stubs/mswin/mtxrun.lua b/scripts/context/stubs/mswin/mtxrun.lua index 99c9fd3f2..555e662e3 100644 --- a/scripts/context/stubs/mswin/mtxrun.lua +++ b/scripts/context/stubs/mswin/mtxrun.lua @@ -9213,6 +9213,2827 @@ end -- of closure do -- create closure to overcome 200 locals limit +package.loaded["util-soc-imp-reset"] = package.loaded["util-soc-imp-reset"] or true + +-- original size: 374, stripped down to: 282 + +local loaded=package.loaded +loaded["socket"]=nil +loaded["copas"]=nil +loaded["ltn12"]=nil +loaded["mbox"]=nil +loaded["mime"]=nil +loaded["socket.url"]=nil +loaded["socket.headers"]=nil +loaded["socket.tp"]=nil +loaded["socket.http"]=nil +loaded["socket.ftp"]=nil +loaded["socket.smtp"]=nil + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +package.loaded["util-soc-imp-socket"] = package.loaded["util-soc-imp-socket"] or true + +-- original size: 4867, stripped down to: 3858 + + +local type,tostring,setmetatable=type,tostring,setmetatable +local min=math.min +local format=string.format +local socket=require("socket.core") +local connect=socket.connect +local tcp4=socket.tcp4 +local tcp6=socket.tcp6 +local getaddrinfo=socket.dns.getaddrinfo +local defaulthost="0.0.0.0" +local function report(fmt,first,...) + if logs then + report=logs and logs.reporter("socket") + report(fmt,first,...) + elseif fmt then + fmt="socket: "..fmt + if first then + print(format(fmt,first,...)) + else + print(fmt) + end + end +end +socket.report=report +function socket.connect4(address,port,laddress,lport) + return connect(address,port,laddress,lport,"inet") +end +function socket.connect6(address,port,laddress,lport) + return connect(address,port,laddress,lport,"inet6") +end +function socket.bind(host,port,backlog) + if host=="*" or host=="" then + host=defaulthost + end + local addrinfo,err=getaddrinfo(host) + if not addrinfo then + return nil,err + end + for i=1,#addrinfo do + local alt=addrinfo[i] + local sock,err=(alt.family=="inet" and tcp4 or tcp6)() + if not sock then + return nil,err or "unknown error" + end + sock:setoption("reuseaddr",true) + local res,err=sock:bind(alt.addr,port) + if res then + res,err=sock:listen(backlog) + if res then + return sock + else + sock:close() + end + else + sock:close() + end + end + return nil,"invalid address" +end +socket.try=socket.newtry() +function socket.choose(list) + return function(name,opt1,opt2) + if type(name)~="string" then + name,opt1,opt2="default",name,opt1 + end + local f=list[name or "nil"] + if f then + return f(opt1,opt2) + else + report("error: unknown key '%s'",tostring(name)) + end + end +end +local sourcet={} +local sinkt={} +socket.sourcet=sourcet +socket.sinkt=sinkt +socket.BLOCKSIZE=2048 +sinkt["close-when-done"]=function(sock) + return setmetatable ( + { + getfd=function() return sock:getfd() end, + dirty=function() return sock:dirty() end, + }, + { + __call=function(self,chunk,err) + if chunk then + return sock:send(chunk) + else + sock:close() + return 1 + end + end + } + ) +end +sinkt["keep-open"]=function(sock) + return setmetatable ( + { + getfd=function() return sock:getfd() end, + dirty=function() return sock:dirty() end, + },{ + __call=function(self,chunk,err) + if chunk then + return sock:send(chunk) + else + return 1 + end + end + } + ) +end +sinkt["default"]=sinkt["keep-open"] +socket.sink=socket.choose(sinkt) +sourcet["by-length"]=function(sock,length) + local blocksize=socket.BLOCKSIZE + return setmetatable ( + { + getfd=function() return sock:getfd() end, + dirty=function() return sock:dirty() end, + }, + { + __call=function() + if length<=0 then + return nil + end + local chunk,err=sock:receive(min(blocksize,length)) + if err then + return nil,err + end + length=length-#chunk + return chunk + end + } + ) +end +sourcet["until-closed"]=function(sock) + local blocksize=socket.BLOCKSIZE + local done=false + return setmetatable ( + { + getfd=function() return sock:getfd() end, + dirty=function() return sock:dirty() end, + },{ + __call=function() + if done then + return nil + end + local chunk,status,partial=sock:receive(blocksize) + if not status then + return chunk + elseif status=="closed" then + sock:close() + done=true + return partial + else + return nil,status + end + end + } + ) +end +sourcet["default"]=sourcet["until-closed"] +socket.source=socket.choose(sourcet) +_G.socket=socket +package.loaded.socket=socket + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +package.loaded["util-soc-imp-copas"] = package.loaded["util-soc-imp-copas"] or true + +-- original size: 25841, stripped down to: 16063 + + +local socket=socket or require("socket") +local ssl=ssl or nil +local WATCH_DOG_TIMEOUT=120 +local UDP_DATAGRAM_MAX=8192 +local type,next,pcall,getmetatable,tostring=type,next,pcall,getmetatable,tostring +local min,max,random=math.min,math.max,math.random +local find=string.find +local insert,remove=table.insert,table.remove +local gettime=socket.gettime +local selectsocket=socket.select +local createcoroutine=coroutine.create +local resumecoroutine=coroutine.resume +local yieldcoroutine=coroutine.yield +local runningcoroutine=coroutine.running +local function report(fmt,first,...) + if logs then + report=logs and logs.reporter("copas") + report(fmt,first,...) + elseif fmt then + fmt="copas: "..fmt + if first then + print(format(fmt,first,...)) + else + print(fmt) + end + end +end +local copas={ + _COPYRIGHT="Copyright (C) 2005-2016 Kepler Project", + _DESCRIPTION="Coroutine Oriented Portable Asynchronous Services", + _VERSION="Copas 2.0.1", + autoclose=true, + running=false, + report=report, +} +local function statushandler(status,...) + if status then + return... + end + local err=(...) + if type(err)=="table" then + err=err[1] + end + report("error: %s",tostring(err)) + return nil,err +end +function socket.protect(func) + return function(...) + return statushandler(pcall(func,...)) + end +end +function socket.newtry(finalizer) + return function (...) + local status=(...) + if not status then + local detail=select(2,...) + pcall(finalizer,detail) + report("error: %s",tostring(detail)) + return + end + return... + end +end +local function newset() + local reverse={} + local set={} + local queue={} + setmetatable(set,{ + __index={ + insert=function(set,value) + if not reverse[value] then + local n=#set+1 + set[n]=value + reverse[value]=n + end + end, + remove=function(set,value) + local index=reverse[value] + if index then + reverse[value]=nil + local n=#set + local top=set[n] + set[n]=nil + if top~=value then + reverse[top]=index + set[index]=top + end + end + end, + push=function (set,key,itm) + local entry=queue[key] + if entry==nil then + queue[key]={ itm } + else + entry[#entry+1]=itm + end + end, + pop=function (set,key) + local top=queue[key] + if top~=nil then + local ret=remove(top,1) + if top[1]==nil then + queue[key]=nil + end + return ret + end + end + } + } ) + return set +end +local _sleeping={ + times={}, + cos={}, + lethargy={}, + insert=function() + end, + remove=function() + end, + push=function(self,sleeptime,co) + if not co then + return + end + if sleeptime<0 then + self.lethargy[co]=true + return + else + sleeptime=gettime()+sleeptime + end + local t=self.times + local c=self.cos + local i=1 + local n=#t + while i<=n and t[i]<=sleeptime do + i=i+1 + end + insert(t,i,sleeptime) + insert(c,i,co) + end, + getnext= + function(self) + local t=self.times + local delay=t[1] and t[1]-gettime() or nil + return delay and max(delay,0) or nil + end, + pop= + function(self,time) + local t=self.times + local c=self.cos + if #t==0 or time<t[1] then + return + end + local co=c[1] + remove(t,1) + remove(c,1) + return co + end, + wakeup=function(self,co) + local let=self.lethargy + if let[co] then + self:push(0,co) + let[co]=nil + else + local c=self.cos + local t=self.times + for i=1,#c do + if c[i]==co then + remove(c,i) + remove(t,i) + self:push(0,co) + return + end + end + end + end +} +local _servers=newset() +local _reading=newset() +local _writing=newset() +local _reading_log={} +local _writing_log={} +local _is_timeout={ + timeout=true, + wantread=true, + wantwrite=true, +} +local function isTCP(socket) + return not find(tostring(socket),"^udp") +end +local function copasreceive(client,pattern,part) + if not pattern or pattern=="" then + pattern="*l" + end + local current_log=_reading_log + local s,err + repeat + s,err,part=client:receive(pattern,part) + if s or (not _is_timeout[err]) then + current_log[client]=nil + return s,err,part + end + if err=="wantwrite" then + current_log=_writing_log + current_log[client]=gettime() + yieldcoroutine(client,_writing) + else + current_log=_reading_log + current_log[client]=gettime() + yieldcoroutine(client,_reading) + end + until false +end +local function copasreceivefrom(client,size) + local s,err,port + if not size or size==0 then + size=UDP_DATAGRAM_MAX + end + repeat + s,err,port=client:receivefrom(size) + if s or err~="timeout" then + _reading_log[client]=nil + return s,err,port + end + _reading_log[client]=gettime() + yieldcoroutine(client,_reading) + until false +end +local function copasreceivepartial(client,pattern,part) + if not pattern or pattern=="" then + pattern="*l" + end + local logger=_reading_log + local queue=_reading + local s,err + repeat + s,err,part=client:receive(pattern,part) + if s or (type(pattern)=="number" and part~="" and part) or not _is_timeout[err] then + logger[client]=nil + return s,err,part + end + if err=="wantwrite" then + logger=_writing_log + queue=_writing + else + logger=_reading_log + queue=_reading + end + logger[client]=gettime() + yieldcoroutine(client,queue) + until false +end +local function copassend(client,data,from,to) + if not from then + from=1 + end + local lastIndex=from-1 + local logger=_writing_log + local queue=_writing + local s,err + repeat + s,err,lastIndex=client:send(data,lastIndex+1,to) + if random(100)>90 then + logger[client]=gettime() + yieldcoroutine(client,queue) + end + if s or not _is_timeout[err] then + logger[client]=nil + return s,err,lastIndex + end + if err=="wantread" then + logger=_reading_log + queue=_reading + else + logger=_writing_log + queue=_writing + end + logger[client]=gettime() + yieldcoroutine(client,queue) + until false +end +local function copassendto(client,data,ip,port) + repeat + local s,err=client:sendto(data,ip,port) + if random(100)>90 then + _writing_log[client]=gettime() + yieldcoroutine(client,_writing) + end + if s or err~="timeout" then + _writing_log[client]=nil + return s,err + end + _writing_log[client]=gettime() + yieldcoroutine(client,_writing) + until false +end +local function copasconnect(skt,host,port) + skt:settimeout(0) + local ret,err,tried_more_than_once + repeat + ret,err=skt:connect (host,port) + if ret or (err~="timeout" and err~="Operation already in progress") then + if not ret and err=="already connected" and tried_more_than_once then + ret=1 + err=nil + end + _writing_log[skt]=nil + return ret,err + end + tried_more_than_once=tried_more_than_once or true + _writing_log[skt]=gettime() + yieldcoroutine(skt,_writing) + until false +end +local function copasdohandshake(skt,sslt) + if not ssl then + ssl=require("ssl") + end + if not ssl then + report("error: no ssl library") + return + end + local nskt,err=ssl.wrap(skt,sslt) + if not nskt then + report("error: %s",tostring(err)) + return + end + nskt:settimeout(0) + local queue + repeat + local success,err=nskt:dohandshake() + if success then + return nskt + elseif err=="wantwrite" then + queue=_writing + elseif err=="wantread" then + queue=_reading + else + report("error: %s",tostring(err)) + return + end + yieldcoroutine(nskt,queue) + until false +end +local function copasflush(client) +end +copas.connect=copassconnect +copas.send=copassend +copas.sendto=copassendto +copas.receive=copasreceive +copas.receivefrom=copasreceivefrom +copas.copasreceivepartial=copasreceivepartial +copas.copasreceivePartial=copasreceivepartial +copas.dohandshake=copasdohandshake +copas.flush=copasflush +local function _skt_mt_tostring(self) + return tostring(self.socket).." (copas wrapped)" +end +local _skt_mt_tcp_index={ + send=function(self,data,from,to) + return copassend (self.socket,data,from,to) + end, + receive=function (self,pattern,prefix) + if self.timeout==0 then + return copasreceivePartial(self.socket,pattern,prefix) + else + return copasreceive(self.socket,pattern,prefix) + end + end, + flush=function (self) + return copasflush(self.socket) + end, + settimeout=function (self,time) + self.timeout=time + return true + end, + connect=function(self,...) + local res,err=copasconnect(self.socket,...) + if res and self.ssl_params then + res,err=self:dohandshake() + end + return res,err + end, + close=function(self,...) + return self.socket:close(...) + end, + bind=function(self,...) + return self.socket:bind(...) + end, + getsockname=function(self,...) + return self.socket:getsockname(...) + end, + getstats=function(self,...) + return self.socket:getstats(...) + end, + setstats=function(self,...) + return self.socket:setstats(...) + end, + listen=function(self,...) + return self.socket:listen(...) + end, + accept=function(self,...) + return self.socket:accept(...) + end, + setoption=function(self,...) + return self.socket:setoption(...) + end, + getpeername=function(self,...) + return self.socket:getpeername(...) + end, + shutdown=function(self,...) + return self.socket:shutdown(...) + end, + dohandshake=function(self,sslt) + self.ssl_params=sslt or self.ssl_params + local nskt,err=copasdohandshake(self.socket,self.ssl_params) + if not nskt then + return nskt,err + end + self.socket=nskt + return self + end, +} +local _skt_mt_tcp={ + __tostring=_skt_mt_tostring, + __index=_skt_mt_tcp_index, +} +local _skt_mt_udp_index={ + sendto=function (self,...) + return copassendto(self.socket,...) + end, + receive=function (self,size) + return copasreceive(self.socket,size or UDP_DATAGRAM_MAX) + end, + receivefrom=function (self,size) + return copasreceivefrom(self.socket,size or UDP_DATAGRAM_MAX) + end, + setpeername=function(self,...) + return self.socket:getpeername(...) + end, + setsockname=function(self,...) + return self.socket:setsockname(...) + end, + close=function(self,...) + return true + end +} +local _skt_mt_udp={ + __tostring=_skt_mt_tostring, + __index=_skt_mt_udp_index, +} +for k,v in next,_skt_mt_tcp_index do + if not _skt_mt_udp_index[k] then + _skt_mt_udp_index[k]=v + end +end +local function wrap(skt,sslt) + if getmetatable(skt)==_skt_mt_tcp or getmetatable(skt)==_skt_mt_udp then + return skt + end + skt:settimeout(0) + if isTCP(skt) then + return setmetatable ({ socket=skt,ssl_params=sslt },_skt_mt_tcp) + else + return setmetatable ({ socket=skt },_skt_mt_udp) + end +end +copas.wrap=wrap +function copas.handler(handler,sslparams) + return function (skt,...) + skt=wrap(skt) + if sslparams then + skt:dohandshake(sslparams) + end + return handler(skt,...) + end +end +local _errhandlers={} +function copas.setErrorHandler(err) + local co=runningcoroutine() + if co then + _errhandlers[co]=err + end +end +local function _deferror (msg,co,skt) + report("%s (%s) (%s)",msg,tostring(co),tostring(skt)) +end +local function _doTick (co,skt,...) + if not co then + return + end + local ok,res,new_q=resumecoroutine(co,skt,...) + if ok and res and new_q then + new_q:insert(res) + new_q:push(res,co) + else + if not ok then + pcall(_errhandlers[co] or _deferror,res,co,skt) + end + if skt and copas.autoclose and isTCP(skt) then + skt:close() + end + _errhandlers[co]=nil + end +end +local function _accept(input,handler) + local client=input:accept() + if client then + client:settimeout(0) + local co=createcoroutine(handler) + _doTick (co,client) + end + return client +end +local function _tickRead(skt) + _doTick(_reading:pop(skt),skt) +end +local function _tickWrite(skt) + _doTick(_writing:pop(skt),skt) +end +local function addTCPserver(server,handler,timeout) + server:settimeout(timeout or 0) + _servers[server]=handler + _reading:insert(server) +end +local function addUDPserver(server,handler,timeout) + server:settimeout(timeout or 0) + local co=createcoroutine(handler) + _reading:insert(server) + _doTick(co,server) +end +function copas.addserver(server,handler,timeout) + if isTCP(server) then + addTCPserver(server,handler,timeout) + else + addUDPserver(server,handler,timeout) + end +end +function copas.removeserver(server,keep_open) + local s=server + local mt=getmetatable(server) + if mt==_skt_mt_tcp or mt==_skt_mt_udp then + s=server.socket + end + _servers[s]=nil + _reading:remove(s) + if keep_open then + return true + end + return server:close() +end +function copas.addthread(handler,...) + local thread=createcoroutine(function(_,...) return handler(...) end) + _doTick(thread,nil,...) + return thread +end +local _tasks={} +local function addtaskRead(task) + task.def_tick=_tickRead + _tasks[task]=true +end +local function addtaskWrite(task) + task.def_tick=_tickWrite + _tasks[task]=true +end +local function tasks() + return next,_tasks +end +local _readable_t={ + events=function(self) + local i=0 + return function () + i=i+1 + return self._evs[i] + end + end, + tick=function(self,input) + local handler=_servers[input] + if handler then + input=_accept(input,handler) + else + _reading:remove(input) + self.def_tick(input) + end + end +} +addtaskRead(_readable_t) +local _writable_t={ + events=function(self) + local i=0 + return function() + i=i+1 + return self._evs[i] + end + end, + tick=function(self,output) + _writing:remove(output) + self.def_tick(output) + end +} +addtaskWrite(_writable_t) +local _sleeping_t={ + tick=function(self,time,...) + _doTick(_sleeping:pop(time),...) + end +} +function copas.sleep(sleeptime) + yieldcoroutine((sleeptime or 0),_sleeping) +end +function copas.wakeup(co) + _sleeping:wakeup(co) +end +local last_cleansing=0 +local function _select(timeout) + local now=gettime() + local r_evs,w_evs,err=selectsocket(_reading,_writing,timeout) + _readable_t._evs=r_evs + _writable_t._evs=w_evs + if (last_cleansing-now)>WATCH_DOG_TIMEOUT then + last_cleansing=now + for skt,time in next,_reading_log do + if not r_evs[skt] and (time-now)>WATCH_DOG_TIMEOUT then + local n=#r_evs+1 + _reading_log[skt]=nil + r_evs[n]=skt + r_evs[skt]=n + end + end + for skt,time in next,_writing_log do + if not w_evs[skt] and (time-now)>WATCH_DOG_TIMEOUT then + local n=#w_evs+1 + _writing_log[skt]=nil + w_evs[n]=skt + w_evs[skt]=n + end + end + end + if err=="timeout" and #r_evs+#w_evs>0 then + return nil + else + return err + end +end +local function copasfinished() + return not (next(_reading) or next(_writing) or _sleeping:getnext()) +end +local function copasstep(timeout) + _sleeping_t:tick(gettime()) + local nextwait=_sleeping:getnext() + if nextwait then + timeout=timeout and min(nextwait,timeout) or nextwait + elseif copasfinished() then + return false + end + local err=_select(timeout) + if err then + if err=="timeout" then + return false + end + return nil,err + end + for task in tasks() do + for event in task:events() do + task:tick(event) + end + end + return true +end +copas.finished=copasfinished +copas.step=copasstep +function copas.loop(timeout) + copas.running=true + while not copasfinished() do + copasstep(timeout) + end + copas.running=false +end +package.loaded.copas=copas + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +package.loaded["util-soc-imp-ltn12"] = package.loaded["util-soc-imp-ltn12"] or true + +-- original size: 8706, stripped down to: 6102 + + +local select,unpack=select,unpack +local insert,remove=table.insert,table.remove +local sub=string.sub +local function report(fmt,first,...) + if logs then + report=logs and logs.reporter("ltn12") + report(fmt,first,...) + elseif fmt then + fmt="ltn12: "..fmt + if first then + print(format(fmt,first,...)) + else + print(fmt) + end + end +end +local filter={} +local source={} +local sink={} +local pump={} +local ltn12={ + _VERSION="LTN12 1.0.3", + BLOCKSIZE=2048, + filter=filter, + source=source, + sink=sink, + pump=pump, + report=report, +} +function filter.cycle(low,ctx,extra) + if low then + return function(chunk) + return (low(ctx,chunk,extra)) + end + end +end +function filter.chain(...) + local arg={... } + local n=select('#',...) + local top=1 + local index=1 + local retry="" + return function(chunk) + retry=chunk and retry + while true do + local action=arg[index] + if index==top then + chunk=action(chunk) + if chunk=="" or top==n then + return chunk + elseif chunk then + index=index+1 + else + top=top+1 + index=top + end + else + chunk=action(chunk or "") + if chunk=="" then + index=index-1 + chunk=retry + elseif chunk then + if index==n then + return chunk + else + index=index+1 + end + else + report("error: filter returned inappropriate 'nil'") + return + end + end + end + end +end +local function empty() + return nil +end +function source.empty() + return empty +end +local function sourceerror(err) + return function() + return nil,err + end +end +source.error=sourceerror +function source.file(handle,io_err) + if handle then + local blocksize=ltn12.BLOCKSIZE + return function() + local chunk=handle:read(blocksize) + if not chunk then + handle:close() + end + return chunk + end + else + return sourceerror(io_err or "unable to open file") + end +end +function source.simplify(src) + return function() + local chunk,err_or_new=src() + if err_or_new then + src=err_or_new + end + if chunk then + return chunk + else + return nil,err_or_new + end + end +end +function source.string(s) + if s then + local blocksize=ltn12.BLOCKSIZE + local i=1 + return function() + local nexti=i+blocksize + local chunk=sub(s,i,nexti-1) + i=nexti + if chunk~="" then + return chunk + else + return nil + end + end + else return source.empty() end +end +function source.rewind(src) + local t={} + return function(chunk) + if chunk then + insert(t,chunk) + else + chunk=remove(t) + if chunk then + return chunk + else + return src() + end + end + end +end +function source.chain(src,f,...) + if... then + f=filter.chain(f,...) + end + local last_in="" + local last_out="" + local state="feeding" + local err + return function() + if not last_out then + report("error: source is empty") + return + end + while true do + if state=="feeding" then + last_in,err=src() + if err then + return nil,err + end + last_out=f(last_in) + if not last_out then + if last_in then + report("error: filter returned inappropriate 'nil'") + end + return nil + elseif last_out~="" then + state="eating" + if last_in then + last_in="" + end + return last_out + end + else + last_out=f(last_in) + if last_out=="" then + if last_in=="" then + state="feeding" + else + report("error: filter returned nothing") + return + end + elseif not last_out then + if last_in then + report("filter returned inappropriate 'nil'") + end + return nil + else + return last_out + end + end + end + end +end +function source.cat(...) + local arg={... } + local src=remove(arg,1) + return function() + while src do + local chunk,err=src() + if chunk then + return chunk + end + if err then + return nil,err + end + src=remove(arg,1) + end + end +end +function sink.table(t) + if not t then + t={} + end + local f=function(chunk,err) + if chunk then + insert(t,chunk) + end + return 1 + end + return f,t +end +function sink.simplify(snk) + return function(chunk,err) + local ret,err_or_new=snk(chunk,err) + if not ret then + return nil,err_or_new + end + if err_or_new then + snk=err_or_new + end + return 1 + end +end +local function null() + return 1 +end +function sink.null() + return null +end +local function sinkerror(err) + return function() + return nil,err + end +end +sink.error=sinkerror +function sink.file(handle,io_err) + if handle then + return function(chunk,err) + if not chunk then + handle:close() + return 1 + else + return handle:write(chunk) + end + end + else + return sinkerror(io_err or "unable to open file") + end +end +function sink.chain(f,snk,...) + if... then + local args={ f,snk,... } + snk=remove(args,#args) + f=filter.chain(unpack(args)) + end + return function(chunk,err) + if chunk~="" then + local filtered=f(chunk) + local done=chunk and "" + while true do + local ret,snkerr=snk(filtered,err) + if not ret then + return nil,snkerr + end + if filtered==done then + return 1 + end + filtered=f(done) + end + else + return 1 + end + end +end +function pump.step(src,snk) + local chunk,src_err=src() + local ret,snk_err=snk(chunk,src_err) + if chunk and ret then + return 1 + else + return nil,src_err or snk_err + end +end +function pump.all(src,snk,step) + if not step then + step=pump.step + end + while true do + local ret,err=step(src,snk) + if not ret then + if err then + return nil,err + else + return 1 + end + end + end +end +package.loaded.ltn12=ltn12 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +package.loaded["util-soc-imp-mime"] = package.loaded["util-soc-imp-mime"] or true + +-- original size: 2325, stripped down to: 1927 + + +local type,tostring=type,tostring +local mime=require("mime.core") +local ltn12=ltn12 or require("ltn12") +local filtercycle=ltn12.filter.cycle +local function report(fmt,first,...) + if logs then + report=logs and logs.reporter("mime") + report(fmt,first,...) + elseif fmt then + fmt="mime: "..fmt + if first then + print(format(fmt,first,...)) + else + print(fmt) + end + end +end +mime.report=report +local encodet={} +local decodet={} +local wrapt={} +mime.encodet=encodet +mime.decodet=decodet +mime.wrapt=wrapt +local mime_b64=mime.b64 +local mime_qp=mime.qp +local mime_unb64=mime.unb64 +local mime_unqp=mime.unqp +local mime_wrp=mime.wrp +local mime_qpwrp=mime.qpwrp +local mime_eol=mime_eol +local mime_dot=mime_dot +encodet['base64']=function() + return filtercycle(mime_b64,"") +end +encodet['quoted-printable']=function(mode) + return filtercycle(mime_qp,"",mode=="binary" and "=0D=0A" or "\r\n") +end +decodet['base64']=function() + return filtercycle(mime_unb64,"") +end +decodet['quoted-printable']=function() + return filtercycle(mime_unqp,"") +end +local wraptext=function(length) + if not length then + length=76 + end + return filtercycle(mime_wrp,length,length) +end +local wrapquoted=function() + return filtercycle(mime_qpwrp,76,76) +end +wrapt['text']=wraptext +wrapt['base64']=wraptext +wrapt['default']=wraptext +wrapt['quoted-printable']=wrapquoted +function mime.normalize(marker) + return filtercycle(mime_eol,0,marker) +end +function mime.stuff() + return filtercycle(mime_dot,2) +end +local function choose(list) + return function(name,opt1,opt2) + if type(name)~="string" then + name,opt1,opt2="default",name,opt1 + end + local filter=list[name or "nil"] + if filter then + return filter(opt1,opt2) + else + report("error: unknown key '%s'",tostring(name)) + end + end +end +mime.encode=choose(encodet) +mime.decode=choose(decodet) +mime.wrap=choose(wrapt) +package.loaded.mime=mime + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +package.loaded["util-soc-imp-url"] = package.loaded["util-soc-imp-url"] or true + +-- original size: 6827, stripped down to: 5624 + + +local tonumber,tostring,type=tonumber,tostring,type +local gsub,sub,match,find,format,byte,char=string.gsub,string.sub,string.match,string.find,string.format,string.byte,string.char +local insert=table.insert +local socket=socket or require("socket") +local url={ + _VERSION="URL 1.0.3", +} +socket.url=url +function url.escape(s) + return (gsub(s,"([^A-Za-z0-9_])",function(c) + return format("%%%02x",byte(c)) + end)) +end +local function make_set(t) + local s={} + for i=1,#t do + s[t[i]]=true + end + return s +end +local segment_set=make_set { + "-","_",".","!","~","*","'","(", + ")",":","@","&","=","+","$",",", +} +local function protect_segment(s) + return gsub(s,"([^A-Za-z0-9_])",function(c) + if segment_set[c] then + return c + else + return format("%%%02X",byte(c)) + end + end) +end +function url.unescape(s) + return (gsub(s,"%%(%x%x)",function(hex) + return char(tonumber(hex,16)) + end)) +end +local function absolute_path(base_path,relative_path) + if find(relative_path,"^/") then + return relative_path + end + local path=gsub(base_path,"[^/]*$","") + path=path..relative_path + path=gsub(path,"([^/]*%./)",function (s) + if s~="./" then + return s + else + return "" + end + end) + path=gsub(path,"/%.$","/") + local reduced + while reduced~=path do + reduced=path + path=gsub(reduced,"([^/]*/%.%./)",function (s) + if s~="../../" then + return "" + else + return s + end + end) + end + path=gsub(reduced,"([^/]*/%.%.)$",function (s) + if s~="../.." then + return "" + else + return s + end + end) + return path +end +function url.parse(url,default) + local parsed={} + for k,v in next,default or parsed do + parsed[k]=v + end + if not url or url=="" then + return nil,"invalid url" + end + url=gsub(url,"#(.*)$",function(f) + parsed.fragment=f + return "" + end) + url=gsub(url,"^([%w][%w%+%-%.]*)%:",function(s) + parsed.scheme=s + return "" + end) + url=gsub(url,"^//([^/]*)",function(n) + parsed.authority=n + return "" + end) + url=gsub(url,"%?(.*)",function(q) + parsed.query=q + return "" + end) + url=gsub(url,"%;(.*)",function(p) + parsed.params=p + return "" + end) + if url~="" then + parsed.path=url + end + local authority=parsed.authority + if not authority then + return parsed + end + authority=gsub(authority,"^([^@]*)@",function(u) + parsed.userinfo=u + return "" + end) + authority=gsub(authority,":([^:%]]*)$",function(p) + parsed.port=p + return "" + end) + if authority~="" then + parsed.host=match(authority,"^%[(.+)%]$") or authority + end + local userinfo=parsed.userinfo + if not userinfo then + return parsed + end + userinfo=gsub(userinfo,":([^:]*)$",function(p) + parsed.password=p + return "" + end) + parsed.user=userinfo + return parsed +end +function url.build(parsed) + local url=parsed.path or "" + if parsed.params then + url=url..";"..parsed.params + end + if parsed.query then + url=url.."?"..parsed.query + end + local authority=parsed.authority + if parsed.host then + authority=parsed.host + if find(authority,":") then + authority="["..authority.."]" + end + if parsed.port then + authority=authority..":"..tostring(parsed.port) + end + local userinfo=parsed.userinfo + if parsed.user then + userinfo=parsed.user + if parsed.password then + userinfo=userinfo..":"..parsed.password + end + end + if userinfo then authority=userinfo.."@"..authority end + end + if authority then + url="//"..authority..url + end + if parsed.scheme then + url=parsed.scheme..":"..url + end + if parsed.fragment then + url=url.."#"..parsed.fragment + end + return url +end +function url.absolute(base_url,relative_url) + local base_parsed + if type(base_url)=="table" then + base_parsed=base_url + base_url=url.build(base_parsed) + else + base_parsed=url.parse(base_url) + end + local relative_parsed=url.parse(relative_url) + if not base_parsed then + return relative_url + elseif not relative_parsed then + return base_url + elseif relative_parsed.scheme then + return relative_url + else + relative_parsed.scheme=base_parsed.scheme + if not relative_parsed.authority then + relative_parsed.authority=base_parsed.authority + if not relative_parsed.path then + relative_parsed.path=base_parsed.path + if not relative_parsed.params then + relative_parsed.params=base_parsed.params + if not relative_parsed.query then + relative_parsed.query=base_parsed.query + end + end + else + relative_parsed.path=absolute_path(base_parsed.path or "",relative_parsed.path) + end + end + return url.build(relative_parsed) + end +end +function url.parse_path(path) + local parsed={} + path=path or "" + gsub(path,"([^/]+)",function (s) + insert(parsed,s) + end) + for i=1,#parsed do + parsed[i]=url.unescape(parsed[i]) + end + if sub(path,1,1)=="/" then + parsed.is_absolute=1 + end + if sub(path,-1,-1)=="/" then + parsed.is_directory=1 + end + return parsed +end +function url.build_path(parsed,unsafe) + local path="" + local n=#parsed + if unsafe then + for i=1,n-1 do + path=path..parsed[i].."/" + end + if n>0 then + path=path..parsed[n] + if parsed.is_directory then + path=path.."/" + end + end + else + for i=1,n-1 do + path=path..protect_segment(parsed[i]).."/" + end + if n>0 then + path=path..protect_segment(parsed[n]) + if parsed.is_directory then + path=path.."/" + end + end + end + if parsed.is_absolute then + path="/"..path + end + return path +end + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +package.loaded["util-soc-imp-headers"] = package.loaded["util-soc-imp-headers"] or true + +-- original size: 5712, stripped down to: 3865 + + +local next=next +local lower=string.lower +local concat=table.concat +local socket=socket or require("socket") +local canonic={ + ["accept"]="Accept", + ["accept-charset"]="Accept-Charset", + ["accept-encoding"]="Accept-Encoding", + ["accept-language"]="Accept-Language", + ["accept-ranges"]="Accept-Ranges", + ["action"]="Action", + ["alternate-recipient"]="Alternate-Recipient", + ["age"]="Age", + ["allow"]="Allow", + ["arrival-date"]="Arrival-Date", + ["authorization"]="Authorization", + ["bcc"]="Bcc", + ["cache-control"]="Cache-Control", + ["cc"]="Cc", + ["comments"]="Comments", + ["connection"]="Connection", + ["content-description"]="Content-Description", + ["content-disposition"]="Content-Disposition", + ["content-encoding"]="Content-Encoding", + ["content-id"]="Content-ID", + ["content-language"]="Content-Language", + ["content-length"]="Content-Length", + ["content-location"]="Content-Location", + ["content-md5"]="Content-MD5", + ["content-range"]="Content-Range", + ["content-transfer-encoding"]="Content-Transfer-Encoding", + ["content-type"]="Content-Type", + ["cookie"]="Cookie", + ["date"]="Date", + ["diagnostic-code"]="Diagnostic-Code", + ["dsn-gateway"]="DSN-Gateway", + ["etag"]="ETag", + ["expect"]="Expect", + ["expires"]="Expires", + ["final-log-id"]="Final-Log-ID", + ["final-recipient"]="Final-Recipient", + ["from"]="From", + ["host"]="Host", + ["if-match"]="If-Match", + ["if-modified-since"]="If-Modified-Since", + ["if-none-match"]="If-None-Match", + ["if-range"]="If-Range", + ["if-unmodified-since"]="If-Unmodified-Since", + ["in-reply-to"]="In-Reply-To", + ["keywords"]="Keywords", + ["last-attempt-date"]="Last-Attempt-Date", + ["last-modified"]="Last-Modified", + ["location"]="Location", + ["max-forwards"]="Max-Forwards", + ["message-id"]="Message-ID", + ["mime-version"]="MIME-Version", + ["original-envelope-id"]="Original-Envelope-ID", + ["original-recipient"]="Original-Recipient", + ["pragma"]="Pragma", + ["proxy-authenticate"]="Proxy-Authenticate", + ["proxy-authorization"]="Proxy-Authorization", + ["range"]="Range", + ["received"]="Received", + ["received-from-mta"]="Received-From-MTA", + ["references"]="References", + ["referer"]="Referer", + ["remote-mta"]="Remote-MTA", + ["reply-to"]="Reply-To", + ["reporting-mta"]="Reporting-MTA", + ["resent-bcc"]="Resent-Bcc", + ["resent-cc"]="Resent-Cc", + ["resent-date"]="Resent-Date", + ["resent-from"]="Resent-From", + ["resent-message-id"]="Resent-Message-ID", + ["resent-reply-to"]="Resent-Reply-To", + ["resent-sender"]="Resent-Sender", + ["resent-to"]="Resent-To", + ["retry-after"]="Retry-After", + ["return-path"]="Return-Path", + ["sender"]="Sender", + ["server"]="Server", + ["smtp-remote-recipient"]="SMTP-Remote-Recipient", + ["status"]="Status", + ["subject"]="Subject", + ["te"]="TE", + ["to"]="To", + ["trailer"]="Trailer", + ["transfer-encoding"]="Transfer-Encoding", + ["upgrade"]="Upgrade", + ["user-agent"]="User-Agent", + ["vary"]="Vary", + ["via"]="Via", + ["warning"]="Warning", + ["will-retry-until"]="Will-Retry-Until", + ["www-authenticate"]="WWW-Authenticate", + ["x-mailer"]="X-Mailer", +} +setmetatable(canonic,{ + __index=function(t,k) + socket.report("invalid header: %s",k) + t[k]=k + return k + end +}) +local function normalizeheaders(headers) + if not headers then + return {} + end + local normalized={} + for k,v in next,headers do + normalized[#normalized+1]=canonic[k]..": "..v + end + normalized[#normalized+1]="" + normalized[#normalized+1]="" + return concat(normalized,"\r\n") +end +local function lowerheaders(lowered,headers) + if not lowered then + return {} + end + if not headers then + lowered,headers={},lowered + end + for k,v in next,headers do + lowered[lower(k)]=v + end + return lowered +end +socket.headers={ + canonic=canonic, + normalize=normalizeheaders, + lower=lowerheaders, +} + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +package.loaded["util-soc-imp-tp"] = package.loaded["util-soc-imp-tp"] or true + +-- original size: 3082, stripped down to: 2612 + + +local setmetatable,next,type,tonumber=setmetatable,next,type,tonumber +local find,upper=string.find,string,upper +local socket=socket or require("socket") +local ltn12=ltn12 or require("ltn12") +local skipsocket=socket.skip +local sinksocket=socket.sink +local tcpsocket=socket.tcp +local ltn12pump=ltn12.pump +local pumpall=ltn12pump.all +local pumpstep=ltn12pump.step +local tp={ + TIMEOUT=60, +} +socket.tp=tp +local function get_reply(c) + local line,err=c:receive() + local reply=line + if err then return + nil,err + end + local code,sep=skipsocket(2,find(line,"^(%d%d%d)(.?)")) + if not code then + return nil,"invalid server reply" + end + if sep=="-" then + local current + repeat + line,err=c:receive() + if err then + return nil,err + end + current,sep=skipsocket(2,find(line,"^(%d%d%d)(.?)")) + reply=reply.."\n"..line + until code==current and sep==" " + end + return code,reply +end +local methods={} +local mt={ __index=methods } +function methods.getpeername(self) + return self.c:getpeername() +end +function methods.getsockname(self) + return self.c:getpeername() +end +function methods.check(self,ok) + local code,reply=get_reply(self.c) + if not code then + return nil,reply + end + local c=tonumber(code) + local t=type(ok) + if t=="function" then + return ok(c,reply) + elseif t=="table" then + for i=1,#ok do + if find(code,ok[i]) then + return c,reply + end + end + return nil,reply + elseif find(code,ok) then + return c,reply + else + return nil,reply + end +end +function methods.command(self,cmd,arg) + cmd=upper(cmd) + if arg then + cmd=cmd.." "..arg.."\r\n" + else + cmd=cmd.."\r\n" + end + return self.c:send(cmd) +end +function methods.sink(self,snk,pat) + local chunk,err=self.c:receive(pat) + return snk(chunk,err) +end +function methods.send(self,data) + return self.c:send(data) +end +function methods.receive(self,pat) + return self.c:receive(pat) +end +function methods.getfd(self) + return self.c:getfd() +end +function methods.dirty(self) + return self.c:dirty() +end +function methods.getcontrol(self) + return self.c +end +function methods.source(self,source,step) + local sink=sinksocket("keep-open",self.c) + local ret,err=pumpall(source,sink,step or pumpstep) + return ret,err +end +function methods.close(self) + self.c:close() + return 1 +end +function tp.connect(host,port,timeout,create) + local c,e=(create or tcpsocket)() + if not c then + return nil,e + end + c:settimeout(timeout or tp.TIMEOUT) + local r,e=c:connect(host,port) + if not r then + c:close() + return nil,e + end + return setmetatable({ c=c },mt) +end + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +package.loaded["util-soc-imp-http"] = package.loaded["util-soc-imp-http"] or true + +-- original size: 12499, stripped down to: 10001 + + +local tostring,tonumber,setmetatable,next,type=tostring,tonumber,setmetatable,next,type +local find,lower,format,gsub,match=string.find,string.lower,string.format,string.gsub,string.match +local concat=table.concat +local socket=socket or require("socket") +local url=socket.url or require("socket.url") +local ltn12=ltn12 or require("ltn12") +local mime=mime or require("mime") +local headers=socket.headers or require("socket.headers") +local normalizeheaders=headers.normalize +local parseurl=url.parse +local buildurl=url.build +local absoluteurl=url.absolute +local unescapeurl=url.unescape +local skipsocket=socket.skip +local sinksocket=socket.sink +local sourcesocket=socket.source +local trysocket=socket.try +local tcpsocket=socket.tcp +local newtrysocket=socket.newtry +local protectsocket=socket.protect +local emptysource=ltn12.source.empty +local stringsource=ltn12.source.string +local rewindsource=ltn12.source.rewind +local pumpstep=ltn12.pump.step +local pumpall=ltn12.pump.all +local sinknull=ltn12.sink.null +local sinktable=ltn12.sink.table +local mimeb64=mime.b64 +local http={ + TIMEOUT=60, + USERAGENT=socket._VERSION, +} +socket.http=http +local PORT=80 +local SCHEMES={ + http=true, +} +local function receiveheaders(sock,headers) + if not headers then + headers={} + end + local line,err=sock:receive() + if err then + return nil,err + end + while line~="" do + local name,value=skipsocket(2,find(line,"^(.-):%s*(.*)")) + if not (name and value) then + return nil,"malformed reponse headers" + end + name=lower(name) + line,err=sock:receive() + if err then + return nil,err + end + while find(line,"^%s") do + value=value..line + line=sock:receive() + if err then + return nil,err + end + end + local found=headers[name] + if found then + value=found..", "..value + end + headers[name]=value + end + return headers +end +socket.sourcet["http-chunked"]=function(sock,headers) + return setmetatable ( + { + getfd=function() return sock:getfd() end, + dirty=function() return sock:dirty() end, + },{ + __call=function() + local line,err=sock:receive() + if err then + return nil,err + end + local size=tonumber(gsub(line,";.*",""),16) + if not size then + return nil,"invalid chunk size" + end + if size>0 then + local chunk,err,part=sock:receive(size) + if chunk then + sock:receive() + end + return chunk,err + else + headers,err=receiveheaders(sock,headers) + if not headers then + return nil,err + end + end + end + } + ) +end +socket.sinkt["http-chunked"]=function(sock) + return setmetatable( + { + getfd=function() return sock:getfd() end, + dirty=function() return sock:dirty() end, + }, + { + __call=function(self,chunk,err) + if not chunk then + chunk="" + end + return sock:send(format("%X\r\n%s\r\n",#chunk,chunk)) + end + }) +end +local methods={} +local mt={ __index=methods } +local function openhttp(host,port,create) + local c=trysocket((create or tcpsocket)()) + local h=setmetatable({ c=c },mt) + local try=newtrysocket(function() h:close() end) + h.try=try + try(c:settimeout(http.TIMEOUT)) + try(c:connect(host,port or PORT)) + return h +end +http.open=openhttp +function methods.sendrequestline(self,method,uri) + local requestline=format("%s %s HTTP/1.1\r\n",method or "GET",uri) + return self.try(self.c:send(requestline)) +end +function methods.sendheaders(self,headers) + self.try(self.c:send(normalizeheaders(headers))) + return 1 +end +function methods.sendbody(self,headers,source,step) + if not source then + source=emptysource() + end + if not step then + step=pumpstep + end + local mode="http-chunked" + if headers["content-length"] then + mode="keep-open" + end + return self.try(pumpall(source,sinksocket(mode,self.c),step)) +end +function methods.receivestatusline(self) + local try=self.try + local status=try(self.c:receive(5)) + if status~="HTTP/" then + return nil,status + end + status=try(self.c:receive("*l",status)) + local code=skipsocket(2,find(status,"HTTP/%d*%.%d* (%d%d%d)")) + return try(tonumber(code),status) +end +function methods.receiveheaders(self) + return self.try(receiveheaders(self.c)) +end +function methods.receivebody(self,headers,sink,step) + if not sink then + sink=sinknull() + end + if not step then + step=pumpstep + end + local length=tonumber(headers["content-length"]) + local encoding=headers["transfer-encoding"] + local mode="default" + if encoding and encoding~="identity" then + mode="http-chunked" + elseif length then + mode="by-length" + end + return self.try(pumpall(sourcesocket(mode,self.c,length),sink,step)) +end +function methods.receive09body(self,status,sink,step) + local source=rewindsource(sourcesocket("until-closed",self.c)) + source(status) + return self.try(pumpall(source,sink,step)) +end +function methods.close(self) + return self.c:close() +end +local function adjusturi(request) + if not request.proxy and not http.PROXY then + request={ + path=trysocket(request.path,"invalid path 'nil'"), + params=request.params, + query=request.query, + fragment=request.fragment, + } + end + return buildurl(request) +end +local function adjustheaders(request) + local headers={ + ["user-agent"]=http.USERAGENT, + ["host"]=gsub(request.authority,"^.-@",""), + ["connection"]="close, TE", + ["te"]="trailers" + } + local username=request.user + local password=request.password + if username and password then + headers["authorization"]="Basic "..(mimeb64(username..":"..unescapeurl(password))) + end + local proxy=request.proxy or http.PROXY + if proxy then + proxy=parseurl(proxy) + local username=proxy.user + local password=proxy.password + if username and password then + headers["proxy-authorization"]="Basic "..(mimeb64(username..":"..password)) + end + end + local requestheaders=request.headers + if requestheaders then + headers=lowerheaders(headers,requestheaders) + end + return headers +end +local default={ + host="", + port=PORT, + path="/", + scheme="http" +} +local function adjustrequest(originalrequest) + local url=originalrequest.url + local request=url and parseurl(url,default) or {} + for k,v in next,originalrequest do + request[k]=v + end + local host=request.host + local port=request.port + local uri=request.uri + if not host or host=="" then + trysocket(nil,"invalid host '"..tostring(host).."'") + end + if port=="" then + request.port=PORT + end + if not uri or uri=="" then + request.uri=adjusturi(request) + end + request.headers=adjustheaders(request) + local proxy=request.proxy or http.PROXY + if proxy then + proxy=parseurl(proxy) + request.host=proxy.host + request.port=proxy.port or 3128 + end + return request +end +local maxredericts=4 +local validredirects={ [301]=true,[302]=true,[303]=true,[307]=true } +local validmethods={ [false]=true,GET=true,HEAD=true } +local function shouldredirect(request,code,headers) + local location=headers.location + if not location then + return false + end + location=gsub(location,"%s","") + if location=="" then + return false + end + local scheme=match(location,"^([%w][%w%+%-%.]*)%:") + if scheme and not SCHEMES[scheme] then + return false + end + local method=request.method + local redirect=request.redirect + local redirects=request.nredirects or 0 + return redirect and validredirects[code] and validmethods[method] and redirects<=maxredericts +end +local function shouldreceivebody(request,code) + if request.method=="HEAD" then + return nil + end + if code==204 or code==304 then + return nil + end + if code>=100 and code<200 then + return nil + end + return 1 +end +local tredirect,trequest,srequest +tredirect=function(request,location) + local result,code,headers,status=trequest { + url=absoluteurl(request.url,location), + source=request.source, + sink=request.sink, + headers=request.headers, + proxy=request.proxy, + nredirects=(request.nredirects or 0)+1, + create=request.create, + } + if not headers then + headers={} + end + if not headers.location then + headers.location=location + end + return result,code,headers,status +end +trequest=function(originalrequest) + local request=adjustrequest(originalrequest) + local connection=openhttp(request.host,request.port,request.create) + local headers=request.headers + connection:sendrequestline(request.method,request.uri) + connection:sendheaders(headers) + if request.source then + connection:sendbody(headers,request.source,request.step) + end + local code,status=connection:receivestatusline() + if not code then + connection:receive09body(status,request.sink,request.step) + return 1,200 + end + while code==100 do + headers=connection:receiveheaders() + code,status=connection:receivestatusline() + end + headers=connection:receiveheaders() + if shouldredirect(request,code,headers) and not request.source then + connection:close() + return tredirect(originalrequest,headers.location) + end + if shouldreceivebody(request,code) then + connection:receivebody(headers,request.sink,request.step) + end + connection:close() + return 1,code,headers,status +end +local function genericform(url,body) + local buffer={} + local request={ + url=url, + sink=sinktable(buffer), + target=buffer, + } + if body then + request.source=stringsource(body) + request.method="POST" + request.headers={ + ["content-length"]=#body, + ["content-type"]="application/x-www-form-urlencoded" + } + end + return request +end +http.genericform=genericform +srequest=function(url,body) + local request=genericform(url,body) + local _,code,headers,status=trequest(request) + return concat(request.target),code,headers,status +end +http.request=protectsocket(function(request,body) + if type(request)=="string" then + return srequest(request,body) + else + return trequest(request) + end +end) + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +package.loaded["util-soc-imp-ftp"] = package.loaded["util-soc-imp-ftp"] or true + +-- original size: 10321, stripped down to: 8867 + + +local setmetatable,type,next=setmetatable,type,next +local find,format,gsub,match=string.find,string.format,string.gsub,string.match +local concat=table.concat +local mod=math.mod +local socket=socket or require("socket") +local url=socket.url or require("socket.url") +local tp=socket.tp or require("socket.tp") +local ltn12=ltn12 or require("ltn12") +local tcpsocket=socket.tcp +local trysocket=socket.try +local skipsocket=socket.skip +local sinksocket=socket.sink +local selectsocket=socket.select +local bindsocket=socket.bind +local newtrysocket=socket.newtry +local sourcesocket=socket.source +local protectsocket=socket.protect +local parseurl=url.parse +local unescapeurl=url.unescape +local pumpall=ltn12.pump.all +local pumpstep=ltn12.pump.step +local sourcestring=ltn12.source.string +local sinktable=ltn12.sink.table +local ftp={ + TIMEOUT=60, + USER="ftp", + PASSWORD="anonymous@anonymous.org", +} +socket.ftp=ftp +local PORT=21 +local methods={} +local mt={ __index=methods } +function ftp.open(server,port,create) + local tp=trysocket(tp.connect(server,port or PORT,ftp.TIMEOUT,create)) + local f=setmetatable({ tp=tp },metat) + f.try=newtrysocket(function() f:close() end) + return f +end +function methods.portconnect(self) + local try=self.try + local server=self.server + try(server:settimeout(ftp.TIMEOUT)) + self.data=try(server:accept()) + try(self.data:settimeout(ftp.TIMEOUT)) +end +function methods.pasvconnect(self) + local try=self.try + self.data=try(tcpsocket()) + self(self.data:settimeout(ftp.TIMEOUT)) + self(self.data:connect(self.pasvt.address,self.pasvt.port)) +end +function methods.login(self,user,password) + local try=self.try + local tp=self.tp + try(tp:command("user",user or ftp.USER)) + local code,reply=try(tp:check{"2..",331}) + if code==331 then + try(tp:command("pass",password or ftp.PASSWORD)) + try(tp:check("2..")) + end + return 1 +end +function methods.pasv(self) + local try=self.try + local tp=self.tp + try(tp:command("pasv")) + local code,reply=try(self.tp:check("2..")) + local pattern="(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)" + local a,b,c,d,p1,p2=skipsocket(2,find(reply,pattern)) + try(a and b and c and d and p1 and p2,reply) + local address=format("%d.%d.%d.%d",a,b,c,d) + local port=p1*256+p2 + local server=self.server + self.pasvt={ + address=address, + port=port, + } + if server then + server:close() + self.server=nil + end + return address,port +end +function methods.epsv(self) + local try=self.try + local tp=self.tp + try(tp:command("epsv")) + local code,reply=try(tp:check("229")) + local pattern="%((.)(.-)%1(.-)%1(.-)%1%)" + local d,prt,address,port=match(reply,pattern) + try(port,"invalid epsv response") + local address=tp:getpeername() + local server=self.server + self.pasvt={ + address=address, + port=port, + } + if self.server then + server:close() + self.server=nil + end + return address,port +end +function methods.port(self,address,port) + local try=self.try + local tp=self.tp + self.pasvt=nil + if not address then + address,port=try(tp:getsockname()) + self.server=try(bindsocket(address,0)) + address,port=try(self.server:getsockname()) + try(self.server:settimeout(ftp.TIMEOUT)) + end + local pl=mod(port,256) + local ph=(port-pl)/256 + local arg=gsub(format("%s,%d,%d",address,ph,pl),"%.",",") + try(tp:command("port",arg)) + try(tp:check("2..")) + return 1 +end +function methods.eprt(self,family,address,port) + local try=self.try + local tp=self.tp + self.pasvt=nil + if not address then + address,port=try(tp:getsockname()) + self.server=try(bindsocket(address,0)) + address,port=try(self.server:getsockname()) + try(self.server:settimeout(ftp.TIMEOUT)) + end + local arg=format("|%s|%s|%d|",family,address,port) + try(tp:command("eprt",arg)) + try(tp:check("2..")) + return 1 +end +function methods.send(self,sendt) + local try=self.try + local tp=self.tp + try(self.pasvt or self.server,"need port or pasv first") + if self.pasvt then + self:pasvconnect() + end + local argument=sendt.argument or unescapeurl(gsub(sendt.path or "","^[/\\]","")) + if argument=="" then + argument=nil + end + local command=sendt.command or "stor" + try(tp:command(command,argument)) + local code,reply=try(tp:check{"2..","1.."}) + if not self.pasvt then + self:portconnect() + end + local step=sendt.step or pumpstep + local readt={ tp } + local checkstep=function(src,snk) + local readyt=selectsocket(readt,nil,0) + if readyt[tp] then + code=try(tp:check("2..")) + end + return step(src,snk) + end + local sink=sinksocket("close-when-done",self.data) + try(pumpall(sendt.source,sink,checkstep)) + if find(code,"1..") then + try(tp:check("2..")) + end + self.data:close() + local sent=skipsocket(1,self.data:getstats()) + self.data=nil + return sent +end +function methods.receive(self,recvt) + local try=self.try + local tp=self.tp + try(self.pasvt or self.server,"need port or pasv first") + if self.pasvt then self:pasvconnect() end + local argument=recvt.argument or unescapeurl(gsub(recvt.path or "","^[/\\]","")) + if argument=="" then + argument=nil + end + local command=recvt.command or "retr" + try(tp:command(command,argument)) + local code,reply=try(tp:check{"1..","2.."}) + if code>=200 and code<=299 then + recvt.sink(reply) + return 1 + end + if not self.pasvt then + self:portconnect() + end + local source=sourcesocket("until-closed",self.data) + local step=recvt.step or pumpstep + try(pumpall(source,recvt.sink,step)) + if find(code,"1..") then + try(tp:check("2..")) + end + self.data:close() + self.data=nil + return 1 +end +function methods.cwd(self,dir) + local try=self.try + local tp=self.tp + try(tp:command("cwd",dir)) + try(tp:check(250)) + return 1 +end +function methods.type(self,typ) + local try=self.try + local tp=self.tp + try(tp:command("type",typ)) + try(tp:check(200)) + return 1 +end +function methods.greet(self) + local try=self.try + local tp=self.tp + local code=try(tp:check{"1..","2.."}) + if find(code,"1..") then + try(tp:check("2..")) + end + return 1 +end +function methods.quit(self) + local try=self.try + try(self.tp:command("quit")) + try(self.tp:check("2..")) + return 1 +end +function methods.close(self) + local data=self.data + if data then + data:close() + end + local server=self.server + if server then + server:close() + end + local tp=self.tp + if tp then + tp:close() + end +end +local function override(t) + if t.url then + local u=parseurl(t.url) + for k,v in next,t do + u[k]=v + end + return u + else + return t + end +end +local function tput(putt) + putt=override(putt) + local host=putt.host + trysocket(host,"missing hostname") + local f=ftp.open(host,putt.port,putt.create) + f:greet() + f:login(putt.user,putt.password) + local typ=putt.type + if typ then + f:type(typ) + end + f:epsv() + local sent=f:send(putt) + f:quit() + f:close() + return sent +end +local default={ + path="/", + scheme="ftp", +} +local function genericform(u) + local t=trysocket(parseurl(u,default)) + trysocket(t.scheme=="ftp","wrong scheme '"..t.scheme.."'") + trysocket(t.host,"missing hostname") + local pat="^type=(.)$" + if t.params then + local typ=skipsocket(2,find(t.params,pat)) + t.type=typ + trysocket(typ=="a" or typ=="i","invalid type '"..typ.."'") + end + return t +end +ftp.genericform=genericform +local function sput(u,body) + local putt=genericform(u) + putt.source=sourcestring(body) + return tput(putt) +end +ftp.put=protectsocket(function(putt,body) + if type(putt)=="string" then + return sput(putt,body) + else + return tput(putt) + end +end) +local function tget(gett) + gett=override(gett) + local host=gett.host + trysocket(host,"missing hostname") + local f=ftp.open(host,gett.port,gett.create) + f:greet() + f:login(gett.user,gett.password) + if gett.type then + f:type(gett.type) + end + f:epsv() + f:receive(gett) + f:quit() + return f:close() +end +local function sget(u) + local gett=genericform(u) + local t={} + gett.sink=sinktable(t) + tget(gett) + return concat(t) +end +ftp.command=protectsocket(function(cmdt) + cmdt=override(cmdt) + local command=cmdt.command + local argument=cmdt.argument + local check=cmdt.check + local host=cmdt.host + trysocket(host,"missing hostname") + trysocket(command,"missing command") + local f=ftp.open(host,cmdt.port,cmdt.create) + local try=f.try + local tp=f.tp + f:greet() + f:login(cmdt.user,cmdt.password) + if type(command)=="table" then + local argument=argument or {} + for i=1,#command do + local cmd=command[i] + try(tp:command(cmd,argument[i])) + if check and check[i] then + try(tp:check(check[i])) + end + end + else + try(tp:command(command,argument)) + if check then + try(tp:check(check)) + end + end + f:quit() + return f:close() +end) +ftp.get=protectsocket(function(gett) + if type(gett)=="string" then + return sget(gett) + else + return tget(gett) + end +end) + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +package.loaded["util-soc-imp-smtp"] = package.loaded["util-soc-imp-smtp"] or true + +-- original size: 6975, stripped down to: 6055 + + +local type,setmetatable,next=type,setmetatable,next +local find,lower,format=string.find,string.lower,string.format +local osdate,osgetenv=os.data,os.getenv +local random=math.random +local socket=socket or require("socket") +local headers=socket.headers or require("socket.headers") +local ltn12=ltn12 or require("ltn12") +local tp=socket.tp or require("socket.tp") +local mime=mime or require("mime") +local mimeb64=mime.b64 +local mimestuff=mime.stuff +local skipsocket=socket.skip +local trysocket=socket.try +local newtrysocket=socket.newtry +local protectsocket=socket.protect +local normalizeheaders=headers.normalize +local lowerheaders=headers.lower +local createcoroutine=coroutine.create +local resumecoroutine=coroutine.resume +local yieldcoroutine=coroutine.resume +local smtp={ + TIMEOUT=60, + SERVER="localhost", + PORT=25, + DOMAIN=osgetenv("SERVER_NAME") or "localhost", + ZONE="-0000", +} +socket.smtp=smtp +local methods={} +local mt={ __index=methods } +function methods.greet(self,domain) + local try=self.try + local tp=self.tp + try(tp:check("2..")) + try(tp:command("EHLO",domain or _M.DOMAIN)) + return skipsocket(1,try(tp:check("2.."))) +end +function methods.mail(self,from) + local try=self.try + local tp=self.tp + try(tp:command("MAIL","FROM:"..from)) + return try(tp:check("2..")) +end +function methods.rcpt(self,to) + local try=self.try + local tp=self.tp + try(tp:command("RCPT","TO:"..to)) + return try(tp:check("2..")) +end +function methods.data(self,src,step) + local try=self.try + local tp=self.tp + try(tp:command("DATA")) + try(tp:check("3..")) + try(tp:source(src,step)) + try(tp:send("\r\n.\r\n")) + return try(tp:check("2..")) +end +function methods.quit(self) + local try=self.try + local tp=self.tp + try(tp:command("QUIT")) + return try(tp:check("2..")) +end +function methods.close(self) + return self.tp:close() +end +function methods.login(self,user,password) + local try=self.try + local tp=self.tp + try(tp:command("AUTH","LOGIN")) + try(tp:check("3..")) + try(tp:send(mimeb64(user).."\r\n")) + try(tp:check("3..")) + try(tp:send(mimeb64(password).."\r\n")) + return try(tp:check("2..")) +end +function methods.plain(self,user,password) + local try=self.try + local tp=self.tp + local auth="PLAIN "..mimeb64("\0"..user.."\0"..password) + try(tp:command("AUTH",auth)) + return try(tp:check("2..")) +end +function methods.auth(self,user,password,ext) + if not user or not password then + return 1 + end + local try=self.try + if find(ext,"AUTH[^\n]+LOGIN") then + return self:login(user,password) + elseif find(ext,"AUTH[^\n]+PLAIN") then + return self:plain(user,password) + else + try(nil,"authentication not supported") + end +end +function methods.send(self,mail) + self:mail(mail.from) + local receipt=mail.rcpt + if type(receipt)=="table" then + for i=1,#receipt do + self:rcpt(receipt[i]) + end + elseif receipt then + self:rcpt(receipt) + end + self:data(ltn12.source.chain(mail.source,mimestuff()),mail.step) +end +local function opensmtp(self,server,port,create) + if not server or server=="" then + server=smtp.SERVER + end + if not port or port=="" then + port=smtp.PORT + end + local s={ + tp=trysocket(tp.connect(server,port,smtp.TIMEOUT,create)), + try=newtrysocket(function() + s:close() + end), + } + setmetatable(s,mt) + return s +end +smtp.open=opensmtp +local nofboundaries=0 +local function newboundary() + nofboundaries=nofboundaries+1 + return format('%s%05d==%05u',osdate('%d%m%Y%H%M%S'),random(0,99999),nofboundaries) +end +local send_message +local function send_headers(headers) + yieldcoroutine(normalizeheaders(headers)) +end +local function send_multipart(message) + local boundary=newboundary() + local headers=lowerheaders(message.headers) + local body=message.body + local preamble=body.preamble + local epilogue=body.epilogue + local content=headers['content-type'] or 'multipart/mixed' + headers['content-type']=content..'; boundary="'..boundary..'"' + send_headers(headers) + if preamble then + yieldcoroutine(preamble) + yieldcoroutine("\r\n") + end + for i=1,#body do + yieldcoroutine("\r\n--"..boundary.."\r\n") + send_message(body[i]) + end + yieldcoroutine("\r\n--"..boundary.."--\r\n\r\n") + if epilogue then + yieldcoroutine(epilogue) + yieldcoroutine("\r\n") + end +end +local default_content_type='text/plain; charset="UTF-8"' +local function send_source(message) + local headers=lowerheaders(message.headers) + if not headers['content-type'] then + headers['content-type']=default_content_type + end + send_headers(headers) + local getchunk=message.body + while true do + local chunk,err=getchunk() + if err then + yieldcoroutine(nil,err) + elseif chunk then + yieldcoroutine(chunk) + else + break + end + end +end +local function send_string(message) + local headers=lowerheaders(message.headers) + if not headers['content-type'] then + headers['content-type']=default_content_type + end + send_headers(headers) + yieldcoroutine(message.body) +end +function send_message(message) + local body=message.body + if type(body)=="table" then + send_multipart(message) + elseif type(body)=="function" then + send_source(message) + else + send_string(message) + end +end +local function adjust_headers(message) + local headers=lowerheaders(message.headers) + if not headers["date"] then + headers["date"]=osdate("!%a, %d %b %Y %H:%M:%S ")..(message.zone or smtp.ZONE) + end + if not headers["x-mailer"] then + headers["x-mailer"]=socket._VERSION + end + headers["mime-version"]="1.0" + return headers +end +function smtp.message(message) + message.headers=adjust_headers(message) + local action=createcoroutine(function() + send_message(message) + end) + return function() + local ret,a,b=resumecoroutine(action) + if ret then + return a,b + else + return nil,a + end + end +end +smtp.send=protectsocket(function(mail) + local snd=opensmtp(mail.server,mail.port,mail.create) + local ext=snd:greet(mail.domain) + snd:auth(mail.user,mail.password,ext) + snd:send(mail) + snd:quit() + return snd:close() +end) + + +end -- of closure + +do -- create closure to overcome 200 locals limit + package.loaded["trac-set"] = package.loaded["trac-set"] or true -- original size: 13340, stripped down to: 9459 @@ -21733,10 +24554,10 @@ end end -- of closure --- used libraries : l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua --- skipped libraries : util-soc-imp-reset util-soc-imp-socket util-soc-imp-copas util-soc-imp-ltn12 util-soc-imp-mime util-soc-imp-url util-soc-imp-headers util-soc-imp-tp util-soc-imp-http util-soc-imp-ftp util-soc-imp-smtp --- original bytes : 893485 --- stripped bytes : 323975 +-- used libraries : l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua util-soc-imp-reset.lua util-soc-imp-socket.lua util-soc-imp-copas.lua util-soc-imp-ltn12.lua util-soc-imp-mime.lua util-soc-imp-url.lua util-soc-imp-headers.lua util-soc-imp-tp.lua util-soc-imp-http.lua util-soc-imp-ftp.lua util-soc-imp-smtp.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua +-- skipped libraries : - +-- original bytes : 981014 +-- stripped bytes : 346248 -- end library merge @@ -21788,18 +24609,18 @@ local ownlibs = { -- order can be made better 'util-prs.lua', 'util-fmt.lua', - 'util-soc-imp-reset', - 'util-soc-imp-socket', - 'util-soc-imp-copas', - 'util-soc-imp-ltn12', - -- 'util-soc-imp-mbox', - 'util-soc-imp-mime', - 'util-soc-imp-url', - 'util-soc-imp-headers', - 'util-soc-imp-tp', - 'util-soc-imp-http', - 'util-soc-imp-ftp', - 'util-soc-imp-smtp', + 'util-soc-imp-reset.lua', + 'util-soc-imp-socket.lua', + 'util-soc-imp-copas.lua', + 'util-soc-imp-ltn12.lua', + -- 'util-soc-imp-mbox.lua', + 'util-soc-imp-mime.lua', + 'util-soc-imp-url.lua', + 'util-soc-imp-headers.lua', + 'util-soc-imp-tp.lua', + 'util-soc-imp-http.lua', + 'util-soc-imp-ftp.lua', + 'util-soc-imp-smtp.lua', 'trac-set.lua', 'trac-log.lua', diff --git a/scripts/context/stubs/unix/mtxrun b/scripts/context/stubs/unix/mtxrun index 99c9fd3f2..555e662e3 100644 --- a/scripts/context/stubs/unix/mtxrun +++ b/scripts/context/stubs/unix/mtxrun @@ -9213,6 +9213,2827 @@ end -- of closure do -- create closure to overcome 200 locals limit +package.loaded["util-soc-imp-reset"] = package.loaded["util-soc-imp-reset"] or true + +-- original size: 374, stripped down to: 282 + +local loaded=package.loaded +loaded["socket"]=nil +loaded["copas"]=nil +loaded["ltn12"]=nil +loaded["mbox"]=nil +loaded["mime"]=nil +loaded["socket.url"]=nil +loaded["socket.headers"]=nil +loaded["socket.tp"]=nil +loaded["socket.http"]=nil +loaded["socket.ftp"]=nil +loaded["socket.smtp"]=nil + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +package.loaded["util-soc-imp-socket"] = package.loaded["util-soc-imp-socket"] or true + +-- original size: 4867, stripped down to: 3858 + + +local type,tostring,setmetatable=type,tostring,setmetatable +local min=math.min +local format=string.format +local socket=require("socket.core") +local connect=socket.connect +local tcp4=socket.tcp4 +local tcp6=socket.tcp6 +local getaddrinfo=socket.dns.getaddrinfo +local defaulthost="0.0.0.0" +local function report(fmt,first,...) + if logs then + report=logs and logs.reporter("socket") + report(fmt,first,...) + elseif fmt then + fmt="socket: "..fmt + if first then + print(format(fmt,first,...)) + else + print(fmt) + end + end +end +socket.report=report +function socket.connect4(address,port,laddress,lport) + return connect(address,port,laddress,lport,"inet") +end +function socket.connect6(address,port,laddress,lport) + return connect(address,port,laddress,lport,"inet6") +end +function socket.bind(host,port,backlog) + if host=="*" or host=="" then + host=defaulthost + end + local addrinfo,err=getaddrinfo(host) + if not addrinfo then + return nil,err + end + for i=1,#addrinfo do + local alt=addrinfo[i] + local sock,err=(alt.family=="inet" and tcp4 or tcp6)() + if not sock then + return nil,err or "unknown error" + end + sock:setoption("reuseaddr",true) + local res,err=sock:bind(alt.addr,port) + if res then + res,err=sock:listen(backlog) + if res then + return sock + else + sock:close() + end + else + sock:close() + end + end + return nil,"invalid address" +end +socket.try=socket.newtry() +function socket.choose(list) + return function(name,opt1,opt2) + if type(name)~="string" then + name,opt1,opt2="default",name,opt1 + end + local f=list[name or "nil"] + if f then + return f(opt1,opt2) + else + report("error: unknown key '%s'",tostring(name)) + end + end +end +local sourcet={} +local sinkt={} +socket.sourcet=sourcet +socket.sinkt=sinkt +socket.BLOCKSIZE=2048 +sinkt["close-when-done"]=function(sock) + return setmetatable ( + { + getfd=function() return sock:getfd() end, + dirty=function() return sock:dirty() end, + }, + { + __call=function(self,chunk,err) + if chunk then + return sock:send(chunk) + else + sock:close() + return 1 + end + end + } + ) +end +sinkt["keep-open"]=function(sock) + return setmetatable ( + { + getfd=function() return sock:getfd() end, + dirty=function() return sock:dirty() end, + },{ + __call=function(self,chunk,err) + if chunk then + return sock:send(chunk) + else + return 1 + end + end + } + ) +end +sinkt["default"]=sinkt["keep-open"] +socket.sink=socket.choose(sinkt) +sourcet["by-length"]=function(sock,length) + local blocksize=socket.BLOCKSIZE + return setmetatable ( + { + getfd=function() return sock:getfd() end, + dirty=function() return sock:dirty() end, + }, + { + __call=function() + if length<=0 then + return nil + end + local chunk,err=sock:receive(min(blocksize,length)) + if err then + return nil,err + end + length=length-#chunk + return chunk + end + } + ) +end +sourcet["until-closed"]=function(sock) + local blocksize=socket.BLOCKSIZE + local done=false + return setmetatable ( + { + getfd=function() return sock:getfd() end, + dirty=function() return sock:dirty() end, + },{ + __call=function() + if done then + return nil + end + local chunk,status,partial=sock:receive(blocksize) + if not status then + return chunk + elseif status=="closed" then + sock:close() + done=true + return partial + else + return nil,status + end + end + } + ) +end +sourcet["default"]=sourcet["until-closed"] +socket.source=socket.choose(sourcet) +_G.socket=socket +package.loaded.socket=socket + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +package.loaded["util-soc-imp-copas"] = package.loaded["util-soc-imp-copas"] or true + +-- original size: 25841, stripped down to: 16063 + + +local socket=socket or require("socket") +local ssl=ssl or nil +local WATCH_DOG_TIMEOUT=120 +local UDP_DATAGRAM_MAX=8192 +local type,next,pcall,getmetatable,tostring=type,next,pcall,getmetatable,tostring +local min,max,random=math.min,math.max,math.random +local find=string.find +local insert,remove=table.insert,table.remove +local gettime=socket.gettime +local selectsocket=socket.select +local createcoroutine=coroutine.create +local resumecoroutine=coroutine.resume +local yieldcoroutine=coroutine.yield +local runningcoroutine=coroutine.running +local function report(fmt,first,...) + if logs then + report=logs and logs.reporter("copas") + report(fmt,first,...) + elseif fmt then + fmt="copas: "..fmt + if first then + print(format(fmt,first,...)) + else + print(fmt) + end + end +end +local copas={ + _COPYRIGHT="Copyright (C) 2005-2016 Kepler Project", + _DESCRIPTION="Coroutine Oriented Portable Asynchronous Services", + _VERSION="Copas 2.0.1", + autoclose=true, + running=false, + report=report, +} +local function statushandler(status,...) + if status then + return... + end + local err=(...) + if type(err)=="table" then + err=err[1] + end + report("error: %s",tostring(err)) + return nil,err +end +function socket.protect(func) + return function(...) + return statushandler(pcall(func,...)) + end +end +function socket.newtry(finalizer) + return function (...) + local status=(...) + if not status then + local detail=select(2,...) + pcall(finalizer,detail) + report("error: %s",tostring(detail)) + return + end + return... + end +end +local function newset() + local reverse={} + local set={} + local queue={} + setmetatable(set,{ + __index={ + insert=function(set,value) + if not reverse[value] then + local n=#set+1 + set[n]=value + reverse[value]=n + end + end, + remove=function(set,value) + local index=reverse[value] + if index then + reverse[value]=nil + local n=#set + local top=set[n] + set[n]=nil + if top~=value then + reverse[top]=index + set[index]=top + end + end + end, + push=function (set,key,itm) + local entry=queue[key] + if entry==nil then + queue[key]={ itm } + else + entry[#entry+1]=itm + end + end, + pop=function (set,key) + local top=queue[key] + if top~=nil then + local ret=remove(top,1) + if top[1]==nil then + queue[key]=nil + end + return ret + end + end + } + } ) + return set +end +local _sleeping={ + times={}, + cos={}, + lethargy={}, + insert=function() + end, + remove=function() + end, + push=function(self,sleeptime,co) + if not co then + return + end + if sleeptime<0 then + self.lethargy[co]=true + return + else + sleeptime=gettime()+sleeptime + end + local t=self.times + local c=self.cos + local i=1 + local n=#t + while i<=n and t[i]<=sleeptime do + i=i+1 + end + insert(t,i,sleeptime) + insert(c,i,co) + end, + getnext= + function(self) + local t=self.times + local delay=t[1] and t[1]-gettime() or nil + return delay and max(delay,0) or nil + end, + pop= + function(self,time) + local t=self.times + local c=self.cos + if #t==0 or time<t[1] then + return + end + local co=c[1] + remove(t,1) + remove(c,1) + return co + end, + wakeup=function(self,co) + local let=self.lethargy + if let[co] then + self:push(0,co) + let[co]=nil + else + local c=self.cos + local t=self.times + for i=1,#c do + if c[i]==co then + remove(c,i) + remove(t,i) + self:push(0,co) + return + end + end + end + end +} +local _servers=newset() +local _reading=newset() +local _writing=newset() +local _reading_log={} +local _writing_log={} +local _is_timeout={ + timeout=true, + wantread=true, + wantwrite=true, +} +local function isTCP(socket) + return not find(tostring(socket),"^udp") +end +local function copasreceive(client,pattern,part) + if not pattern or pattern=="" then + pattern="*l" + end + local current_log=_reading_log + local s,err + repeat + s,err,part=client:receive(pattern,part) + if s or (not _is_timeout[err]) then + current_log[client]=nil + return s,err,part + end + if err=="wantwrite" then + current_log=_writing_log + current_log[client]=gettime() + yieldcoroutine(client,_writing) + else + current_log=_reading_log + current_log[client]=gettime() + yieldcoroutine(client,_reading) + end + until false +end +local function copasreceivefrom(client,size) + local s,err,port + if not size or size==0 then + size=UDP_DATAGRAM_MAX + end + repeat + s,err,port=client:receivefrom(size) + if s or err~="timeout" then + _reading_log[client]=nil + return s,err,port + end + _reading_log[client]=gettime() + yieldcoroutine(client,_reading) + until false +end +local function copasreceivepartial(client,pattern,part) + if not pattern or pattern=="" then + pattern="*l" + end + local logger=_reading_log + local queue=_reading + local s,err + repeat + s,err,part=client:receive(pattern,part) + if s or (type(pattern)=="number" and part~="" and part) or not _is_timeout[err] then + logger[client]=nil + return s,err,part + end + if err=="wantwrite" then + logger=_writing_log + queue=_writing + else + logger=_reading_log + queue=_reading + end + logger[client]=gettime() + yieldcoroutine(client,queue) + until false +end +local function copassend(client,data,from,to) + if not from then + from=1 + end + local lastIndex=from-1 + local logger=_writing_log + local queue=_writing + local s,err + repeat + s,err,lastIndex=client:send(data,lastIndex+1,to) + if random(100)>90 then + logger[client]=gettime() + yieldcoroutine(client,queue) + end + if s or not _is_timeout[err] then + logger[client]=nil + return s,err,lastIndex + end + if err=="wantread" then + logger=_reading_log + queue=_reading + else + logger=_writing_log + queue=_writing + end + logger[client]=gettime() + yieldcoroutine(client,queue) + until false +end +local function copassendto(client,data,ip,port) + repeat + local s,err=client:sendto(data,ip,port) + if random(100)>90 then + _writing_log[client]=gettime() + yieldcoroutine(client,_writing) + end + if s or err~="timeout" then + _writing_log[client]=nil + return s,err + end + _writing_log[client]=gettime() + yieldcoroutine(client,_writing) + until false +end +local function copasconnect(skt,host,port) + skt:settimeout(0) + local ret,err,tried_more_than_once + repeat + ret,err=skt:connect (host,port) + if ret or (err~="timeout" and err~="Operation already in progress") then + if not ret and err=="already connected" and tried_more_than_once then + ret=1 + err=nil + end + _writing_log[skt]=nil + return ret,err + end + tried_more_than_once=tried_more_than_once or true + _writing_log[skt]=gettime() + yieldcoroutine(skt,_writing) + until false +end +local function copasdohandshake(skt,sslt) + if not ssl then + ssl=require("ssl") + end + if not ssl then + report("error: no ssl library") + return + end + local nskt,err=ssl.wrap(skt,sslt) + if not nskt then + report("error: %s",tostring(err)) + return + end + nskt:settimeout(0) + local queue + repeat + local success,err=nskt:dohandshake() + if success then + return nskt + elseif err=="wantwrite" then + queue=_writing + elseif err=="wantread" then + queue=_reading + else + report("error: %s",tostring(err)) + return + end + yieldcoroutine(nskt,queue) + until false +end +local function copasflush(client) +end +copas.connect=copassconnect +copas.send=copassend +copas.sendto=copassendto +copas.receive=copasreceive +copas.receivefrom=copasreceivefrom +copas.copasreceivepartial=copasreceivepartial +copas.copasreceivePartial=copasreceivepartial +copas.dohandshake=copasdohandshake +copas.flush=copasflush +local function _skt_mt_tostring(self) + return tostring(self.socket).." (copas wrapped)" +end +local _skt_mt_tcp_index={ + send=function(self,data,from,to) + return copassend (self.socket,data,from,to) + end, + receive=function (self,pattern,prefix) + if self.timeout==0 then + return copasreceivePartial(self.socket,pattern,prefix) + else + return copasreceive(self.socket,pattern,prefix) + end + end, + flush=function (self) + return copasflush(self.socket) + end, + settimeout=function (self,time) + self.timeout=time + return true + end, + connect=function(self,...) + local res,err=copasconnect(self.socket,...) + if res and self.ssl_params then + res,err=self:dohandshake() + end + return res,err + end, + close=function(self,...) + return self.socket:close(...) + end, + bind=function(self,...) + return self.socket:bind(...) + end, + getsockname=function(self,...) + return self.socket:getsockname(...) + end, + getstats=function(self,...) + return self.socket:getstats(...) + end, + setstats=function(self,...) + return self.socket:setstats(...) + end, + listen=function(self,...) + return self.socket:listen(...) + end, + accept=function(self,...) + return self.socket:accept(...) + end, + setoption=function(self,...) + return self.socket:setoption(...) + end, + getpeername=function(self,...) + return self.socket:getpeername(...) + end, + shutdown=function(self,...) + return self.socket:shutdown(...) + end, + dohandshake=function(self,sslt) + self.ssl_params=sslt or self.ssl_params + local nskt,err=copasdohandshake(self.socket,self.ssl_params) + if not nskt then + return nskt,err + end + self.socket=nskt + return self + end, +} +local _skt_mt_tcp={ + __tostring=_skt_mt_tostring, + __index=_skt_mt_tcp_index, +} +local _skt_mt_udp_index={ + sendto=function (self,...) + return copassendto(self.socket,...) + end, + receive=function (self,size) + return copasreceive(self.socket,size or UDP_DATAGRAM_MAX) + end, + receivefrom=function (self,size) + return copasreceivefrom(self.socket,size or UDP_DATAGRAM_MAX) + end, + setpeername=function(self,...) + return self.socket:getpeername(...) + end, + setsockname=function(self,...) + return self.socket:setsockname(...) + end, + close=function(self,...) + return true + end +} +local _skt_mt_udp={ + __tostring=_skt_mt_tostring, + __index=_skt_mt_udp_index, +} +for k,v in next,_skt_mt_tcp_index do + if not _skt_mt_udp_index[k] then + _skt_mt_udp_index[k]=v + end +end +local function wrap(skt,sslt) + if getmetatable(skt)==_skt_mt_tcp or getmetatable(skt)==_skt_mt_udp then + return skt + end + skt:settimeout(0) + if isTCP(skt) then + return setmetatable ({ socket=skt,ssl_params=sslt },_skt_mt_tcp) + else + return setmetatable ({ socket=skt },_skt_mt_udp) + end +end +copas.wrap=wrap +function copas.handler(handler,sslparams) + return function (skt,...) + skt=wrap(skt) + if sslparams then + skt:dohandshake(sslparams) + end + return handler(skt,...) + end +end +local _errhandlers={} +function copas.setErrorHandler(err) + local co=runningcoroutine() + if co then + _errhandlers[co]=err + end +end +local function _deferror (msg,co,skt) + report("%s (%s) (%s)",msg,tostring(co),tostring(skt)) +end +local function _doTick (co,skt,...) + if not co then + return + end + local ok,res,new_q=resumecoroutine(co,skt,...) + if ok and res and new_q then + new_q:insert(res) + new_q:push(res,co) + else + if not ok then + pcall(_errhandlers[co] or _deferror,res,co,skt) + end + if skt and copas.autoclose and isTCP(skt) then + skt:close() + end + _errhandlers[co]=nil + end +end +local function _accept(input,handler) + local client=input:accept() + if client then + client:settimeout(0) + local co=createcoroutine(handler) + _doTick (co,client) + end + return client +end +local function _tickRead(skt) + _doTick(_reading:pop(skt),skt) +end +local function _tickWrite(skt) + _doTick(_writing:pop(skt),skt) +end +local function addTCPserver(server,handler,timeout) + server:settimeout(timeout or 0) + _servers[server]=handler + _reading:insert(server) +end +local function addUDPserver(server,handler,timeout) + server:settimeout(timeout or 0) + local co=createcoroutine(handler) + _reading:insert(server) + _doTick(co,server) +end +function copas.addserver(server,handler,timeout) + if isTCP(server) then + addTCPserver(server,handler,timeout) + else + addUDPserver(server,handler,timeout) + end +end +function copas.removeserver(server,keep_open) + local s=server + local mt=getmetatable(server) + if mt==_skt_mt_tcp or mt==_skt_mt_udp then + s=server.socket + end + _servers[s]=nil + _reading:remove(s) + if keep_open then + return true + end + return server:close() +end +function copas.addthread(handler,...) + local thread=createcoroutine(function(_,...) return handler(...) end) + _doTick(thread,nil,...) + return thread +end +local _tasks={} +local function addtaskRead(task) + task.def_tick=_tickRead + _tasks[task]=true +end +local function addtaskWrite(task) + task.def_tick=_tickWrite + _tasks[task]=true +end +local function tasks() + return next,_tasks +end +local _readable_t={ + events=function(self) + local i=0 + return function () + i=i+1 + return self._evs[i] + end + end, + tick=function(self,input) + local handler=_servers[input] + if handler then + input=_accept(input,handler) + else + _reading:remove(input) + self.def_tick(input) + end + end +} +addtaskRead(_readable_t) +local _writable_t={ + events=function(self) + local i=0 + return function() + i=i+1 + return self._evs[i] + end + end, + tick=function(self,output) + _writing:remove(output) + self.def_tick(output) + end +} +addtaskWrite(_writable_t) +local _sleeping_t={ + tick=function(self,time,...) + _doTick(_sleeping:pop(time),...) + end +} +function copas.sleep(sleeptime) + yieldcoroutine((sleeptime or 0),_sleeping) +end +function copas.wakeup(co) + _sleeping:wakeup(co) +end +local last_cleansing=0 +local function _select(timeout) + local now=gettime() + local r_evs,w_evs,err=selectsocket(_reading,_writing,timeout) + _readable_t._evs=r_evs + _writable_t._evs=w_evs + if (last_cleansing-now)>WATCH_DOG_TIMEOUT then + last_cleansing=now + for skt,time in next,_reading_log do + if not r_evs[skt] and (time-now)>WATCH_DOG_TIMEOUT then + local n=#r_evs+1 + _reading_log[skt]=nil + r_evs[n]=skt + r_evs[skt]=n + end + end + for skt,time in next,_writing_log do + if not w_evs[skt] and (time-now)>WATCH_DOG_TIMEOUT then + local n=#w_evs+1 + _writing_log[skt]=nil + w_evs[n]=skt + w_evs[skt]=n + end + end + end + if err=="timeout" and #r_evs+#w_evs>0 then + return nil + else + return err + end +end +local function copasfinished() + return not (next(_reading) or next(_writing) or _sleeping:getnext()) +end +local function copasstep(timeout) + _sleeping_t:tick(gettime()) + local nextwait=_sleeping:getnext() + if nextwait then + timeout=timeout and min(nextwait,timeout) or nextwait + elseif copasfinished() then + return false + end + local err=_select(timeout) + if err then + if err=="timeout" then + return false + end + return nil,err + end + for task in tasks() do + for event in task:events() do + task:tick(event) + end + end + return true +end +copas.finished=copasfinished +copas.step=copasstep +function copas.loop(timeout) + copas.running=true + while not copasfinished() do + copasstep(timeout) + end + copas.running=false +end +package.loaded.copas=copas + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +package.loaded["util-soc-imp-ltn12"] = package.loaded["util-soc-imp-ltn12"] or true + +-- original size: 8706, stripped down to: 6102 + + +local select,unpack=select,unpack +local insert,remove=table.insert,table.remove +local sub=string.sub +local function report(fmt,first,...) + if logs then + report=logs and logs.reporter("ltn12") + report(fmt,first,...) + elseif fmt then + fmt="ltn12: "..fmt + if first then + print(format(fmt,first,...)) + else + print(fmt) + end + end +end +local filter={} +local source={} +local sink={} +local pump={} +local ltn12={ + _VERSION="LTN12 1.0.3", + BLOCKSIZE=2048, + filter=filter, + source=source, + sink=sink, + pump=pump, + report=report, +} +function filter.cycle(low,ctx,extra) + if low then + return function(chunk) + return (low(ctx,chunk,extra)) + end + end +end +function filter.chain(...) + local arg={... } + local n=select('#',...) + local top=1 + local index=1 + local retry="" + return function(chunk) + retry=chunk and retry + while true do + local action=arg[index] + if index==top then + chunk=action(chunk) + if chunk=="" or top==n then + return chunk + elseif chunk then + index=index+1 + else + top=top+1 + index=top + end + else + chunk=action(chunk or "") + if chunk=="" then + index=index-1 + chunk=retry + elseif chunk then + if index==n then + return chunk + else + index=index+1 + end + else + report("error: filter returned inappropriate 'nil'") + return + end + end + end + end +end +local function empty() + return nil +end +function source.empty() + return empty +end +local function sourceerror(err) + return function() + return nil,err + end +end +source.error=sourceerror +function source.file(handle,io_err) + if handle then + local blocksize=ltn12.BLOCKSIZE + return function() + local chunk=handle:read(blocksize) + if not chunk then + handle:close() + end + return chunk + end + else + return sourceerror(io_err or "unable to open file") + end +end +function source.simplify(src) + return function() + local chunk,err_or_new=src() + if err_or_new then + src=err_or_new + end + if chunk then + return chunk + else + return nil,err_or_new + end + end +end +function source.string(s) + if s then + local blocksize=ltn12.BLOCKSIZE + local i=1 + return function() + local nexti=i+blocksize + local chunk=sub(s,i,nexti-1) + i=nexti + if chunk~="" then + return chunk + else + return nil + end + end + else return source.empty() end +end +function source.rewind(src) + local t={} + return function(chunk) + if chunk then + insert(t,chunk) + else + chunk=remove(t) + if chunk then + return chunk + else + return src() + end + end + end +end +function source.chain(src,f,...) + if... then + f=filter.chain(f,...) + end + local last_in="" + local last_out="" + local state="feeding" + local err + return function() + if not last_out then + report("error: source is empty") + return + end + while true do + if state=="feeding" then + last_in,err=src() + if err then + return nil,err + end + last_out=f(last_in) + if not last_out then + if last_in then + report("error: filter returned inappropriate 'nil'") + end + return nil + elseif last_out~="" then + state="eating" + if last_in then + last_in="" + end + return last_out + end + else + last_out=f(last_in) + if last_out=="" then + if last_in=="" then + state="feeding" + else + report("error: filter returned nothing") + return + end + elseif not last_out then + if last_in then + report("filter returned inappropriate 'nil'") + end + return nil + else + return last_out + end + end + end + end +end +function source.cat(...) + local arg={... } + local src=remove(arg,1) + return function() + while src do + local chunk,err=src() + if chunk then + return chunk + end + if err then + return nil,err + end + src=remove(arg,1) + end + end +end +function sink.table(t) + if not t then + t={} + end + local f=function(chunk,err) + if chunk then + insert(t,chunk) + end + return 1 + end + return f,t +end +function sink.simplify(snk) + return function(chunk,err) + local ret,err_or_new=snk(chunk,err) + if not ret then + return nil,err_or_new + end + if err_or_new then + snk=err_or_new + end + return 1 + end +end +local function null() + return 1 +end +function sink.null() + return null +end +local function sinkerror(err) + return function() + return nil,err + end +end +sink.error=sinkerror +function sink.file(handle,io_err) + if handle then + return function(chunk,err) + if not chunk then + handle:close() + return 1 + else + return handle:write(chunk) + end + end + else + return sinkerror(io_err or "unable to open file") + end +end +function sink.chain(f,snk,...) + if... then + local args={ f,snk,... } + snk=remove(args,#args) + f=filter.chain(unpack(args)) + end + return function(chunk,err) + if chunk~="" then + local filtered=f(chunk) + local done=chunk and "" + while true do + local ret,snkerr=snk(filtered,err) + if not ret then + return nil,snkerr + end + if filtered==done then + return 1 + end + filtered=f(done) + end + else + return 1 + end + end +end +function pump.step(src,snk) + local chunk,src_err=src() + local ret,snk_err=snk(chunk,src_err) + if chunk and ret then + return 1 + else + return nil,src_err or snk_err + end +end +function pump.all(src,snk,step) + if not step then + step=pump.step + end + while true do + local ret,err=step(src,snk) + if not ret then + if err then + return nil,err + else + return 1 + end + end + end +end +package.loaded.ltn12=ltn12 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +package.loaded["util-soc-imp-mime"] = package.loaded["util-soc-imp-mime"] or true + +-- original size: 2325, stripped down to: 1927 + + +local type,tostring=type,tostring +local mime=require("mime.core") +local ltn12=ltn12 or require("ltn12") +local filtercycle=ltn12.filter.cycle +local function report(fmt,first,...) + if logs then + report=logs and logs.reporter("mime") + report(fmt,first,...) + elseif fmt then + fmt="mime: "..fmt + if first then + print(format(fmt,first,...)) + else + print(fmt) + end + end +end +mime.report=report +local encodet={} +local decodet={} +local wrapt={} +mime.encodet=encodet +mime.decodet=decodet +mime.wrapt=wrapt +local mime_b64=mime.b64 +local mime_qp=mime.qp +local mime_unb64=mime.unb64 +local mime_unqp=mime.unqp +local mime_wrp=mime.wrp +local mime_qpwrp=mime.qpwrp +local mime_eol=mime_eol +local mime_dot=mime_dot +encodet['base64']=function() + return filtercycle(mime_b64,"") +end +encodet['quoted-printable']=function(mode) + return filtercycle(mime_qp,"",mode=="binary" and "=0D=0A" or "\r\n") +end +decodet['base64']=function() + return filtercycle(mime_unb64,"") +end +decodet['quoted-printable']=function() + return filtercycle(mime_unqp,"") +end +local wraptext=function(length) + if not length then + length=76 + end + return filtercycle(mime_wrp,length,length) +end +local wrapquoted=function() + return filtercycle(mime_qpwrp,76,76) +end +wrapt['text']=wraptext +wrapt['base64']=wraptext +wrapt['default']=wraptext +wrapt['quoted-printable']=wrapquoted +function mime.normalize(marker) + return filtercycle(mime_eol,0,marker) +end +function mime.stuff() + return filtercycle(mime_dot,2) +end +local function choose(list) + return function(name,opt1,opt2) + if type(name)~="string" then + name,opt1,opt2="default",name,opt1 + end + local filter=list[name or "nil"] + if filter then + return filter(opt1,opt2) + else + report("error: unknown key '%s'",tostring(name)) + end + end +end +mime.encode=choose(encodet) +mime.decode=choose(decodet) +mime.wrap=choose(wrapt) +package.loaded.mime=mime + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +package.loaded["util-soc-imp-url"] = package.loaded["util-soc-imp-url"] or true + +-- original size: 6827, stripped down to: 5624 + + +local tonumber,tostring,type=tonumber,tostring,type +local gsub,sub,match,find,format,byte,char=string.gsub,string.sub,string.match,string.find,string.format,string.byte,string.char +local insert=table.insert +local socket=socket or require("socket") +local url={ + _VERSION="URL 1.0.3", +} +socket.url=url +function url.escape(s) + return (gsub(s,"([^A-Za-z0-9_])",function(c) + return format("%%%02x",byte(c)) + end)) +end +local function make_set(t) + local s={} + for i=1,#t do + s[t[i]]=true + end + return s +end +local segment_set=make_set { + "-","_",".","!","~","*","'","(", + ")",":","@","&","=","+","$",",", +} +local function protect_segment(s) + return gsub(s,"([^A-Za-z0-9_])",function(c) + if segment_set[c] then + return c + else + return format("%%%02X",byte(c)) + end + end) +end +function url.unescape(s) + return (gsub(s,"%%(%x%x)",function(hex) + return char(tonumber(hex,16)) + end)) +end +local function absolute_path(base_path,relative_path) + if find(relative_path,"^/") then + return relative_path + end + local path=gsub(base_path,"[^/]*$","") + path=path..relative_path + path=gsub(path,"([^/]*%./)",function (s) + if s~="./" then + return s + else + return "" + end + end) + path=gsub(path,"/%.$","/") + local reduced + while reduced~=path do + reduced=path + path=gsub(reduced,"([^/]*/%.%./)",function (s) + if s~="../../" then + return "" + else + return s + end + end) + end + path=gsub(reduced,"([^/]*/%.%.)$",function (s) + if s~="../.." then + return "" + else + return s + end + end) + return path +end +function url.parse(url,default) + local parsed={} + for k,v in next,default or parsed do + parsed[k]=v + end + if not url or url=="" then + return nil,"invalid url" + end + url=gsub(url,"#(.*)$",function(f) + parsed.fragment=f + return "" + end) + url=gsub(url,"^([%w][%w%+%-%.]*)%:",function(s) + parsed.scheme=s + return "" + end) + url=gsub(url,"^//([^/]*)",function(n) + parsed.authority=n + return "" + end) + url=gsub(url,"%?(.*)",function(q) + parsed.query=q + return "" + end) + url=gsub(url,"%;(.*)",function(p) + parsed.params=p + return "" + end) + if url~="" then + parsed.path=url + end + local authority=parsed.authority + if not authority then + return parsed + end + authority=gsub(authority,"^([^@]*)@",function(u) + parsed.userinfo=u + return "" + end) + authority=gsub(authority,":([^:%]]*)$",function(p) + parsed.port=p + return "" + end) + if authority~="" then + parsed.host=match(authority,"^%[(.+)%]$") or authority + end + local userinfo=parsed.userinfo + if not userinfo then + return parsed + end + userinfo=gsub(userinfo,":([^:]*)$",function(p) + parsed.password=p + return "" + end) + parsed.user=userinfo + return parsed +end +function url.build(parsed) + local url=parsed.path or "" + if parsed.params then + url=url..";"..parsed.params + end + if parsed.query then + url=url.."?"..parsed.query + end + local authority=parsed.authority + if parsed.host then + authority=parsed.host + if find(authority,":") then + authority="["..authority.."]" + end + if parsed.port then + authority=authority..":"..tostring(parsed.port) + end + local userinfo=parsed.userinfo + if parsed.user then + userinfo=parsed.user + if parsed.password then + userinfo=userinfo..":"..parsed.password + end + end + if userinfo then authority=userinfo.."@"..authority end + end + if authority then + url="//"..authority..url + end + if parsed.scheme then + url=parsed.scheme..":"..url + end + if parsed.fragment then + url=url.."#"..parsed.fragment + end + return url +end +function url.absolute(base_url,relative_url) + local base_parsed + if type(base_url)=="table" then + base_parsed=base_url + base_url=url.build(base_parsed) + else + base_parsed=url.parse(base_url) + end + local relative_parsed=url.parse(relative_url) + if not base_parsed then + return relative_url + elseif not relative_parsed then + return base_url + elseif relative_parsed.scheme then + return relative_url + else + relative_parsed.scheme=base_parsed.scheme + if not relative_parsed.authority then + relative_parsed.authority=base_parsed.authority + if not relative_parsed.path then + relative_parsed.path=base_parsed.path + if not relative_parsed.params then + relative_parsed.params=base_parsed.params + if not relative_parsed.query then + relative_parsed.query=base_parsed.query + end + end + else + relative_parsed.path=absolute_path(base_parsed.path or "",relative_parsed.path) + end + end + return url.build(relative_parsed) + end +end +function url.parse_path(path) + local parsed={} + path=path or "" + gsub(path,"([^/]+)",function (s) + insert(parsed,s) + end) + for i=1,#parsed do + parsed[i]=url.unescape(parsed[i]) + end + if sub(path,1,1)=="/" then + parsed.is_absolute=1 + end + if sub(path,-1,-1)=="/" then + parsed.is_directory=1 + end + return parsed +end +function url.build_path(parsed,unsafe) + local path="" + local n=#parsed + if unsafe then + for i=1,n-1 do + path=path..parsed[i].."/" + end + if n>0 then + path=path..parsed[n] + if parsed.is_directory then + path=path.."/" + end + end + else + for i=1,n-1 do + path=path..protect_segment(parsed[i]).."/" + end + if n>0 then + path=path..protect_segment(parsed[n]) + if parsed.is_directory then + path=path.."/" + end + end + end + if parsed.is_absolute then + path="/"..path + end + return path +end + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +package.loaded["util-soc-imp-headers"] = package.loaded["util-soc-imp-headers"] or true + +-- original size: 5712, stripped down to: 3865 + + +local next=next +local lower=string.lower +local concat=table.concat +local socket=socket or require("socket") +local canonic={ + ["accept"]="Accept", + ["accept-charset"]="Accept-Charset", + ["accept-encoding"]="Accept-Encoding", + ["accept-language"]="Accept-Language", + ["accept-ranges"]="Accept-Ranges", + ["action"]="Action", + ["alternate-recipient"]="Alternate-Recipient", + ["age"]="Age", + ["allow"]="Allow", + ["arrival-date"]="Arrival-Date", + ["authorization"]="Authorization", + ["bcc"]="Bcc", + ["cache-control"]="Cache-Control", + ["cc"]="Cc", + ["comments"]="Comments", + ["connection"]="Connection", + ["content-description"]="Content-Description", + ["content-disposition"]="Content-Disposition", + ["content-encoding"]="Content-Encoding", + ["content-id"]="Content-ID", + ["content-language"]="Content-Language", + ["content-length"]="Content-Length", + ["content-location"]="Content-Location", + ["content-md5"]="Content-MD5", + ["content-range"]="Content-Range", + ["content-transfer-encoding"]="Content-Transfer-Encoding", + ["content-type"]="Content-Type", + ["cookie"]="Cookie", + ["date"]="Date", + ["diagnostic-code"]="Diagnostic-Code", + ["dsn-gateway"]="DSN-Gateway", + ["etag"]="ETag", + ["expect"]="Expect", + ["expires"]="Expires", + ["final-log-id"]="Final-Log-ID", + ["final-recipient"]="Final-Recipient", + ["from"]="From", + ["host"]="Host", + ["if-match"]="If-Match", + ["if-modified-since"]="If-Modified-Since", + ["if-none-match"]="If-None-Match", + ["if-range"]="If-Range", + ["if-unmodified-since"]="If-Unmodified-Since", + ["in-reply-to"]="In-Reply-To", + ["keywords"]="Keywords", + ["last-attempt-date"]="Last-Attempt-Date", + ["last-modified"]="Last-Modified", + ["location"]="Location", + ["max-forwards"]="Max-Forwards", + ["message-id"]="Message-ID", + ["mime-version"]="MIME-Version", + ["original-envelope-id"]="Original-Envelope-ID", + ["original-recipient"]="Original-Recipient", + ["pragma"]="Pragma", + ["proxy-authenticate"]="Proxy-Authenticate", + ["proxy-authorization"]="Proxy-Authorization", + ["range"]="Range", + ["received"]="Received", + ["received-from-mta"]="Received-From-MTA", + ["references"]="References", + ["referer"]="Referer", + ["remote-mta"]="Remote-MTA", + ["reply-to"]="Reply-To", + ["reporting-mta"]="Reporting-MTA", + ["resent-bcc"]="Resent-Bcc", + ["resent-cc"]="Resent-Cc", + ["resent-date"]="Resent-Date", + ["resent-from"]="Resent-From", + ["resent-message-id"]="Resent-Message-ID", + ["resent-reply-to"]="Resent-Reply-To", + ["resent-sender"]="Resent-Sender", + ["resent-to"]="Resent-To", + ["retry-after"]="Retry-After", + ["return-path"]="Return-Path", + ["sender"]="Sender", + ["server"]="Server", + ["smtp-remote-recipient"]="SMTP-Remote-Recipient", + ["status"]="Status", + ["subject"]="Subject", + ["te"]="TE", + ["to"]="To", + ["trailer"]="Trailer", + ["transfer-encoding"]="Transfer-Encoding", + ["upgrade"]="Upgrade", + ["user-agent"]="User-Agent", + ["vary"]="Vary", + ["via"]="Via", + ["warning"]="Warning", + ["will-retry-until"]="Will-Retry-Until", + ["www-authenticate"]="WWW-Authenticate", + ["x-mailer"]="X-Mailer", +} +setmetatable(canonic,{ + __index=function(t,k) + socket.report("invalid header: %s",k) + t[k]=k + return k + end +}) +local function normalizeheaders(headers) + if not headers then + return {} + end + local normalized={} + for k,v in next,headers do + normalized[#normalized+1]=canonic[k]..": "..v + end + normalized[#normalized+1]="" + normalized[#normalized+1]="" + return concat(normalized,"\r\n") +end +local function lowerheaders(lowered,headers) + if not lowered then + return {} + end + if not headers then + lowered,headers={},lowered + end + for k,v in next,headers do + lowered[lower(k)]=v + end + return lowered +end +socket.headers={ + canonic=canonic, + normalize=normalizeheaders, + lower=lowerheaders, +} + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +package.loaded["util-soc-imp-tp"] = package.loaded["util-soc-imp-tp"] or true + +-- original size: 3082, stripped down to: 2612 + + +local setmetatable,next,type,tonumber=setmetatable,next,type,tonumber +local find,upper=string.find,string,upper +local socket=socket or require("socket") +local ltn12=ltn12 or require("ltn12") +local skipsocket=socket.skip +local sinksocket=socket.sink +local tcpsocket=socket.tcp +local ltn12pump=ltn12.pump +local pumpall=ltn12pump.all +local pumpstep=ltn12pump.step +local tp={ + TIMEOUT=60, +} +socket.tp=tp +local function get_reply(c) + local line,err=c:receive() + local reply=line + if err then return + nil,err + end + local code,sep=skipsocket(2,find(line,"^(%d%d%d)(.?)")) + if not code then + return nil,"invalid server reply" + end + if sep=="-" then + local current + repeat + line,err=c:receive() + if err then + return nil,err + end + current,sep=skipsocket(2,find(line,"^(%d%d%d)(.?)")) + reply=reply.."\n"..line + until code==current and sep==" " + end + return code,reply +end +local methods={} +local mt={ __index=methods } +function methods.getpeername(self) + return self.c:getpeername() +end +function methods.getsockname(self) + return self.c:getpeername() +end +function methods.check(self,ok) + local code,reply=get_reply(self.c) + if not code then + return nil,reply + end + local c=tonumber(code) + local t=type(ok) + if t=="function" then + return ok(c,reply) + elseif t=="table" then + for i=1,#ok do + if find(code,ok[i]) then + return c,reply + end + end + return nil,reply + elseif find(code,ok) then + return c,reply + else + return nil,reply + end +end +function methods.command(self,cmd,arg) + cmd=upper(cmd) + if arg then + cmd=cmd.." "..arg.."\r\n" + else + cmd=cmd.."\r\n" + end + return self.c:send(cmd) +end +function methods.sink(self,snk,pat) + local chunk,err=self.c:receive(pat) + return snk(chunk,err) +end +function methods.send(self,data) + return self.c:send(data) +end +function methods.receive(self,pat) + return self.c:receive(pat) +end +function methods.getfd(self) + return self.c:getfd() +end +function methods.dirty(self) + return self.c:dirty() +end +function methods.getcontrol(self) + return self.c +end +function methods.source(self,source,step) + local sink=sinksocket("keep-open",self.c) + local ret,err=pumpall(source,sink,step or pumpstep) + return ret,err +end +function methods.close(self) + self.c:close() + return 1 +end +function tp.connect(host,port,timeout,create) + local c,e=(create or tcpsocket)() + if not c then + return nil,e + end + c:settimeout(timeout or tp.TIMEOUT) + local r,e=c:connect(host,port) + if not r then + c:close() + return nil,e + end + return setmetatable({ c=c },mt) +end + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +package.loaded["util-soc-imp-http"] = package.loaded["util-soc-imp-http"] or true + +-- original size: 12499, stripped down to: 10001 + + +local tostring,tonumber,setmetatable,next,type=tostring,tonumber,setmetatable,next,type +local find,lower,format,gsub,match=string.find,string.lower,string.format,string.gsub,string.match +local concat=table.concat +local socket=socket or require("socket") +local url=socket.url or require("socket.url") +local ltn12=ltn12 or require("ltn12") +local mime=mime or require("mime") +local headers=socket.headers or require("socket.headers") +local normalizeheaders=headers.normalize +local parseurl=url.parse +local buildurl=url.build +local absoluteurl=url.absolute +local unescapeurl=url.unescape +local skipsocket=socket.skip +local sinksocket=socket.sink +local sourcesocket=socket.source +local trysocket=socket.try +local tcpsocket=socket.tcp +local newtrysocket=socket.newtry +local protectsocket=socket.protect +local emptysource=ltn12.source.empty +local stringsource=ltn12.source.string +local rewindsource=ltn12.source.rewind +local pumpstep=ltn12.pump.step +local pumpall=ltn12.pump.all +local sinknull=ltn12.sink.null +local sinktable=ltn12.sink.table +local mimeb64=mime.b64 +local http={ + TIMEOUT=60, + USERAGENT=socket._VERSION, +} +socket.http=http +local PORT=80 +local SCHEMES={ + http=true, +} +local function receiveheaders(sock,headers) + if not headers then + headers={} + end + local line,err=sock:receive() + if err then + return nil,err + end + while line~="" do + local name,value=skipsocket(2,find(line,"^(.-):%s*(.*)")) + if not (name and value) then + return nil,"malformed reponse headers" + end + name=lower(name) + line,err=sock:receive() + if err then + return nil,err + end + while find(line,"^%s") do + value=value..line + line=sock:receive() + if err then + return nil,err + end + end + local found=headers[name] + if found then + value=found..", "..value + end + headers[name]=value + end + return headers +end +socket.sourcet["http-chunked"]=function(sock,headers) + return setmetatable ( + { + getfd=function() return sock:getfd() end, + dirty=function() return sock:dirty() end, + },{ + __call=function() + local line,err=sock:receive() + if err then + return nil,err + end + local size=tonumber(gsub(line,";.*",""),16) + if not size then + return nil,"invalid chunk size" + end + if size>0 then + local chunk,err,part=sock:receive(size) + if chunk then + sock:receive() + end + return chunk,err + else + headers,err=receiveheaders(sock,headers) + if not headers then + return nil,err + end + end + end + } + ) +end +socket.sinkt["http-chunked"]=function(sock) + return setmetatable( + { + getfd=function() return sock:getfd() end, + dirty=function() return sock:dirty() end, + }, + { + __call=function(self,chunk,err) + if not chunk then + chunk="" + end + return sock:send(format("%X\r\n%s\r\n",#chunk,chunk)) + end + }) +end +local methods={} +local mt={ __index=methods } +local function openhttp(host,port,create) + local c=trysocket((create or tcpsocket)()) + local h=setmetatable({ c=c },mt) + local try=newtrysocket(function() h:close() end) + h.try=try + try(c:settimeout(http.TIMEOUT)) + try(c:connect(host,port or PORT)) + return h +end +http.open=openhttp +function methods.sendrequestline(self,method,uri) + local requestline=format("%s %s HTTP/1.1\r\n",method or "GET",uri) + return self.try(self.c:send(requestline)) +end +function methods.sendheaders(self,headers) + self.try(self.c:send(normalizeheaders(headers))) + return 1 +end +function methods.sendbody(self,headers,source,step) + if not source then + source=emptysource() + end + if not step then + step=pumpstep + end + local mode="http-chunked" + if headers["content-length"] then + mode="keep-open" + end + return self.try(pumpall(source,sinksocket(mode,self.c),step)) +end +function methods.receivestatusline(self) + local try=self.try + local status=try(self.c:receive(5)) + if status~="HTTP/" then + return nil,status + end + status=try(self.c:receive("*l",status)) + local code=skipsocket(2,find(status,"HTTP/%d*%.%d* (%d%d%d)")) + return try(tonumber(code),status) +end +function methods.receiveheaders(self) + return self.try(receiveheaders(self.c)) +end +function methods.receivebody(self,headers,sink,step) + if not sink then + sink=sinknull() + end + if not step then + step=pumpstep + end + local length=tonumber(headers["content-length"]) + local encoding=headers["transfer-encoding"] + local mode="default" + if encoding and encoding~="identity" then + mode="http-chunked" + elseif length then + mode="by-length" + end + return self.try(pumpall(sourcesocket(mode,self.c,length),sink,step)) +end +function methods.receive09body(self,status,sink,step) + local source=rewindsource(sourcesocket("until-closed",self.c)) + source(status) + return self.try(pumpall(source,sink,step)) +end +function methods.close(self) + return self.c:close() +end +local function adjusturi(request) + if not request.proxy and not http.PROXY then + request={ + path=trysocket(request.path,"invalid path 'nil'"), + params=request.params, + query=request.query, + fragment=request.fragment, + } + end + return buildurl(request) +end +local function adjustheaders(request) + local headers={ + ["user-agent"]=http.USERAGENT, + ["host"]=gsub(request.authority,"^.-@",""), + ["connection"]="close, TE", + ["te"]="trailers" + } + local username=request.user + local password=request.password + if username and password then + headers["authorization"]="Basic "..(mimeb64(username..":"..unescapeurl(password))) + end + local proxy=request.proxy or http.PROXY + if proxy then + proxy=parseurl(proxy) + local username=proxy.user + local password=proxy.password + if username and password then + headers["proxy-authorization"]="Basic "..(mimeb64(username..":"..password)) + end + end + local requestheaders=request.headers + if requestheaders then + headers=lowerheaders(headers,requestheaders) + end + return headers +end +local default={ + host="", + port=PORT, + path="/", + scheme="http" +} +local function adjustrequest(originalrequest) + local url=originalrequest.url + local request=url and parseurl(url,default) or {} + for k,v in next,originalrequest do + request[k]=v + end + local host=request.host + local port=request.port + local uri=request.uri + if not host or host=="" then + trysocket(nil,"invalid host '"..tostring(host).."'") + end + if port=="" then + request.port=PORT + end + if not uri or uri=="" then + request.uri=adjusturi(request) + end + request.headers=adjustheaders(request) + local proxy=request.proxy or http.PROXY + if proxy then + proxy=parseurl(proxy) + request.host=proxy.host + request.port=proxy.port or 3128 + end + return request +end +local maxredericts=4 +local validredirects={ [301]=true,[302]=true,[303]=true,[307]=true } +local validmethods={ [false]=true,GET=true,HEAD=true } +local function shouldredirect(request,code,headers) + local location=headers.location + if not location then + return false + end + location=gsub(location,"%s","") + if location=="" then + return false + end + local scheme=match(location,"^([%w][%w%+%-%.]*)%:") + if scheme and not SCHEMES[scheme] then + return false + end + local method=request.method + local redirect=request.redirect + local redirects=request.nredirects or 0 + return redirect and validredirects[code] and validmethods[method] and redirects<=maxredericts +end +local function shouldreceivebody(request,code) + if request.method=="HEAD" then + return nil + end + if code==204 or code==304 then + return nil + end + if code>=100 and code<200 then + return nil + end + return 1 +end +local tredirect,trequest,srequest +tredirect=function(request,location) + local result,code,headers,status=trequest { + url=absoluteurl(request.url,location), + source=request.source, + sink=request.sink, + headers=request.headers, + proxy=request.proxy, + nredirects=(request.nredirects or 0)+1, + create=request.create, + } + if not headers then + headers={} + end + if not headers.location then + headers.location=location + end + return result,code,headers,status +end +trequest=function(originalrequest) + local request=adjustrequest(originalrequest) + local connection=openhttp(request.host,request.port,request.create) + local headers=request.headers + connection:sendrequestline(request.method,request.uri) + connection:sendheaders(headers) + if request.source then + connection:sendbody(headers,request.source,request.step) + end + local code,status=connection:receivestatusline() + if not code then + connection:receive09body(status,request.sink,request.step) + return 1,200 + end + while code==100 do + headers=connection:receiveheaders() + code,status=connection:receivestatusline() + end + headers=connection:receiveheaders() + if shouldredirect(request,code,headers) and not request.source then + connection:close() + return tredirect(originalrequest,headers.location) + end + if shouldreceivebody(request,code) then + connection:receivebody(headers,request.sink,request.step) + end + connection:close() + return 1,code,headers,status +end +local function genericform(url,body) + local buffer={} + local request={ + url=url, + sink=sinktable(buffer), + target=buffer, + } + if body then + request.source=stringsource(body) + request.method="POST" + request.headers={ + ["content-length"]=#body, + ["content-type"]="application/x-www-form-urlencoded" + } + end + return request +end +http.genericform=genericform +srequest=function(url,body) + local request=genericform(url,body) + local _,code,headers,status=trequest(request) + return concat(request.target),code,headers,status +end +http.request=protectsocket(function(request,body) + if type(request)=="string" then + return srequest(request,body) + else + return trequest(request) + end +end) + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +package.loaded["util-soc-imp-ftp"] = package.loaded["util-soc-imp-ftp"] or true + +-- original size: 10321, stripped down to: 8867 + + +local setmetatable,type,next=setmetatable,type,next +local find,format,gsub,match=string.find,string.format,string.gsub,string.match +local concat=table.concat +local mod=math.mod +local socket=socket or require("socket") +local url=socket.url or require("socket.url") +local tp=socket.tp or require("socket.tp") +local ltn12=ltn12 or require("ltn12") +local tcpsocket=socket.tcp +local trysocket=socket.try +local skipsocket=socket.skip +local sinksocket=socket.sink +local selectsocket=socket.select +local bindsocket=socket.bind +local newtrysocket=socket.newtry +local sourcesocket=socket.source +local protectsocket=socket.protect +local parseurl=url.parse +local unescapeurl=url.unescape +local pumpall=ltn12.pump.all +local pumpstep=ltn12.pump.step +local sourcestring=ltn12.source.string +local sinktable=ltn12.sink.table +local ftp={ + TIMEOUT=60, + USER="ftp", + PASSWORD="anonymous@anonymous.org", +} +socket.ftp=ftp +local PORT=21 +local methods={} +local mt={ __index=methods } +function ftp.open(server,port,create) + local tp=trysocket(tp.connect(server,port or PORT,ftp.TIMEOUT,create)) + local f=setmetatable({ tp=tp },metat) + f.try=newtrysocket(function() f:close() end) + return f +end +function methods.portconnect(self) + local try=self.try + local server=self.server + try(server:settimeout(ftp.TIMEOUT)) + self.data=try(server:accept()) + try(self.data:settimeout(ftp.TIMEOUT)) +end +function methods.pasvconnect(self) + local try=self.try + self.data=try(tcpsocket()) + self(self.data:settimeout(ftp.TIMEOUT)) + self(self.data:connect(self.pasvt.address,self.pasvt.port)) +end +function methods.login(self,user,password) + local try=self.try + local tp=self.tp + try(tp:command("user",user or ftp.USER)) + local code,reply=try(tp:check{"2..",331}) + if code==331 then + try(tp:command("pass",password or ftp.PASSWORD)) + try(tp:check("2..")) + end + return 1 +end +function methods.pasv(self) + local try=self.try + local tp=self.tp + try(tp:command("pasv")) + local code,reply=try(self.tp:check("2..")) + local pattern="(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)" + local a,b,c,d,p1,p2=skipsocket(2,find(reply,pattern)) + try(a and b and c and d and p1 and p2,reply) + local address=format("%d.%d.%d.%d",a,b,c,d) + local port=p1*256+p2 + local server=self.server + self.pasvt={ + address=address, + port=port, + } + if server then + server:close() + self.server=nil + end + return address,port +end +function methods.epsv(self) + local try=self.try + local tp=self.tp + try(tp:command("epsv")) + local code,reply=try(tp:check("229")) + local pattern="%((.)(.-)%1(.-)%1(.-)%1%)" + local d,prt,address,port=match(reply,pattern) + try(port,"invalid epsv response") + local address=tp:getpeername() + local server=self.server + self.pasvt={ + address=address, + port=port, + } + if self.server then + server:close() + self.server=nil + end + return address,port +end +function methods.port(self,address,port) + local try=self.try + local tp=self.tp + self.pasvt=nil + if not address then + address,port=try(tp:getsockname()) + self.server=try(bindsocket(address,0)) + address,port=try(self.server:getsockname()) + try(self.server:settimeout(ftp.TIMEOUT)) + end + local pl=mod(port,256) + local ph=(port-pl)/256 + local arg=gsub(format("%s,%d,%d",address,ph,pl),"%.",",") + try(tp:command("port",arg)) + try(tp:check("2..")) + return 1 +end +function methods.eprt(self,family,address,port) + local try=self.try + local tp=self.tp + self.pasvt=nil + if not address then + address,port=try(tp:getsockname()) + self.server=try(bindsocket(address,0)) + address,port=try(self.server:getsockname()) + try(self.server:settimeout(ftp.TIMEOUT)) + end + local arg=format("|%s|%s|%d|",family,address,port) + try(tp:command("eprt",arg)) + try(tp:check("2..")) + return 1 +end +function methods.send(self,sendt) + local try=self.try + local tp=self.tp + try(self.pasvt or self.server,"need port or pasv first") + if self.pasvt then + self:pasvconnect() + end + local argument=sendt.argument or unescapeurl(gsub(sendt.path or "","^[/\\]","")) + if argument=="" then + argument=nil + end + local command=sendt.command or "stor" + try(tp:command(command,argument)) + local code,reply=try(tp:check{"2..","1.."}) + if not self.pasvt then + self:portconnect() + end + local step=sendt.step or pumpstep + local readt={ tp } + local checkstep=function(src,snk) + local readyt=selectsocket(readt,nil,0) + if readyt[tp] then + code=try(tp:check("2..")) + end + return step(src,snk) + end + local sink=sinksocket("close-when-done",self.data) + try(pumpall(sendt.source,sink,checkstep)) + if find(code,"1..") then + try(tp:check("2..")) + end + self.data:close() + local sent=skipsocket(1,self.data:getstats()) + self.data=nil + return sent +end +function methods.receive(self,recvt) + local try=self.try + local tp=self.tp + try(self.pasvt or self.server,"need port or pasv first") + if self.pasvt then self:pasvconnect() end + local argument=recvt.argument or unescapeurl(gsub(recvt.path or "","^[/\\]","")) + if argument=="" then + argument=nil + end + local command=recvt.command or "retr" + try(tp:command(command,argument)) + local code,reply=try(tp:check{"1..","2.."}) + if code>=200 and code<=299 then + recvt.sink(reply) + return 1 + end + if not self.pasvt then + self:portconnect() + end + local source=sourcesocket("until-closed",self.data) + local step=recvt.step or pumpstep + try(pumpall(source,recvt.sink,step)) + if find(code,"1..") then + try(tp:check("2..")) + end + self.data:close() + self.data=nil + return 1 +end +function methods.cwd(self,dir) + local try=self.try + local tp=self.tp + try(tp:command("cwd",dir)) + try(tp:check(250)) + return 1 +end +function methods.type(self,typ) + local try=self.try + local tp=self.tp + try(tp:command("type",typ)) + try(tp:check(200)) + return 1 +end +function methods.greet(self) + local try=self.try + local tp=self.tp + local code=try(tp:check{"1..","2.."}) + if find(code,"1..") then + try(tp:check("2..")) + end + return 1 +end +function methods.quit(self) + local try=self.try + try(self.tp:command("quit")) + try(self.tp:check("2..")) + return 1 +end +function methods.close(self) + local data=self.data + if data then + data:close() + end + local server=self.server + if server then + server:close() + end + local tp=self.tp + if tp then + tp:close() + end +end +local function override(t) + if t.url then + local u=parseurl(t.url) + for k,v in next,t do + u[k]=v + end + return u + else + return t + end +end +local function tput(putt) + putt=override(putt) + local host=putt.host + trysocket(host,"missing hostname") + local f=ftp.open(host,putt.port,putt.create) + f:greet() + f:login(putt.user,putt.password) + local typ=putt.type + if typ then + f:type(typ) + end + f:epsv() + local sent=f:send(putt) + f:quit() + f:close() + return sent +end +local default={ + path="/", + scheme="ftp", +} +local function genericform(u) + local t=trysocket(parseurl(u,default)) + trysocket(t.scheme=="ftp","wrong scheme '"..t.scheme.."'") + trysocket(t.host,"missing hostname") + local pat="^type=(.)$" + if t.params then + local typ=skipsocket(2,find(t.params,pat)) + t.type=typ + trysocket(typ=="a" or typ=="i","invalid type '"..typ.."'") + end + return t +end +ftp.genericform=genericform +local function sput(u,body) + local putt=genericform(u) + putt.source=sourcestring(body) + return tput(putt) +end +ftp.put=protectsocket(function(putt,body) + if type(putt)=="string" then + return sput(putt,body) + else + return tput(putt) + end +end) +local function tget(gett) + gett=override(gett) + local host=gett.host + trysocket(host,"missing hostname") + local f=ftp.open(host,gett.port,gett.create) + f:greet() + f:login(gett.user,gett.password) + if gett.type then + f:type(gett.type) + end + f:epsv() + f:receive(gett) + f:quit() + return f:close() +end +local function sget(u) + local gett=genericform(u) + local t={} + gett.sink=sinktable(t) + tget(gett) + return concat(t) +end +ftp.command=protectsocket(function(cmdt) + cmdt=override(cmdt) + local command=cmdt.command + local argument=cmdt.argument + local check=cmdt.check + local host=cmdt.host + trysocket(host,"missing hostname") + trysocket(command,"missing command") + local f=ftp.open(host,cmdt.port,cmdt.create) + local try=f.try + local tp=f.tp + f:greet() + f:login(cmdt.user,cmdt.password) + if type(command)=="table" then + local argument=argument or {} + for i=1,#command do + local cmd=command[i] + try(tp:command(cmd,argument[i])) + if check and check[i] then + try(tp:check(check[i])) + end + end + else + try(tp:command(command,argument)) + if check then + try(tp:check(check)) + end + end + f:quit() + return f:close() +end) +ftp.get=protectsocket(function(gett) + if type(gett)=="string" then + return sget(gett) + else + return tget(gett) + end +end) + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +package.loaded["util-soc-imp-smtp"] = package.loaded["util-soc-imp-smtp"] or true + +-- original size: 6975, stripped down to: 6055 + + +local type,setmetatable,next=type,setmetatable,next +local find,lower,format=string.find,string.lower,string.format +local osdate,osgetenv=os.data,os.getenv +local random=math.random +local socket=socket or require("socket") +local headers=socket.headers or require("socket.headers") +local ltn12=ltn12 or require("ltn12") +local tp=socket.tp or require("socket.tp") +local mime=mime or require("mime") +local mimeb64=mime.b64 +local mimestuff=mime.stuff +local skipsocket=socket.skip +local trysocket=socket.try +local newtrysocket=socket.newtry +local protectsocket=socket.protect +local normalizeheaders=headers.normalize +local lowerheaders=headers.lower +local createcoroutine=coroutine.create +local resumecoroutine=coroutine.resume +local yieldcoroutine=coroutine.resume +local smtp={ + TIMEOUT=60, + SERVER="localhost", + PORT=25, + DOMAIN=osgetenv("SERVER_NAME") or "localhost", + ZONE="-0000", +} +socket.smtp=smtp +local methods={} +local mt={ __index=methods } +function methods.greet(self,domain) + local try=self.try + local tp=self.tp + try(tp:check("2..")) + try(tp:command("EHLO",domain or _M.DOMAIN)) + return skipsocket(1,try(tp:check("2.."))) +end +function methods.mail(self,from) + local try=self.try + local tp=self.tp + try(tp:command("MAIL","FROM:"..from)) + return try(tp:check("2..")) +end +function methods.rcpt(self,to) + local try=self.try + local tp=self.tp + try(tp:command("RCPT","TO:"..to)) + return try(tp:check("2..")) +end +function methods.data(self,src,step) + local try=self.try + local tp=self.tp + try(tp:command("DATA")) + try(tp:check("3..")) + try(tp:source(src,step)) + try(tp:send("\r\n.\r\n")) + return try(tp:check("2..")) +end +function methods.quit(self) + local try=self.try + local tp=self.tp + try(tp:command("QUIT")) + return try(tp:check("2..")) +end +function methods.close(self) + return self.tp:close() +end +function methods.login(self,user,password) + local try=self.try + local tp=self.tp + try(tp:command("AUTH","LOGIN")) + try(tp:check("3..")) + try(tp:send(mimeb64(user).."\r\n")) + try(tp:check("3..")) + try(tp:send(mimeb64(password).."\r\n")) + return try(tp:check("2..")) +end +function methods.plain(self,user,password) + local try=self.try + local tp=self.tp + local auth="PLAIN "..mimeb64("\0"..user.."\0"..password) + try(tp:command("AUTH",auth)) + return try(tp:check("2..")) +end +function methods.auth(self,user,password,ext) + if not user or not password then + return 1 + end + local try=self.try + if find(ext,"AUTH[^\n]+LOGIN") then + return self:login(user,password) + elseif find(ext,"AUTH[^\n]+PLAIN") then + return self:plain(user,password) + else + try(nil,"authentication not supported") + end +end +function methods.send(self,mail) + self:mail(mail.from) + local receipt=mail.rcpt + if type(receipt)=="table" then + for i=1,#receipt do + self:rcpt(receipt[i]) + end + elseif receipt then + self:rcpt(receipt) + end + self:data(ltn12.source.chain(mail.source,mimestuff()),mail.step) +end +local function opensmtp(self,server,port,create) + if not server or server=="" then + server=smtp.SERVER + end + if not port or port=="" then + port=smtp.PORT + end + local s={ + tp=trysocket(tp.connect(server,port,smtp.TIMEOUT,create)), + try=newtrysocket(function() + s:close() + end), + } + setmetatable(s,mt) + return s +end +smtp.open=opensmtp +local nofboundaries=0 +local function newboundary() + nofboundaries=nofboundaries+1 + return format('%s%05d==%05u',osdate('%d%m%Y%H%M%S'),random(0,99999),nofboundaries) +end +local send_message +local function send_headers(headers) + yieldcoroutine(normalizeheaders(headers)) +end +local function send_multipart(message) + local boundary=newboundary() + local headers=lowerheaders(message.headers) + local body=message.body + local preamble=body.preamble + local epilogue=body.epilogue + local content=headers['content-type'] or 'multipart/mixed' + headers['content-type']=content..'; boundary="'..boundary..'"' + send_headers(headers) + if preamble then + yieldcoroutine(preamble) + yieldcoroutine("\r\n") + end + for i=1,#body do + yieldcoroutine("\r\n--"..boundary.."\r\n") + send_message(body[i]) + end + yieldcoroutine("\r\n--"..boundary.."--\r\n\r\n") + if epilogue then + yieldcoroutine(epilogue) + yieldcoroutine("\r\n") + end +end +local default_content_type='text/plain; charset="UTF-8"' +local function send_source(message) + local headers=lowerheaders(message.headers) + if not headers['content-type'] then + headers['content-type']=default_content_type + end + send_headers(headers) + local getchunk=message.body + while true do + local chunk,err=getchunk() + if err then + yieldcoroutine(nil,err) + elseif chunk then + yieldcoroutine(chunk) + else + break + end + end +end +local function send_string(message) + local headers=lowerheaders(message.headers) + if not headers['content-type'] then + headers['content-type']=default_content_type + end + send_headers(headers) + yieldcoroutine(message.body) +end +function send_message(message) + local body=message.body + if type(body)=="table" then + send_multipart(message) + elseif type(body)=="function" then + send_source(message) + else + send_string(message) + end +end +local function adjust_headers(message) + local headers=lowerheaders(message.headers) + if not headers["date"] then + headers["date"]=osdate("!%a, %d %b %Y %H:%M:%S ")..(message.zone or smtp.ZONE) + end + if not headers["x-mailer"] then + headers["x-mailer"]=socket._VERSION + end + headers["mime-version"]="1.0" + return headers +end +function smtp.message(message) + message.headers=adjust_headers(message) + local action=createcoroutine(function() + send_message(message) + end) + return function() + local ret,a,b=resumecoroutine(action) + if ret then + return a,b + else + return nil,a + end + end +end +smtp.send=protectsocket(function(mail) + local snd=opensmtp(mail.server,mail.port,mail.create) + local ext=snd:greet(mail.domain) + snd:auth(mail.user,mail.password,ext) + snd:send(mail) + snd:quit() + return snd:close() +end) + + +end -- of closure + +do -- create closure to overcome 200 locals limit + package.loaded["trac-set"] = package.loaded["trac-set"] or true -- original size: 13340, stripped down to: 9459 @@ -21733,10 +24554,10 @@ end end -- of closure --- used libraries : l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua --- skipped libraries : util-soc-imp-reset util-soc-imp-socket util-soc-imp-copas util-soc-imp-ltn12 util-soc-imp-mime util-soc-imp-url util-soc-imp-headers util-soc-imp-tp util-soc-imp-http util-soc-imp-ftp util-soc-imp-smtp --- original bytes : 893485 --- stripped bytes : 323975 +-- used libraries : l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua util-soc-imp-reset.lua util-soc-imp-socket.lua util-soc-imp-copas.lua util-soc-imp-ltn12.lua util-soc-imp-mime.lua util-soc-imp-url.lua util-soc-imp-headers.lua util-soc-imp-tp.lua util-soc-imp-http.lua util-soc-imp-ftp.lua util-soc-imp-smtp.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua +-- skipped libraries : - +-- original bytes : 981014 +-- stripped bytes : 346248 -- end library merge @@ -21788,18 +24609,18 @@ local ownlibs = { -- order can be made better 'util-prs.lua', 'util-fmt.lua', - 'util-soc-imp-reset', - 'util-soc-imp-socket', - 'util-soc-imp-copas', - 'util-soc-imp-ltn12', - -- 'util-soc-imp-mbox', - 'util-soc-imp-mime', - 'util-soc-imp-url', - 'util-soc-imp-headers', - 'util-soc-imp-tp', - 'util-soc-imp-http', - 'util-soc-imp-ftp', - 'util-soc-imp-smtp', + 'util-soc-imp-reset.lua', + 'util-soc-imp-socket.lua', + 'util-soc-imp-copas.lua', + 'util-soc-imp-ltn12.lua', + -- 'util-soc-imp-mbox.lua', + 'util-soc-imp-mime.lua', + 'util-soc-imp-url.lua', + 'util-soc-imp-headers.lua', + 'util-soc-imp-tp.lua', + 'util-soc-imp-http.lua', + 'util-soc-imp-ftp.lua', + 'util-soc-imp-smtp.lua', 'trac-set.lua', 'trac-log.lua', diff --git a/scripts/context/stubs/win64/mtxrun.lua b/scripts/context/stubs/win64/mtxrun.lua index 99c9fd3f2..555e662e3 100644 --- a/scripts/context/stubs/win64/mtxrun.lua +++ b/scripts/context/stubs/win64/mtxrun.lua @@ -9213,6 +9213,2827 @@ end -- of closure do -- create closure to overcome 200 locals limit +package.loaded["util-soc-imp-reset"] = package.loaded["util-soc-imp-reset"] or true + +-- original size: 374, stripped down to: 282 + +local loaded=package.loaded +loaded["socket"]=nil +loaded["copas"]=nil +loaded["ltn12"]=nil +loaded["mbox"]=nil +loaded["mime"]=nil +loaded["socket.url"]=nil +loaded["socket.headers"]=nil +loaded["socket.tp"]=nil +loaded["socket.http"]=nil +loaded["socket.ftp"]=nil +loaded["socket.smtp"]=nil + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +package.loaded["util-soc-imp-socket"] = package.loaded["util-soc-imp-socket"] or true + +-- original size: 4867, stripped down to: 3858 + + +local type,tostring,setmetatable=type,tostring,setmetatable +local min=math.min +local format=string.format +local socket=require("socket.core") +local connect=socket.connect +local tcp4=socket.tcp4 +local tcp6=socket.tcp6 +local getaddrinfo=socket.dns.getaddrinfo +local defaulthost="0.0.0.0" +local function report(fmt,first,...) + if logs then + report=logs and logs.reporter("socket") + report(fmt,first,...) + elseif fmt then + fmt="socket: "..fmt + if first then + print(format(fmt,first,...)) + else + print(fmt) + end + end +end +socket.report=report +function socket.connect4(address,port,laddress,lport) + return connect(address,port,laddress,lport,"inet") +end +function socket.connect6(address,port,laddress,lport) + return connect(address,port,laddress,lport,"inet6") +end +function socket.bind(host,port,backlog) + if host=="*" or host=="" then + host=defaulthost + end + local addrinfo,err=getaddrinfo(host) + if not addrinfo then + return nil,err + end + for i=1,#addrinfo do + local alt=addrinfo[i] + local sock,err=(alt.family=="inet" and tcp4 or tcp6)() + if not sock then + return nil,err or "unknown error" + end + sock:setoption("reuseaddr",true) + local res,err=sock:bind(alt.addr,port) + if res then + res,err=sock:listen(backlog) + if res then + return sock + else + sock:close() + end + else + sock:close() + end + end + return nil,"invalid address" +end +socket.try=socket.newtry() +function socket.choose(list) + return function(name,opt1,opt2) + if type(name)~="string" then + name,opt1,opt2="default",name,opt1 + end + local f=list[name or "nil"] + if f then + return f(opt1,opt2) + else + report("error: unknown key '%s'",tostring(name)) + end + end +end +local sourcet={} +local sinkt={} +socket.sourcet=sourcet +socket.sinkt=sinkt +socket.BLOCKSIZE=2048 +sinkt["close-when-done"]=function(sock) + return setmetatable ( + { + getfd=function() return sock:getfd() end, + dirty=function() return sock:dirty() end, + }, + { + __call=function(self,chunk,err) + if chunk then + return sock:send(chunk) + else + sock:close() + return 1 + end + end + } + ) +end +sinkt["keep-open"]=function(sock) + return setmetatable ( + { + getfd=function() return sock:getfd() end, + dirty=function() return sock:dirty() end, + },{ + __call=function(self,chunk,err) + if chunk then + return sock:send(chunk) + else + return 1 + end + end + } + ) +end +sinkt["default"]=sinkt["keep-open"] +socket.sink=socket.choose(sinkt) +sourcet["by-length"]=function(sock,length) + local blocksize=socket.BLOCKSIZE + return setmetatable ( + { + getfd=function() return sock:getfd() end, + dirty=function() return sock:dirty() end, + }, + { + __call=function() + if length<=0 then + return nil + end + local chunk,err=sock:receive(min(blocksize,length)) + if err then + return nil,err + end + length=length-#chunk + return chunk + end + } + ) +end +sourcet["until-closed"]=function(sock) + local blocksize=socket.BLOCKSIZE + local done=false + return setmetatable ( + { + getfd=function() return sock:getfd() end, + dirty=function() return sock:dirty() end, + },{ + __call=function() + if done then + return nil + end + local chunk,status,partial=sock:receive(blocksize) + if not status then + return chunk + elseif status=="closed" then + sock:close() + done=true + return partial + else + return nil,status + end + end + } + ) +end +sourcet["default"]=sourcet["until-closed"] +socket.source=socket.choose(sourcet) +_G.socket=socket +package.loaded.socket=socket + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +package.loaded["util-soc-imp-copas"] = package.loaded["util-soc-imp-copas"] or true + +-- original size: 25841, stripped down to: 16063 + + +local socket=socket or require("socket") +local ssl=ssl or nil +local WATCH_DOG_TIMEOUT=120 +local UDP_DATAGRAM_MAX=8192 +local type,next,pcall,getmetatable,tostring=type,next,pcall,getmetatable,tostring +local min,max,random=math.min,math.max,math.random +local find=string.find +local insert,remove=table.insert,table.remove +local gettime=socket.gettime +local selectsocket=socket.select +local createcoroutine=coroutine.create +local resumecoroutine=coroutine.resume +local yieldcoroutine=coroutine.yield +local runningcoroutine=coroutine.running +local function report(fmt,first,...) + if logs then + report=logs and logs.reporter("copas") + report(fmt,first,...) + elseif fmt then + fmt="copas: "..fmt + if first then + print(format(fmt,first,...)) + else + print(fmt) + end + end +end +local copas={ + _COPYRIGHT="Copyright (C) 2005-2016 Kepler Project", + _DESCRIPTION="Coroutine Oriented Portable Asynchronous Services", + _VERSION="Copas 2.0.1", + autoclose=true, + running=false, + report=report, +} +local function statushandler(status,...) + if status then + return... + end + local err=(...) + if type(err)=="table" then + err=err[1] + end + report("error: %s",tostring(err)) + return nil,err +end +function socket.protect(func) + return function(...) + return statushandler(pcall(func,...)) + end +end +function socket.newtry(finalizer) + return function (...) + local status=(...) + if not status then + local detail=select(2,...) + pcall(finalizer,detail) + report("error: %s",tostring(detail)) + return + end + return... + end +end +local function newset() + local reverse={} + local set={} + local queue={} + setmetatable(set,{ + __index={ + insert=function(set,value) + if not reverse[value] then + local n=#set+1 + set[n]=value + reverse[value]=n + end + end, + remove=function(set,value) + local index=reverse[value] + if index then + reverse[value]=nil + local n=#set + local top=set[n] + set[n]=nil + if top~=value then + reverse[top]=index + set[index]=top + end + end + end, + push=function (set,key,itm) + local entry=queue[key] + if entry==nil then + queue[key]={ itm } + else + entry[#entry+1]=itm + end + end, + pop=function (set,key) + local top=queue[key] + if top~=nil then + local ret=remove(top,1) + if top[1]==nil then + queue[key]=nil + end + return ret + end + end + } + } ) + return set +end +local _sleeping={ + times={}, + cos={}, + lethargy={}, + insert=function() + end, + remove=function() + end, + push=function(self,sleeptime,co) + if not co then + return + end + if sleeptime<0 then + self.lethargy[co]=true + return + else + sleeptime=gettime()+sleeptime + end + local t=self.times + local c=self.cos + local i=1 + local n=#t + while i<=n and t[i]<=sleeptime do + i=i+1 + end + insert(t,i,sleeptime) + insert(c,i,co) + end, + getnext= + function(self) + local t=self.times + local delay=t[1] and t[1]-gettime() or nil + return delay and max(delay,0) or nil + end, + pop= + function(self,time) + local t=self.times + local c=self.cos + if #t==0 or time<t[1] then + return + end + local co=c[1] + remove(t,1) + remove(c,1) + return co + end, + wakeup=function(self,co) + local let=self.lethargy + if let[co] then + self:push(0,co) + let[co]=nil + else + local c=self.cos + local t=self.times + for i=1,#c do + if c[i]==co then + remove(c,i) + remove(t,i) + self:push(0,co) + return + end + end + end + end +} +local _servers=newset() +local _reading=newset() +local _writing=newset() +local _reading_log={} +local _writing_log={} +local _is_timeout={ + timeout=true, + wantread=true, + wantwrite=true, +} +local function isTCP(socket) + return not find(tostring(socket),"^udp") +end +local function copasreceive(client,pattern,part) + if not pattern or pattern=="" then + pattern="*l" + end + local current_log=_reading_log + local s,err + repeat + s,err,part=client:receive(pattern,part) + if s or (not _is_timeout[err]) then + current_log[client]=nil + return s,err,part + end + if err=="wantwrite" then + current_log=_writing_log + current_log[client]=gettime() + yieldcoroutine(client,_writing) + else + current_log=_reading_log + current_log[client]=gettime() + yieldcoroutine(client,_reading) + end + until false +end +local function copasreceivefrom(client,size) + local s,err,port + if not size or size==0 then + size=UDP_DATAGRAM_MAX + end + repeat + s,err,port=client:receivefrom(size) + if s or err~="timeout" then + _reading_log[client]=nil + return s,err,port + end + _reading_log[client]=gettime() + yieldcoroutine(client,_reading) + until false +end +local function copasreceivepartial(client,pattern,part) + if not pattern or pattern=="" then + pattern="*l" + end + local logger=_reading_log + local queue=_reading + local s,err + repeat + s,err,part=client:receive(pattern,part) + if s or (type(pattern)=="number" and part~="" and part) or not _is_timeout[err] then + logger[client]=nil + return s,err,part + end + if err=="wantwrite" then + logger=_writing_log + queue=_writing + else + logger=_reading_log + queue=_reading + end + logger[client]=gettime() + yieldcoroutine(client,queue) + until false +end +local function copassend(client,data,from,to) + if not from then + from=1 + end + local lastIndex=from-1 + local logger=_writing_log + local queue=_writing + local s,err + repeat + s,err,lastIndex=client:send(data,lastIndex+1,to) + if random(100)>90 then + logger[client]=gettime() + yieldcoroutine(client,queue) + end + if s or not _is_timeout[err] then + logger[client]=nil + return s,err,lastIndex + end + if err=="wantread" then + logger=_reading_log + queue=_reading + else + logger=_writing_log + queue=_writing + end + logger[client]=gettime() + yieldcoroutine(client,queue) + until false +end +local function copassendto(client,data,ip,port) + repeat + local s,err=client:sendto(data,ip,port) + if random(100)>90 then + _writing_log[client]=gettime() + yieldcoroutine(client,_writing) + end + if s or err~="timeout" then + _writing_log[client]=nil + return s,err + end + _writing_log[client]=gettime() + yieldcoroutine(client,_writing) + until false +end +local function copasconnect(skt,host,port) + skt:settimeout(0) + local ret,err,tried_more_than_once + repeat + ret,err=skt:connect (host,port) + if ret or (err~="timeout" and err~="Operation already in progress") then + if not ret and err=="already connected" and tried_more_than_once then + ret=1 + err=nil + end + _writing_log[skt]=nil + return ret,err + end + tried_more_than_once=tried_more_than_once or true + _writing_log[skt]=gettime() + yieldcoroutine(skt,_writing) + until false +end +local function copasdohandshake(skt,sslt) + if not ssl then + ssl=require("ssl") + end + if not ssl then + report("error: no ssl library") + return + end + local nskt,err=ssl.wrap(skt,sslt) + if not nskt then + report("error: %s",tostring(err)) + return + end + nskt:settimeout(0) + local queue + repeat + local success,err=nskt:dohandshake() + if success then + return nskt + elseif err=="wantwrite" then + queue=_writing + elseif err=="wantread" then + queue=_reading + else + report("error: %s",tostring(err)) + return + end + yieldcoroutine(nskt,queue) + until false +end +local function copasflush(client) +end +copas.connect=copassconnect +copas.send=copassend +copas.sendto=copassendto +copas.receive=copasreceive +copas.receivefrom=copasreceivefrom +copas.copasreceivepartial=copasreceivepartial +copas.copasreceivePartial=copasreceivepartial +copas.dohandshake=copasdohandshake +copas.flush=copasflush +local function _skt_mt_tostring(self) + return tostring(self.socket).." (copas wrapped)" +end +local _skt_mt_tcp_index={ + send=function(self,data,from,to) + return copassend (self.socket,data,from,to) + end, + receive=function (self,pattern,prefix) + if self.timeout==0 then + return copasreceivePartial(self.socket,pattern,prefix) + else + return copasreceive(self.socket,pattern,prefix) + end + end, + flush=function (self) + return copasflush(self.socket) + end, + settimeout=function (self,time) + self.timeout=time + return true + end, + connect=function(self,...) + local res,err=copasconnect(self.socket,...) + if res and self.ssl_params then + res,err=self:dohandshake() + end + return res,err + end, + close=function(self,...) + return self.socket:close(...) + end, + bind=function(self,...) + return self.socket:bind(...) + end, + getsockname=function(self,...) + return self.socket:getsockname(...) + end, + getstats=function(self,...) + return self.socket:getstats(...) + end, + setstats=function(self,...) + return self.socket:setstats(...) + end, + listen=function(self,...) + return self.socket:listen(...) + end, + accept=function(self,...) + return self.socket:accept(...) + end, + setoption=function(self,...) + return self.socket:setoption(...) + end, + getpeername=function(self,...) + return self.socket:getpeername(...) + end, + shutdown=function(self,...) + return self.socket:shutdown(...) + end, + dohandshake=function(self,sslt) + self.ssl_params=sslt or self.ssl_params + local nskt,err=copasdohandshake(self.socket,self.ssl_params) + if not nskt then + return nskt,err + end + self.socket=nskt + return self + end, +} +local _skt_mt_tcp={ + __tostring=_skt_mt_tostring, + __index=_skt_mt_tcp_index, +} +local _skt_mt_udp_index={ + sendto=function (self,...) + return copassendto(self.socket,...) + end, + receive=function (self,size) + return copasreceive(self.socket,size or UDP_DATAGRAM_MAX) + end, + receivefrom=function (self,size) + return copasreceivefrom(self.socket,size or UDP_DATAGRAM_MAX) + end, + setpeername=function(self,...) + return self.socket:getpeername(...) + end, + setsockname=function(self,...) + return self.socket:setsockname(...) + end, + close=function(self,...) + return true + end +} +local _skt_mt_udp={ + __tostring=_skt_mt_tostring, + __index=_skt_mt_udp_index, +} +for k,v in next,_skt_mt_tcp_index do + if not _skt_mt_udp_index[k] then + _skt_mt_udp_index[k]=v + end +end +local function wrap(skt,sslt) + if getmetatable(skt)==_skt_mt_tcp or getmetatable(skt)==_skt_mt_udp then + return skt + end + skt:settimeout(0) + if isTCP(skt) then + return setmetatable ({ socket=skt,ssl_params=sslt },_skt_mt_tcp) + else + return setmetatable ({ socket=skt },_skt_mt_udp) + end +end +copas.wrap=wrap +function copas.handler(handler,sslparams) + return function (skt,...) + skt=wrap(skt) + if sslparams then + skt:dohandshake(sslparams) + end + return handler(skt,...) + end +end +local _errhandlers={} +function copas.setErrorHandler(err) + local co=runningcoroutine() + if co then + _errhandlers[co]=err + end +end +local function _deferror (msg,co,skt) + report("%s (%s) (%s)",msg,tostring(co),tostring(skt)) +end +local function _doTick (co,skt,...) + if not co then + return + end + local ok,res,new_q=resumecoroutine(co,skt,...) + if ok and res and new_q then + new_q:insert(res) + new_q:push(res,co) + else + if not ok then + pcall(_errhandlers[co] or _deferror,res,co,skt) + end + if skt and copas.autoclose and isTCP(skt) then + skt:close() + end + _errhandlers[co]=nil + end +end +local function _accept(input,handler) + local client=input:accept() + if client then + client:settimeout(0) + local co=createcoroutine(handler) + _doTick (co,client) + end + return client +end +local function _tickRead(skt) + _doTick(_reading:pop(skt),skt) +end +local function _tickWrite(skt) + _doTick(_writing:pop(skt),skt) +end +local function addTCPserver(server,handler,timeout) + server:settimeout(timeout or 0) + _servers[server]=handler + _reading:insert(server) +end +local function addUDPserver(server,handler,timeout) + server:settimeout(timeout or 0) + local co=createcoroutine(handler) + _reading:insert(server) + _doTick(co,server) +end +function copas.addserver(server,handler,timeout) + if isTCP(server) then + addTCPserver(server,handler,timeout) + else + addUDPserver(server,handler,timeout) + end +end +function copas.removeserver(server,keep_open) + local s=server + local mt=getmetatable(server) + if mt==_skt_mt_tcp or mt==_skt_mt_udp then + s=server.socket + end + _servers[s]=nil + _reading:remove(s) + if keep_open then + return true + end + return server:close() +end +function copas.addthread(handler,...) + local thread=createcoroutine(function(_,...) return handler(...) end) + _doTick(thread,nil,...) + return thread +end +local _tasks={} +local function addtaskRead(task) + task.def_tick=_tickRead + _tasks[task]=true +end +local function addtaskWrite(task) + task.def_tick=_tickWrite + _tasks[task]=true +end +local function tasks() + return next,_tasks +end +local _readable_t={ + events=function(self) + local i=0 + return function () + i=i+1 + return self._evs[i] + end + end, + tick=function(self,input) + local handler=_servers[input] + if handler then + input=_accept(input,handler) + else + _reading:remove(input) + self.def_tick(input) + end + end +} +addtaskRead(_readable_t) +local _writable_t={ + events=function(self) + local i=0 + return function() + i=i+1 + return self._evs[i] + end + end, + tick=function(self,output) + _writing:remove(output) + self.def_tick(output) + end +} +addtaskWrite(_writable_t) +local _sleeping_t={ + tick=function(self,time,...) + _doTick(_sleeping:pop(time),...) + end +} +function copas.sleep(sleeptime) + yieldcoroutine((sleeptime or 0),_sleeping) +end +function copas.wakeup(co) + _sleeping:wakeup(co) +end +local last_cleansing=0 +local function _select(timeout) + local now=gettime() + local r_evs,w_evs,err=selectsocket(_reading,_writing,timeout) + _readable_t._evs=r_evs + _writable_t._evs=w_evs + if (last_cleansing-now)>WATCH_DOG_TIMEOUT then + last_cleansing=now + for skt,time in next,_reading_log do + if not r_evs[skt] and (time-now)>WATCH_DOG_TIMEOUT then + local n=#r_evs+1 + _reading_log[skt]=nil + r_evs[n]=skt + r_evs[skt]=n + end + end + for skt,time in next,_writing_log do + if not w_evs[skt] and (time-now)>WATCH_DOG_TIMEOUT then + local n=#w_evs+1 + _writing_log[skt]=nil + w_evs[n]=skt + w_evs[skt]=n + end + end + end + if err=="timeout" and #r_evs+#w_evs>0 then + return nil + else + return err + end +end +local function copasfinished() + return not (next(_reading) or next(_writing) or _sleeping:getnext()) +end +local function copasstep(timeout) + _sleeping_t:tick(gettime()) + local nextwait=_sleeping:getnext() + if nextwait then + timeout=timeout and min(nextwait,timeout) or nextwait + elseif copasfinished() then + return false + end + local err=_select(timeout) + if err then + if err=="timeout" then + return false + end + return nil,err + end + for task in tasks() do + for event in task:events() do + task:tick(event) + end + end + return true +end +copas.finished=copasfinished +copas.step=copasstep +function copas.loop(timeout) + copas.running=true + while not copasfinished() do + copasstep(timeout) + end + copas.running=false +end +package.loaded.copas=copas + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +package.loaded["util-soc-imp-ltn12"] = package.loaded["util-soc-imp-ltn12"] or true + +-- original size: 8706, stripped down to: 6102 + + +local select,unpack=select,unpack +local insert,remove=table.insert,table.remove +local sub=string.sub +local function report(fmt,first,...) + if logs then + report=logs and logs.reporter("ltn12") + report(fmt,first,...) + elseif fmt then + fmt="ltn12: "..fmt + if first then + print(format(fmt,first,...)) + else + print(fmt) + end + end +end +local filter={} +local source={} +local sink={} +local pump={} +local ltn12={ + _VERSION="LTN12 1.0.3", + BLOCKSIZE=2048, + filter=filter, + source=source, + sink=sink, + pump=pump, + report=report, +} +function filter.cycle(low,ctx,extra) + if low then + return function(chunk) + return (low(ctx,chunk,extra)) + end + end +end +function filter.chain(...) + local arg={... } + local n=select('#',...) + local top=1 + local index=1 + local retry="" + return function(chunk) + retry=chunk and retry + while true do + local action=arg[index] + if index==top then + chunk=action(chunk) + if chunk=="" or top==n then + return chunk + elseif chunk then + index=index+1 + else + top=top+1 + index=top + end + else + chunk=action(chunk or "") + if chunk=="" then + index=index-1 + chunk=retry + elseif chunk then + if index==n then + return chunk + else + index=index+1 + end + else + report("error: filter returned inappropriate 'nil'") + return + end + end + end + end +end +local function empty() + return nil +end +function source.empty() + return empty +end +local function sourceerror(err) + return function() + return nil,err + end +end +source.error=sourceerror +function source.file(handle,io_err) + if handle then + local blocksize=ltn12.BLOCKSIZE + return function() + local chunk=handle:read(blocksize) + if not chunk then + handle:close() + end + return chunk + end + else + return sourceerror(io_err or "unable to open file") + end +end +function source.simplify(src) + return function() + local chunk,err_or_new=src() + if err_or_new then + src=err_or_new + end + if chunk then + return chunk + else + return nil,err_or_new + end + end +end +function source.string(s) + if s then + local blocksize=ltn12.BLOCKSIZE + local i=1 + return function() + local nexti=i+blocksize + local chunk=sub(s,i,nexti-1) + i=nexti + if chunk~="" then + return chunk + else + return nil + end + end + else return source.empty() end +end +function source.rewind(src) + local t={} + return function(chunk) + if chunk then + insert(t,chunk) + else + chunk=remove(t) + if chunk then + return chunk + else + return src() + end + end + end +end +function source.chain(src,f,...) + if... then + f=filter.chain(f,...) + end + local last_in="" + local last_out="" + local state="feeding" + local err + return function() + if not last_out then + report("error: source is empty") + return + end + while true do + if state=="feeding" then + last_in,err=src() + if err then + return nil,err + end + last_out=f(last_in) + if not last_out then + if last_in then + report("error: filter returned inappropriate 'nil'") + end + return nil + elseif last_out~="" then + state="eating" + if last_in then + last_in="" + end + return last_out + end + else + last_out=f(last_in) + if last_out=="" then + if last_in=="" then + state="feeding" + else + report("error: filter returned nothing") + return + end + elseif not last_out then + if last_in then + report("filter returned inappropriate 'nil'") + end + return nil + else + return last_out + end + end + end + end +end +function source.cat(...) + local arg={... } + local src=remove(arg,1) + return function() + while src do + local chunk,err=src() + if chunk then + return chunk + end + if err then + return nil,err + end + src=remove(arg,1) + end + end +end +function sink.table(t) + if not t then + t={} + end + local f=function(chunk,err) + if chunk then + insert(t,chunk) + end + return 1 + end + return f,t +end +function sink.simplify(snk) + return function(chunk,err) + local ret,err_or_new=snk(chunk,err) + if not ret then + return nil,err_or_new + end + if err_or_new then + snk=err_or_new + end + return 1 + end +end +local function null() + return 1 +end +function sink.null() + return null +end +local function sinkerror(err) + return function() + return nil,err + end +end +sink.error=sinkerror +function sink.file(handle,io_err) + if handle then + return function(chunk,err) + if not chunk then + handle:close() + return 1 + else + return handle:write(chunk) + end + end + else + return sinkerror(io_err or "unable to open file") + end +end +function sink.chain(f,snk,...) + if... then + local args={ f,snk,... } + snk=remove(args,#args) + f=filter.chain(unpack(args)) + end + return function(chunk,err) + if chunk~="" then + local filtered=f(chunk) + local done=chunk and "" + while true do + local ret,snkerr=snk(filtered,err) + if not ret then + return nil,snkerr + end + if filtered==done then + return 1 + end + filtered=f(done) + end + else + return 1 + end + end +end +function pump.step(src,snk) + local chunk,src_err=src() + local ret,snk_err=snk(chunk,src_err) + if chunk and ret then + return 1 + else + return nil,src_err or snk_err + end +end +function pump.all(src,snk,step) + if not step then + step=pump.step + end + while true do + local ret,err=step(src,snk) + if not ret then + if err then + return nil,err + else + return 1 + end + end + end +end +package.loaded.ltn12=ltn12 + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +package.loaded["util-soc-imp-mime"] = package.loaded["util-soc-imp-mime"] or true + +-- original size: 2325, stripped down to: 1927 + + +local type,tostring=type,tostring +local mime=require("mime.core") +local ltn12=ltn12 or require("ltn12") +local filtercycle=ltn12.filter.cycle +local function report(fmt,first,...) + if logs then + report=logs and logs.reporter("mime") + report(fmt,first,...) + elseif fmt then + fmt="mime: "..fmt + if first then + print(format(fmt,first,...)) + else + print(fmt) + end + end +end +mime.report=report +local encodet={} +local decodet={} +local wrapt={} +mime.encodet=encodet +mime.decodet=decodet +mime.wrapt=wrapt +local mime_b64=mime.b64 +local mime_qp=mime.qp +local mime_unb64=mime.unb64 +local mime_unqp=mime.unqp +local mime_wrp=mime.wrp +local mime_qpwrp=mime.qpwrp +local mime_eol=mime_eol +local mime_dot=mime_dot +encodet['base64']=function() + return filtercycle(mime_b64,"") +end +encodet['quoted-printable']=function(mode) + return filtercycle(mime_qp,"",mode=="binary" and "=0D=0A" or "\r\n") +end +decodet['base64']=function() + return filtercycle(mime_unb64,"") +end +decodet['quoted-printable']=function() + return filtercycle(mime_unqp,"") +end +local wraptext=function(length) + if not length then + length=76 + end + return filtercycle(mime_wrp,length,length) +end +local wrapquoted=function() + return filtercycle(mime_qpwrp,76,76) +end +wrapt['text']=wraptext +wrapt['base64']=wraptext +wrapt['default']=wraptext +wrapt['quoted-printable']=wrapquoted +function mime.normalize(marker) + return filtercycle(mime_eol,0,marker) +end +function mime.stuff() + return filtercycle(mime_dot,2) +end +local function choose(list) + return function(name,opt1,opt2) + if type(name)~="string" then + name,opt1,opt2="default",name,opt1 + end + local filter=list[name or "nil"] + if filter then + return filter(opt1,opt2) + else + report("error: unknown key '%s'",tostring(name)) + end + end +end +mime.encode=choose(encodet) +mime.decode=choose(decodet) +mime.wrap=choose(wrapt) +package.loaded.mime=mime + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +package.loaded["util-soc-imp-url"] = package.loaded["util-soc-imp-url"] or true + +-- original size: 6827, stripped down to: 5624 + + +local tonumber,tostring,type=tonumber,tostring,type +local gsub,sub,match,find,format,byte,char=string.gsub,string.sub,string.match,string.find,string.format,string.byte,string.char +local insert=table.insert +local socket=socket or require("socket") +local url={ + _VERSION="URL 1.0.3", +} +socket.url=url +function url.escape(s) + return (gsub(s,"([^A-Za-z0-9_])",function(c) + return format("%%%02x",byte(c)) + end)) +end +local function make_set(t) + local s={} + for i=1,#t do + s[t[i]]=true + end + return s +end +local segment_set=make_set { + "-","_",".","!","~","*","'","(", + ")",":","@","&","=","+","$",",", +} +local function protect_segment(s) + return gsub(s,"([^A-Za-z0-9_])",function(c) + if segment_set[c] then + return c + else + return format("%%%02X",byte(c)) + end + end) +end +function url.unescape(s) + return (gsub(s,"%%(%x%x)",function(hex) + return char(tonumber(hex,16)) + end)) +end +local function absolute_path(base_path,relative_path) + if find(relative_path,"^/") then + return relative_path + end + local path=gsub(base_path,"[^/]*$","") + path=path..relative_path + path=gsub(path,"([^/]*%./)",function (s) + if s~="./" then + return s + else + return "" + end + end) + path=gsub(path,"/%.$","/") + local reduced + while reduced~=path do + reduced=path + path=gsub(reduced,"([^/]*/%.%./)",function (s) + if s~="../../" then + return "" + else + return s + end + end) + end + path=gsub(reduced,"([^/]*/%.%.)$",function (s) + if s~="../.." then + return "" + else + return s + end + end) + return path +end +function url.parse(url,default) + local parsed={} + for k,v in next,default or parsed do + parsed[k]=v + end + if not url or url=="" then + return nil,"invalid url" + end + url=gsub(url,"#(.*)$",function(f) + parsed.fragment=f + return "" + end) + url=gsub(url,"^([%w][%w%+%-%.]*)%:",function(s) + parsed.scheme=s + return "" + end) + url=gsub(url,"^//([^/]*)",function(n) + parsed.authority=n + return "" + end) + url=gsub(url,"%?(.*)",function(q) + parsed.query=q + return "" + end) + url=gsub(url,"%;(.*)",function(p) + parsed.params=p + return "" + end) + if url~="" then + parsed.path=url + end + local authority=parsed.authority + if not authority then + return parsed + end + authority=gsub(authority,"^([^@]*)@",function(u) + parsed.userinfo=u + return "" + end) + authority=gsub(authority,":([^:%]]*)$",function(p) + parsed.port=p + return "" + end) + if authority~="" then + parsed.host=match(authority,"^%[(.+)%]$") or authority + end + local userinfo=parsed.userinfo + if not userinfo then + return parsed + end + userinfo=gsub(userinfo,":([^:]*)$",function(p) + parsed.password=p + return "" + end) + parsed.user=userinfo + return parsed +end +function url.build(parsed) + local url=parsed.path or "" + if parsed.params then + url=url..";"..parsed.params + end + if parsed.query then + url=url.."?"..parsed.query + end + local authority=parsed.authority + if parsed.host then + authority=parsed.host + if find(authority,":") then + authority="["..authority.."]" + end + if parsed.port then + authority=authority..":"..tostring(parsed.port) + end + local userinfo=parsed.userinfo + if parsed.user then + userinfo=parsed.user + if parsed.password then + userinfo=userinfo..":"..parsed.password + end + end + if userinfo then authority=userinfo.."@"..authority end + end + if authority then + url="//"..authority..url + end + if parsed.scheme then + url=parsed.scheme..":"..url + end + if parsed.fragment then + url=url.."#"..parsed.fragment + end + return url +end +function url.absolute(base_url,relative_url) + local base_parsed + if type(base_url)=="table" then + base_parsed=base_url + base_url=url.build(base_parsed) + else + base_parsed=url.parse(base_url) + end + local relative_parsed=url.parse(relative_url) + if not base_parsed then + return relative_url + elseif not relative_parsed then + return base_url + elseif relative_parsed.scheme then + return relative_url + else + relative_parsed.scheme=base_parsed.scheme + if not relative_parsed.authority then + relative_parsed.authority=base_parsed.authority + if not relative_parsed.path then + relative_parsed.path=base_parsed.path + if not relative_parsed.params then + relative_parsed.params=base_parsed.params + if not relative_parsed.query then + relative_parsed.query=base_parsed.query + end + end + else + relative_parsed.path=absolute_path(base_parsed.path or "",relative_parsed.path) + end + end + return url.build(relative_parsed) + end +end +function url.parse_path(path) + local parsed={} + path=path or "" + gsub(path,"([^/]+)",function (s) + insert(parsed,s) + end) + for i=1,#parsed do + parsed[i]=url.unescape(parsed[i]) + end + if sub(path,1,1)=="/" then + parsed.is_absolute=1 + end + if sub(path,-1,-1)=="/" then + parsed.is_directory=1 + end + return parsed +end +function url.build_path(parsed,unsafe) + local path="" + local n=#parsed + if unsafe then + for i=1,n-1 do + path=path..parsed[i].."/" + end + if n>0 then + path=path..parsed[n] + if parsed.is_directory then + path=path.."/" + end + end + else + for i=1,n-1 do + path=path..protect_segment(parsed[i]).."/" + end + if n>0 then + path=path..protect_segment(parsed[n]) + if parsed.is_directory then + path=path.."/" + end + end + end + if parsed.is_absolute then + path="/"..path + end + return path +end + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +package.loaded["util-soc-imp-headers"] = package.loaded["util-soc-imp-headers"] or true + +-- original size: 5712, stripped down to: 3865 + + +local next=next +local lower=string.lower +local concat=table.concat +local socket=socket or require("socket") +local canonic={ + ["accept"]="Accept", + ["accept-charset"]="Accept-Charset", + ["accept-encoding"]="Accept-Encoding", + ["accept-language"]="Accept-Language", + ["accept-ranges"]="Accept-Ranges", + ["action"]="Action", + ["alternate-recipient"]="Alternate-Recipient", + ["age"]="Age", + ["allow"]="Allow", + ["arrival-date"]="Arrival-Date", + ["authorization"]="Authorization", + ["bcc"]="Bcc", + ["cache-control"]="Cache-Control", + ["cc"]="Cc", + ["comments"]="Comments", + ["connection"]="Connection", + ["content-description"]="Content-Description", + ["content-disposition"]="Content-Disposition", + ["content-encoding"]="Content-Encoding", + ["content-id"]="Content-ID", + ["content-language"]="Content-Language", + ["content-length"]="Content-Length", + ["content-location"]="Content-Location", + ["content-md5"]="Content-MD5", + ["content-range"]="Content-Range", + ["content-transfer-encoding"]="Content-Transfer-Encoding", + ["content-type"]="Content-Type", + ["cookie"]="Cookie", + ["date"]="Date", + ["diagnostic-code"]="Diagnostic-Code", + ["dsn-gateway"]="DSN-Gateway", + ["etag"]="ETag", + ["expect"]="Expect", + ["expires"]="Expires", + ["final-log-id"]="Final-Log-ID", + ["final-recipient"]="Final-Recipient", + ["from"]="From", + ["host"]="Host", + ["if-match"]="If-Match", + ["if-modified-since"]="If-Modified-Since", + ["if-none-match"]="If-None-Match", + ["if-range"]="If-Range", + ["if-unmodified-since"]="If-Unmodified-Since", + ["in-reply-to"]="In-Reply-To", + ["keywords"]="Keywords", + ["last-attempt-date"]="Last-Attempt-Date", + ["last-modified"]="Last-Modified", + ["location"]="Location", + ["max-forwards"]="Max-Forwards", + ["message-id"]="Message-ID", + ["mime-version"]="MIME-Version", + ["original-envelope-id"]="Original-Envelope-ID", + ["original-recipient"]="Original-Recipient", + ["pragma"]="Pragma", + ["proxy-authenticate"]="Proxy-Authenticate", + ["proxy-authorization"]="Proxy-Authorization", + ["range"]="Range", + ["received"]="Received", + ["received-from-mta"]="Received-From-MTA", + ["references"]="References", + ["referer"]="Referer", + ["remote-mta"]="Remote-MTA", + ["reply-to"]="Reply-To", + ["reporting-mta"]="Reporting-MTA", + ["resent-bcc"]="Resent-Bcc", + ["resent-cc"]="Resent-Cc", + ["resent-date"]="Resent-Date", + ["resent-from"]="Resent-From", + ["resent-message-id"]="Resent-Message-ID", + ["resent-reply-to"]="Resent-Reply-To", + ["resent-sender"]="Resent-Sender", + ["resent-to"]="Resent-To", + ["retry-after"]="Retry-After", + ["return-path"]="Return-Path", + ["sender"]="Sender", + ["server"]="Server", + ["smtp-remote-recipient"]="SMTP-Remote-Recipient", + ["status"]="Status", + ["subject"]="Subject", + ["te"]="TE", + ["to"]="To", + ["trailer"]="Trailer", + ["transfer-encoding"]="Transfer-Encoding", + ["upgrade"]="Upgrade", + ["user-agent"]="User-Agent", + ["vary"]="Vary", + ["via"]="Via", + ["warning"]="Warning", + ["will-retry-until"]="Will-Retry-Until", + ["www-authenticate"]="WWW-Authenticate", + ["x-mailer"]="X-Mailer", +} +setmetatable(canonic,{ + __index=function(t,k) + socket.report("invalid header: %s",k) + t[k]=k + return k + end +}) +local function normalizeheaders(headers) + if not headers then + return {} + end + local normalized={} + for k,v in next,headers do + normalized[#normalized+1]=canonic[k]..": "..v + end + normalized[#normalized+1]="" + normalized[#normalized+1]="" + return concat(normalized,"\r\n") +end +local function lowerheaders(lowered,headers) + if not lowered then + return {} + end + if not headers then + lowered,headers={},lowered + end + for k,v in next,headers do + lowered[lower(k)]=v + end + return lowered +end +socket.headers={ + canonic=canonic, + normalize=normalizeheaders, + lower=lowerheaders, +} + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +package.loaded["util-soc-imp-tp"] = package.loaded["util-soc-imp-tp"] or true + +-- original size: 3082, stripped down to: 2612 + + +local setmetatable,next,type,tonumber=setmetatable,next,type,tonumber +local find,upper=string.find,string,upper +local socket=socket or require("socket") +local ltn12=ltn12 or require("ltn12") +local skipsocket=socket.skip +local sinksocket=socket.sink +local tcpsocket=socket.tcp +local ltn12pump=ltn12.pump +local pumpall=ltn12pump.all +local pumpstep=ltn12pump.step +local tp={ + TIMEOUT=60, +} +socket.tp=tp +local function get_reply(c) + local line,err=c:receive() + local reply=line + if err then return + nil,err + end + local code,sep=skipsocket(2,find(line,"^(%d%d%d)(.?)")) + if not code then + return nil,"invalid server reply" + end + if sep=="-" then + local current + repeat + line,err=c:receive() + if err then + return nil,err + end + current,sep=skipsocket(2,find(line,"^(%d%d%d)(.?)")) + reply=reply.."\n"..line + until code==current and sep==" " + end + return code,reply +end +local methods={} +local mt={ __index=methods } +function methods.getpeername(self) + return self.c:getpeername() +end +function methods.getsockname(self) + return self.c:getpeername() +end +function methods.check(self,ok) + local code,reply=get_reply(self.c) + if not code then + return nil,reply + end + local c=tonumber(code) + local t=type(ok) + if t=="function" then + return ok(c,reply) + elseif t=="table" then + for i=1,#ok do + if find(code,ok[i]) then + return c,reply + end + end + return nil,reply + elseif find(code,ok) then + return c,reply + else + return nil,reply + end +end +function methods.command(self,cmd,arg) + cmd=upper(cmd) + if arg then + cmd=cmd.." "..arg.."\r\n" + else + cmd=cmd.."\r\n" + end + return self.c:send(cmd) +end +function methods.sink(self,snk,pat) + local chunk,err=self.c:receive(pat) + return snk(chunk,err) +end +function methods.send(self,data) + return self.c:send(data) +end +function methods.receive(self,pat) + return self.c:receive(pat) +end +function methods.getfd(self) + return self.c:getfd() +end +function methods.dirty(self) + return self.c:dirty() +end +function methods.getcontrol(self) + return self.c +end +function methods.source(self,source,step) + local sink=sinksocket("keep-open",self.c) + local ret,err=pumpall(source,sink,step or pumpstep) + return ret,err +end +function methods.close(self) + self.c:close() + return 1 +end +function tp.connect(host,port,timeout,create) + local c,e=(create or tcpsocket)() + if not c then + return nil,e + end + c:settimeout(timeout or tp.TIMEOUT) + local r,e=c:connect(host,port) + if not r then + c:close() + return nil,e + end + return setmetatable({ c=c },mt) +end + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +package.loaded["util-soc-imp-http"] = package.loaded["util-soc-imp-http"] or true + +-- original size: 12499, stripped down to: 10001 + + +local tostring,tonumber,setmetatable,next,type=tostring,tonumber,setmetatable,next,type +local find,lower,format,gsub,match=string.find,string.lower,string.format,string.gsub,string.match +local concat=table.concat +local socket=socket or require("socket") +local url=socket.url or require("socket.url") +local ltn12=ltn12 or require("ltn12") +local mime=mime or require("mime") +local headers=socket.headers or require("socket.headers") +local normalizeheaders=headers.normalize +local parseurl=url.parse +local buildurl=url.build +local absoluteurl=url.absolute +local unescapeurl=url.unescape +local skipsocket=socket.skip +local sinksocket=socket.sink +local sourcesocket=socket.source +local trysocket=socket.try +local tcpsocket=socket.tcp +local newtrysocket=socket.newtry +local protectsocket=socket.protect +local emptysource=ltn12.source.empty +local stringsource=ltn12.source.string +local rewindsource=ltn12.source.rewind +local pumpstep=ltn12.pump.step +local pumpall=ltn12.pump.all +local sinknull=ltn12.sink.null +local sinktable=ltn12.sink.table +local mimeb64=mime.b64 +local http={ + TIMEOUT=60, + USERAGENT=socket._VERSION, +} +socket.http=http +local PORT=80 +local SCHEMES={ + http=true, +} +local function receiveheaders(sock,headers) + if not headers then + headers={} + end + local line,err=sock:receive() + if err then + return nil,err + end + while line~="" do + local name,value=skipsocket(2,find(line,"^(.-):%s*(.*)")) + if not (name and value) then + return nil,"malformed reponse headers" + end + name=lower(name) + line,err=sock:receive() + if err then + return nil,err + end + while find(line,"^%s") do + value=value..line + line=sock:receive() + if err then + return nil,err + end + end + local found=headers[name] + if found then + value=found..", "..value + end + headers[name]=value + end + return headers +end +socket.sourcet["http-chunked"]=function(sock,headers) + return setmetatable ( + { + getfd=function() return sock:getfd() end, + dirty=function() return sock:dirty() end, + },{ + __call=function() + local line,err=sock:receive() + if err then + return nil,err + end + local size=tonumber(gsub(line,";.*",""),16) + if not size then + return nil,"invalid chunk size" + end + if size>0 then + local chunk,err,part=sock:receive(size) + if chunk then + sock:receive() + end + return chunk,err + else + headers,err=receiveheaders(sock,headers) + if not headers then + return nil,err + end + end + end + } + ) +end +socket.sinkt["http-chunked"]=function(sock) + return setmetatable( + { + getfd=function() return sock:getfd() end, + dirty=function() return sock:dirty() end, + }, + { + __call=function(self,chunk,err) + if not chunk then + chunk="" + end + return sock:send(format("%X\r\n%s\r\n",#chunk,chunk)) + end + }) +end +local methods={} +local mt={ __index=methods } +local function openhttp(host,port,create) + local c=trysocket((create or tcpsocket)()) + local h=setmetatable({ c=c },mt) + local try=newtrysocket(function() h:close() end) + h.try=try + try(c:settimeout(http.TIMEOUT)) + try(c:connect(host,port or PORT)) + return h +end +http.open=openhttp +function methods.sendrequestline(self,method,uri) + local requestline=format("%s %s HTTP/1.1\r\n",method or "GET",uri) + return self.try(self.c:send(requestline)) +end +function methods.sendheaders(self,headers) + self.try(self.c:send(normalizeheaders(headers))) + return 1 +end +function methods.sendbody(self,headers,source,step) + if not source then + source=emptysource() + end + if not step then + step=pumpstep + end + local mode="http-chunked" + if headers["content-length"] then + mode="keep-open" + end + return self.try(pumpall(source,sinksocket(mode,self.c),step)) +end +function methods.receivestatusline(self) + local try=self.try + local status=try(self.c:receive(5)) + if status~="HTTP/" then + return nil,status + end + status=try(self.c:receive("*l",status)) + local code=skipsocket(2,find(status,"HTTP/%d*%.%d* (%d%d%d)")) + return try(tonumber(code),status) +end +function methods.receiveheaders(self) + return self.try(receiveheaders(self.c)) +end +function methods.receivebody(self,headers,sink,step) + if not sink then + sink=sinknull() + end + if not step then + step=pumpstep + end + local length=tonumber(headers["content-length"]) + local encoding=headers["transfer-encoding"] + local mode="default" + if encoding and encoding~="identity" then + mode="http-chunked" + elseif length then + mode="by-length" + end + return self.try(pumpall(sourcesocket(mode,self.c,length),sink,step)) +end +function methods.receive09body(self,status,sink,step) + local source=rewindsource(sourcesocket("until-closed",self.c)) + source(status) + return self.try(pumpall(source,sink,step)) +end +function methods.close(self) + return self.c:close() +end +local function adjusturi(request) + if not request.proxy and not http.PROXY then + request={ + path=trysocket(request.path,"invalid path 'nil'"), + params=request.params, + query=request.query, + fragment=request.fragment, + } + end + return buildurl(request) +end +local function adjustheaders(request) + local headers={ + ["user-agent"]=http.USERAGENT, + ["host"]=gsub(request.authority,"^.-@",""), + ["connection"]="close, TE", + ["te"]="trailers" + } + local username=request.user + local password=request.password + if username and password then + headers["authorization"]="Basic "..(mimeb64(username..":"..unescapeurl(password))) + end + local proxy=request.proxy or http.PROXY + if proxy then + proxy=parseurl(proxy) + local username=proxy.user + local password=proxy.password + if username and password then + headers["proxy-authorization"]="Basic "..(mimeb64(username..":"..password)) + end + end + local requestheaders=request.headers + if requestheaders then + headers=lowerheaders(headers,requestheaders) + end + return headers +end +local default={ + host="", + port=PORT, + path="/", + scheme="http" +} +local function adjustrequest(originalrequest) + local url=originalrequest.url + local request=url and parseurl(url,default) or {} + for k,v in next,originalrequest do + request[k]=v + end + local host=request.host + local port=request.port + local uri=request.uri + if not host or host=="" then + trysocket(nil,"invalid host '"..tostring(host).."'") + end + if port=="" then + request.port=PORT + end + if not uri or uri=="" then + request.uri=adjusturi(request) + end + request.headers=adjustheaders(request) + local proxy=request.proxy or http.PROXY + if proxy then + proxy=parseurl(proxy) + request.host=proxy.host + request.port=proxy.port or 3128 + end + return request +end +local maxredericts=4 +local validredirects={ [301]=true,[302]=true,[303]=true,[307]=true } +local validmethods={ [false]=true,GET=true,HEAD=true } +local function shouldredirect(request,code,headers) + local location=headers.location + if not location then + return false + end + location=gsub(location,"%s","") + if location=="" then + return false + end + local scheme=match(location,"^([%w][%w%+%-%.]*)%:") + if scheme and not SCHEMES[scheme] then + return false + end + local method=request.method + local redirect=request.redirect + local redirects=request.nredirects or 0 + return redirect and validredirects[code] and validmethods[method] and redirects<=maxredericts +end +local function shouldreceivebody(request,code) + if request.method=="HEAD" then + return nil + end + if code==204 or code==304 then + return nil + end + if code>=100 and code<200 then + return nil + end + return 1 +end +local tredirect,trequest,srequest +tredirect=function(request,location) + local result,code,headers,status=trequest { + url=absoluteurl(request.url,location), + source=request.source, + sink=request.sink, + headers=request.headers, + proxy=request.proxy, + nredirects=(request.nredirects or 0)+1, + create=request.create, + } + if not headers then + headers={} + end + if not headers.location then + headers.location=location + end + return result,code,headers,status +end +trequest=function(originalrequest) + local request=adjustrequest(originalrequest) + local connection=openhttp(request.host,request.port,request.create) + local headers=request.headers + connection:sendrequestline(request.method,request.uri) + connection:sendheaders(headers) + if request.source then + connection:sendbody(headers,request.source,request.step) + end + local code,status=connection:receivestatusline() + if not code then + connection:receive09body(status,request.sink,request.step) + return 1,200 + end + while code==100 do + headers=connection:receiveheaders() + code,status=connection:receivestatusline() + end + headers=connection:receiveheaders() + if shouldredirect(request,code,headers) and not request.source then + connection:close() + return tredirect(originalrequest,headers.location) + end + if shouldreceivebody(request,code) then + connection:receivebody(headers,request.sink,request.step) + end + connection:close() + return 1,code,headers,status +end +local function genericform(url,body) + local buffer={} + local request={ + url=url, + sink=sinktable(buffer), + target=buffer, + } + if body then + request.source=stringsource(body) + request.method="POST" + request.headers={ + ["content-length"]=#body, + ["content-type"]="application/x-www-form-urlencoded" + } + end + return request +end +http.genericform=genericform +srequest=function(url,body) + local request=genericform(url,body) + local _,code,headers,status=trequest(request) + return concat(request.target),code,headers,status +end +http.request=protectsocket(function(request,body) + if type(request)=="string" then + return srequest(request,body) + else + return trequest(request) + end +end) + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +package.loaded["util-soc-imp-ftp"] = package.loaded["util-soc-imp-ftp"] or true + +-- original size: 10321, stripped down to: 8867 + + +local setmetatable,type,next=setmetatable,type,next +local find,format,gsub,match=string.find,string.format,string.gsub,string.match +local concat=table.concat +local mod=math.mod +local socket=socket or require("socket") +local url=socket.url or require("socket.url") +local tp=socket.tp or require("socket.tp") +local ltn12=ltn12 or require("ltn12") +local tcpsocket=socket.tcp +local trysocket=socket.try +local skipsocket=socket.skip +local sinksocket=socket.sink +local selectsocket=socket.select +local bindsocket=socket.bind +local newtrysocket=socket.newtry +local sourcesocket=socket.source +local protectsocket=socket.protect +local parseurl=url.parse +local unescapeurl=url.unescape +local pumpall=ltn12.pump.all +local pumpstep=ltn12.pump.step +local sourcestring=ltn12.source.string +local sinktable=ltn12.sink.table +local ftp={ + TIMEOUT=60, + USER="ftp", + PASSWORD="anonymous@anonymous.org", +} +socket.ftp=ftp +local PORT=21 +local methods={} +local mt={ __index=methods } +function ftp.open(server,port,create) + local tp=trysocket(tp.connect(server,port or PORT,ftp.TIMEOUT,create)) + local f=setmetatable({ tp=tp },metat) + f.try=newtrysocket(function() f:close() end) + return f +end +function methods.portconnect(self) + local try=self.try + local server=self.server + try(server:settimeout(ftp.TIMEOUT)) + self.data=try(server:accept()) + try(self.data:settimeout(ftp.TIMEOUT)) +end +function methods.pasvconnect(self) + local try=self.try + self.data=try(tcpsocket()) + self(self.data:settimeout(ftp.TIMEOUT)) + self(self.data:connect(self.pasvt.address,self.pasvt.port)) +end +function methods.login(self,user,password) + local try=self.try + local tp=self.tp + try(tp:command("user",user or ftp.USER)) + local code,reply=try(tp:check{"2..",331}) + if code==331 then + try(tp:command("pass",password or ftp.PASSWORD)) + try(tp:check("2..")) + end + return 1 +end +function methods.pasv(self) + local try=self.try + local tp=self.tp + try(tp:command("pasv")) + local code,reply=try(self.tp:check("2..")) + local pattern="(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)" + local a,b,c,d,p1,p2=skipsocket(2,find(reply,pattern)) + try(a and b and c and d and p1 and p2,reply) + local address=format("%d.%d.%d.%d",a,b,c,d) + local port=p1*256+p2 + local server=self.server + self.pasvt={ + address=address, + port=port, + } + if server then + server:close() + self.server=nil + end + return address,port +end +function methods.epsv(self) + local try=self.try + local tp=self.tp + try(tp:command("epsv")) + local code,reply=try(tp:check("229")) + local pattern="%((.)(.-)%1(.-)%1(.-)%1%)" + local d,prt,address,port=match(reply,pattern) + try(port,"invalid epsv response") + local address=tp:getpeername() + local server=self.server + self.pasvt={ + address=address, + port=port, + } + if self.server then + server:close() + self.server=nil + end + return address,port +end +function methods.port(self,address,port) + local try=self.try + local tp=self.tp + self.pasvt=nil + if not address then + address,port=try(tp:getsockname()) + self.server=try(bindsocket(address,0)) + address,port=try(self.server:getsockname()) + try(self.server:settimeout(ftp.TIMEOUT)) + end + local pl=mod(port,256) + local ph=(port-pl)/256 + local arg=gsub(format("%s,%d,%d",address,ph,pl),"%.",",") + try(tp:command("port",arg)) + try(tp:check("2..")) + return 1 +end +function methods.eprt(self,family,address,port) + local try=self.try + local tp=self.tp + self.pasvt=nil + if not address then + address,port=try(tp:getsockname()) + self.server=try(bindsocket(address,0)) + address,port=try(self.server:getsockname()) + try(self.server:settimeout(ftp.TIMEOUT)) + end + local arg=format("|%s|%s|%d|",family,address,port) + try(tp:command("eprt",arg)) + try(tp:check("2..")) + return 1 +end +function methods.send(self,sendt) + local try=self.try + local tp=self.tp + try(self.pasvt or self.server,"need port or pasv first") + if self.pasvt then + self:pasvconnect() + end + local argument=sendt.argument or unescapeurl(gsub(sendt.path or "","^[/\\]","")) + if argument=="" then + argument=nil + end + local command=sendt.command or "stor" + try(tp:command(command,argument)) + local code,reply=try(tp:check{"2..","1.."}) + if not self.pasvt then + self:portconnect() + end + local step=sendt.step or pumpstep + local readt={ tp } + local checkstep=function(src,snk) + local readyt=selectsocket(readt,nil,0) + if readyt[tp] then + code=try(tp:check("2..")) + end + return step(src,snk) + end + local sink=sinksocket("close-when-done",self.data) + try(pumpall(sendt.source,sink,checkstep)) + if find(code,"1..") then + try(tp:check("2..")) + end + self.data:close() + local sent=skipsocket(1,self.data:getstats()) + self.data=nil + return sent +end +function methods.receive(self,recvt) + local try=self.try + local tp=self.tp + try(self.pasvt or self.server,"need port or pasv first") + if self.pasvt then self:pasvconnect() end + local argument=recvt.argument or unescapeurl(gsub(recvt.path or "","^[/\\]","")) + if argument=="" then + argument=nil + end + local command=recvt.command or "retr" + try(tp:command(command,argument)) + local code,reply=try(tp:check{"1..","2.."}) + if code>=200 and code<=299 then + recvt.sink(reply) + return 1 + end + if not self.pasvt then + self:portconnect() + end + local source=sourcesocket("until-closed",self.data) + local step=recvt.step or pumpstep + try(pumpall(source,recvt.sink,step)) + if find(code,"1..") then + try(tp:check("2..")) + end + self.data:close() + self.data=nil + return 1 +end +function methods.cwd(self,dir) + local try=self.try + local tp=self.tp + try(tp:command("cwd",dir)) + try(tp:check(250)) + return 1 +end +function methods.type(self,typ) + local try=self.try + local tp=self.tp + try(tp:command("type",typ)) + try(tp:check(200)) + return 1 +end +function methods.greet(self) + local try=self.try + local tp=self.tp + local code=try(tp:check{"1..","2.."}) + if find(code,"1..") then + try(tp:check("2..")) + end + return 1 +end +function methods.quit(self) + local try=self.try + try(self.tp:command("quit")) + try(self.tp:check("2..")) + return 1 +end +function methods.close(self) + local data=self.data + if data then + data:close() + end + local server=self.server + if server then + server:close() + end + local tp=self.tp + if tp then + tp:close() + end +end +local function override(t) + if t.url then + local u=parseurl(t.url) + for k,v in next,t do + u[k]=v + end + return u + else + return t + end +end +local function tput(putt) + putt=override(putt) + local host=putt.host + trysocket(host,"missing hostname") + local f=ftp.open(host,putt.port,putt.create) + f:greet() + f:login(putt.user,putt.password) + local typ=putt.type + if typ then + f:type(typ) + end + f:epsv() + local sent=f:send(putt) + f:quit() + f:close() + return sent +end +local default={ + path="/", + scheme="ftp", +} +local function genericform(u) + local t=trysocket(parseurl(u,default)) + trysocket(t.scheme=="ftp","wrong scheme '"..t.scheme.."'") + trysocket(t.host,"missing hostname") + local pat="^type=(.)$" + if t.params then + local typ=skipsocket(2,find(t.params,pat)) + t.type=typ + trysocket(typ=="a" or typ=="i","invalid type '"..typ.."'") + end + return t +end +ftp.genericform=genericform +local function sput(u,body) + local putt=genericform(u) + putt.source=sourcestring(body) + return tput(putt) +end +ftp.put=protectsocket(function(putt,body) + if type(putt)=="string" then + return sput(putt,body) + else + return tput(putt) + end +end) +local function tget(gett) + gett=override(gett) + local host=gett.host + trysocket(host,"missing hostname") + local f=ftp.open(host,gett.port,gett.create) + f:greet() + f:login(gett.user,gett.password) + if gett.type then + f:type(gett.type) + end + f:epsv() + f:receive(gett) + f:quit() + return f:close() +end +local function sget(u) + local gett=genericform(u) + local t={} + gett.sink=sinktable(t) + tget(gett) + return concat(t) +end +ftp.command=protectsocket(function(cmdt) + cmdt=override(cmdt) + local command=cmdt.command + local argument=cmdt.argument + local check=cmdt.check + local host=cmdt.host + trysocket(host,"missing hostname") + trysocket(command,"missing command") + local f=ftp.open(host,cmdt.port,cmdt.create) + local try=f.try + local tp=f.tp + f:greet() + f:login(cmdt.user,cmdt.password) + if type(command)=="table" then + local argument=argument or {} + for i=1,#command do + local cmd=command[i] + try(tp:command(cmd,argument[i])) + if check and check[i] then + try(tp:check(check[i])) + end + end + else + try(tp:command(command,argument)) + if check then + try(tp:check(check)) + end + end + f:quit() + return f:close() +end) +ftp.get=protectsocket(function(gett) + if type(gett)=="string" then + return sget(gett) + else + return tget(gett) + end +end) + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +package.loaded["util-soc-imp-smtp"] = package.loaded["util-soc-imp-smtp"] or true + +-- original size: 6975, stripped down to: 6055 + + +local type,setmetatable,next=type,setmetatable,next +local find,lower,format=string.find,string.lower,string.format +local osdate,osgetenv=os.data,os.getenv +local random=math.random +local socket=socket or require("socket") +local headers=socket.headers or require("socket.headers") +local ltn12=ltn12 or require("ltn12") +local tp=socket.tp or require("socket.tp") +local mime=mime or require("mime") +local mimeb64=mime.b64 +local mimestuff=mime.stuff +local skipsocket=socket.skip +local trysocket=socket.try +local newtrysocket=socket.newtry +local protectsocket=socket.protect +local normalizeheaders=headers.normalize +local lowerheaders=headers.lower +local createcoroutine=coroutine.create +local resumecoroutine=coroutine.resume +local yieldcoroutine=coroutine.resume +local smtp={ + TIMEOUT=60, + SERVER="localhost", + PORT=25, + DOMAIN=osgetenv("SERVER_NAME") or "localhost", + ZONE="-0000", +} +socket.smtp=smtp +local methods={} +local mt={ __index=methods } +function methods.greet(self,domain) + local try=self.try + local tp=self.tp + try(tp:check("2..")) + try(tp:command("EHLO",domain or _M.DOMAIN)) + return skipsocket(1,try(tp:check("2.."))) +end +function methods.mail(self,from) + local try=self.try + local tp=self.tp + try(tp:command("MAIL","FROM:"..from)) + return try(tp:check("2..")) +end +function methods.rcpt(self,to) + local try=self.try + local tp=self.tp + try(tp:command("RCPT","TO:"..to)) + return try(tp:check("2..")) +end +function methods.data(self,src,step) + local try=self.try + local tp=self.tp + try(tp:command("DATA")) + try(tp:check("3..")) + try(tp:source(src,step)) + try(tp:send("\r\n.\r\n")) + return try(tp:check("2..")) +end +function methods.quit(self) + local try=self.try + local tp=self.tp + try(tp:command("QUIT")) + return try(tp:check("2..")) +end +function methods.close(self) + return self.tp:close() +end +function methods.login(self,user,password) + local try=self.try + local tp=self.tp + try(tp:command("AUTH","LOGIN")) + try(tp:check("3..")) + try(tp:send(mimeb64(user).."\r\n")) + try(tp:check("3..")) + try(tp:send(mimeb64(password).."\r\n")) + return try(tp:check("2..")) +end +function methods.plain(self,user,password) + local try=self.try + local tp=self.tp + local auth="PLAIN "..mimeb64("\0"..user.."\0"..password) + try(tp:command("AUTH",auth)) + return try(tp:check("2..")) +end +function methods.auth(self,user,password,ext) + if not user or not password then + return 1 + end + local try=self.try + if find(ext,"AUTH[^\n]+LOGIN") then + return self:login(user,password) + elseif find(ext,"AUTH[^\n]+PLAIN") then + return self:plain(user,password) + else + try(nil,"authentication not supported") + end +end +function methods.send(self,mail) + self:mail(mail.from) + local receipt=mail.rcpt + if type(receipt)=="table" then + for i=1,#receipt do + self:rcpt(receipt[i]) + end + elseif receipt then + self:rcpt(receipt) + end + self:data(ltn12.source.chain(mail.source,mimestuff()),mail.step) +end +local function opensmtp(self,server,port,create) + if not server or server=="" then + server=smtp.SERVER + end + if not port or port=="" then + port=smtp.PORT + end + local s={ + tp=trysocket(tp.connect(server,port,smtp.TIMEOUT,create)), + try=newtrysocket(function() + s:close() + end), + } + setmetatable(s,mt) + return s +end +smtp.open=opensmtp +local nofboundaries=0 +local function newboundary() + nofboundaries=nofboundaries+1 + return format('%s%05d==%05u',osdate('%d%m%Y%H%M%S'),random(0,99999),nofboundaries) +end +local send_message +local function send_headers(headers) + yieldcoroutine(normalizeheaders(headers)) +end +local function send_multipart(message) + local boundary=newboundary() + local headers=lowerheaders(message.headers) + local body=message.body + local preamble=body.preamble + local epilogue=body.epilogue + local content=headers['content-type'] or 'multipart/mixed' + headers['content-type']=content..'; boundary="'..boundary..'"' + send_headers(headers) + if preamble then + yieldcoroutine(preamble) + yieldcoroutine("\r\n") + end + for i=1,#body do + yieldcoroutine("\r\n--"..boundary.."\r\n") + send_message(body[i]) + end + yieldcoroutine("\r\n--"..boundary.."--\r\n\r\n") + if epilogue then + yieldcoroutine(epilogue) + yieldcoroutine("\r\n") + end +end +local default_content_type='text/plain; charset="UTF-8"' +local function send_source(message) + local headers=lowerheaders(message.headers) + if not headers['content-type'] then + headers['content-type']=default_content_type + end + send_headers(headers) + local getchunk=message.body + while true do + local chunk,err=getchunk() + if err then + yieldcoroutine(nil,err) + elseif chunk then + yieldcoroutine(chunk) + else + break + end + end +end +local function send_string(message) + local headers=lowerheaders(message.headers) + if not headers['content-type'] then + headers['content-type']=default_content_type + end + send_headers(headers) + yieldcoroutine(message.body) +end +function send_message(message) + local body=message.body + if type(body)=="table" then + send_multipart(message) + elseif type(body)=="function" then + send_source(message) + else + send_string(message) + end +end +local function adjust_headers(message) + local headers=lowerheaders(message.headers) + if not headers["date"] then + headers["date"]=osdate("!%a, %d %b %Y %H:%M:%S ")..(message.zone or smtp.ZONE) + end + if not headers["x-mailer"] then + headers["x-mailer"]=socket._VERSION + end + headers["mime-version"]="1.0" + return headers +end +function smtp.message(message) + message.headers=adjust_headers(message) + local action=createcoroutine(function() + send_message(message) + end) + return function() + local ret,a,b=resumecoroutine(action) + if ret then + return a,b + else + return nil,a + end + end +end +smtp.send=protectsocket(function(mail) + local snd=opensmtp(mail.server,mail.port,mail.create) + local ext=snd:greet(mail.domain) + snd:auth(mail.user,mail.password,ext) + snd:send(mail) + snd:quit() + return snd:close() +end) + + +end -- of closure + +do -- create closure to overcome 200 locals limit + package.loaded["trac-set"] = package.loaded["trac-set"] or true -- original size: 13340, stripped down to: 9459 @@ -21733,10 +24554,10 @@ end end -- of closure --- used libraries : l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua --- skipped libraries : util-soc-imp-reset util-soc-imp-socket util-soc-imp-copas util-soc-imp-ltn12 util-soc-imp-mime util-soc-imp-url util-soc-imp-headers util-soc-imp-tp util-soc-imp-http util-soc-imp-ftp util-soc-imp-smtp --- original bytes : 893485 --- stripped bytes : 323975 +-- used libraries : l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua util-soc-imp-reset.lua util-soc-imp-socket.lua util-soc-imp-copas.lua util-soc-imp-ltn12.lua util-soc-imp-mime.lua util-soc-imp-url.lua util-soc-imp-headers.lua util-soc-imp-tp.lua util-soc-imp-http.lua util-soc-imp-ftp.lua util-soc-imp-smtp.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua +-- skipped libraries : - +-- original bytes : 981014 +-- stripped bytes : 346248 -- end library merge @@ -21788,18 +24609,18 @@ local ownlibs = { -- order can be made better 'util-prs.lua', 'util-fmt.lua', - 'util-soc-imp-reset', - 'util-soc-imp-socket', - 'util-soc-imp-copas', - 'util-soc-imp-ltn12', - -- 'util-soc-imp-mbox', - 'util-soc-imp-mime', - 'util-soc-imp-url', - 'util-soc-imp-headers', - 'util-soc-imp-tp', - 'util-soc-imp-http', - 'util-soc-imp-ftp', - 'util-soc-imp-smtp', + 'util-soc-imp-reset.lua', + 'util-soc-imp-socket.lua', + 'util-soc-imp-copas.lua', + 'util-soc-imp-ltn12.lua', + -- 'util-soc-imp-mbox.lua', + 'util-soc-imp-mime.lua', + 'util-soc-imp-url.lua', + 'util-soc-imp-headers.lua', + 'util-soc-imp-tp.lua', + 'util-soc-imp-http.lua', + 'util-soc-imp-ftp.lua', + 'util-soc-imp-smtp.lua', 'trac-set.lua', 'trac-log.lua', diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii index bbc4328b2..84973fd1b 100644 --- a/tex/context/base/mkii/cont-new.mkii +++ b/tex/context/base/mkii/cont-new.mkii @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2018.08.21 08:33} +\newcontextversion{2018.08.24 19:18} %D This file is loaded at runtime, thereby providing an %D excellent place for hacks, patches, extensions and new diff --git a/tex/context/base/mkii/context.mkii b/tex/context/base/mkii/context.mkii index 969760423..15db8fef4 100644 --- a/tex/context/base/mkii/context.mkii +++ b/tex/context/base/mkii/context.mkii @@ -20,7 +20,7 @@ %D your styles an modules. \edef\contextformat {\jobname} -\edef\contextversion{2018.08.21 08:33} +\edef\contextversion{2018.08.24 19:18} %D For those who want to use this: diff --git a/tex/context/base/mkiv/attr-col.lua b/tex/context/base/mkiv/attr-col.lua index f970fb8e7..4e5f59fb1 100644 --- a/tex/context/base/mkiv/attr-col.lua +++ b/tex/context/base/mkiv/attr-col.lua @@ -295,7 +295,7 @@ function colors.spot(parent,f,d,p) local v = values[n] if v then -- the via cmyk hack is dirty, but it scales better - local c, m, y, k = p*v[6], p*v[7], p*v[8], p*v[8] + local c, m, y, k = p*v[6], p*v[7], p*v[8], p*v[9] local r, g, b = cmyktorgb(c,m,y,k) local s = cmyktogray(c,m,y,k) return { 5, s, r, g, b, c, m, y, k, parent, f, d, p } @@ -318,7 +318,7 @@ function colors.spot(parent,f,d,p) c = c + p*v[6] m = m + p*v[7] y = y + p*v[8] - k = k + p*v[8] + k = k + p*v[9] done = true end end diff --git a/tex/context/base/mkiv/colo-ini.lua b/tex/context/base/mkiv/colo-ini.lua index f8b9cff7f..d24939896 100644 --- a/tex/context/base/mkiv/colo-ini.lua +++ b/tex/context/base/mkiv/colo-ini.lua @@ -274,7 +274,9 @@ local function forcedmodel(model) -- delayed till the backend but mp directly return 2 end elseif model == 5 then -- spot - if cmyk_okay then + if spot_okay then + return 5 + elseif cmyk_okay then return 4 elseif rgb_okay then return 3 @@ -565,7 +567,7 @@ local function f(i,colors,fraction) return otf end -local function definemixcolor(makename,name,fractions,cs,global,freeze) +local function definemixcolor(makecolor,name,fractions,cs,global,freeze) local values = { } for i=1,#cs do -- do fraction in here local v = colorvalues[cs[i]] @@ -593,7 +595,7 @@ local function definemixcolor(makename,name,fractions,cs,global,freeze) end definecolor(name,ca,global,freeze) else - report_colors("invalid specification of components for color %a",makename) + report_colors("invalid specification of components for color %a",makecolor) end end @@ -609,12 +611,12 @@ local function definemultitonecolor(name,multispec,colorspec,selfspec) nn = concat(nn,'_') local parent = gsub(lower(nn),"[^%d%a%.]+","_") if not colorspec or colorspec == "" then + -- this can happens when we come from metapost local cc = { } for i=1,max do --- cc[i] = l_color[dd[i]] cc[i] = resolvedname(dd[i]) end - definemixcolor(name,parent,pp,cc,global,freeze) -- can become local + definemixcolor(name,parent,pp,cc,true,true) else if selfspec ~= "" then colorspec = colorspec .. "," .. selfspec @@ -646,24 +648,29 @@ colors.definemultitonecolor = definemultitonecolor -- that we cannot cast .. so we really need to use (s,s,s) for gray in order -- to be able to map onto 'color' -local function mpcolor(model,ca,ta,default) +local function mpcolor(model,ca,ta,default,name) local cv = colorvalues[ca] if cv then local tv = transparencyvalues[ta] + -- maybe move the 5 logic into the forcedmodel call + local cm = cv[1] if model == 1 then - model = cv[1] + model = cm end model = forcedmodel(model) + if cm == 5 and model == 4 then + model = 5 -- a cheat but ok as spot colors have a representation + end if tv then if model == 2 then return formatters["transparent(%s,%s,(%s,%s,%s))"](tv[1],tv[2],cv[3],cv[4],cv[5]) elseif model == 3 then return formatters["transparent(%s,%s,(%s,%s,%s))"](tv[1],tv[2],cv[3],cv[4],cv[5]) elseif model == 4 then - return formatters["transparent(%s,%s,cmyk(%s,%s,%s,%s))"](tv[1],tv[2],cv[6],cv[7],cv[8],cv[9]) + return formatters["transparent(%s,%s,(%s,%s,%s,%s))"](tv[1],tv[2],cv[6],cv[7],cv[8],cv[9]) elseif model == 5 then -- return formatters['transparent(%s,%s,multitonecolor("%s",%s,"%s","%s"))'](tv[1],tv[2],cv[10],cv[11],cv[12],cv[13]) - return formatters['transparent(%s,%s,namedcolor("%s"))'](tv[1],tv[2],cv[10]) + return formatters['transparent(%s,%s,namedcolor("%s"))'](tv[1],tv[2],name or cv[10]) else -- see ** in meta-ini.mkiv: return formatters["transparent(%s,%s,(%s))"](tv[1],tv[2],cv[2]) return formatters["transparent(%s,%s,(%s,%s,%s))"](tv[1],tv[2],cv[3],cv[4],cv[5]) end @@ -673,10 +680,9 @@ local function mpcolor(model,ca,ta,default) elseif model == 3 then return formatters["(%s,%s,%s)"](cv[3],cv[4],cv[5]) elseif model == 4 then - return formatters["cmyk(%s,%s,%s,%s)"](cv[6],cv[7],cv[8],cv[9]) + return formatters["(%s,%s,%s,%s)"](cv[6],cv[7],cv[8],cv[9]) elseif model == 5 then - -- return formatters['multitonecolor("%s",%s,"%s","%s")'](cv[10],cv[11],cv[12],cv[13]) - return formatters['namedcolor("%s")'](cv[10]) + return formatters['namedcolor("%s")'](name or cv[10]) else -- see ** in meta-ini.mkiv: return formatters["%s"]((cv[2])) return formatters["(%s,%s,%s)"](cv[3],cv[4],cv[5]) end @@ -736,7 +742,8 @@ end colors.namedcolorattributes = namedcolorattributes -- can be used local local function mpnamedcolor(name) - return mpcolor(namedcolorattributes(name)) + local model, ca, ta = namedcolorattributes(name) + return mpcolor(model,ca,ta,nil,name) end local function mpoptions(model,ca,ta,default) -- will move to mlib-col .. not really needed diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv index 80d9f45ab..5deb1b759 100644 --- a/tex/context/base/mkiv/cont-new.mkiv +++ b/tex/context/base/mkiv/cont-new.mkiv @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2018.08.21 08:33} +\newcontextversion{2018.08.24 19:18} %D This file is loaded at runtime, thereby providing an excellent place for %D hacks, patches, extensions and new features. diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv index 3afecfd75..89fc73650 100644 --- a/tex/context/base/mkiv/context.mkiv +++ b/tex/context/base/mkiv/context.mkiv @@ -42,7 +42,7 @@ %D has to match \type {YYYY.MM.DD HH:MM} format. \edef\contextformat {\jobname} -\edef\contextversion{2018.08.21 08:33} +\edef\contextversion{2018.08.24 19:18} \edef\contextkind {beta} %D For those who want to use this: diff --git a/tex/context/base/mkiv/lang-ini.mkiv b/tex/context/base/mkiv/lang-ini.mkiv index bb31da839..cc8a8ef16 100644 --- a/tex/context/base/mkiv/lang-ini.mkiv +++ b/tex/context/base/mkiv/lang-ini.mkiv @@ -620,6 +620,14 @@ \newcount\mainlanguagenumber +%D Beware: you might need to use \type {\dontleavehmode} outside and|/|or \type {\par} +%D inside the group! + +\unexpanded\def\startlanguage + {\begingroup\language} + +\let\stoplanguage\endgroup + % \unexpanded\def\mainlanguage[#1]% % {\edef\askedlanguage{#1}% % \ifx\askedlanguage\empty \else diff --git a/tex/context/base/mkiv/lpdf-col.lua b/tex/context/base/mkiv/lpdf-col.lua index d1a1af97d..bb7e933aa 100644 --- a/tex/context/base/mkiv/lpdf-col.lua +++ b/tex/context/base/mkiv/lpdf-col.lua @@ -617,7 +617,7 @@ function lpdf.colorvalues(model,ca,default) return cv[3], cv[4], cv[5] elseif model == 4 then return cv[6], cv[7], cv[8], cv[9] - elseif model == 4 then + elseif model == 5 then return cv[13] end else diff --git a/tex/context/base/mkiv/mlib-pps.lua b/tex/context/base/mkiv/mlib-pps.lua index 0c52aa0b9..03f712fbc 100644 --- a/tex/context/base/mkiv/mlib-pps.lua +++ b/tex/context/base/mkiv/mlib-pps.lua @@ -102,6 +102,7 @@ local f_gray = formatters["%.3F g %.3F G"] local f_rgb = formatters["%.3F %.3F %.3F rg %.3F %.3F %.3F RG"] local f_cmyk = formatters["%.3F %.3F %.3F %.3F k %.3F %.3F %.3F %.3F K"] local f_cm_b = formatters["q %.6F %.6F %.6F %.6F %.6F %.6F cm"] +local f_scn = formatters["%.3F"] local f_shade = formatters["MpSh%s"] local f_spot = formatters["/%s cs /%s CS %s SCN %s scn"] @@ -114,6 +115,7 @@ directives.register("metapost.stripzeros",function() f_rgb = formatters["%.3N %.3N %.3N rg %.3N %.3N %.3N RG"] f_cmyk = formatters["%.3N %.3N %.3N %.3N k %.3N %.3N %.3N %.3N K"] f_cm_b = formatters["q %.6N %.6N %.6N %.6N %.6N %.6N cm"] + f_scn = formatters["%.3N"] end) local function checked_color_pair(color,...) @@ -1701,14 +1703,27 @@ local remappers = { [4] = formatters["c=%s,m=%s,y=%s,k=%s"], } +local processlast = 0 +local processhash = setmetatableindex(function(t,k) + processlast = processlast + 1 + local v = formatters["mp_%s"](processlast) + defineprocesscolor(v,k,true,true) + t[k] = v + return v +end) + +local function checked_transparency(alternative,transparency,before,after) + alternative = tonumber(alternative) or 1 + transparency = tonumber(transparency) or 0 + before[#before+1] = formatters["/Tr%s gs"](registertransparency(nil,alternative,transparency,true)) + after [#after +1] = "/Tr0 gs" -- outertransparency +end + local function tr_process(object,prescript,before,after) -- before can be shortcut to t local tr_alternative = prescript.tr_alternative if tr_alternative then - tr_alternative = tonumber(tr_alternative) - local tr_transparency = tonumber(prescript.tr_transparency) - before[#before+1] = formatters["/Tr%s gs"](registertransparency(nil,tr_alternative,tr_transparency,true)) - after[#after+1] = "/Tr0 gs" -- outertransparency + checked_transparency(tr_alternative,prescript.tr_transparency,before,after) end local cs = object.color if cs and #cs > 0 then @@ -1719,29 +1734,35 @@ local function tr_process(object,prescript,before,after) else local sp_name = prescript.sp_name or "black" if sp_type == "spot" then - local sp_value = prescript.sp_value or "s:1" - local sp_temp = formatters["mp:%s"](sp_value) - local s = split(sp_value,":") - local r = remappers[#s] - defineprocesscolor(sp_temp,r and r(unpack(s)) or "s=0",true,true) - definespotcolor(sp_name,sp_temp,"p=1",true) + local sp_value = prescript.sp_value or "1" + local components = split(sp_value,":") + local specification = remappers[#components] + if specification then + specification = specification(unpack(components)) + else + specification = "s=0" + end + local sp_spec = processhash[specification] + definespotcolor(sp_name,sp_spec,"p=1",true) sp_type = "named" elseif sp_type == "multitone" then -- (fractions of a multitone) don't work well in mupdf - local sp_value = prescript.sp_value or "s:1" - local sp_spec = { } + local sp_value = prescript.sp_value or "1" + local sp_specs = { } local sp_list = split(sp_value," ") for i=1,#sp_list do - local v = sp_list[i] - local t = formatters["mp:%s"](v) - local s = split(v,":") - local r = remappers[#s] - defineprocesscolor(t,r and r(unpack(s)) or "s=0",true,true) - local tt = formatters["ms:%s"](v) - definespotcolor(tt,t,"p=1",true) - sp_spec[#sp_spec+1] = formatters["%s=1"](t) + local sp_value = sp_list[i] + local components = split(sp_value,":") + local specification = remappers[#components] + if specification then + specification = specification(unpack(components)) + else + specification = "s=0" + end + local sp_spec = processhash[specification] + sp_specs[i] = formatters["%s=1"](sp_spec) end - sp_spec = concat(sp_spec,",") - definemultitonecolor(sp_name,sp_spec,"","",true) + sp_specs = concat(sp_specs,",") + definemultitonecolor(sp_name,sp_specs,"","") sp_type = "named" end if sp_type == "named" then @@ -1753,8 +1774,7 @@ local function tr_process(object,prescript,before,after) local t = t_list[sp_name] -- string or attribute local v = t and transparencyvalue(t) if v then - before[#before+1] = formatters["/Tr%s gs"](registertransparency(nil,v[1],v[2],true)) - after[#after+1] = "/Tr0 gs" -- outertransparency + checked_transparency(v[1],v[2],before,after) end end local c = c_list[sp_name] -- string or attribute @@ -1762,29 +1782,34 @@ local function tr_process(object,prescript,before,after) if v then -- all=1 gray=2 rgb=3 cmyk=4 local colorspace = v[1] - local f = cs[1] + local factor = cs[1] if colorspace == 2 then - local s = f*v[2] + local s = factor * v[2] c_b, c_a = checked_color_pair(f_gray,s,s) elseif colorspace == 3 then - local r, g, b = f*v[3], f*v[4], f*v[5] + local r = factor * v[3] + local g = factor * v[4] + local b = factor * v[5] c_b, c_a = checked_color_pair(f_rgb,r,g,b,r,g,b) elseif colorspace == 4 or colorspace == 1 then - local c, m, y, k = f*v[6], f*v[7], f*v[8], f*v[9] + local c = factor * v[6] + local m = factor * v[7] + local y = factor * v[8] + local k = factor * v[9] c_b, c_a = checked_color_pair(f_cmyk,c,m,y,k,c,m,y,k) elseif colorspace == 5 then -- not all viewers show the fractions ok local name = v[10] local value = split(v[13],",") - if f ~= 1 then + if factor ~= 1 then for i=1,#value do - value[i] = f * (tonumber(value[i]) or 1) + value[i] = f_scn(factor * (tonumber(value[i]) or 1)) end end value = concat(value," ") c_b, c_a = checked_color_pair(f_spot,name,name,value,value) else - local s = f*v[2] + local s = factor *v[2] c_b, c_a = checked_color_pair(f_gray,s,s) end end diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf Binary files differindex bcf832f06..10ef69c69 100644 --- a/tex/context/base/mkiv/status-files.pdf +++ b/tex/context/base/mkiv/status-files.pdf diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf Binary files differindex 01064bbff..bf0b7d9d8 100644 --- a/tex/context/base/mkiv/status-lua.pdf +++ b/tex/context/base/mkiv/status-lua.pdf diff --git a/tex/context/base/mkiv/util-soc-imp-copas.lua b/tex/context/base/mkiv/util-soc-imp-copas.lua index 8e2278eb2..0c6f65899 100644 --- a/tex/context/base/mkiv/util-soc-imp-copas.lua +++ b/tex/context/base/mkiv/util-soc-imp-copas.lua @@ -25,8 +25,11 @@ local runningcoroutine = coroutine.running -- Meta information is public even if beginning with an "_" -local report = logs and logs.reporter("copas") or function(fmt,first,...) - if fmt then +local function report(fmt,first,...) + if logs then + report = logs and logs.reporter("copas") + report(fmt,first,...) + elseif fmt then fmt = "copas: " .. fmt if first then print(format(fmt,first,...)) @@ -734,16 +737,16 @@ local _tasks = { } -- Lets tasks call the default _tick(). -local function addtaskRead(tsk) - tsk.def_tick = _tickRead - _tasks[tsk] = true +local function addtaskRead(task) + task.def_tick = _tickRead + _tasks[task] = true end -- Lets tasks call the default _tick(). -local function addtaskWrite(tsk) - tsk.def_tick = _tickWrite - _tasks[tsk] = true +local function addtaskWrite(task) + task.def_tick = _tickWrite + _tasks[task] = true end local function tasks() @@ -823,7 +826,7 @@ local function _select(timeout) local now = gettime() - local r_evs, w__evs, err = selectsocket(_reading, _writing, timeout) + local r_evs, w_evs, err = selectsocket(_reading, _writing, timeout) _readable_t._evs = r_evs _writable_t._evs = w_evs @@ -888,7 +891,7 @@ local function copasstep(timeout) local nextwait = _sleeping:getnext() if nextwait then timeout = timeout and min(nextwait,timeout) or nextwait - elseif finished() then + elseif copasfinished() then return false end @@ -902,7 +905,7 @@ local function copasstep(timeout) for task in tasks() do for event in task:events() do - tsk:tick(event) + task:tick(event) end end return true @@ -921,10 +924,8 @@ function copas.loop(timeout) copas.running = false end -if logs then - _G.copas = copas - package.loaded.copas = copas - -- report("module (re)installed") -end +-- _G.copas = copas + +package.loaded.copas = copas return copas diff --git a/tex/context/base/mkiv/util-soc-imp-ltn12.lua b/tex/context/base/mkiv/util-soc-imp-ltn12.lua index 0a389896b..f94c9f04f 100644 --- a/tex/context/base/mkiv/util-soc-imp-ltn12.lua +++ b/tex/context/base/mkiv/util-soc-imp-ltn12.lua @@ -5,8 +5,11 @@ local select, unpack = select, unpack local insert, remove = table.insert, table.remove local sub = string.sub -local report = logs and logs.reporter("ltn12") or function(fmt,first,...) - if fmt then +local function report(fmt,first,...) + if logs then + report = logs and logs.reporter("ltn12") + report(fmt,first,...) + elseif fmt then fmt = "ltn12: " .. fmt if first then print(format(fmt,first,...)) @@ -379,10 +382,6 @@ function pump.all(src, snk, step) end end -if logs then - _G.ltn12 = ltn12 - package.loaded.ltn12 = ltn12 - -- report("module (re)installed") -end +package.loaded.ltn12 = ltn12 return ltn12 diff --git a/tex/context/base/mkiv/util-soc-imp-mime.lua b/tex/context/base/mkiv/util-soc-imp-mime.lua index b1a5827ac..aea205728 100644 --- a/tex/context/base/mkiv/util-soc-imp-mime.lua +++ b/tex/context/base/mkiv/util-soc-imp-mime.lua @@ -8,8 +8,11 @@ local ltn12 = ltn12 or require("ltn12") local filtercycle = ltn12.filter.cycle -local report = logs and logs.reporter("mime") or function(fmt,first,...) - if fmt then +local function report(fmt,first,...) + if logs then + report = logs and logs.reporter("mime") + report(fmt,first,...) + elseif fmt then fmt = "mime: " .. fmt if first then print(format(fmt,first,...)) @@ -96,10 +99,6 @@ mime.encode = choose(encodet) mime.decode = choose(decodet) mime.wrap = choose(wrapt) -if logs then - _G.mime = mime - package.loaded.mime = mime - -- report("module (re)installed") -end +package.loaded.mime = mime return mime diff --git a/tex/context/base/mkiv/util-soc-imp-socket.lua b/tex/context/base/mkiv/util-soc-imp-socket.lua index 0ad685d75..424b08e8f 100644 --- a/tex/context/base/mkiv/util-soc-imp-socket.lua +++ b/tex/context/base/mkiv/util-soc-imp-socket.lua @@ -12,8 +12,13 @@ local tcp4 = socket.tcp4 local tcp6 = socket.tcp6 local getaddrinfo = socket.dns.getaddrinfo -local report = logs and logs.reporter("socket") or function(fmt,first,...) - if fmt then +local defaulthost = "0.0.0.0" + +local function report(fmt,first,...) + if logs then + report = logs and logs.reporter("socket") + report(fmt,first,...) + elseif fmt then fmt = "socket: " .. fmt if first then print(format(fmt,first,...)) @@ -181,10 +186,8 @@ sourcet["default"] = sourcet["until-closed"] socket.source = socket.choose(sourcet) -if logs then - _G.socket = socket - package.loaded.socket = socket - -- report("module (re)installed") -end +_G.socket = socket -- for now global + +package.loaded.socket = socket return socket diff --git a/tex/context/base/mkiv/util-sql-imp-ffi.lua b/tex/context/base/mkiv/util-sql-imp-ffi.lua index e18736171..c4086d561 100644 --- a/tex/context/base/mkiv/util-sql-imp-ffi.lua +++ b/tex/context/base/mkiv/util-sql-imp-ffi.lua @@ -278,6 +278,7 @@ local function execute(t,query) if query and query ~= "" then local connection = t._connection_ local result = mysql_execute_query(connection,query,#query) +print(connection,result,query) if result == 0 then local result = mysql_store_result(connection) if result ~= NULL then @@ -331,6 +332,7 @@ local function open(t,database,username,password,host,port) local t = { _connection_ = connection, } +-- ffi_gc(connection, mysql_close) return setmetatable(t,mt) end end @@ -348,13 +350,14 @@ local mt = { connect = open, close = close, message = message, - } + }, } local function initialize() local session = { _session_ = mysql_initialize(instance) -- maybe share, single thread anyway } + -- ffi_gc(session, mysql_close) return setmetatable(session,mt) end @@ -457,10 +460,11 @@ local function datafetched(specification,query,converter) if type(r) == "table" then result = r okay = true - elseif not m then + elseif not m then okay = true end end + local data, keys if result then if converter then @@ -477,25 +481,13 @@ local function datafetched(specification,query,converter) report_state("message %s",message) end - if not result then -- can go - if session then - session:close() - end - if connection then - connection:close() - end - if id then - cache[id] = nil - end - return "execution error" - end - if not keys then keys = { } end if not data then data = { } end + if not id then if connection then connection:close() diff --git a/tex/context/base/mkiv/util-sql-logins.lua b/tex/context/base/mkiv/util-sql-logins.lua index 6773f91bf..c19bfbdf8 100644 --- a/tex/context/base/mkiv/util-sql-logins.lua +++ b/tex/context/base/mkiv/util-sql-logins.lua @@ -211,9 +211,10 @@ end logins.userpurge = userpurge local function verdict(okay,...) - if not trace_logins then - -- no tracing - elseif okay then +-- if not trace_logins then +-- -- no tracing +-- else + if okay then report_logins("%s, granted",formatter(...)) else report_logins("%s, blocked",formatter(...)) diff --git a/tex/context/base/mkiv/util-sql-users.lua b/tex/context/base/mkiv/util-sql-users.lua index 7204fb310..ee1f10b74 100644 --- a/tex/context/base/mkiv/util-sql-users.lua +++ b/tex/context/base/mkiv/util-sql-users.lua @@ -238,9 +238,7 @@ function users.valid(db,username,password,address) name = username, }, } - local data = data and data[1] - if not data then return false, "unknown user" elseif not data.enabled then diff --git a/tex/context/fonts/mkiv/type-imp-firacode.mkiv b/tex/context/fonts/mkiv/type-imp-firacode.mkiv new file mode 100644 index 000000000..a4cec3af5 --- /dev/null +++ b/tex/context/fonts/mkiv/type-imp-firacode.mkiv @@ -0,0 +1,54 @@ +%D \module +%D [ file=type-imp-firacode, +%D version=2018.08.24, +%D title=\CONTEXT\ Typescript Macros, +%D subtitle=Firacode, +%D author=Taco Hoekwater \& Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + + +\starttypescriptcollection[firacode] + + \usetypescriptfile[dejavu] + + \definefontfeature + [firacode] + [mode=node,script=dflt,language=dflt, + calt=yes,mark=yes,mkmk=yes] + + \starttypescript [\s!mono] [firacode] + \definefontsynonym[FiraRetina] [\s!name:firacoderetina] [\s!features=firacode] + \definefontsynonym[FiraLight] [\s!name:firacodelight] [\s!features=firacode] + \definefontsynonym[FiraRegular][\s!name:firacoderegular][\s!features=firacode] + \definefontsynonym[FiraMedium] [\s!name:firacodemedium] [\s!features=firacode] + \definefontsynonym[FiraBold] [\s!name:firacodebold] [\s!features=firacode] + \stoptypescript + + \starttypescript [\s!mono] [firacode-light] + \setups[\s!font:\s!fallback:\s!mono] + \definefontsynonym[\s!Mono] [FiraLight] + \definefontsynonym[\s!MonoBold][FiraMedium] + \stoptypescript + + \starttypescript [\s!mono] [firacode] + \setups[\s!font:\s!fallback:\s!mono] + \definefontsynonym[\s!Mono] [FiraRegular] + \definefontsynonym[\s!MonoBold][FiraBold] + \stoptypescript + + \starttypescript[firacode] + \definetypeface[firacode][\s!rm][\s!serif][dejavu] [\s!default] + \definetypeface[firacode][\s!ss][\s!sans] [dejavu] [\s!default] + \definetypeface[firacode][\s!mm][\s!math] [dejavu] [\s!default] + \definetypeface[firacode][\s!tt][\s!mono] [firacode][\s!default] + \stoptypescript + +\stoptypescriptcollection + +% \setupbodyfont[firacode,12pt] + diff --git a/tex/context/interface/mkiv/i-context.pdf b/tex/context/interface/mkiv/i-context.pdf Binary files differindex 481f716ed..41053bae2 100644 --- a/tex/context/interface/mkiv/i-context.pdf +++ b/tex/context/interface/mkiv/i-context.pdf diff --git a/tex/context/interface/mkiv/i-readme.pdf b/tex/context/interface/mkiv/i-readme.pdf Binary files differindex 9c5a5ec6f..9c3eb7259 100644 --- a/tex/context/interface/mkiv/i-readme.pdf +++ b/tex/context/interface/mkiv/i-readme.pdf diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index e29a8ab22..7e833e1b3 100644 --- a/tex/generic/context/luatex/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex/luatex-fonts-merged.lua @@ -1,6 +1,6 @@ -- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua -- parent file : c:/data/develop/context/sources/luatex-fonts.lua --- merge date : 08/21/18 08:33:57 +-- merge date : 08/24/18 19:18:34 do -- begin closure to overcome local limits and interference |