text:
helpText = """The following environmental variables can be defined for the SST compiler
SSTMAC_VERBOSE=0 or 1:        produce verbose output from the SST compiler (default 0)
SSTMAC_DELETE_TEMPS=0 or 1:   remove all temp source-to-source files (default 1)
SSTMAC_SRC2SRC=0 or 1: run a source-to-source pass converting globals to TLS (default 1)
"""

def argify(x):
  if ' ' in x:
    return "'%s'" % x
  else:
    return x

def delete(files):
  import os
  os.system("rm -f %s" % (" ".join(files)))

def swapSuffix(suffix, path):
  splitter = path.split(".")[:-1]
  splitter.append(suffix)
  return ".".join(splitter)

def addPrefix(prefix, path):
  import os
  splitPath = os.path.split(path)
  if len(splitPath) == 2:
    return os.path.join(splitPath[0], prefix + splitPath[1])
  else:
    return prefix + path

def addClangArg(a, ret):
  ret.append("--extra-arg=%s" % a)

def addClangArgs(argList, ret):
  for a in argList:
    addClangArg(a,ret)
  return ret

def runCmdArr(cmdArr,verbose):
  import sys,os
  if cmdArr:
    cmd = " ".join(cmdArr)
    if verbose: sys.stderr.write("%s\n" % cmd)
    return os.system(cmd)
  else:
    return 0

def run(typ, extraLibs="", includeMain=True, makeLibrary=False, redefineSymbols=True):
  extraLibsStr = extraLibs
  extraLibs = extraLibs.split()
  import os
  import sys
  from configlib import getstatusoutput
  from sstccvars import sstLdFlags, sstCppFlags
  from sstccvars import prefix, execPrefix, includeDir, cc, cxx
  from sstccvars import sstCxxFlagsStr, sstCFlagsStr
  from sstccvars import includeDir
  from sstccvars import sstCore
  from sstccvars import soFlagsStr
  from sstccvars import clangCppFlagsStr, clangLdFlagsStr
  from sstccvars import clangLibtoolingCxxFlagsStr, clangLibtoolingCFlagsStr

  def cleanFlag(flag):
    return flag.replace("${includedir}", includeDir).replace("${exec_prefix}", execPrefix).replace("${prefix}",prefix)

  sstLibs = []
  if not sstCore:
    sstLibs = [
      '-lsstmac',
      '-lsprockit',
      '-lundumpi',
    ]

  clangCppArgs = [
    cleanFlag("-I${includedir}/sstmac/clang_replacements"),
  ]
  clangCxxArgs = [
    "-std=c++1y",
    "-stdlib=libc++",
  ]
  clangCxxArgs.extend(clangLibtoolingCxxFlagsStr.strip().split())

  verbose = False
  delTempFiles = True
  if "SSTMAC_VERBOSE" in os.environ:
    flag = int(os.environ["SSTMAC_VERBOSE"])
    verbose = verbose or flag
  if "SSTMAC_DELETE_TEMPS" in os.environ:
    flag = int(os.environ["SSTMAC_DELETE_TEMPS"])
    delTempFiles = delTempFiles and flag

  haveClangSrcToSrc = bool(clangCppFlagsStr)
  clangDeglobal = None
  if haveClangSrcToSrc:
    clangDeglobal = os.path.join(prefix, "bin", "sstmac_clang_deglobal")

  newCppFlags = []
  for entry in sstCppFlags:
    newCppFlags.append(cleanFlag(entry))
  sstCppFlags = newCppFlags

  newLdFlags = []
  for entry in sstLdFlags:
    newLdFlags.append(cleanFlag(entry))
  for entry in sstLibs:
    newLdFlags.append(cleanFlag(entry))
  sstLdFlags = newLdFlags

  sstCppFlagsStr=" ".join(sstCppFlags)
  sstLdFlagsStr =  " ".join(sstLdFlags)
  ld = cc
  repldir = os.path.join(includeDir, "sstmac", "replacements")
  repldir = cleanFlag(repldir)

  sysargs = sys.argv[1:]

  asmFiles = False
  givenFlags = []
  controlArgs = []
  linkerArgs = []
  sourceFiles = []
  objectFiles = []
  optFlags = []
  objTarget = None
  ldTarget = None
  getObjTarget = False
  givenStdFlag = None
  for arg in sysargs:
    sarg = arg.strip().strip("'")
    #okay, well, the flags might have literal quotes in them
    #which get lost passing into here - restore all " to literal quotes
    sarg = sarg.replace("\"",r'\"')
    sarg = sarg.replace(" ", r'\ ')
    if sarg.endswith('.o'):
      objectFiles.append(sarg)
      if getObjTarget:
        objTarget = sarg
        getObjTarget=False
      else:
        cxxInitFile = addPrefix("sstGlobals.", sarg)
        if os.path.isfile(cxxInitFile):
          objectFiles.append(cxxInitFile)
    elif sarg.startswith("-Wl"):
      linkerArgs.append(sarg)
    elif sarg.startswith("-L"):
      linkerArgs.append(sarg)
    elif sarg.startswith("-l"):
      linkerArgs.append(sarg)
    elif sarg.startswith("-O"):
      givenFlags.append(sarg)
      optFlags.append(sarg)
    elif sarg == "-g":
      givenFlags.append(sarg)
      optFlags.append(sarg)
    elif "-std=" in sarg:
      givenStdFlag=sarg
    elif sarg.endswith('.cpp') or sarg.endswith('.cc') or sarg.endswith('.c') or sarg.endswith(".cxx"):
      sourceFiles.append(sarg)
    elif sarg.endswith('.S'):
      asmFiles = True
    elif sarg == "--verbose":
      verbose = True
    elif sarg in ("-c","-E"):
      controlArgs.append(sarg)
    elif sarg in ('-o',):
      getObjTarget=True
    elif getObjTarget:
      ldTarget = sarg
      getObjTarget=False
    else:
      givenFlags.append(sarg)

  exeFromSrc = sourceFiles and not objectFiles and not '-c' in sysargs

  if sstCore:
    givenFlags.append(" -DSSTMAC_EXTERNAL_SKELETON")

  if sourceFiles and len(objectFiles) > 1:
    sys.exit("Specified multiple object files for source compilation: %" % " ".join(objectFiles))

  directIncludes = []

  if type == "c++":
    directIncludes.append("-include cstdint")
  else:
    directIncludes.append("-include stdint.h")
  directIncludes.append("-include sstmac/compute.h")

  src2src = True
  if "SSTMAC_SRC2SRC" in os.environ:
    src2src = int(os.environ["SSTMAC_SRC2SRC"])

  if sys.argv[1] == "--version" or sys.argv[1] == "-V":
    import inspect, os
    pathStr = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
    print(pathStr)
    cmd = "%s %s" % (cxx, sys.argv[1])
    os.system(cmd)
    sys.exit()
  elif sys.argv[1] == "--flags":
    sys.stderr.write("LDFLAGS=%s\n" % sstLdFlagsStr)
    sys.stderr.write("CPPFLAGS=%s\n" % sstCppFlagsStr)
    sys.stderr.write("CXXFLAGS=%s\n" % sstCxxFlagsStr)
    sys.exit()
  elif sys.argv[1] == "--help":
    cmd = "%s --help" % (cxx)
    os.system(cmd)
    sys.stderr.write(helpText)
    sys.exit()

  sstCompilerFlagsStr = ""
  compiler = ""
  cxxCmd = ""
  if includeMain:
    extraLibsStr += " -lsstmac_main"
  #always c++ no matter what for now
  if typ.lower() == "c++":
    sstCompilerFlagsStr = cleanFlag(sstCxxFlagsStr)
    compiler = cxx
    ld = cxx
  elif typ.lower() == "c":
    sstCompilerFlagsStr = cleanFlag(sstCFlagsStr)
    compiler = cc
    ld = cxx #always use c++ for linking since we are bringing a bunch of sstmac C++ into the game

  sstCompilerFlags = []
  sstStdFlag = None
  for flag in sstCompilerFlagsStr.split():
    if "-std=" in flag:
      sstStdFlag = flag
    elif not flag.startswith("-O") and not flag == "-g":
      sstCompilerFlags.append(flag)
  sstCompilerFlagsStr = " ".join(sstCompilerFlags)

  sstCxxFlagsStr = cleanFlag(sstCxxFlagsStr)
  sstCxxFlags = []
  sstStdFlag = None
  for flag in sstCxxFlagsStr.split():
    if not flag.startswith("-O") and not flag == "-g":
      sstCxxFlags.append(flag)
    if "-std=" in flag:
      #don't automatically propagate the sst c++11 flag...
      sstStdFlag = flag
  sstCxxFlagsStr = " ".join(sstCxxFlags)

  sstCFlagsStr = cleanFlag(sstCFlagsStr)
  sstCFlags = []
  for flag in sstCFlagsStr.split():
    if not flag.startswith("-O") and not flag == "-g":
      sstCFlags.append(flag)
  sstCFlagsStr = " ".join(sstCFlags)

  objectFilesStr = " ".join(objectFiles)

  sstCompilerFlagsArr = sstCompilerFlagsStr.split()
  sstCompilerFlags = []
  for entry in sstCompilerFlagsArr:
    if entry[:2] == "-O": #do not send optimization flags forward
      pass
    elif entry == "-g": #do not send debug flags forward
      pass
    else:
      sstCompilerFlags.append(entry)
  sstCompilerFlagsStr = " ".join(sstCompilerFlags)

  #okay, figure out which -std flag to include in compilation
  #treat it as a given flag on the command line

  if typ == "c++":
    if sstStdFlag and givenStdFlag:
      #take whichever is greater
      if sstStdFlag > givenStdFlag:
        givenFlags.append(sstStdFlag)
      else:
        givenFlags.append(givenStdFlag)
    elif sstStdFlag:
      givenFlags.append(sstStdFlag)
    elif givenStdFlag:
      givenFlags.append(givenStdFlag)
    else:
      sys.stderr.write("no -std= flag obtained from SST - how did you compiled without C++11 or greater?")
      return 1

  directIncludesStr = " ".join(directIncludes)

  extraCppFlags = []
  if redefineSymbols:
    extraCppFlags = [
      "-I%s/include/sumi" % prefix,
      "-DSSTMAC=1",
      "-D__thread=thread_local_not_yet_allowed",
      "-Dthread_local=thread_local_not_yet_allowed",
    ]

  if asmFiles:
    extraCppFlags = [] #add nothing

  if "--no-integrated-cpp" in sysargs:
    extraCppFlags = [] #add nothing

  ldpathMaker = "-Wl,-rpath,%s/lib" % prefix

  if redefineSymbols:
    extraCppFlags.insert(0,"-I%s" % repldir)

  cxxCmdArr = []
  ldCmdArr = []
  arCmdArr = []
  ppOnly = "-E" in controlArgs
  runClang = haveClangSrcToSrc and src2src
  controlArgStr = " ".join(controlArgs)
  extraCppFlagsStr = " ".join(extraCppFlags)
  givenFlagsStr = " ".join(givenFlags)
  sourceFilesStr = " ".join(sourceFiles)
  #We need to separate specific flags
  srcFileStr = " ".join(sourceFiles)
  ppCmdArr = [
    compiler,
    "-include sstmac/skeleton.h",
    directIncludesStr,
    extraCppFlagsStr,
    givenFlagsStr,
    sstCppFlagsStr,
    sstCompilerFlagsStr,
    "-E"
  ]
  sourceFileCompileFlags = [
    sourceFilesStr,
    sstCppFlagsStr,
    extraCppFlagsStr,
    givenFlagsStr,
    sstCompilerFlagsStr
  ]
  if '-c' in sysargs or ppOnly:
    runClang = runClang and (not ppOnly)
    if runClang:
      #we run clang on a direct source file with no includes
      #only put cxxflags in the cmd arr for now
      cxxCmdArr = [
        compiler,
        sstCompilerFlagsStr,
        givenFlagsStr
      ]
    else:
      cxxCmdArr = [
        compiler,
        extraCppFlagsStr,
        givenFlagsStr,
        sstCppFlagsStr,
        sstCompilerFlagsStr,
        controlArgStr,
        srcFileStr
      ]
      if objTarget:
        folder, obj = os.path.split(objTarget)
        if folder:
          if not os.path.isdir(folder):
            try: os.makedirs(folder)
            except OSError: pass
        cxxCmdArr.append("-o")
        cxxCmdArr.append(objTarget)
    allCompilerFlags = sstCxxFlagsStr + sstCppFlagsStr + givenFlagsStr
    if not "fPIC" in allCompilerFlags:
      sys.stderr.write("Linker/dlopen will eventually fail on .so file: fPIC not in C/CXXFLAGS\n")
  elif objTarget and sourceFiles:
    cxxCmdArr = [
      compiler,
      extraCppFlagsStr,
      sstCppFlagsStr,
      givenFlagsStr,
      sstCompilerFlagsStr,
      givenFlagsStr,
      sourceFilesStr,
      sstLdflagsStr,
      extraLibsStr,
      ldpathMaker
    ]
  else:
    if not ldTarget: ldTarget = "a.out"
    #linking executable/lib from object files (or source files)
    runClang = runClang and sourceFiles

    if not sstCore:
      ldCmdArr = [
        ld,
        objectFilesStr,
        extraLibsStr,
        sstLdFlagsStr,
        givenFlagsStr,
        sstCompilerFlagsStr,
        extraLibsStr,
        ldpathMaker,
        "-o",
        ldTarget
      ]
      ldCmdArr.extend(linkerArgs)
      if sourceFiles and not runClang:
        ldCmdArr.extend(sourceFileCompileFlags)
    else:
      libTarget = ldTarget
      if not libTarget.endswith(".so"):
        libTarget += ".so"
      if not libTarget.startswith("lib"):
        libTarget = "lib" + libTarget

      arCmdArr = [
        ld,
        soFlagsStr,
        objectFilesStr,
        sstLdFlagsStr,
        givenFlagsStr,
        sstCompilerFlagsStr,
        ldpathMaker,
        "-o",
        libTarget
      ]
      if sourceFiles and not runClang:
        arCmdArr.extend(sourceFileCompileFlags)
      arCmdArr.extend(linkerArgs)

  clangExtraArgs = []
  if runClang:
    #this is more complicated - we have to use clang to do a source to source transformation
    #then we need to run the compiler on that modified source
    for srcFile in sourceFiles:
      ppTmpFile = addPrefix("pp.",srcFile)
      cmdArr = ppCmdArr[:]
      cmdArr.append(srcFile)
      cmdArr.append("> %s" % ppTmpFile)
      ppCmd = " ".join(cmdArr)
      if verbose: sys.stderr.write("%s\n" % ppCmd)
      rc = os.system(ppCmd)
      if not rc == 0:
        if delTempFiles:
          os.system("rm -f %s" % ppTmpFile)
        return rc

      srcRepl = addPrefix("sst.pp.",srcFile)
      cxxInitSrcFile = addPrefix("sstGlobals.pp.",srcFile) + ".cpp"

      clangCmdArr = [clangDeglobal]
      if typ == "c++":
        addClangArgs(clangCxxArgs, clangCmdArr)
        addClangArgs(clangLibtoolingCxxFlagsStr.split(), clangCmdArr)
      else:
        addClangArgs(clangLibtoolingCFlagsStr.split(), clangCmdArr)
      clangCmdArr.append(ppTmpFile)
      clangCmdArr.append("--")
      clangCmd = " ".join(clangCmdArr)
      if verbose: sys.stderr.write("%s\n" % clangCmd)
      rc = os.system(clangCmd)
      if not rc == 0:
        if delTempFiles:
          os.system("rm -f %s" % ppTmpFile)
          os.system("rm -f %s" % srcRepl)
          os.system("rm -f %s" % cxxInitSrcFile)
        return rc

      #the source to source generates temp .cc files
      #we need the compile command to generate .o files from the temp .cc files
      #update the command to point to them
      cmdArr = [
        compiler,
        extraCppFlagsStr,
        sstCppFlagsStr,
        sstCompilerFlagsStr,
        givenFlagsStr
      ]
      target = objTarget
      if not objTarget:
        srcName = os.path.split(srcFile)[-1]
        target = swapSuffix("o", srcName)
      cmdArr.append("-o")
      cmdArr.append(target)
      cmdArr.append("-c")
      cmdArr.append(srcRepl)
      cmdArr.append("--no-integrated-cpp")
      cxxCmd = " ".join(cmdArr)
      if verbose: sys.stderr.write("%s\n" % cxxCmd)
      rc = os.system(cxxCmd)
      if not rc == 0:
        if delTempFiles:
          os.system("rm -f %s" % ppTmpFile)
          os.system("rm -f %s" % srcRepl)
          os.system("rm -f %s" % target)
          os.system("rm -f %s" % cxxInitSrcFile)
        return rc

      #now we generate the .o file containing the CXX linkage
      #for global variable CXX init - because C is stupid
      cxxInitObjFile = addPrefix("sstGlobals.",target)
      cxxInitCmdArr = [
        cxx,
        sstCxxFlagsStr,
        sstCppFlagsStr,
        "-o",
        cxxInitObjFile,
        "-I%s/include" % prefix,
        "-c",
        cxxInitSrcFile
      ]
      cxxInitCompileCmd = " ".join(cxxInitCmdArr)
      if verbose: sys.stderr.write("%s\n" % cxxInitCompileCmd)
      rc = os.system(cxxInitCompileCmd)
      if delTempFiles:
        os.system("rm -f %s %s %s" % (ppTmpFile, cxxInitSrcFile, srcRepl))
      if not rc == 0:
        return rc

    #some generate multiple .o files at once, I don't know why
    manyObjects = objTarget == None #no specific target specified
    mergeCmdArr = [compiler]
    mergeCmdArr.append("-Wl,-r -nostdlib")
    allObjects = []
    for srcFile in sourceFiles:
      srcFileNoSuffix = ".".join(srcFile.split(".")[:-1])
      cxxInitObjFile = addPrefix("sstGlobals.", swapSuffix("o",srcFile))
      if exeFromSrc:
        if objTarget:
          allObjects.append(objTarget)
        else:
          allObjects.append(swapSuffix("o", srcFile))
        allObjects.append(cxxInitObjFile)

    if exeFromSrc:
      if ldCmdArr:
        ldCmdArr.extend(allObjects)
        rc = runCmdArr(ldCmdArr,verbose)
        if not rc == 0: return rc
      if arCmdArr:
        arCmdArr.extend(allObjects)
        rc = runCmdArr(arCmdArr,verbose)
        if not rc == 0: return rc
      if delTempFiles:
        delete(allObjects)
    return 0

  else:
    rc = runCmdArr(cxxCmdArr,verbose)
    if not rc == 0: return rc
    rc = runCmdArr(ldCmdArr,verbose)
    if not rc == 0: return rc
    rc = runCmdArr(arCmdArr,verbose)
    return rc


text:
namespace Simple.Http.CodeGeneration
{
    using System;

    internal static class TypeEx
    {
        internal static bool IsNullable(this Type type)
        {
            return type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>);
        }
    }
}

redpajama_set_name: RedPajamaGithub


text:
describe('PathnameRouter', function() {
  it('should reflect prefix in handler', function() {
    var PREFIX = '/hello';
    var router = foam.net.node.PathnameRouter.create();
    var handler = router.addPathnamePrefix(
        PREFIX, foam.net.node.PathnamePrefixHandler.create());
    expect(handler.pathnamePrefix).toBe(PREFIX);
  });

  it('should compose over routers', function() {
    var PREFIX1 = '/hello';
    var PREFIX2 = '/world';
    var router1 = foam.net.node.PathnameRouter.create();
    var router2 = router1.addPathnamePrefix(
        PREFIX1, foam.net.node.PathnameRouter.create());
    var handler = router2.addPathnamePrefix(
        PREFIX2, foam.net.node.PathnamePrefixHandler.create());
    expect(handler.pathnamePrefix).toBe(`${PREFIX1}${PREFIX2}`);
  });
});


text:
require "spec_helper"
require "chef/mixin/path_sanity"

describe Chef::Mixin::ShellOut do
  include Chef::Mixin::PathSanity

  let(:shell_out_class) { Class.new { include Chef::Mixin::ShellOut } }
  subject(:shell_out_obj) { shell_out_class.new }

  def env_path
    if Chef::Platform.windows?
      "Path"
    else
      "PATH"
    end
  end

  context "when testing individual methods" do
    before(:each) do
      @original_env = ENV.to_hash
      ENV.clear
    end

    after(:each) do
      ENV.clear
      ENV.update(@original_env)
    end

    let(:retobj) { instance_double(Mixlib::ShellOut, "error!" => false) }
    let(:cmd) { "echo '#{rand(1000)}'" }

    [ :shell_out, :shell_out! ].each do |method|
      describe "##{method}" do

        describe "when the last argument is a Hash" do
          describe "and environment is an option" do
            it "should not change environment language settings when they are set to nil" do
              options = { environment: { "LC_ALL" => nil, "LANGUAGE" => nil, "LANG" => nil, env_path => nil } }
              expect(Chef::Mixin::ShellOut).to receive(:shell_out_command).with(cmd, options).and_return(retobj)
              shell_out_obj.send(method, cmd, options)
            end

            it "should not change environment language settings when they are set to non-nil" do
              options = { environment: { "LC_ALL" => "en_US.UTF-8", "LANGUAGE" => "en_US.UTF-8", "LANG" => "en_US.UTF-8", env_path => "foo:bar:baz" } }
              expect(Chef::Mixin::ShellOut).to receive(:shell_out_command).with(cmd, options).and_return(retobj)
              shell_out_obj.send(method, cmd, options)
            end

            it "should set environment language settings to the configured internal locale when they are not present" do
              options = { environment: { "HOME" => "/Users/morty" } }
              expect(Chef::Mixin::ShellOut).to receive(:shell_out_command).with(cmd, {
                environment: {
                  "HOME"     => "/Users/morty",
                  "LC_ALL"   => Chef::Config[:internal_locale],
                  "LANG"     => Chef::Config[:internal_locale],
                  "LANGUAGE" => Chef::Config[:internal_locale],
                  env_path   => sanitized_path,
                },
              }).and_return(retobj)
              shell_out_obj.send(method, cmd, options)
            end

            it "should not mutate the options hash when it adds language settings" do
              options = { environment: { "HOME" => "/Users/morty" } }
              expect(Chef::Mixin::ShellOut).to receive(:shell_out_command).with(cmd, {
                environment: {
                  "HOME"     => "/Users/morty",
                  "LC_ALL"   => Chef::Config[:internal_locale],
                  "LANG"     => Chef::Config[:internal_locale],
                  "LANGUAGE" => Chef::Config[:internal_locale],
                  env_path   => sanitized_path,
                },
              }).and_return(retobj)
              shell_out_obj.send(method, cmd, options)
              expect(options[:environment].key?("LC_ALL")).to be false
            end
          end

          describe "and env is an option" do
            it "should not change env when langauge options are set to nil" do
              options = { env: { "LC_ALL" => nil, "LANG" => nil, "LANGUAGE" => nil, env_path => nil } }
              expect(Chef::Mixin::ShellOut).to receive(:shell_out_command).with(cmd, options).and_return(retobj)
              shell_out_obj.send(method, cmd, options)
            end

            it "should not change env when language options are set to non-nil" do
              options = { env: { "LC_ALL" => "de_DE.UTF-8", "LANG" => "de_DE.UTF-8", "LANGUAGE" => "de_DE.UTF-8", env_path => "foo:bar:baz" } }
              expect(Chef::Mixin::ShellOut).to receive(:shell_out_command).with(cmd, options).and_return(retobj)
              shell_out_obj.send(method, cmd, options)
            end

            it "should set environment language settings to the configured internal locale when they are not present" do
              options = { env: { "HOME" => "/Users/morty" } }
              expect(Chef::Mixin::ShellOut).to receive(:shell_out_command).with(cmd, {
                env: {
                  "HOME"     => "/Users/morty",
                  "LC_ALL"   => Chef::Config[:internal_locale],
                  "LANG"     => Chef::Config[:internal_locale],
                  "LANGUAGE" => Chef::Config[:internal_locale],
                  env_path   => sanitized_path,
                },
              }).and_return(retobj)
              shell_out_obj.send(method, cmd, options)
            end

            it "should not mutate the options hash when it adds language settings" do
              options = { env: { "HOME" => "/Users/morty" } }
              expect(Chef::Mixin::ShellOut).to receive(:shell_out_command).with(cmd, {
                env: {
                  "HOME"     => "/Users/morty",
                  "LC_ALL"   => Chef::Config[:internal_locale],
                  "LANG"     => Chef::Config[:internal_locale],
                  "LANGUAGE" => Chef::Config[:internal_locale],
                  env_path   => sanitized_path,
                },
              }).and_return(retobj)
              shell_out_obj.send(method, cmd, options)
              expect(options[:env].key?("LC_ALL")).to be false
            end
          end

          describe "and no env/environment option is present" do
            it "should set environment language settings to the configured internal locale" do
              options = { user: "morty" }
              expect(Chef::Mixin::ShellOut).to receive(:shell_out_command).with(cmd, {
                user: "morty",
                environment: {
                  "LC_ALL"   => Chef::Config[:internal_locale],
                  "LANG"     => Chef::Config[:internal_locale],
                  "LANGUAGE" => Chef::Config[:internal_locale],
                  env_path   => sanitized_path,
                },
              }).and_return(retobj)
              shell_out_obj.send(method, cmd, options)
            end
          end
        end

        describe "when the last argument is not a Hash" do
          it "should set environment language settings to the configured internal locale" do
            expect(Chef::Mixin::ShellOut).to receive(:shell_out_command).with(cmd, {
              environment: {
                "LC_ALL"   => Chef::Config[:internal_locale],
                "LANG"     => Chef::Config[:internal_locale],
                "LANGUAGE" => Chef::Config[:internal_locale],
                env_path   => sanitized_path,
              },
            }).and_return(retobj)
            shell_out_obj.send(method, cmd)
          end
        end
      end
    end

    describe "#shell_out default_env: false" do

      describe "when the last argument is a Hash" do
        describe "and environment is an option" do
          it "should not change environment['LC_ALL'] when set to nil" do
            options = { environment: { "LC_ALL" => nil } }
            expect(Chef::Mixin::ShellOut).to receive(:shell_out_command).with(cmd, options).and_return(true)
            shell_out_obj.shell_out(cmd, **options, default_env: false)
          end

          it "should not change environment['LC_ALL'] when set to non-nil" do
            options = { environment: { "LC_ALL" => "en_US.UTF-8" } }
            expect(Chef::Mixin::ShellOut).to receive(:shell_out_command).with(cmd, options).and_return(true)
            shell_out_obj.shell_out(cmd, **options, default_env: false)
          end

          it "should no longer set environment['LC_ALL'] to nil when 'LC_ALL' not present" do
            options = { environment: { "HOME" => "/Users/morty" } }
            expect(Chef::Mixin::ShellOut).to receive(:shell_out_command).with(cmd, options).and_return(true)
            shell_out_obj.shell_out(cmd, **options, default_env: false)
          end
        end

        describe "and env is an option" do
          it "should not change env when set to nil" do
            options = { env: { "LC_ALL" => nil } }
            expect(Chef::Mixin::ShellOut).to receive(:shell_out_command).with(cmd, options).and_return(true)
            shell_out_obj.shell_out(cmd, **options, default_env: false)
          end

          it "should not change env when set to non-nil" do
            options = { env: { "LC_ALL" => "en_US.UTF-8" } }
            expect(Chef::Mixin::ShellOut).to receive(:shell_out_command).with(cmd, options).and_return(true)
            shell_out_obj.shell_out(cmd, **options, default_env: false)
          end

          it "should no longer set env['LC_ALL'] to nil when 'LC_ALL' not present" do
            options = { env: { "HOME" => "/Users/morty" } }
            expect(Chef::Mixin::ShellOut).to receive(:shell_out_command).with(cmd, options).and_return(true)
            shell_out_obj.shell_out(cmd, **options, default_env: false)
          end
        end

        describe "and no env/environment option is present" do
          it "should no longer add environment option and set environment['LC_ALL'] to nil" do
            options = { user: "morty" }
            expect(Chef::Mixin::ShellOut).to receive(:shell_out_command).with(cmd, options).and_return(true)
            shell_out_obj.shell_out(cmd, **options, default_env: false)
          end
        end
      end

      describe "when the last argument is not a Hash" do
        it "should no longer add environment options and set environment['LC_ALL'] to nil" do
          expect(Chef::Mixin::ShellOut).to receive(:shell_out_command).with(cmd).and_return(true)
          shell_out_obj.shell_out(cmd, default_env: false)
        end
      end
    end

    describe "Custom Resource timeouts" do
      class CustomResource < Chef::Resource
        provides :whatever

        property :timeout, Numeric

        action :install do
        end
      end

      let(:new_resource) { CustomResource.new("foo") }
      let(:provider) { new_resource.provider_for_action(:install) }

      describe "on Chef-15", chef: ">= 15" do
        [ :shell_out, :shell_out! ].each do |method|
          stubbed_method = (method == :shell_out) ? :shell_out_compacted : :shell_out_compacted!
          it "#{method} defaults to 900 seconds" do
            expect(provider).to receive(stubbed_method).with("foo", timeout: 900)
            provider.send(method, "foo")
          end
          it "#{method} overrides the default timeout with its options" do
            expect(provider).to receive(stubbed_method).with("foo", timeout: 1)
            provider.send(method, "foo", timeout: 1)
          end
          it "#{method} overrides the new_resource.timeout with the timeout option" do
            new_resource.timeout(99)
            expect(provider).to receive(stubbed_method).with("foo", timeout: 1)
            provider.send(method, "foo", timeout: 1)
          end
          it "#{method} defaults to 900 seconds and preserves options" do
            expect(provider).to receive(stubbed_method).with("foo", env: nil, timeout: 900)
            provider.send(method, "foo", env: nil)
          end
          it "#{method} overrides the default timeout with its options and preserves options" do
            expect(provider).to receive(stubbed_method).with("foo", timeout: 1, env: nil)
            provider.send(method, "foo", timeout: 1, env: nil)
          end
          it "#{method} overrides the new_resource.timeout with the timeout option and preseves options" do
            new_resource.timeout(99)
            expect(provider).to receive(stubbed_method).with("foo", timeout: 1, env: nil)
            provider.send(method, "foo", timeout: 1, env: nil)
          end
        end
      end
    end

    describe "timeouts" do
      let(:new_resource) { Chef::Resource::Package.new("foo") }
      let(:provider) { new_resource.provider_for_action(:install) }

      [ :shell_out, :shell_out! ].each do |method|
        stubbed_method = (method == :shell_out) ? :shell_out_compacted : :shell_out_compacted!
        it "#{method} defaults to 900 seconds" do
          expect(provider).to receive(stubbed_method).with("foo", timeout: 900)
          provider.send(method, "foo")
        end
        it "#{method} overrides the default timeout with its options" do
          expect(provider).to receive(stubbed_method).with("foo", timeout: 1)
          provider.send(method, "foo", timeout: 1)
        end
        it "#{method} overrides the new_resource.timeout with the timeout option" do
          new_resource.timeout(99)
          expect(provider).to receive(stubbed_method).with("foo", timeout: 1)
          provider.send(method, "foo", timeout: 1)
        end
        it "#{method} defaults to 900 seconds and preserves options" do
          expect(provider).to receive(stubbed_method).with("foo", env: nil, timeout: 900)
          provider.send(method, "foo", env: nil)
        end
        it "#{method} overrides the default timeout with its options and preserves options" do
          expect(provider).to receive(stubbed_method).with("foo", timeout: 1, env: nil)
          provider.send(method, "foo", timeout: 1, env: nil)
        end
        it "#{method} overrides the new_resource.timeout with the timeout option and preseves options" do
          new_resource.timeout(99)
          expect(provider).to receive(stubbed_method).with("foo", timeout: 1, env: nil)
          provider.send(method, "foo", timeout: 1, env: nil)
        end
      end
    end
  end
end


text:
package org.optaplanner.core.impl.score.stream.bavet.tri;

import java.math.BigDecimal;
import java.util.List;
import java.util.function.Consumer;

import org.optaplanner.core.api.function.QuadFunction;
import org.optaplanner.core.api.function.ToIntTriFunction;
import org.optaplanner.core.api.function.ToLongTriFunction;
import org.optaplanner.core.api.function.TriFunction;
import org.optaplanner.core.api.score.Score;
import org.optaplanner.core.api.score.stream.tri.TriConstraintStream;
import org.optaplanner.core.impl.score.inliner.BigDecimalWeightedScoreImpacter;
import org.optaplanner.core.impl.score.inliner.IntWeightedScoreImpacter;
import org.optaplanner.core.impl.score.inliner.LongWeightedScoreImpacter;
import org.optaplanner.core.impl.score.inliner.ScoreInliner;
import org.optaplanner.core.impl.score.inliner.UndoScoreImpacter;
import org.optaplanner.core.impl.score.inliner.WeightedScoreImpacter;
import org.optaplanner.core.impl.score.stream.bavet.BavetConstraint;
import org.optaplanner.core.impl.score.stream.bavet.BavetConstraintFactory;
import org.optaplanner.core.impl.score.stream.bavet.common.BavetNodeBuildPolicy;
import org.optaplanner.core.impl.score.stream.bavet.uni.BavetFromUniConstraintStream;

public final class BavetScoringTriConstraintStream<Solution_, A, B, C>
        extends BavetAbstractTriConstraintStream<Solution_, A, B, C> {

    private final BavetAbstractTriConstraintStream<Solution_, A, B, C> parent;
    private final BavetConstraint<Solution_> constraint;
    private final boolean noMatchWeigher;
    private final ToIntTriFunction<A, B, C> intMatchWeigher;
    private final ToLongTriFunction<A, B, C> longMatchWeigher;
    private final TriFunction<A, B, C, BigDecimal> bigDecimalMatchWeigher;

    public BavetScoringTriConstraintStream(BavetConstraintFactory<Solution_> constraintFactory,
            BavetAbstractTriConstraintStream<Solution_, A, B, C> parent,
            BavetConstraint<Solution_> constraint) {
        this(constraintFactory, parent, constraint, true, null, null, null);
    }

    public BavetScoringTriConstraintStream(BavetConstraintFactory<Solution_> constraintFactory,
            BavetAbstractTriConstraintStream<Solution_, A, B, C> parent,
            BavetConstraint<Solution_> constraint, ToIntTriFunction<A, B, C> intMatchWeigher) {
        this(constraintFactory, parent, constraint, false, intMatchWeigher, null, null);
        if (intMatchWeigher == null) {
            throw new IllegalArgumentException("The matchWeigher (null) cannot be null.");
        }
    }

    public BavetScoringTriConstraintStream(BavetConstraintFactory<Solution_> constraintFactory,
            BavetAbstractTriConstraintStream<Solution_, A, B, C> parent,
            BavetConstraint<Solution_> constraint, ToLongTriFunction<A, B, C> longMatchWeigher) {
        this(constraintFactory, parent, constraint, false, null, longMatchWeigher, null);
        if (longMatchWeigher == null) {
            throw new IllegalArgumentException("The matchWeigher (null) cannot be null.");
        }
    }

    public BavetScoringTriConstraintStream(BavetConstraintFactory<Solution_> constraintFactory,
            BavetAbstractTriConstraintStream<Solution_, A, B, C> parent,
            BavetConstraint<Solution_> constraint, TriFunction<A, B, C, BigDecimal> bigDecimalMatchWeigher) {
        this(constraintFactory, parent, constraint, false, null, null, bigDecimalMatchWeigher);
        if (bigDecimalMatchWeigher == null) {
            throw new IllegalArgumentException("The matchWeigher (null) cannot be null.");
        }
    }

    private BavetScoringTriConstraintStream(BavetConstraintFactory<Solution_> constraintFactory,
            BavetAbstractTriConstraintStream<Solution_, A, B, C> parent,
            BavetConstraint<Solution_> constraint, boolean noMatchWeigher,
            ToIntTriFunction<A, B, C> intMatchWeigher, ToLongTriFunction<A, B, C> longMatchWeigher,
            TriFunction<A, B, C, BigDecimal> bigDecimalMatchWeigher) {
        super(constraintFactory);
        this.parent = parent;
        this.constraint = constraint;
        this.noMatchWeigher = noMatchWeigher;
        this.intMatchWeigher = intMatchWeigher;
        this.longMatchWeigher = longMatchWeigher;
        this.bigDecimalMatchWeigher = bigDecimalMatchWeigher;
    }

    @Override
    public List<BavetFromUniConstraintStream<Solution_, Object>> getFromStreamList() {
        return parent.getFromStreamList();
    }

    // ************************************************************************
    // Node creation
    // ************************************************************************

    @Override
    protected BavetScoringTriNode<A, B, C> createNode(BavetNodeBuildPolicy<Solution_> buildPolicy,
            Score<?> constraintWeight, int nodeOrder, BavetAbstractTriNode<A, B, C> parentNode) {
        ScoreInliner scoreInliner = buildPolicy.getSession().getScoreInliner();
        WeightedScoreImpacter weightedScoreImpacter = scoreInliner.buildWeightedScoreImpacter(constraintWeight);
        QuadFunction<A, B, C, Consumer<Score<?>>, UndoScoreImpacter> scoreImpacter;
        if (weightedScoreImpacter instanceof IntWeightedScoreImpacter) {
            IntWeightedScoreImpacter castedWeightedScoreImpacter = (IntWeightedScoreImpacter) weightedScoreImpacter;
            if (intMatchWeigher != null) {
                scoreImpacter = (A a, B b, C c, Consumer<Score<?>> matchScoreConsumer) -> {
                    int matchWeight = intMatchWeigher.applyAsInt(a, b, c);
                    constraint.assertCorrectImpact(matchWeight);
                    return castedWeightedScoreImpacter.impactScore(matchWeight, matchScoreConsumer);
                };
            } else if (noMatchWeigher) {
                scoreImpacter = (A a, B b, C c, Consumer<Score<?>> matchScoreConsumer) -> castedWeightedScoreImpacter
                        .impactScore(1, matchScoreConsumer);
            } else {
                throw new IllegalStateException("The matchWeigher of " + TriConstraintStream.class.getSimpleName()
                        + ".penalize(matchWeigher) of the constraint (" + constraint.getConstraintId()
                        + ") must return an int.");
            }
        } else if (weightedScoreImpacter instanceof LongWeightedScoreImpacter) {
            LongWeightedScoreImpacter castedWeightedScoreImpacter = (LongWeightedScoreImpacter) weightedScoreImpacter;
            if (longMatchWeigher != null) {
                scoreImpacter = (A a, B b, C c, Consumer<Score<?>> matchScoreConsumer) -> {
                    long matchWeight = longMatchWeigher.applyAsLong(a, b, c);
                    constraint.assertCorrectImpact(matchWeight);
                    return castedWeightedScoreImpacter.impactScore(matchWeight, matchScoreConsumer);
                };
            } else if (noMatchWeigher) {
                scoreImpacter = (A a, B b, C c, Consumer<Score<?>> matchScoreConsumer) -> castedWeightedScoreImpacter
                        .impactScore(1L, matchScoreConsumer);
            } else {
                throw new IllegalStateException("The matchWeigher of " + TriConstraintStream.class.getSimpleName()
                        + ".penalize(matchWeigher) of the constraint (" + constraint.getConstraintId()
                        + ") must return a long.");
            }
        } else if (weightedScoreImpacter instanceof BigDecimalWeightedScoreImpacter) {
            BigDecimalWeightedScoreImpacter castedWeightedScoreImpacter =
                    (BigDecimalWeightedScoreImpacter) weightedScoreImpacter;
            if (bigDecimalMatchWeigher != null) {
                scoreImpacter = (A a, B b, C c, Consumer<Score<?>> matchScoreConsumer) -> {
                    BigDecimal matchWeight = bigDecimalMatchWeigher.apply(a, b, c);
                    constraint.assertCorrectImpact(matchWeight);
                    return castedWeightedScoreImpacter.impactScore(matchWeight, matchScoreConsumer);
                };
            } else if (noMatchWeigher) {
                scoreImpacter = (A a, B b, C c, Consumer<Score<?>> matchScoreConsumer) -> castedWeightedScoreImpacter
                        .impactScore(BigDecimal.ONE, matchScoreConsumer);
            } else {
                throw new IllegalStateException("The matchWeigher of " + TriConstraintStream.class.getSimpleName()
                        + ".penalize(matchWeigher) of the constraint (" + constraint.getConstraintId()
                        + ") must return a " + BigDecimal.class.getSimpleName() + ".");
            }
        } else {
            throw new IllegalStateException("Unsupported weightedScoreImpacter (" + weightedScoreImpacter + ").");
        }
        BavetScoringTriNode<A, B, C> node = new BavetScoringTriNode<>(buildPolicy.getSession(), nodeOrder,
                constraint.getConstraintPackage(), constraint.getConstraintName(),
                constraintWeight, scoreImpacter);
        buildPolicy.addScoringNode(node);
        return node;
    }

    @Override
    protected void createChildNodeChains(BavetNodeBuildPolicy<Solution_> buildPolicy, Score<?> constraintWeight, int nodeOrder,
            BavetAbstractTriNode<A, B, C> node) {
        if (!childStreamList.isEmpty()) {
            throw new IllegalStateException("Impossible state: the stream (" + this
                    + ") has an non-empty childStreamList (" + childStreamList + ") but it's an endpoint.");
        }
    }

    @Override
    public String toString() {
        return "Scoring()";
    }

    // ************************************************************************
    // Getters/setters
    // ************************************************************************

}


text:
require 'torch'
require 'nn'
require 'image'
require 'optim'
require 'lfs'
require 'io'

--------------------------------------------------------------------------------

local cmd = torch.CmdLine()

-- Basic options
cmd:option('-train_dir', 'train/')
cmd:option('-test_dir', 'test/')
cmd:option('-test_template', 'test_template.csv')
cmd:option('-train_labels', 'train_labels.csv')
cmd:option('-content_size', 224, 'Size for content')
cmd:option('-style_size', 400, 'Size for style')
cmd:option('-gpu', 0, 'Zero-indexed ID of the GPU to use; for CPU mode set -gpu = -1')
cmd:option('-input_file', '')

-- Output options
cmd:option('-output_file', 'network.data')
cmd:option('-output_labels', 'test_results.csv')

-- Other options
cmd:option('-step_size', 1e-10)
cmd:option('-style_scale', 1.0)
cmd:option('-dropout', 0.5)
cmd:option('-num_strides', 1)
cmd:option('-save_iter', 2000)
cmd:option('-start_iter', 1)
cmd:option('-batch_size', 5)
cmd:option('-max_num_images', 45000)
cmd:option('-pooling', 'max', 'max|avg')
cmd:option('-model_file', 'content.data')
cmd:option('-backend', 'nn', 'nn|cudnn|clnn')
cmd:option('-seed', -1)
cmd:option('-print_memory', false)
cmd:option('-flip', false)

cmd:option('-content_layer', 37, 'layer to learn from') -- pool5
cmd:option('-style_layers', '2,7', 'layers for style') -- relu1_1, relu2_1

function nn.SpatialConvolutionMM:accGradParameters()
   -- nop.  not needed by our net
end

local function main(params)
   if params.gpu >= 0 then
      if params.backend ~= 'clnn' then
	 require 'cutorch'
	 require 'cunn'
	 cutorch.setDevice(params.gpu + 1)
      else
	 require 'clnn'
	 require 'cltorch'
	 cltorch.setDevice(params.gpu + 1)
      end
   else
      params.backend = 'nn'
   end

   if params.backend == 'cudnn' then
      require 'cudnn'
      if params.cudnn_autotune then
	 cudnn.benchmark = true
      end
      cudnn.SpatialConvolution.accGradParameters = nn.SpatialConvolutionMM.accGradParameters -- ie: nop
   end

   if params.seed >= 0 then
      torch.manualSeed(params.seed)
   end

   print('loadbasenet')
   local obj = torch.load(params.model_file)
   local cnn = obj.net:get(1)
   cnn:clearState()
   obj = nil

   print('loadlabels')
   -- load labels
   local flabels = assert(io.open(params.train_labels, "r"))
   local images = {}
   local fake_test = {}
   local i0 = 0
   while true do
      local line = flabels:read('*line')
      if line == nil or i0>100000 then
	 break
      end
      i0 = i0+1
      local parts = line:split('\n')[1]:split(';')
      if #parts == 2 and parts[1] ~= 'ID' then
	 parts[1] = params.train_dir..parts[1]..'.jpg'
	 parts[2] = tonumber(parts[2])
	 if #images >= params.max_num_images then
	    table.insert(fake_test, parts)
	 else
	    table.insert(images, parts)
	 end
      end
   end
   print("Training set: ", #images, #fake_test)
   flabels:close()

   print('loadtest')
   -- load test template
   flabels = assert(io.open(params.test_template, "r"))
   local test_images = {}
   i0 = 0
   while true do
      local line = flabels:read('*line')
      if line == nil or i0>100000 then
	 break
      end
      i0 = i0+1
      local parts = line:split('\n')[1]:split(';')
      if #parts == 2 and parts[1] ~= 'ID' then
	 table.insert(test_images, tonumber(parts[1]))
      end
   end
   print("Testing set: ", #test_images)
   flabels:close()

   -- Set up the network, inserting style descriptor modules

   local style_layers = params.style_layers:split(",")

   local qualitynet = nil
   if params.input_file ~= '' then
      print('loading network')
      obj = torch.load(params.input_file)
      qualitynet = obj.net
      obj = nil
   end

   print('reading caffe')
   local style_descrs = {}
   local content_descr = nil
   local next_style_idx = 1
   local style_net = nn.Sequential()
   local content_net = nn.Sequential()
   local content_net2 = nil
   if qualitynet == nil then
      content_net2 = nn.Sequential()
   end
   local content_tocome = true
   print(#cnn)
   for i = 1, #cnn do
      if content_tocome or next_style_idx <= #style_layers then
	 local layer = cnn:get(i)
	 local name = layer.name
	 print(i)
	 local layer_type = torch.type(layer)
	 if next_style_idx <= #style_layers then
	    style_net:add(layer)
	    content_net:add(layer)
	 elseif content_tocome then
	    content_net2:add(layer)
	 end
	 if i == params.content_layer then
	    print("Setting up content layer  ", i, ":", layer.name)
	    content_tocome = false
	 end
	 if i == tonumber(style_layers[next_style_idx]) then
	    print("Setting up style layer  ", i, ":", layer.name)
	    local nlayer = nn.StyleDescr(false)
	    if params.backend ~= 'clnn' then
		nlayer:cuda()
	    else
		nlayer:cl()
	    end
	    style_net:add(nlayer)
	    table.insert(style_descrs, nlayer)
	    next_style_idx = next_style_idx + 1
	 end
      end
   end

   -- We don't need the base CNN anymore, so clean it up to save memory.
   cnn = nil
   for i=1, #content_net.modules do
      local module = content_net.modules[i]
      if torch.type(module) == 'nn.SpatialConvolutionMM' then
	 -- remove these, not used, but uses gpu memory
	 module.gradWeight = nil
	 module.gradBias = nil
      end
   end

   collectgarbage()

   local img_size = params.image_size
   local criterion = nn.MSECriterion()

   if qualitynet == nil then
      local img = image.load(images[1][1], 3)
      local res = computeFeatures(params, style_net, style_descrs, content_net, img)
      qualitynet = buildNet(params, res, content_net2)
   else
      for i=1, #qualitynet.modules do
         local module = qualitynet.modules[i]
         if torch.type(module) == 'nn.Dropout' then
             module:setp(params.dropout)
         end
      end
   end

   local target = torch.Tensor(1)
   if params.backend ~= 'clnn' then
      target = target:cuda()
      criterion:cuda()
   else
      target = target:cl()
      criterion:cuda()
   end
   local offset = 1
   local totcount = 0
   local trainorder = torch.randperm(#images)
   local x, dl_dx
   x, dl_dx = qualitynet:getParameters()

   local feval = function(x_new)
       -- copy the weight if are changed
       collectgarbage()
       if x ~= x_new then
           x:copy(x_new)
       end

       if offset > #images then
          trainorder = torch.randperm(#images)
	  offset = 1
       end

       local indices = trainorder[offset]
       local fname = images[indices][1]
       local iscore = images[indices][2]

       local img = image.load(fname, 3)
       if params.flip and math.random(2) == 1 then
	  img = image.hflip(img)
       end
       target[1] = iscore
       offset = offset + 1
       dl_dx:zero()

       -- evaluate the loss function and its derivative with respect to x
       local features = computeFeatures(params, style_net, style_descrs, content_net, img)

       local prediction = qualitynet:forward(features)

       print('prediction', math.ceil(prediction[1]), 'objective',  target[1])

       if params.print_memory then
	  local freeMemory, totalMemory = cutorch.getMemoryUsage(params.gpu+1)
	  print('Memory: ', freeMemory/1024/1024, 'MB free of ', totalMemory/1024/1024)
       end

       local loss_x = criterion:forward(prediction, target)

       qualitynet:backward(features, criterion:backward(prediction, target))

       if params.print_memory then
	  local freeMemory, totalMemory = cutorch.getMemoryUsage(params.gpu+1)
	  print('Memory: ', freeMemory/1024/1024, 'MB free of ', totalMemory/1024/1024)
       end

       return loss_x, dl_dx
   end

   print('learning')
   local optim_params = {learningRate = params.step_size}
   local niter = 1
   local toterror = 0
   local errors = {}
   while totcount <= #images * params.num_strides do
      _, fs = optim.adam(feval, x, optim_params)

      print('Iteration '..niter, '                       error:', math.floor(fs[1]+0.5))
      toterror = toterror + fs[1]
      totcount = totcount + 1

      if niter % params.save_iter == 0 then
	 print(errors)
	 print('Total error', toterror/params.save_iter)
	 table.insert(errors, toterror/params.save_iter)
	 toterror = 0
	 qualitynet:clearState()
         torch.save(params.output_file, {net=qualitynet})
      end
      niter = niter + 1
   end
   if params.num_strides > 0 then
      qualitynet:clearState()
      torch.save(params.output_file, {net=qualitynet})
   end

   print('now testing')
   local fout = io.open('local_tests.csv', 'w')
   fout:write('ID,result,expected')
   if qualitynet~= nil then
      qualitynet:evaluate()
      for i=1, #qualitynet.modules do
         local module = qualitynet.modules[i]
         if torch.type(module) == 'nn.Dropout' or torch.type(module) == 'nn.Dropout2' then
             module:setp(0)
         end
      end
   end
   local toterror =0
   local output = torch.Tensor(1)
   output = output:cuda()
   for i=1, #fake_test do
      print('processing image '..i..': '..fake_test[i][1])
      collectgarbage()
      if params.print_memory then
	 local freeMemory, totalMemory = cutorch.getMemoryUsage(params.gpu+1)
	 print('Memory: ', freeMemory/1024/1024, 'MB free of ', totalMemory/1024/1024)
      end
      local nimg = fake_test[i][1]
      local img = image.load(nimg, 3)

      if img then
	 local features = computeFeatures(params, style_net, style_descrs, content_net, img)
         local prediction = qualitynet:forward(features)
	 output[1] = fake_test[i][2]
         criterion:forward(prediction, output)
	 print('Note:', math.floor(prediction[1]+0.5), 'expected:', output[1], 'error:', math.floor(criterion.output+0.5))
	 toterror = toterror + criterion.output
	 fout:write('\n'..nimg..','..math.min(100, math.max(0, math.floor(prediction[1]+0.5)))..','..output[1])
      end
   end
   fout:close()
   print('\n\n\nExpected score:', toterror/(#fake_test), '\n\n\n')

   fout = io.open(params.output_labels, 'w')
   fout:write('ID;aesthetic_score')
   for i=1, #test_images do
      print('processing image '..i..': '..test_images[i])
      collectgarbage()
      local nimg = test_images[i]
      local fname = string.format('%s%07d.jpg', params.test_dir, nimg)
      local img = image.load(fname, 3)

      if img then
	 local features = computeFeatures(params, style_net, style_descrs, content_net, img)
         local prediction = qualitynet:forward(features)
	 print(nimg, prediction[1])
	 fout:write('\r'..nimg..';'..math.min(100, math.max(0, math.floor(prediction[1]+0.5))))
      end
   end
   fout:close()
end

function shuffle(t)
   for i = #t, 2, -1 do
      local j = math.random(i)
      t[i], t[j] = t[j], t[i]
   end
end

function buildNet(params, res, content_net2)
   local qualitynet = nn.Sequential()
   -- Style
   local pstyle = nn.ParallelTable()
   local nEl = 0
   for i = 1, #(res[1]) do
      local j = nn.Sequential()
      local sz = res[1][i]:size(1)
      j:add(nn.View(sz*sz))
      nEl = nEl + sz*sz
      pstyle:add(j)
   end
   print(nEl)
   local lstyle = nn.Sequential()
   lstyle:add(pstyle)
   lstyle:add(nn.JoinTable(1, 1))
   lstyle:add(nn.Linear(nEl, 512))
   -- Content
   local lcontent = nn.Sequential()
   local res2b = content_net2:forward(res[2])
   lcontent:add(content_net2)
   lcontent:add(nn.View(res2b:nElement()))
   lcontent:add(nn.Linear(res2b:nElement(), 1024))
   -- Merge
   local merg = nn.ParallelTable()
   merg:add(lstyle)
   merg:add(lcontent)
   qualitynet:add(merg)
   qualitynet:add(nn.JoinTable(1, 1))
   -- Quality Network
   qualitynet:add(nn.ReLU())
   qualitynet:add(nn.Dropout(params.dropout))
   qualitynet:add(nn.Linear(1536, 1024))
   qualitynet:add(nn.ReLU())
   qualitynet:add(nn.Dropout(params.dropout))
   qualitynet:add(nn.Linear(1024, 512))
   qualitynet:add(nn.ReLU())
   qualitynet:add(nn.Dropout(params.dropout))
   qualitynet:add(nn.Linear(512, 64))
   qualitynet:add(nn.Dropout2(params.dropout))
   qualitynet:add(nn.Max(1))
   if params.gpu >= 0 then
      if params.backend ~= 'clnn' then
          qualitynet:cuda()
      else
          qualitynet:cl()
      end
   end
   return qualitynet
end

function computeFeatures(params, style_net, style_descrs, content_net, imag)
   -- style features
   local imgs
   local im = image.scale(imag, params.style_size, 'bilinear')
   imgs = preprocess(im):float()
   if params.gpu >= 0 then
      if params.backend ~= 'clnn' then
	imgs = imgs:cuda()
      else
	imgs = imgs:cl()
      end
   end
   if params.print_memory then
      local freeMemory, totalMemory = cutorch.getMemoryUsage(params.gpu+1)
      print('Memory: ', freeMemory/1024/1024, 'MB free of ', totalMemory/1024/1024)
   end
   style_net:forward(imgs)
   local res1 = {}
   for j, mod in ipairs(style_descrs) do
      table.insert(res1, mod.G)
   end
   -- content features
   im = image.scale(imag, params.content_size, params.content_size, 'bilinear')
   imgs = preprocess(im):float()
   if params.gpu >= 0 then
      if params.backend ~= 'clnn' then
	imgs = imgs:cuda()
      else
	imgs = imgs:cl()
      end
   end
   local res2 = content_net:forward(imgs)

   return {res1, res2}
end

-- Preprocess an image before passing it to a Caffe model.
-- We need to rescale from [0, 1] to [0, 255], convert from RGB to BGR,
-- and subtract the mean pixel.
function preprocess(img)
   local mean_pixel = torch.DoubleTensor({103.939, 116.779, 123.68})
   local perm = torch.LongTensor{3, 2, 1}
   img = img:index(1, perm):mul(256.0)
   mean_pixel = mean_pixel:view(3, 1, 1):expandAs(img)
   img:add(-1, mean_pixel)
   return img
end

-- Returns a network that computes the CxC Gram matrix from inputs
-- of size C x H x W
function GramMatrix(batchSize)
  local net = nn.Sequential()
  net:add(nn.View(-1):setNumInputDims(2))
--  net:add(nn.Normalize(2))
  local concat = nn.ConcatTable()
  concat:add(nn.Identity())
  concat:add(nn.Identity())
  net:add(concat)
  net:add(nn.MM(false, true))
  return net
end

-- Define an nn Module to compute style description (Gram Matrix) in-place
local StyleDescr, parent = torch.class('nn.StyleDescr', 'nn.Module')

function StyleDescr:__init(cgrad)
   parent.__init(self)
   self.strength = 1
   self.cgrad = cgrad or false

   self.gram = GramMatrix()
   self.G = nil
end

function StyleDescr:updateOutput(input)
   self.G = torch.triu(self.gram:forward(input))
   self.G:div(input:nElement())

   self.output = input
   return self.output
end

function StyleDescr:updateGradInput(input, gradOutput)
  if not self.cgrad then
    self.gradInput = self.gradOutput
    return self.gradInput
  end
  self.gradInput = self.gram:backward(input, gradOutput)
  self.gradInput:div(input:nElement())
  self.gradInput:mul(self.strength)
  return self.gradInput
end

local Dropout2, Parent = torch.class('nn.Dropout2', 'nn.Dropout')

function Dropout2:__init(p,v1,inplace)
   Parent.__init(self,p,v1,inplace)
end

function Dropout2:updateOutput(input)
   if self.inplace then
      self.output = input
   else
      self.output:resizeAs(input):copy(input)
   end
   if self.p > 0 then
      if self.train then
         self.noise:resizeAs(input)
         self.noise:bernoulli(1-self.p)
         self.output:cmul(self.noise)
      end
   end
   return self.output
end

function Dropout2:updateGradInput(input, gradOutput)
   if self.train then
      if self.inplace then
         self.gradInput = gradOutput
      else
         self.gradInput:resizeAs(gradOutput):copy(gradOutput)
      end
      if self.p > 0 then
         self.gradInput:cmul(self.noise) -- simply mask the gradients with the noise vector
      end
   else
      if self.inplace then
         self.gradInput = gradOutput
      else
         self.gradInput:resizeAs(gradOutput):copy(gradOutput)
      end
   end
   return self.gradInput
end

local params = cmd:parse(arg)
main(params)


text:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="70dp"
    android:orientation="horizontal"
    android:gravity="center_vertical"
    android:background="#ffffff"
    >
    <com.miaotu.view.CircleImageView
        android:id="@+id/iv_head_photo"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        android:layout_marginTop="15dp"
        android:layout_marginBottom="15dp"
        android:src="@drawable/chat_image_selector"
        app:border_color="#f1f3f6"
        app:border_width="0dp"
        />
    <TextView
        android:id="@+id/tv_username"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="14sp"
        android:text="54545454"
        />
</LinearLayout>


text:
package org.piccolo2d.extras.pswing;

import java.awt.Rectangle;
import java.awt.geom.Rectangle2D;
import java.io.Serializable;
import java.util.Vector;

import javax.swing.ComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.plaf.basic.BasicComboBoxUI;
import javax.swing.plaf.basic.BasicComboPopup;
import javax.swing.plaf.basic.ComboPopup;

/**
 * The PComboBox is used instead of a JComboBox in a Piccolo scene graph.
 * This PComboBox won't work properly if it is located in an abnormal hierarchy
 * of Cameras. Support is provided for only one (or zero) view transforms.
 *

 * A ComboBox for use in Piccolo. This still has an associated JPopupMenu (which
 * is always potentially heavyweight depending on component location relative to
 * containing window borders.) However, this ComboBox places the PopupMenu
 * component of the ComboBox in the appropriate position relative to the
 * permanent part of the ComboBox. The PopupMenu is never transformed.
 *

 *

 * This class was not designed for subclassing. If different behavior is
 * required, it seems more appropriate to subclass JComboBox directly using this
 * class as a model.
 *

 *

 * NOTE: There is currently a known bug, namely, if the ComboBox receives focus
 * through 'tab' focus traversal and the keyboard is used to interact with the
 * ComboBox, there may be unexpected results.
 *

 *

 * Warning: Serialized objects of this class will not be compatible with
 * future Piccolo releases. The current serialization support is appropriate for
 * short term storage or RMI between applications running the same version of
 * Piccolo. A future release of Piccolo will provide support for long term
 * persistence.
 *

 *
 * @author Lance Good
 */
public class PComboBox extends JComboBox implements Serializable {

    /**
     *
     */
    private static final long serialVersionUID = 1L;
    private PSwing pSwing;
    private PSwingCanvas canvas;

    /**
     * Creates a PComboBox that takes its items from an existing ComboBoxModel.
     *
     * @param model The ComboBoxModel from which the list will be created
     */
    public PComboBox(final ComboBoxModel model) {
        super(model);
        init();
    }

    /**
     * Creates a PComboBox that contains the elements in the specified array.
     *
     * @param items The items to populate the PComboBox list
     */
    public PComboBox(final Object[] items) {
        super(items);
        init();
    }

    /**
     * Creates a PComboBox that contains the elements in the specified Vector.
     *
     * @param items The items to populate the PComboBox list
     */
    public PComboBox(final Vector items) {
        super(items);
        init();
    }

    /**
     * Create an empty PComboBox.
     */
    public PComboBox() {
        super();
        init();
    }

    /**
     * Substitute our UI for the default.
     */
    private void init() {
        setUI(new PBasicComboBoxUI());
    }

    /**
     * Clients must set the PSwing and PSwingCanvas environment for this
     * PComboBox to work properly.
     *
     * @param pSwingNode node that this PComboBox is attached to
     * @param canvasEnvirnoment canvas on which the pSwing node is embedded
     */
    public void setEnvironment(final PSwing pSwingNode, final PSwingCanvas canvasEnvirnoment) {
        this.pSwing = pSwingNode;
        this.canvas = canvasEnvirnoment;
    }

    /**
     * The substitute look and feel - used to capture the mouse events on the
     * arrowButton and the component itself and to create our PopupMenu rather
     * than the default.
     */
    protected class PBasicComboBoxUI extends BasicComboBoxUI {

        /**
         * Create our Popup instead of swing's default.
         *
         * @return a new ComboPopup
         */
        protected ComboPopup createPopup() {
            final PBasicComboPopup popup = new PBasicComboPopup(comboBox);
            popup.getAccessibleContext().setAccessibleParent(comboBox);
            return popup;
        }
    }

    /**
     * The substitute ComboPopupMenu that places itself correctly in Piccolo2d.
     */
    protected class PBasicComboPopup extends BasicComboPopup {
        private static final long serialVersionUID = 1L;

        /**
         * Creates a PBasicComboPopup that will position itself correctly in
         * relation to the provided JComboBox.
         *
         * @param combo The associated ComboBox
         */
        public PBasicComboPopup(final JComboBox combo) {
            super(combo);
        }

        /**
         * Computes the bounds for the Popup in Piccolo2D if a PMouseEvent has
         * been received. Otherwise, it uses the default algorithm for placing
         * the popup.
         *
         * @param px corresponds to the x coordinate of the popup
         * @param py corresponds to the y coordinate of the popup
         * @param pw corresponds to the width of the popup
         * @param ph corresponds to the height of the popup
         * @return The bounds for the PopupMenu
         */
        protected Rectangle computePopupBounds(final int px, final int py, final int pw, final int ph) {
            final Rectangle2D r = getNodeBoundsInCanvas();
            final Rectangle sup = super.computePopupBounds(px, py, pw, ph);
            return new Rectangle((int) r.getX(), (int) r.getMaxY(), (int) sup.getWidth(), (int) sup.getHeight());
        }
    }

    private Rectangle2D getNodeBoundsInCanvas() {
        if (pSwing == null || canvas == null) {
            throw new RuntimeException(
                    "PComboBox.setEnvironment( swing, pCanvas );//has to be done manually at present");
        }
        Rectangle2D r1c = new Rectangle2D.Double(pSwing.getX(), pSwing.getY(), getWidth(), getHeight());
        pSwing.localToGlobal(r1c);
        canvas.getCamera().globalToLocal(r1c);
        r1c = canvas.getCamera().getViewTransform().createTransformedShape(r1c).getBounds2D();
        return r1c;
    }

    /**
     * Returns the associated PSwing node.
     *
     * @return associated PSwing node
     */
    public PSwing getPSwing() {
        return pSwing;
    }

    /**
     * Returns the canvas on which the PSwing node is embedded.
     *
     * @return canvas on which the PSwing node is embedded
     */
    public PSwingCanvas getCanvas() {
        return canvas;
    }

}


text:
package com.datastax.oss.driver.internal.core.loadbalancing.nodeset;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;

import com.datastax.oss.driver.api.core.metadata.Node;
import org.junit.Test;

public class DcAgnosticNodeSetTest {

  @Test
  public void should_add_node() {
    DcAgnosticNodeSet set = new DcAgnosticNodeSet();
    Node node = mock(Node.class);
    assertThat(set.add(node)).isTrue();
    assertThat(set.add(node)).isFalse();
  }

  @Test
  public void should_remove_node() {
    DcAgnosticNodeSet set = new DcAgnosticNodeSet();
    Node node = mock(Node.class);
    set.add(node);
    assertThat(set.remove(node)).isTrue();
    assertThat(set.remove(node)).isFalse();
  }

  @Test
  public void should_return_all_nodes() {
    DcAgnosticNodeSet set = new DcAgnosticNodeSet();
    Node node1 = mock(Node.class);
    set.add(node1);
    Node node2 = mock(Node.class);
    set.add(node2);
    assertThat(set.dc(null)).contains(node1, node2);
    assertThat(set.dc("irrelevant")).contains(node1, node2);
  }

  @Test
  public void should_return_empty_dcs() {
    DcAgnosticNodeSet set = new DcAgnosticNodeSet();
    assertThat(set.dcs()).isEmpty();
  }
}


text:
@javax.xml.bind.annotation.XmlSchema(namespace = "http://rest.immobilienscout24.de/schema/customer/1.0", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package de.immobilienscout24.rest.schema.customer._1;


text:
import React from 'react'
import Head from 'next/head'
import Link from 'next/link'
import NProgress from 'nprogress'
import Router from 'next/router'

Router.onRouteChangeStart = (url) => {
  console.log(`Loading: ${url}`)
  NProgress.start()
  NProgress.set(0.3)
}
Router.onRouteChangeComplete = () => NProgress.done()
Router.onRouteChangeError = () => NProgress.done()

const linkStyle = {
  margin: '0 10px 0 0'
}

export default () => (
  <div style={{ marginBottom: 20 }}>
    <style jsx global>{`
      #nprogress {
        pointer-events: none;
      }

      #nprogress .bar {
        background: #29d;

        position: fixed;
        z-index: 1031;
        top: 0;
        left: 0;

        width: 100%;
        height: 5px;
      }

      /* Fancy blur effect */
      #nprogress .peg {
        display: block;
        position: absolute;
        right: 0px;
        width: 100px;
        height: 100%;
        box-shadow: 0 0 10px #fff, 0 0 5px #29d;
        opacity: 1.0;

        -webkit-transform: rotate(3deg) translate(0px, -4px);
            -ms-transform: rotate(3deg) translate(0px, -4px);
                transform: rotate(3deg) translate(0px, -4px);
      }

      /* Remove these to get rid of the spinner */
      #nprogress .spinner {
        display: block;
        position: fixed;
        z-index: 1031;
        top: 15px;
        right: 15px;
      }

      #nprogress .spinner-icon {
        width: 18px;
        height: 18px;
        box-sizing: border-box;

        border: solid 2px transparent;
        border-top-color: #29d;
        border-left-color: #29d;
        border-radius: 50%;

        -webkit-animation: nprogress-spinner 400ms linear infinite;
                animation: nprogress-spinner 400ms linear infinite;
      }

      .nprogress-custom-parent {
        overflow: hidden;
        position: relative;
      }

      .nprogress-custom-parent #nprogress .spinner,
      .nprogress-custom-parent #nprogress .bar {
        position: absolute;
      }

      @-webkit-keyframes nprogress-spinner {
        0%   { -webkit-transform: rotate(0deg); }
        100% { -webkit-transform: rotate(360deg); }
      }
      @keyframes nprogress-spinner {
        0%   { transform: rotate(0deg); }
        100% { transform: rotate(360deg); }
      }
    `}</style>
  </div>
)


text:
package example.myapplication.ui.widget;

import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.LinearLayout;
import android.widget.TextView;

import example.myapplication.R;
import example.myapplication.bo.Contact;

/**
 * Created by david on 10/31/16.
 */

public class ContactView extends LinearLayout {

    public ContactView(Context context) {
        super(context);
        init(context);
    }

    public ContactView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public ContactView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    private void init(Context context) {
        setOrientation(VERTICAL);
        setBackgroundResource(R.drawable.contact_view_background);
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.contact_core, this, true);
    }

    public void setContact(Contact contact) {
        TextView name = (TextView) findViewById(R.id.name);
        TextView email = (TextView) findViewById(R.id.email);
        TextView phone = (TextView) findViewById(R.id.phone);

        name.setText(contact.getFullName());
        email.setText(getContext().getString(R.string.email, contact.getEmail()));
        phone.setText(getContext().getString(R.string.phone, contact.getPhone()));
    }

}


text:
'use strict';

var express = require('express');
var app = express();

app.use(express.static('app'));

app.get('/', function(req, res) {
    res.sendfile('./app/index.html');
});

app.listen(5001);


text:
package com.github.rodionovsasha.cache.strategies;

import org.junit.Test;

import static org.junit.Assert.assertEquals;

public class StrategyTypeTest {
    @Test
    public void shouldGetCorrectValuesFromEnumTest() {
        assertEquals(StrategyType.LFU, StrategyType.valueOf("LFU"));
        assertEquals(StrategyType.LRU, StrategyType.valueOf("LRU"));
        assertEquals(StrategyType.MRU, StrategyType.valueOf("MRU"));
    }

    @Test(expected = IllegalArgumentException.class)
    public void shouldThrowExceptionWhenTypeIsNotCorrectTest() {
        StrategyType.valueOf("wrong_value");
    }
}


text:
package blog.common;

import java.util.*;

/**
 * An unmodifiable Set that is backed by a Multiset. The elements in the set are
 * the distinct elements of the multiset.
 */
public class MultisetBackedSet extends AbstractSet {
	/**
	 * Creates a new MultisetBackedSet backed by the given multiset.
	 */
	public MultisetBackedSet(Multiset s) {
		underlying = s;
	}

	/**
	 * Returns the size of this set, which is the number of distinct elements in
	 * the underlying multiset.
	 */
	public int size() {
		return underlying.entrySet().size();
	}

	/**
	 * Returns true if this set contains the given element, that is, if the
	 * underlying multiset contains at least one occurrence of that element.
	 */
	public boolean contains(Object o) {
		return underlying.contains(o);
	}

	/**
	 * Returns an iterator over the elements of this set. This is like calling
	 * entrySet().iterator() on the underlying multiset, except that the objects
	 * returned by the iterator are the elements themselves, not Multiset.Entry
	 * objects.
	 */
	public Iterator iterator() {
		return new WrappingIterator();
	}

	private class WrappingIterator implements Iterator {
		public boolean hasNext() {
			return entryIter.hasNext();
		}

		public Object next() {
			return ((Multiset.Entry) entryIter.next()).getElement();
		}

		public void remove() {
			throw new UnsupportedOperationException();
		}

		private Iterator entryIter = underlying.entrySet().iterator();
	}

	private Multiset underlying;
}


text:
=head1 NAME

Mail::SpamAssassin::Plugin::AccessDB - check message against Access Database

=head1 SYNOPSIS

  loadplugin     Mail::SpamAssassin::Plugin::AccessDB

  header   ACCESSDB  eval:check_access_database('/etc/mail/access.db')
  describe ACCESSDB  Message would have been caught by accessdb
  tflags   ACCESSDB  userconf
  score    ACCESSDB  2

=head1 DESCRIPTION

Many MTAs support access databases, such as Sendmail, Postfix, etc.
This plugin does similar checks to see whether a message would have
been flagged.

The rule returns false if an entry isn't found, or the entry has a RHS of
I<OK> or I<SKIP>.

The rule returns true if an entry exists and has a RHS of I<REJECT>, I<ERROR>,
or I<DISCARD>.

Note: only the first word (split on non-word characters) of the RHS
is checked, so C<error:5.7.1:...> means C<ERROR>.

B<AccessDB Pointers:>

  http://www.faqs.org/docs/securing/chap22sec178.html
  http://www.postfix.org/access.5.html

=cut

package Mail::SpamAssassin::Plugin::AccessDB;

use Mail::SpamAssassin::Plugin;
use Mail::SpamAssassin::Logger;
use Fcntl;
use strict;
use warnings;
use bytes;
use re 'taint';

use vars qw(@ISA);
@ISA = qw(Mail::SpamAssassin::Plugin);

use constant HAS_DB_FILE => eval { require DB_File; };

sub new {
  my $class = shift;
  my $mailsaobject = shift;

  $class = ref($class) || $class;
  my $self = $class->SUPER::new($mailsaobject);
  bless ($self, $class);

  $self->register_eval_rule("check_access_database");

  return $self;
}

sub check_access_database {
  my ($self, $pms, $path) = @_;

  if (!HAS_DB_FILE) {
    return 0;
  }

  my %access;
  my %ok = map { $_ => 1 } qw/ OK SKIP /;
  my %bad = map { $_ => 1 } qw/ REJECT ERROR DISCARD /;

  $path = $self->{main}->sed_path ($path);
  dbg("accessdb: tie-ing to DB file R/O in $path");
  if (tie %access,"DB_File",$path, O_RDONLY) {
    my @lookfor;

    # Look for "From:" versions as well!
    foreach my $from ($pms->all_from_addrs()) {
      # $user."\@"
      # rotate through $domain and check
      my ($user,$domain) = split(/\@/, $from,2);
      push(@lookfor, "From:$from",$from);
      if ($user) {
        push(@lookfor, "From:$user\@", "$user\@");
      }
      if ($domain) {
        while ($domain =~ /\./) {
          push(@lookfor, "From:$domain", $domain);
          $domain =~ s/^[^.]*\.//;
        }
        push(@lookfor, "From:$domain", $domain);
      }
    }

    # we can only match this if we have at least 1 untrusted header
    if ($pms->{num_relays_untrusted} > 0) {
      my $lastunt = $pms->{relays_untrusted}->[0];

      # If there was a reverse lookup, use it in a lookup
      if (! $lastunt->{no_reverse_dns}) {
        my $rdns = $lastunt->{lc_rdns};
        while($rdns =~ /\./) {
          push(@lookfor, "From:$rdns", $rdns);
          $rdns =~ s/^[^.]*\.//;
        }
        push(@lookfor, "From:$rdns", $rdns);
      }

      # do both IP and net (rotate over IP)
      my ($ip) = $lastunt->{ip};
      $ip =~ tr/0-9.//cd;
      while($ip =~ /\./) {
        push(@lookfor, "From:$ip", $ip);
	$ip =~ s/\.[^.]*$//;
      }
      push(@lookfor, "From:$ip", $ip);
    }

    my $retval = 0;
    my %cache;
    foreach (@lookfor) {
      next if ($cache{$_}++);
      dbg("accessdb: looking for $_");

      # Some systems put a null at the end of the key, most don't...
      my $result = $access{$_} || $access{"$_\000"} || next;

      my ($type) = split(/\W/,$result);
      $type = uc $type;

      if (exists $ok{$type}) {
	dbg("accessdb: hit OK: $type, $_");
        $retval = 0;
	last;
      }
      if (exists $bad{$type} || $type =~ /^\d+$/) {
        $retval = 1;
	dbg("accessdb: hit not-OK: $type, $_");
      }
    }

    dbg("accessdb: untie-ing DB file $path");
    untie %access;

    return $retval;
  }
  else {
    dbg("accessdb: cannot open accessdb $path R/O: $!");
  }

  return 0;
}

1;


text:
// Generated from BasicCalculator.g4 by ANTLR 4.5.1

package com.acme.calculator.antlr4;

import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.tree.ErrorNode;
import org.antlr.v4.runtime.tree.TerminalNode;

/**
 * This class provides an empty implementation of {@link BasicCalculatorListener},
 * which can be extended to create a listener which only needs to handle a subset
 * of the available methods.
 */
public class BasicCalculatorBaseListener implements BasicCalculatorListener {
	/**
	 * {@inheritDoc}
	 *
	 *
The default implementation does nothing.

	 */
	@Override public void enterCalc(BasicCalculatorParser.CalcContext ctx) { }
	/**
	 * {@inheritDoc}
	 *
	 *
The default implementation does nothing.

	 */
	@Override public void exitCalc(BasicCalculatorParser.CalcContext ctx) { }
	/**
	 * {@inheritDoc}
	 *
	 *
The default implementation does nothing.

	 */
	@Override public void enterExpr(BasicCalculatorParser.ExprContext ctx) { }
	/**
	 * {@inheritDoc}
	 *
	 *
The default implementation does nothing.

	 */
	@Override public void exitExpr(BasicCalculatorParser.ExprContext ctx) { }
	/**
	 * {@inheritDoc}
	 *
	 *
The default implementation does nothing.

	 */
	@Override public void enterAssignment(BasicCalculatorParser.AssignmentContext ctx) { }
	/**
	 * {@inheritDoc}
	 *
	 *
The default implementation does nothing.

	 */
	@Override public void exitAssignment(BasicCalculatorParser.AssignmentContext ctx) { }
	/**
	 * {@inheritDoc}
	 *
	 *
The default implementation does nothing.

	 */
	@Override public void enterFunction(BasicCalculatorParser.FunctionContext ctx) { }
	/**
	 * {@inheritDoc}
	 *
	 *
The default implementation does nothing.

	 */
	@Override public void exitFunction(BasicCalculatorParser.FunctionContext ctx) { }

	/**
	 * {@inheritDoc}
	 *
	 *
The default implementation does nothing.

	 */
	@Override public void enterEveryRule(ParserRuleContext ctx) { }
	/**
	 * {@inheritDoc}
	 *
	 *
The default implementation does nothing.

	 */
	@Override public void exitEveryRule(ParserRuleContext ctx) { }
	/**
	 * {@inheritDoc}
	 *
	 *
The default implementation does nothing.

	 */
	@Override public void visitTerminal(TerminalNode node) { }
	/**
	 * {@inheritDoc}
	 *
	 *
The default implementation does nothing.

	 */
	@Override public void visitErrorNode(ErrorNode node) { }
}


text:
var App = function (ctx) {
  var examples = Examples.map(function (example) {
    return ScriptRunner(ctx, {example: example});
  })
  return [
    {tag:'h1', render:'Verse'},
    {tag:'div', render: examples}
  ]
}


text:
360° Slider is a UI Component Concept which enables a subject/product to be spun 360° and to be viewed at predetermined "hotspot angles"

View an interactive sample at www.derekknox.com/lab/360slider/.

![Image](assets/images/360-slider-example.png)

## *Notes

This project is a simple rich prototype and could easily be culled from to create a more flexible/dynamic solution (utilize SVG vs. .png, make it a jQuery plugin, % based CSS, etc.). I just wanted to create a quick rich prototype that had some appeal to get a better feel of the interaction/behavior. Feel free to take it to the next level.

## License

	The MIT License (MIT)

	Copyright (c) 2014 Derek Knox | Braindrop Labs

	Permission is hereby granted, free of charge, to any person obtaining a copy
	of this software and associated documentation files (the "Software"), to deal
	in the Software without restriction, including without limitation the rights
	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
	copies of the Software, and to permit persons to whom the Software is
	furnished to do so, subject to the following conditions:

	The above copyright notice and this permission notice shall be included in all
	copies or substantial portions of the Software.

	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
	SOFTWARE.

## Designed and Developed By
Derek Knox | Braindrop Labs

[@derekknox](https://twitter.com/derekknox)


text:
import { Lang } from '../../../../../resources/languages';
import NetRegexes from '../../../../../resources/netregexes';
import { UnreachableCode } from '../../../../../resources/not_reached';
import Outputs from '../../../../../resources/outputs';
import ZoneId from '../../../../../resources/zone_id';
import { OopsyData } from '../../../../../types/data';
import { NetMatches } from '../../../../../types/net_matches';
import { OopsyTriggerSet } from '../../../../../types/oopsy';
import { LocaleText } from '../../../../../types/trigger';
import { playerDamageFields } from '../../../oopsy_common';

export interface Data extends OopsyData {
  decOffset?: number;
  laserNameToNum?: { [name: string]: number };
  sculptureTetherNameToId?: { [name: string]: string };
  sculptureYPositions?: { [sculptureId: string]: number };
  bladeOfFlameCount?: number;
  pillarIdToOwner?: { [pillarId: string]: string };
  smallLionIdToOwner?: { [pillarId: string]: string };
  smallLionOwners?: string[];
  northBigLion?: string;
  fire?: { [name: string]: boolean };
}

// TODO: add separate damageWarn-esque icon for damage downs?
// TODO: 58A6 Under The Weight / 58B2 Classical Sculpture missing somebody in party warning?
// TODO: 58CA Dark Water III / 58C5 Shell Crusher should hit everyone in party
// TODO: Dark Aero III 58D4 should not be a share except on advanced relativity for double aero.
// (for gains effect, single aero = ~23 seconds, double aero = ~31 seconds duration)

// Due to changes introduced in patch 5.2, overhead markers now have a random offset
// added to their ID. This offset currently appears to be set per instance, so
// we can determine what it is from the first overhead marker we see.
// The first 1B marker in the encounter is the formless tankbuster, ID 004F.
const firstHeadmarker = parseInt('00DA', 16);
const getHeadmarkerId = (data: Data, matches: NetMatches['HeadMarker']) => {
  // If we naively just check !data.decOffset and leave it, it breaks if the first marker is 00DA.
  // (This makes the offset 0, and !0 is true.)
  if (typeof data.decOffset === 'undefined')
    data.decOffset = parseInt(matches.id, 16) - firstHeadmarker;
  // The leading zeroes are stripped when converting back to string, so we re-add them here.
  // Fortunately, we don't have to worry about whether or not this is robust,
  // since we know all the IDs that will be present in the encounter.
  return (parseInt(matches.id, 16) - data.decOffset).toString(16).toUpperCase().padStart(4, '0');
};

const triggerSet: OopsyTriggerSet<Data> = {
  zoneId: ZoneId.EdensPromiseEternitySavage,
  damageWarn: {
    'E12S Promise Rapturous Reach Left': '58AD', // Haircut with left safe side
    'E12S Promise Rapturous Reach Right': '58AE', // Haircut with right safe side
    'E12S Promise Temporary Current': '4E44', // Levi get under cast (damage down)
    'E12S Promise Conflag Strike': '4E45', // Ifrit get sides cast (damage down)
    'E12S Promise Ferostorm': '4E46', // Garuda get intercardinals cast (damage down)
    'E12S Promise Judgment Jolt': '4E47', // Ramuh get out cast (damage down)
    'E12S Promise Shatter': '589C', // Ice Pillar explosion if tether not gotten
    'E12S Promise Impact': '58A1', // Titan bomb drop
    'E12S Oracle Dark Blizzard III': '58D3', // Relativity donut mechanic
    'E12S Oracle Apocalypse': '58E6', // Light up circle explosions (damage down)
  },
  damageFail: {
    'E12S Oracle Maelstrom': '58DA', // Advanced Relativity traffic light aoe
  },
  gainsEffectFail: {
    'E12S Oracle Doom': '9D4', // Relativity punishment for multiple mistakes
  },
  shareWarn: {
    'E12S Promise Frigid Stone': '589E', // Shiva spread
    'E12S Oracle Darkest Dance': '4E33', // Farthest target bait + jump before knockback
    'E12S Oracle Dark Current': '58D8', // Baited traffic light lasers
    'E12S Oracle Spirit Taker': '58C6', // Random jump spread mechanic after Shell Crusher
    'E12S Oracle Somber Dance 1': '58BF', // Farthest target bait for Dual Apocalypse
    'E12S Oracle Somber Dance 2': '58C0', // Second somber dance jump
  },
  shareFail: {
    'E12S Promise Weight Of The World': '58A5', // Titan bomb blue marker
    'E12S Promise Pulse Of The Land': '58A3', // Titan bomb yellow marker
    'E12S Oracle Dark Eruption 1': '58CE', // Initial warmup spread mechanic
    'E12S Oracle Dark Eruption 2': '58CD', // Relativity spread mechanic
    'E12S Oracle Black Halo': '58C7', // Tankbuster cleave
  },
  soloWarn: {
    'E12S Promise Force Of The Land': '58A4',
  },
  triggers: [
    {
      // Big circle ground aoes during Shiva junction.
      // This can be shielded through as long as that person doesn't stack.
      id: 'E12S Icicle Impact',
      type: 'Ability',
      netRegex: NetRegexes.abilityFull({ id: '4E5A', ...playerDamageFields }),
      condition: (data, matches) => data.DamageFromMatches(matches) > 0,
      mistake: (_data, matches) => {
        return {
          type: 'warn',
          blame: matches.target,
          reportId: matches.targetId,
          text: matches.ability,
        };
      },
    },
    {
      id: 'E12S Headmarker',
      type: 'HeadMarker',
      netRegex: NetRegexes.headMarker({}),
      run: (data, matches) => {
        const id = getHeadmarkerId(data, matches);
        const firstLaserMarker = '0091';
        const lastLaserMarker = '0098';
        if (id >= firstLaserMarker && id <= lastLaserMarker) {
          // ids are sequential: #1 square, #2 square, #3 square, #4 square, #1 triangle etc
          const decOffset = parseInt(id, 16) - parseInt(firstLaserMarker, 16);

          // decOffset is 0-7, so map 0-3 to 1-4 and 4-7 to 1-4.
          data.laserNameToNum ??= {};
          data.laserNameToNum[matches.target] = decOffset % 4 + 1;
        }
      },
    },
    {
      // These sculptures are added at the start of the fight, so we need to check where they
      // use the "Classical Sculpture" ability and end up on the arena for real.
      id: 'E12S Promise Chiseled Sculpture Classical Sculpture',
      type: 'Ability',
      netRegex: NetRegexes.abilityFull({ source: 'Chiseled Sculpture', id: '58B2' }),
      run: (data, matches) => {
        // This will run per person that gets hit by the same sculpture, but that's fine.
        // Record the y position of each sculpture so we can use it for better text later.
        data.sculptureYPositions ??= {};
        data.sculptureYPositions[matches.sourceId.toUpperCase()] = parseFloat(matches.y);
      },
    },
    {
      // The source of the tether is the player, the target is the sculpture.
      id: 'E12S Promise Chiseled Sculpture Tether',
      type: 'Tether',
      netRegex: NetRegexes.tether({ target: 'Chiseled Sculpture', id: '0011' }),
      run: (data, matches) => {
        data.sculptureTetherNameToId ??= {};
        data.sculptureTetherNameToId[matches.source] = matches.targetId.toUpperCase();
      },
    },
    {
      id: 'E12S Promise Blade Of Flame Counter',
      type: 'Ability',
      netRegex: NetRegexes.ability({ source: 'Chiseled Sculpture', id: '58B3' }),
      delaySeconds: 1,
      suppressSeconds: 1,
      run: (data) => {
        data.bladeOfFlameCount = data.bladeOfFlameCount || 0;
        data.bladeOfFlameCount++;
      },
    },
    {
      // This is the Chiseled Sculpture laser with the limit cut dots.
      id: 'E12S Promise Blade Of Flame',
      type: 'Ability',
      netRegex: NetRegexes.ability({ type: '22', source: 'Chiseled Sculpture', id: '58B3' }),
      mistake: (data, matches) => {
        if (!data.laserNameToNum || !data.sculptureTetherNameToId || !data.sculptureYPositions)
          return;

        // Find the person who has this laser number and is tethered to this statue.
        const number = (data.bladeOfFlameCount || 0) + 1;
        const sourceId = matches.sourceId.toUpperCase();
        const names = Object.keys(data.laserNameToNum);
        const withNum = names.filter((name) => data.laserNameToNum?.[name] === number);
        const owners = withNum.filter((name) => data.sculptureTetherNameToId?.[name] === sourceId);

        // if some logic error, just abort.
        if (owners.length !== 1)
          return;

        // The owner hitting themselves isn't a mistake...technically.
        if (owners[0] === matches.target)
          return;

        // Now try to figure out which statue is which.
        // People can put these wherever.  They could go sideways, or diagonal, or whatever.
        // It seems mooooost people put these north / south (on the south edge of the arena).
        // Let's say a minimum of 2 yalms apart in the y direction to consider them "north/south".
        const minimumYalmsForStatues = 2;

        let isStatuePositionKnown = false;
        let isStatueNorth = false;
        const sculptureIds = Object.keys(data.sculptureYPositions);
        if (sculptureIds.length === 2 && sculptureIds.includes(sourceId)) {
          const otherId = sculptureIds[0] === sourceId ? sculptureIds[1] : sculptureIds[0];
          const sourceY = data.sculptureYPositions[sourceId];
          const otherY = data.sculptureYPositions[otherId ?? ''];
          if (sourceY === undefined || otherY === undefined || otherId === undefined)
            throw new UnreachableCode();
          const yDiff = Math.abs(sourceY - otherY);
          if (yDiff > minimumYalmsForStatues) {
            isStatuePositionKnown = true;
            isStatueNorth = sourceY < otherY;
          }
        }

        const owner = owners[0];
        const ownerNick = data.ShortName(owner);
        let text = {
          en: `${matches.ability} (from ${ownerNick}, #${number})`,
          de: `${matches.ability} (von ${ownerNick}, #${number})`,
          fr: `${matches.ability} (de ${ownerNick}, #${number})`,
          ja: `${matches.ability} (${ownerNick}から、#${number})`,
          cn: `${matches.ability} (来自${ownerNick},#${number})`,
          ko: `${matches.ability} (대상자 "${ownerNick}", ${number}번)`,
        };
        if (isStatuePositionKnown && isStatueNorth) {
          text = {
            en: `${matches.ability} (from ${ownerNick}, #${number} north)`,
            de: `${matches.ability} (von ${ownerNick}, #${number} norden)`,
            fr: `${matches.ability} (de ${ownerNick}, #${number} nord)`,
            ja: `${matches.ability} (北の${ownerNick}から、#${number})`,
            cn: `${matches.ability} (来自北方${ownerNick},#${number})`,
            ko: `${matches.ability} (대상자 "${ownerNick}", ${number}번 북쪽)`,
          };
        } else if (isStatuePositionKnown && !isStatueNorth) {
          text = {
            en: `${matches.ability} (from ${ownerNick}, #${number} south)`,
            de: `${matches.ability} (von ${ownerNick}, #${number} Süden)`,
            fr: `${matches.ability} (de ${ownerNick}, #${number} sud)`,
            ja: `${matches.ability} (南の${ownerNick}から、#${number})`,
            cn: `${matches.ability} (来自南方${ownerNick},#${number})`,
            ko: `${matches.ability} (대상자 "${ownerNick}", ${number}번 남쪽)`,
          };
        }

        return {
          type: 'fail',
          name: matches.target,
          blame: owner,
          reportId: matches.targetId,
          text: text,
        };
      },
    },
    {
      id: 'E12S Promise Ice Pillar Tracker',
      type: 'Tether',
      netRegex: NetRegexes.tether({ source: 'Ice Pillar', id: ['0001', '0039'] }),
      run: (data, matches) => {
        data.pillarIdToOwner ??= {};
        data.pillarIdToOwner[matches.sourceId] = matches.target;
      },
    },
    {
      id: 'E12S Promise Ice Pillar Mistake',
      type: 'Ability',
      netRegex: NetRegexes.ability({ source: 'Ice Pillar', id: '589B' }),
      condition: (data, matches) => {
        if (!data.pillarIdToOwner)
          return false;
        return matches.target !== data.pillarIdToOwner[matches.sourceId];
      },
      mistake: (data, matches) => {
        const pillarOwner = data.ShortName(data.pillarIdToOwner?.[matches.sourceId]);
        return {
          type: 'fail',
          blame: matches.target,
          reportId: matches.targetId,
          text: {
            en: `${matches.ability} (from ${pillarOwner})`,
            de: `${matches.ability} (von ${pillarOwner})`,
            fr: `${matches.ability} (de ${pillarOwner})`,
            ja: `${matches.ability} (${pillarOwner}から)`,
            cn: `${matches.ability} (来自${pillarOwner})`,
            ko: `${matches.ability} (대상자 "${pillarOwner}")`,
          },
        };
      },
    },
    {
      id: 'E12S Promise Gain Fire Resistance Down II',
      type: 'GainsEffect',
      // The Beastly Sculpture gives a 3 second debuff, the Regal Sculpture gives a 14s one.
      netRegex: NetRegexes.gainsEffect({ effectId: '832' }),
      run: (data, matches) => {
        data.fire ??= {};
        data.fire[matches.target] = true;
      },
    },
    {
      id: 'E12S Promise Lose Fire Resistance Down II',
      type: 'LosesEffect',
      netRegex: NetRegexes.losesEffect({ effectId: '832' }),
      run: (data, matches) => {
        data.fire ??= {};
        data.fire[matches.target] = false;
      },
    },
    {
      id: 'E12S Promise Small Lion Tether',
      type: 'Tether',
      netRegex: NetRegexes.tether({ source: 'Beastly Sculpture', id: '0011' }),
      netRegexDe: NetRegexes.tether({ source: 'Abbild Eines Löwen', id: '0011' }),
      netRegexFr: NetRegexes.tether({ source: 'Création Léonine', id: '0011' }),
      netRegexJa: NetRegexes.tether({ source: '創られた獅子', id: '0011' }),
      netRegexCn: NetRegexes.tether({ source: '被创造的狮子', id: '0011' }),
      run: (data, matches) => {
        data.smallLionIdToOwner ??= {};
        data.smallLionIdToOwner[matches.sourceId.toUpperCase()] = matches.target;
        data.smallLionOwners ??= [];
        data.smallLionOwners.push(matches.target);
      },
    },
    {
      id: 'E12S Promise Small Lion Lionsblaze',
      type: 'Ability',
      netRegex: NetRegexes.abilityFull({ source: 'Beastly Sculpture', id: '58B9' }),
      netRegexDe: NetRegexes.abilityFull({ source: 'Abbild Eines Löwen', id: '58B9' }),
      netRegexFr: NetRegexes.abilityFull({ source: 'Création Léonine', id: '58B9' }),
      netRegexJa: NetRegexes.abilityFull({ source: '創られた獅子', id: '58B9' }),
      netRegexCn: NetRegexes.abilityFull({ source: '被创造的狮子', id: '58B9' }),
      mistake: (data, matches) => {
        // Folks baiting the big lion second can take the first small lion hit,
        // so it's not sufficient to check only the owner.
        if (!data.smallLionOwners)
          return;
        const owner = data.smallLionIdToOwner?.[matches.sourceId.toUpperCase()];
        if (!owner)
          return;
        if (matches.target === owner)
          return;

        // If the target also has a small lion tether, that is always a mistake.
        // Otherwise, it's only a mistake if the target has a fire debuff.
        const hasSmallLion = data.smallLionOwners.includes(matches.target);
        const hasFireDebuff = data.fire && data.fire[matches.target];

        if (hasSmallLion || hasFireDebuff) {
          const ownerNick = data.ShortName(owner);

          const centerY = -75;
          const x = parseFloat(matches.x);
          const y = parseFloat(matches.y);
          let dirObj = null;
          if (y < centerY) {
            if (x > 0)
              dirObj = Outputs.dirNE;
            else
              dirObj = Outputs.dirNW;
          } else {
            if (x > 0)
              dirObj = Outputs.dirSE;
            else
              dirObj = Outputs.dirSW;
          }

          return {
            type: 'fail',
            blame: owner,
            name: matches.target,
            reportId: matches.targetId,
            text: {
              en: `${matches.ability} (from ${ownerNick}, ${dirObj['en']})`,
              de: `${matches.ability} (von ${ownerNick}, ${dirObj['de']})`,
              fr: `${matches.ability} (de ${ownerNick}, ${dirObj['fr']})`,
              ja: `${matches.ability} (${ownerNick}から, ${dirObj['ja']})`,
              cn: `${matches.ability} (来自${ownerNick}, ${dirObj['cn']}`,
              ko: `${matches.ability} (대상자 "${ownerNick}", ${dirObj['ko']})`,
            },
          };
        }
      },
    },
    {
      id: 'E12S Promise North Big Lion',
      type: 'AddedCombatant',
      netRegex: NetRegexes.addedCombatantFull({ name: 'Regal Sculpture' }),
      run: (data, matches) => {
        const y = parseFloat(matches.y);
        const centerY = -75;
        if (y < centerY)
          data.northBigLion = matches.id.toUpperCase();
      },
    },
    {
      id: 'E12S Promise Big Lion Kingsblaze',
      type: 'Ability',
      netRegex: NetRegexes.ability({ source: 'Regal Sculpture', id: '4F9E' }),
      netRegexDe: NetRegexes.ability({ source: 'Abbild eines großen Löwen', id: '4F9E' }),
      netRegexFr: NetRegexes.ability({ source: 'création léonine royale', id: '4F9E' }),
      netRegexJa: NetRegexes.ability({ source: '創られた獅子王', id: '4F9E' }),
      netRegexCn: NetRegexes.ability({ source: '被创造的狮子王', id: '4F9E' }),
      mistake: (data, matches) => {
        const singleTarget = matches.type === '21';
        const hasFireDebuff = data.fire && data.fire[matches.target];

        // Success if only one person takes it and they have no fire debuff.
        if (singleTarget && !hasFireDebuff)
          return;

        const northBigLion: LocaleText = {
          en: 'north big lion',
          de: 'Nordem, großer Löwe',
          fr: 'Grand lion du nord',
          ja: '大ライオン(北)',
          cn: '北方大狮子',
          ko: '북쪽 큰 사자',
        };
        const southBigLion: LocaleText = {
          en: 'south big lion',
          de: 'Süden, großer Löwe',
          fr: 'Grand lion du sud',
          ja: '大ライオン(南)',
          cn: '南方大狮子',
          ko: '남쪽 큰 사자',
        };
        const shared: LocaleText = {
          en: 'shared',
          de: 'geteilt',
          fr: 'Partagé(e)',
          ja: '重ねた',
          cn: '重叠',
          ko: '같이 맞음',
        };
        const fireDebuff: LocaleText = {
          en: 'had fire',
          de: 'hatte Feuer',
          fr: 'A eu(e) le feu',
          ja: '炎付き',
          cn: '火Debuff',
          ko: '화염 디버프 받음',
        };

        const labels = [];
        const lang: Lang = data.options.ParserLanguage;

        if (data.northBigLion) {
          if (data.northBigLion === matches.sourceId)
            labels.push(northBigLion[lang] ?? northBigLion['en']);
          else
            labels.push(southBigLion[lang] ?? southBigLion['en']);
        }
        if (!singleTarget)
          labels.push(shared[lang] ?? shared['en']);
        if (hasFireDebuff)
          labels.push(fireDebuff[lang] ?? fireDebuff['en']);

        return {
          type: 'fail',
          name: matches.target,
          reportId: matches.targetId,
          text: `${matches.ability} (${labels.join(', ')})`,
        };
      },
    },
    {
      id: 'E12S Knocked Off',
      type: 'Ability',
      // 589A = Ice Pillar (promise shiva phase)
      // 58B6 = Palm Of Temperance (promise statue hand)
      // 58B7 = Laser Eye (promise lion phase)
      // 58C1 = Darkest Dance (oracle tank jump + knockback in beginning and triple apoc)
      netRegex: NetRegexes.ability({ id: ['589A', '58B6', '58B7', '58C1'] }),
      deathReason: (_data, matches) => {
        return {
          id: matches.targetId,
          name: matches.target,
          text: {
            en: 'Knocked off',
            de: 'Runtergefallen',
            fr: 'Renversé(e)',
            ja: 'ノックバック',
            cn: '击退坠落',
            ko: '넉백',
          },
        };
      },
    },
    {
      id: 'E12S Oracle Shadoweye',
      type: 'Ability',
      netRegex: NetRegexes.abilityFull({ id: '58D2', ...playerDamageFields }),
      condition: (data, matches) => data.DamageFromMatches(matches) > 0,
      mistake: (_data, matches) => {
        return {
          type: 'fail',
          blame: matches.target,
          reportId: matches.targetId,
          text: matches.ability,
        };
      },
    },
  ],
};

export default triggerSet;