diff --git a/.gitignore b/.gitignore index accc2e6..ee63df5 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ *.pyc userfiles/antilist.csv userfiles/config.csv +userfiles/config_anime.csv userfiles/*.json superprompter/model_files superprompter/model_files/*.* diff --git a/OneButtonPromptNodes.py b/OneButtonPromptNodes.py index 11cb6d0..2d3e6e9 100644 --- a/OneButtonPromptNodes.py +++ b/OneButtonPromptNodes.py @@ -19,12 +19,12 @@ allpresets = [OBPresets.RANDOM_PRESET_OBP] + list(OBPresets.opb_presets.keys()) artists = ["all", "all (wild)", "none", "popular", "greg mode", "3D", "abstract", "angular", "anime" ,"architecture", "art nouveau", "art deco", "baroque", "bauhaus", "cartoon", "character", "children's illustration", "cityscape", "cinema", "clean", "cloudscape", "collage", "colorful", "comics", "cubism", "dark", "detailed", "digital", "expressionism", "fantasy", "fashion", "fauvism", "figurativism", "gore", "graffiti", "graphic design", "high contrast", "horror", "impressionism", "installation", "landscape", "light", "line drawing", "low contrast", "luminism", "magical realism", "manga", "melanin", "messy", "monochromatic", "nature", "nudity", "photography", "pop art", "portrait", "primitivism", "psychedelic", "realism", "renaissance", "romanticism", "scene", "sci-fi", "sculpture", "seascape", "space", "stained glass", "still life", "storybook realism", "street art", "streetscape", "surrealism", "symbolism", "textile", "ukiyo-e", "vibrant", "watercolor", "whimsical"] artifyartists = ["all", "all (wild)", "popular", "greg mode", "3D", "abstract", "angular", "anime" ,"architecture", "art nouveau", "art deco", "baroque", "bauhaus", "cartoon", "character", "children's illustration", "cityscape", "cinema", "clean", "cloudscape", "collage", "colorful", "comics", "cubism", "dark", "detailed", "digital", "expressionism", "fantasy", "fashion", "fauvism", "figurativism", "gore", "graffiti", "graphic design", "high contrast", "horror", "impressionism", "installation", "landscape", "light", "line drawing", "low contrast", "luminism", "magical realism", "manga", "melanin", "messy", "monochromatic", "nature", "nudity", "photography", "pop art", "portrait", "primitivism", "psychedelic", "realism", "renaissance", "romanticism", "scene", "sci-fi", "sculpture", "seascape", "space", "stained glass", "still life", "storybook realism", "street art", "streetscape", "surrealism", "symbolism", "textile", "ukiyo-e", "vibrant", "watercolor", "whimsical"] -imagetypes = ["all", "all - force multiple", "none", "photograph", "octane render","digital art","concept art", "painting", "portrait", "anime key visual", "only other types", "only templates mode", "dynamic templates mode", "art blaster mode", "quality vomit mode", "color cannon mode", "unique art mode", "massive madness mode", "photo fantasy mode", "subject only mode", "fixed styles mode", "the tokinator"] +imagetypes = ["all", "all - force multiple", "all - anime", "none", "photograph", "octane render","digital art","concept art", "painting", "portrait", "anime", "only other types", "only templates mode", "dynamic templates mode", "art blaster mode", "quality vomit mode", "color cannon mode", "unique art mode", "massive madness mode", "photo fantasy mode", "subject only mode", "fixed styles mode", "the tokinator"] subjects =["all", "object", "animal", "humanoid", "landscape", "concept"] genders = ["all", "male", "female"] emojis = [False, True] -models = ["SD1.5", "SDXL", "Stable Cascade"] +models = ["SD1.5", "SDXL", "Stable Cascade", "Anime Model"] prompt_enhancers = ["none", "superprompt-v1"] subjects =["------ all"] subjectsubtypesobject = ["all"] diff --git a/build_dynamic_prompt.py b/build_dynamic_prompt.py index 8df54ad..74c7a89 100644 --- a/build_dynamic_prompt.py +++ b/build_dynamic_prompt.py @@ -15,10 +15,12 @@ OBPresets = OneButtonPresets() # Set artistmode to none, to exclude artists def build_dynamic_prompt(insanitylevel = 5, forcesubject = "all", artists = "all", imagetype = "all", onlyartists = False, antivalues = "", prefixprompt = "", suffixprompt ="",promptcompounderlevel ="1", seperator = "comma", givensubject="",smartsubject = True,giventypeofimage="", imagemodechance = 20, gender = "all", subtypeobject="all", subtypehumanoid="all", subtypeconcept="all", advancedprompting=True, hardturnoffemojis=False, seed=-1, overrideoutfit="", prompt_g_and_l = False, base_model = "SD1.5", OBP_preset = "", prompt_enhancer = "none", subtypeanimal="all", subtypelocation="all"): - remove_weights = False + remove_weights = False less_verbose = False add_vomit = True add_quality = True + anime_mode = False + configfilesuffix = "" superprompter = False prompt_enhancer = prompt_enhancer.lower() @@ -126,13 +128,37 @@ def build_dynamic_prompt(insanitylevel = 5, forcesubject = "all", artists = "all outfitmode = 0 animalashuman = False + partlystylemode = False - # load the config file - config = load_config_csv() + # cheat for presets + if(OBP_preset=='Waifu''s' or OBP_preset=='Husbando''s'): + basemodel = "Anime Model" + # Base model options, used to change things in prompt generation. Might be able to extend to different forms like animatediff as well? + base_model_options = ["SD1.5", "SDXL", "Stable Cascade", "Anime Model"] + if base_model not in base_model_options: + base_model = "SD1.5" # Just in case there is no option here. + # "SD1.5" -- Standard, future: More original style prompting + # "SDXL" -- Standard (for now), future: More natural language + # "Stable Cascade" -- Remove weights + if(base_model == "Stable Cascade"): + remove_weights = True + add_vomit = False + add_quality = False + if(base_model == "SD1.5"): + less_verbose = True + if(base_model == "Anime Model"): + less_verbose = True + advancedprompting = False + anime_mode = True + configfilesuffix = "anime" - - + + # load the config file + + config = load_config_csv(configfilesuffix) + + # first build up a complete anti list. Those values are removing during list building # this uses the antivalues string AND the antilist.csv emptylist = [] @@ -145,19 +171,7 @@ def build_dynamic_prompt(insanitylevel = 5, forcesubject = "all", artists = "all # clean up antivalue list: antilist = [s.strip().lower() for s in antilist] - # Base model options, used to change things in prompt generation. Might be able to extend to different forms like animatediff as well? - base_model_options = ["SD1.5", "SDXL", "Stable Cascade"] - if base_model not in base_model_options: - base_model = "SD1.5" # Just in case there is no option here. - # "SD1.5" -- Standard, future: More original style prompting - # "SDXL" -- Standard (for now), future: More natural language - # "Stable Cascade" -- Remove weights - if(base_model == "Stable Cascade"): - remove_weights = True - add_vomit = False - add_quality = False - if(base_model == "SD1.5"): - less_verbose = True + # Some tricks for gender to make sure we can choose Him/Her/It etc on the right time. if(gender=="all"): @@ -207,7 +221,13 @@ def build_dynamic_prompt(insanitylevel = 5, forcesubject = "all", artists = "all hairvomitlist = csv_to_list("hairvomit",antilist,"./csvfiles/",0,"?",False,False) humanoidlist = csv_to_list("humanoids",antilist) - imagetypelist = csv_to_list(csvfilename="imagetypes",antilist=antilist, insanitylevel=insanitylevel, delimiter="?") + if(anime_mode or imagetype=="all - anime"): + if(imagetype == "all"): + imagetype = "all - anime" + imagetypelist = csv_to_list(csvfilename="imagetypes_anime",antilist=antilist, insanitylevel=insanitylevel, delimiter="?") + else: + imagetypelist = csv_to_list(csvfilename="imagetypes",antilist=antilist, insanitylevel=insanitylevel, delimiter="?") + joblist = csv_to_list(csvfilename="jobs",antilist=antilist,skipheader=True,gender=gender) lenslist = csv_to_list(csvfilename="lenses",antilist=antilist, insanitylevel=insanitylevel) lightinglist = csv_to_list(csvfilename="lighting",antilist=antilist, insanitylevel=insanitylevel) @@ -220,6 +240,18 @@ def build_dynamic_prompt(insanitylevel = 5, forcesubject = "all", artists = "all shotsizelist = csv_to_list(csvfilename="shotsizes",antilist=antilist, insanitylevel=insanitylevel) timeperiodlist = csv_to_list("timeperiods",antilist) vomitlist = csv_to_list(csvfilename="vomit",antilist=antilist, insanitylevel=insanitylevel) + if(anime_mode): + replacements = { + "-allstylessuffix-": "-buildfacepart-", + "-artistdescription-": "-buildfacepart-" + } + + for i, item in enumerate(vomitlist): + for old, new in replacements.items(): + item = item.replace(old, new) + vomitlist[i] = item + + foodlist = csv_to_list("foods", antilist) genderdescriptionlist = csv_to_list(csvfilename="genderdescription",antilist=antilist,skipheader=True,gender=gender) minilocationlist = csv_to_list("minilocations", antilist) @@ -247,7 +279,6 @@ def build_dynamic_prompt(insanitylevel = 5, forcesubject = "all", artists = "all coveringlist = csv_to_list("coverings", antilist) facepartlist = csv_to_list("faceparts", antilist) outfitvomitlist = csv_to_list(csvfilename="outfitvomit",antilist=antilist,delimiter="?") - humanexpressionlist = csv_to_list(csvfilename="humanexpressions",antilist=antilist,delimiter="?") humanvomitlist = csv_to_list("humanvomit", antilist) eyecolorlist = csv_to_list("eyecolors", antilist) fashiondesignerlist = csv_to_list("fashiondesigners", antilist) @@ -420,6 +451,7 @@ def build_dynamic_prompt(insanitylevel = 5, forcesubject = "all", artists = "all buildfacelist = csv_to_list("buildface_less_verbose", antilist,"./csvfiles/special_lists/",0,"?") buildaccessorielist = csv_to_list("buildaccessorie_less_verbose", antilist,"./csvfiles/special_lists/",0,"?") humanactivitylist = csv_to_list("human_activities_less_verbose",antilist,"./csvfiles/",0,"?",False,False) + humanexpressionlist = csv_to_list("humanexpressions_less_verbose",antilist,"./csvfiles/",0,"?",False,False) else: buildhairlist = csv_to_list("buildhair", antilist,"./csvfiles/special_lists/",0,"?") buildoutfitlist = csv_to_list("buildoutfit", antilist,"./csvfiles/special_lists/",0,"?") @@ -428,6 +460,7 @@ def build_dynamic_prompt(insanitylevel = 5, forcesubject = "all", artists = "all buildfacelist = csv_to_list("buildface", antilist,"./csvfiles/special_lists/",0,"?") buildaccessorielist = csv_to_list("buildaccessorie", antilist,"./csvfiles/special_lists/",0,"?") humanactivitylist = csv_to_list("human_activities",antilist,"./csvfiles/",0,"?",False,False) + humanexpressionlist = csv_to_list("humanexpressions",antilist,"./csvfiles/",0,"?",False,False) humanactivitylist = humanactivitylist + humanactivitycheatinglist @@ -1449,8 +1482,9 @@ def build_dynamic_prompt(insanitylevel = 5, forcesubject = "all", artists = "all # 0 object, 1 animal, 2 animal as human, 3 ManWoman, 4 Job, 5 fictional, 6 non fictional, 7 humanoid, 8 landscape, 9 event if(mainchooser == "object"): subjectchooser = "object" - if(mainchooser == "animal" and random.randint(0,5) == 5): + if(mainchooser == "animal" and (random.randint(0,5) == 5 or anime_mode)): # sometimes interpret the animal as a human + # for anime_mode this is always true animalashuman = True if(mainchooser == "humanoid"): #humanoidsubjectchooserlist = ["human", "job", "fictional", "non fictional", "humanoid", "manwomanrelation", "firstname"] @@ -1530,7 +1564,7 @@ def build_dynamic_prompt(insanitylevel = 5, forcesubject = "all", artists = "all # After we chose the subject, lets set all things ready for He/She/It etc - if(subjectchooser in ["manwomanmultiple"] and givensubject != "" and subtypehumanoid != "multiple humans"): + if(not less_verbose and subjectchooser in ["manwomanmultiple"] and givensubject != "" and subtypehumanoid != "multiple humans"): heshelist = ["they"] hisherlist = ["their"] himherlist = ["them"] @@ -1539,7 +1573,7 @@ def build_dynamic_prompt(insanitylevel = 5, forcesubject = "all", artists = "all heshelist = ["one of them"] hisherlist = ["one of their"] himherlist = ["one of them"] - elif(subjectchooser in ["human", "job", "fictional", "non fictional", "humanoid", "manwomanrelation","firstname","manwomanmultiple"]): + elif(not less_verbose and subjectchooser in ["human", "job", "fictional", "non fictional", "humanoid", "manwomanrelation","firstname","manwomanmultiple"]): if(gender == "male"): heshelist = ["he"] hisherlist = ["his"] @@ -1548,7 +1582,7 @@ def build_dynamic_prompt(insanitylevel = 5, forcesubject = "all", artists = "all heshelist = ["she"] hisherlist = ["her"] himherlist = ["her"] - if(subjectchooser in ["manwomanmultiple"] and givensubject == ""): + if(not less_verbose and subjectchooser in ["manwomanmultiple"] and givensubject == ""): heshelist = ["they"] hisherlist = ["their"] himherlist = ["them"] @@ -1927,10 +1961,10 @@ def build_dynamic_prompt(insanitylevel = 5, forcesubject = "all", artists = "all if(giventypeofimage == "" and (imagetype == "none" or giventypeofimage=="none") ): generatetype = False if(giventypeofimage=="" and generatetype == True): - if(imagetype != "all" and imagetype != "all - force multiple" and imagetype != "only other types"): + if(imagetype != "all" and imagetype != "all - force multiple" and imagetype != "only other types" and imagetype != "all - anime"): completeprompt += " " + imagetype + ", " - elif(imagetype == "all - force multiple" or unique_dist(insanitylevel)): + elif(imagetype == "all - force multiple" or unique_dist(insanitylevel) and not anime_mode): amountofimagetypes = random.randint(2,3) elif(imagetype == "only other types"): if(amountofimagetypes < 2 and random.randint(0,2) == 0): @@ -1945,14 +1979,14 @@ def build_dynamic_prompt(insanitylevel = 5, forcesubject = "all", artists = "all othertype = 1 completeprompt += random.choice(othertypelist) - if(imagetype == "all" and chance_roll(insanitylevel, imagetypechance) and amountofimagetypes <= 1): + if((imagetype == "all" or imagetype == "all - anime") and chance_roll(insanitylevel, imagetypechance) and amountofimagetypes <= 1): amountofimagetypes = 1 # on lower insanity levels, almost force this - if(imagetype == "all" and insanitylevel <= 3 and amountofimagetypes <= 1 and random.randint(0,1)== 0): + if((imagetype == "all" or imagetype == "all - anime") and insanitylevel <= 3 and amountofimagetypes <= 1 and random.randint(0,1)== 0): amountofimagetypes = 1 - if(imagetype == "all" and insanitylevel <= 2 and amountofimagetypes <= 1): + if((imagetype == "all" or imagetype == "all - anime") and insanitylevel <= 2 and amountofimagetypes <= 1): amountofimagetypes = 1 @@ -1963,24 +1997,15 @@ def build_dynamic_prompt(insanitylevel = 5, forcesubject = "all", artists = "all # one in 6 images is a complex/other type if((chance_roll(insanitylevel, imagetypequalitychance) or originalartistchoice == "greg mode") and generateimagetypequality): completeprompt += "-imagetypequality- " - # if("photography" in artiststyleselector - # or "photography" in artists): - # completeprompt += " photograph, " - # elif("portrait" in artiststyleselector - # or "portrait" in artists): - # completeprompt += " portrait, " - # if("landscape" in artiststyleselector - # or "landscape" in artists): - # completeprompt += " landscape, " - - - + + if(imagetype == "all - anime" and not anime_mode): + completeprompt += " anime" if(random.randint(0,4) < 4 and insanitylevel > 3 ): # woops, never to this as wildcards. We need to know as early as possible wether something is a photo. Lets put it back! completeprompt += " " + random.choice(imagetypelist) + ", " elif(random.randint(0,1) == 0 and insanitylevel <= 3): completeprompt += " " + random.choice(imagetypelist) + ", " - else: + elif(not anime_mode): if(amountofimagetypes < 2 and random.randint(0,1) == 0): partlystylemode = True print("Ohhh! Adding some secret sauce to this prompt") @@ -2080,7 +2105,10 @@ def build_dynamic_prompt(insanitylevel = 5, forcesubject = "all", artists = "all # Common to have 1 description, uncommon to have 2 if(chance_roll(insanitylevel, subjectdescriptor1chance) and generatedescriptors == True): if(animalashuman or subjectchooser in ["human", "job", "fictional", "non fictional", "humanoid", "manwomanrelation", "manwomanmultiple","firstname"]): - completeprompt += "-humandescriptor- " + if(anime_mode and random.randint(0,2)<2): + completeprompt += "-basicbitchdescriptor- " + else: + completeprompt += "-humandescriptor- " elif(mainchooser == "landscape"): completeprompt += "-locationdescriptor- " elif(mainchooser == "animal"): @@ -2090,7 +2118,10 @@ def build_dynamic_prompt(insanitylevel = 5, forcesubject = "all", artists = "all if(chance_roll(insanitylevel, subjectdescriptor2chance) and generatedescriptors == True): if(animalashuman or subjectchooser in ["human", "job", "fictional", "non fictional", "humanoid", "manwomanrelation", "manwomanmultiple","firstname"]): - completeprompt += "-humandescriptor- " + if(anime_mode and random.randint(0,2)<2): + completeprompt += "-basicbitchdescriptor- " + else: + completeprompt += "-humandescriptor- " elif(mainchooser == "landscape"): completeprompt += "-locationdescriptor- " elif(mainchooser == "animal"): @@ -2172,6 +2203,16 @@ def build_dynamic_prompt(insanitylevel = 5, forcesubject = "all", artists = "all if(mainchooser == "animal"): # first add a wildcard that can be used to create prompt strenght completeprompt += " -objectstrengthstart-" + if(anime_mode + and "1girl" not in givensubject + and "1boy" not in givensubject): + anthrolist = ["anthro", "anthrophomorphic", "furry"] + + + if(gender=="male"): + completeprompt += random.choice(anthrolist) + ", 1boy, solo, " + else: + completeprompt += random.choice(anthrolist) + ", 1girl, solo, " # if we have a given subject, we should skip making an actual subject if(givensubject == "" or (subjectingivensubject and givensubject != "")): @@ -2239,9 +2280,24 @@ def build_dynamic_prompt(insanitylevel = 5, forcesubject = "all", artists = "all if(mainchooser == "humanoid"): # first add a wildcard that can be used to create prompt strenght completeprompt += " -objectstrengthstart-" + + if(anime_mode + and "1girl" not in givensubject + and "1boy" not in givensubject): + if(subjectchooser != "manwomanmultiple"): + if(gender=="male"): + completeprompt += "1boy, solo, " + else: + completeprompt += "1girl, solo, " + else: + if(gender=="male"): + completeprompt += "multipleboys, " + else: + completeprompt += "multiplegirls, " + if(givensubject == "" or (subjectingivensubject and givensubject != "")): - if(subjectchooser == "human"): + if(subjectchooser == "human" and not anime_mode): completeprompt += "-manwoman-" if(subjectchooser == "manwomanrelation"): @@ -2251,7 +2307,8 @@ def build_dynamic_prompt(insanitylevel = 5, forcesubject = "all", artists = "all completeprompt += "-manwomanmultiple-" if(subjectchooser == "job"): - completeprompt += "-malefemale- " + if(not anime_mode): + completeprompt += "-malefemale- " completeprompt += "-job-" if(subjectchooser == "fictional"): @@ -2480,7 +2537,10 @@ def build_dynamic_prompt(insanitylevel = 5, forcesubject = "all", artists = "all if(chance_roll(insanitylevel, subjectdescriptor1chance) and generatedescriptors == True): if(animalashuman or subjectchooser in ["human", "job", "fictional", "non fictional", "humanoid", "manwomanrelation","manwomanmultiple", "firstname"]): if(less_verbose): - completeprompt += ", -humandescriptor- " + if(anime_mode and random.randint(0,2)<2): + completeprompt += ", -basicbitchdescriptor- " + else: + completeprompt += ", -humandescriptor- " elif(random.randint(0,3) > 0): completeprompt += ", OR(;-heshe- is;normal) OR(;very;rare) -humandescriptor- " elif(subjectchooser == "manwomanmultiple"): @@ -2572,7 +2632,7 @@ def build_dynamic_prompt(insanitylevel = 5, forcesubject = "all", artists = "all if(random.randint(0,1)==0): completeprompt += ", " + random.choice(humanactivitylist)+ ", " else: - completeprompt += "OR(,; as a;rare) -job-, " + completeprompt += ", OR(,; as a;rare) -job-, " @@ -2774,7 +2834,7 @@ def build_dynamic_prompt(insanitylevel = 5, forcesubject = "all", artists = "all # if not, we could go in random styles descriptor mode - elif(templatemode == False and specialmode == False and uncommon_dist(10 - insanitylevel)): + elif(not anime_mode and templatemode == False and specialmode == False and uncommon_dist(10 - insanitylevel)): for i in range(random.randint(1,max(7,insanitylevel + 2))): # print("adding random crap") completeprompt += ", -allstylessuffix-" @@ -2987,7 +3047,7 @@ def build_dynamic_prompt(insanitylevel = 5, forcesubject = "all", artists = "all completeprompt += chosenstylesuffix templatesmodechance = 0 - if(uncommon_dist(insanitylevel)): + if(uncommon_dist(insanitylevel) and not anime_mode): # not for anime models! templatesmodechance = 1 if(dynamictemplatesmode == True and templatesmodechance == 1): @@ -3353,7 +3413,7 @@ def build_dynamic_prompt(insanitylevel = 5, forcesubject = "all", artists = "all completeprompt = "".join(completeprompt_list) - + # print(completeprompt) # lol, this needs a rewrite :D while ( @@ -4920,6 +4980,9 @@ def cleanup(completeprompt, advancedprompting, insanitylevel = 5): completeprompt = re.sub('-artistdescription-', '', completeprompt) completeprompt = re.sub('- art ', '', completeprompt) + completeprompt = re.sub('anime anime', 'anime', completeprompt) + completeprompt = re.sub('anime, anime', 'anime', completeprompt) + completeprompt = re.sub('shot shot', 'shot', completeprompt) diff --git a/csv_reader.py b/csv_reader.py index bf2058e..ed688c7 100644 --- a/csv_reader.py +++ b/csv_reader.py @@ -176,13 +176,17 @@ def artist_descriptions_csv_to_list(csvfilename): csvlist.append(row["Description"]) return csvlist -def load_config_csv(): +def load_config_csv(suffix=""): csvlist = [] script_dir = os.path.dirname(os.path.abspath(__file__)) full_path_config_file = os.path.join(script_dir, "./userfiles/" ) full_path_default_config_file = os.path.join(script_dir, "./csvfiles/config/" ) - config_file = full_path_config_file + 'config.csv' - default_config_file = full_path_default_config_file + 'default_config.csv' + if(suffix != ""): + config_file = full_path_config_file + 'config_' + suffix + '.csv' + default_config_file = full_path_default_config_file + 'default_config_' + suffix + '.csv' + else: + config_file = full_path_config_file + 'config.csv' + default_config_file = full_path_default_config_file + 'default_config.csv' if not os.path.exists(config_file): shutil.copy2(default_config_file, config_file) diff --git a/csvfiles/accessories.csv b/csvfiles/accessories.csv index ec55866..539ee1d 100644 --- a/csvfiles/accessories.csv +++ b/csvfiles/accessories.csv @@ -51,7 +51,9 @@ OR(Cat;Bunny;Fox) Ears?female -animal- Tail?female Tail?female Fangs?both -Wings?both +OR(Wings;Angel Wings;Bird Wings;Demon Wings;Dragon Wings;Fairy Wings;Bat Wings;Skeletal Wings)?both +OR(Butterfly Wings;Dragonfly Wings;Ladybug Wings;Moth wings)?both +OR(Crystal Wings;Energy Wings;Fiery Wings;Icy Wings;Liquid Wings;Plant Wings)?both Cybernetics?both Mechanical Body Parts?both Mechanical Arms?both @@ -84,6 +86,8 @@ Bowtie?both Earrings?both Earring?both Necklace?both +Chain Necklace?both +Flower Necklace?both Bracelet?both Ring?both Rings?both @@ -151,4 +155,18 @@ Trinkets?both Ruff?both Unicorn horn?both Nonblinding sunglasses?both -Great-eyed?both \ No newline at end of file +Great-eyed?both +Scouter?both +OR(opera glasses;opaque glasses;aviator sunglasses;3D glasses;groucho glasses)?both +Gem-studded?both +Glitter?both +Sequins?both +Magatama?both +Ribbon?both +Pentacle?both +Feather boa?both +Necktie?both +Fur collar?both +Jetpack?both +Automail?both +Severed limb?both \ No newline at end of file diff --git a/csvfiles/config/default_config_anime.csv b/csvfiles/config/default_config_anime.csv new file mode 100644 index 0000000..b0f366f --- /dev/null +++ b/csvfiles/config/default_config_anime.csv @@ -0,0 +1,124 @@ +#this file controls the generation process; +#records starting with # are ignored; +#----; +# main subject generation options; +# these can either be on or off; +#----; +# objects; +subject_object;on +subject_vehicle;on +subject_food;on +subject_space;on +subject_building;on +subject_flora;on +subject_occult;on +# animals; +subject_animal;on +subject_bird;on +subject_cat;on +subject_dog;on +subject_insect;on +subject_pokemon;on +subject_marinelife;on +# humanoids; +subject_manwoman;on +subject_manwomanrelation;on +subject_manwomanmultiple;on +subject_fictional;on +subject_nonfictional;on +subject_humanoid;on +subject_job;on +subject_firstnames;on +# landscape; +subject_location;on +subject_location_fantasy;on +subject_location_scifi;on +subject_location_videogame;on +subject_location_biome;on +subject_location_city;on +# concept; +subject_event;on +subject_concept;on +subject_poemline;on +subject_songline;on +subject_cardname;on +subject_episodetitle;on +subject_conceptmixer;on +#----; +# other main lists, in order of appearance; +# setting the random chance, for normal generation; +# these can be, in order of most appearing to least appearing; +# always, common, normal, uncommon, rare, legendary, unique, extraordinary, novel, never; +custominputprefixrepeats;2 +custominputprefixchance;uncommon +imagetypechance;legendary +imagetypequalitychance;normal +# some prefixes that happen rarely; +minilocationadditionchance;unique +artmovementprefixchance;unique +minivomitprefix1chance;rare +minivomitprefix2chance;unique +# shot size generation; +shotsizechance;common +# subject specific stuff; +subjectdescriptor1chance;common +subjectdescriptor2chance;uncommon +subjectbodytypechance;common +subjectculturechance;uncommon +subjectconceptsuffixchance;unique +# subjectlandscape specific stuff; +subjectlandscapeinsideshotchance;unique +subjectlandscapeaddonlocationchance;normal +subjectlandscapeaddonlocationdescriptorchance;rare +subjectlandscapeaddonlocationculturechance;rare +# all additions; +objectadditionsrepeats;2 +objectadditionschance;uncommon +humanadditionchance;uncommon +overalladditionchance;extraordinary +# humanoid other stuff; +emojichance;legendary +buildfacechance;uncommon +humanexpressionchance;uncommon +humanvomitchance;normal +joboractivitychance;rare +# things in the middle of the prompt; +custominputmidrepeats;2 +custominputmidchance;uncommon +minivomitmidchance;unique +# humanoid main stuff; +outfitchance;common +posechance;common +hairchance;common +accessorychance;uncommon +humanoidinsideshotchance;novel +humanoidbackgroundchance;novel +# minilocation stuff; +landscapeminilocationchance;uncommon +generalminilocationchance;rare +# general stuff add the end of the prompt; +timperiodchance;normal +focuschance;normal +directionchance;normal +moodchance;common +minivomitsuffixchance;unique +artmovementchance;unique +lightingchance;normal +photoadditionchance;unique +lenschance;unique +colorschemechance;normal +vomit1chance;rare +vomit2chance;rare +greatworkchance;never +poemlinechance;never +songlinechance;never +quality1chance;normal +quality2chance;normal +# custom style list (lora and tis); +customstyle1chance;uncommon +customstyle2chance;uncommon +# suffix custom list; +custominputsuffixrepeats;2 +custominputsuffixchance;uncommon +# artists stuff; +artistsatbackchance;uncommon \ No newline at end of file diff --git a/csvfiles/hairstyles.csv b/csvfiles/hairstyles.csv index 912444c..755900c 100644 --- a/csvfiles/hairstyles.csv +++ b/csvfiles/hairstyles.csv @@ -20,6 +20,7 @@ Braids Buzz cut Buzz cut with a fade Caesar cut +Chonmage Chignon Comb-over Cornrows @@ -33,6 +34,8 @@ Drill Dutch braid Faux hawk Fauxhawk +Flipped hair +Folded ponytail Fishtail braid French braid French crop @@ -57,6 +60,7 @@ Low bun Low fade Low ponytail Lushious +Nihongami Man bun Mermaid waves Messy bun @@ -83,6 +87,7 @@ Side swept Side-swept bangs Side-swept curls Sideswept bangs +Side ponytail Slicked-back Space buns Spiky @@ -95,6 +100,7 @@ Top knot Tousled Twist braid Twist out +Twintails Undercut Voluminous Waterfall braid diff --git a/csvfiles/hairstyles2.csv b/csvfiles/hairstyles2.csv index 80d60a7..8c93607 100644 --- a/csvfiles/hairstyles2.csv +++ b/csvfiles/hairstyles2.csv @@ -15,4 +15,7 @@ short braided hair lushious hair hair with pigtails short and slicked back hair -thick and lush hair \ No newline at end of file +thick and lush hair +pixie cut +flipped hair +nihongami hair \ No newline at end of file diff --git a/csvfiles/humanexpressions.csv b/csvfiles/humanexpressions.csv index a7f76f4..a52bd68 100644 --- a/csvfiles/humanexpressions.csv +++ b/csvfiles/humanexpressions.csv @@ -1,4 +1,5 @@ -OR(;-heshe- is feeling;uncommon) OR(;very;normal) angry +OR(;-heshe- is feeling;uncommon) OR(;very;normal) angry OR(;, anger vein;rare) +OR(;-heshe- is feeling;uncommon) OR(;very;normal) annoyed OR(;-heshe- is feeling;uncommon) furious OR(;-heshe- is feeling;uncommon) OR(;very;normal) confused OR(;-heshe- is feeling;uncommon) OR(;very;normal) akward @@ -26,6 +27,8 @@ OR(;-heshe- has a;uncommon) OR(;very;normal) smug smile OR(;-heshe- has a;uncommon) OR(;very;normal) light smile OR(;-heshe- has a;uncommon) OR(;very;normal) radiant smile OR(;-heshe- has a;uncommon) OR(;very;normal) wicked smile +OR(;-heshe- has a;uncommon) OR(;very;normal) seductive smile +OR(;-heshe- has a;uncommon) OR(;very;normal) sad smile OR(;-heshe- is;uncommon) biting -himher- lip OR(;-heshe- is looking;uncommon) OR(;very;normal) OR(neutral;hollow) OR(;-heshe- is feeling;uncommon) OR(;very;normal) shy OR(;, looking away;uncommon) @@ -44,8 +47,16 @@ OR(;-heshe- is ;uncommon) expressing guilt OR(;-heshe- is ;uncommon) expressing joy OR(;-heshe- is;uncommon) laughing OR(;-heshe- is;uncommon) grinning +doyagao OR(;-heshe- is ;uncommon) feeling OR(;very;normal) relaxed OR(;-heshe- is ;uncommon) feeling OR(;very;normal) insecure OR(;-heshe- is ;uncommon) feeling OR(;very;normal) shocked OR(;-heshe- is ;uncommon) feeling OR(;very;normal) worried -OR(;-heshe- is ;uncommon) feeling OR(;very;normal) resentfull \ No newline at end of file +OR(;-heshe- is ;uncommon) feeling OR(;very;normal) resentfull +OR(;-heshe- is ;uncommon) feeling OR(;very;normal) flustered +OR(;-heshe- is ;uncommon) blushing +OR(;-heshe- is ;uncommon) feeling OR(;very;normal) crazy +OR(;-heshe- is ;uncommon) OR(;very;normal) drunk +OR(;-heshe- is ;uncommon) grimacing +OR(;-heshe- is ;uncommon) rolling eyes +OR(;-heshe- is ;uncommon) staring \ No newline at end of file diff --git a/csvfiles/humanexpressions_less_verbose.csv b/csvfiles/humanexpressions_less_verbose.csv new file mode 100644 index 0000000..f96692f --- /dev/null +++ b/csvfiles/humanexpressions_less_verbose.csv @@ -0,0 +1,58 @@ +OR(;very;normal) angry OR(;, anger vein;rare) +OR(;very;normal) annoyed +furious +OR(;very;normal) confused +OR(;very;normal) akward +crying +OR(;very;normal) fearful +OR(;very;normal) disappointed +OR(;very;normal) happy +very happy, glinting eyes +OR(;very;normal) lonely +OR(;very;normal) lustful +OR(;very;normal) sad +screaming +smiling +smirking +chuckling +yawning +bewildered +winking +OR(;very;normal) smug +laughing hysterically +OR(;very;normal) smug smile +OR(;very;normal) light smile +OR(;very;normal) radiant smile +OR(;very;normal) wicked smile +OR(;very;normal) seductive smile +OR(;very;normal) sad smile +biting -himher- lip +OR(;very;normal) shy OR(;, looking away;uncommon) +looking away +in awe +OR(;very;normal) curious +OR(;very;normal) bored +OR(;very;normal) embarrased +OR(;very;normal) in love +feeling OR(;very;normal) melancholy +feeling OR(;very;normal) proud +feeling OR(;very;normal) envious +feeling OR(;very;normal) grateful +expressing shame +expressing guilt +expressing joy +laughing +grinning +doyagao +feeling OR(;very;normal) relaxed +feeling OR(;very;normal) insecure +feeling OR(;very;normal) shocked +feeling OR(;very;normal) worried +feeling OR(;very;normal) resentfull +feeling OR(;very;normal) flustered +blushing +crazy +OR(;very;normal) drunk +grimace +rolling eyes +staring \ No newline at end of file diff --git a/csvfiles/humanvomit.csv b/csvfiles/humanvomit.csv index 898b496..4609ba7 100644 --- a/csvfiles/humanvomit.csv +++ b/csvfiles/humanvomit.csv @@ -16,4 +16,6 @@ matte skin perfect skin skin pores freckles -photo-realistic face \ No newline at end of file +photo-realistic face +-buildfacepart- +-buildfacepart-, -buildfacepart- \ No newline at end of file diff --git a/csvfiles/imagetypes_anime.csv b/csvfiles/imagetypes_anime.csv new file mode 100644 index 0000000..506100f --- /dev/null +++ b/csvfiles/imagetypes_anime.csv @@ -0,0 +1,22 @@ +3D +anime +2D anime +OR(cartoon;illustration;detailed illustration;drawing;sketch) +anime screenshot +OR(artbook;calendar;card) +OR(comic;manga) +OR(cover;album cover;character single;cover page;doujin cover;dvd cover;fake cover;video game cover;magazine cover;manga cover) +OR(fake screenshot;fake phone screenshot) +OR(game cg;game screenshot) +highres +absurdres +OR(icon;logo) +lineart +pixel art +poster +wallpaper +wallpaper forced +widescreen +official wallpaper +OR(concept art;digital art) +OR(fantasy;sci-fi) art \ No newline at end of file diff --git a/csvfiles/lenses.csv b/csvfiles/lenses.csv index aadf3e9..6fbbdfa 100644 --- a/csvfiles/lenses.csv +++ b/csvfiles/lenses.csv @@ -17,4 +17,9 @@ telephoto lens 800mm lens macro lens L USM -pinhole lens \ No newline at end of file +pinhole lens +atmospheric perspective +panorama +perspective +vanishing point +pov \ No newline at end of file diff --git a/csvfiles/lenses_light.csv b/csvfiles/lenses_light.csv index 5c5dcd5..146268f 100644 --- a/csvfiles/lenses_light.csv +++ b/csvfiles/lenses_light.csv @@ -4,4 +4,5 @@ Depth of field 270mm 50mm Selective focus 800mm lens -L USM \ No newline at end of file +L USM +atmospheric perspective \ No newline at end of file diff --git a/csvfiles/lenses_medium.csv b/csvfiles/lenses_medium.csv index a048b82..39550a8 100644 --- a/csvfiles/lenses_medium.csv +++ b/csvfiles/lenses_medium.csv @@ -10,4 +10,6 @@ F/8 F/14 Selective focus 800mm lens -L USM \ No newline at end of file +L USM +atmospheric perspective +pov \ No newline at end of file diff --git a/csvfiles/poses.csv b/csvfiles/poses.csv index acb0fc2..b0160bc 100644 --- a/csvfiles/poses.csv +++ b/csvfiles/poses.csv @@ -4,6 +4,7 @@ looking towards camera looking away from camera looking to the side Looking over the shoulder +Looking away Sitting Standing Jumping @@ -44,6 +45,9 @@ Action pose Sexy pose giving you the finger Pointing at you +Pointing at self +Pointing down +Pointing up Crouching down Vivacious pose Bending forward @@ -78,4 +82,30 @@ Walking towards camera Walking away from camera peace sign pose -humanexpression- pose -Layback pose \ No newline at end of file +Layback pose +Raised eyebrow +Rolling eyes +Kubrick stare +Finger smile +Beckoning +Stroking own chin +Flirting at the camera +Shading -hisher- eyes +Thumbs up pose +Thumbs down pose +Raising fist pose +Curtsey pose +Victory pose +Making V-sign +Butterfly sitting +Hands resting on head +Twisted torso pose +T-posing +Outstretched hand +Knee up pose +Knees apart pose +-animal- style pose +archer pose +Villain pose +Stretched legs pose +-rpgclass- pose \ No newline at end of file diff --git a/csvfiles/special_lists/buildaccessorie.csv b/csvfiles/special_lists/buildaccessorie.csv index d15011e..a6479f4 100644 --- a/csvfiles/special_lists/buildaccessorie.csv +++ b/csvfiles/special_lists/buildaccessorie.csv @@ -1 +1,3 @@ -OR(;-heshe- has a;rare) OR(;-descriptor-;normal) OR(;-culture-;uncommon) OR(;-color-;uncommon) -accessory- OR(; , -accessory-; , -descriptor- -accessory-;rare) OR(; and -accessory-;unique) \ No newline at end of file +OR(;-heshe- has a;rare) OR(;-descriptor-;normal) OR(;-culture-;uncommon) OR(;-color-;uncommon) -accessory- OR(; , -accessory-; , -descriptor- -accessory-;rare) OR(; and -accessory-;unique) +OR(;-heshe- has a;rare) OR(;-descriptor-;normal) -accessory- +OR(;-heshe- has a;rare) OR(;-basicbitchdescriptor-;normal) -accessory- \ No newline at end of file diff --git a/csvfiles/special_lists/buildaccessorie_less_verbose.csv b/csvfiles/special_lists/buildaccessorie_less_verbose.csv index 548bf0f..e9732d9 100644 --- a/csvfiles/special_lists/buildaccessorie_less_verbose.csv +++ b/csvfiles/special_lists/buildaccessorie_less_verbose.csv @@ -1 +1,2 @@ -OR(;-descriptor-;normal) OR(;-culture-;uncommon) OR(;-color-;uncommon) -accessory- OR(; , -accessory-; , -descriptor- -accessory-;rare) OR(; and -accessory-;unique) \ No newline at end of file +OR(;-heshe- has a;rare) OR(;-descriptor-;normal) -accessory- OR(; , -accessory-; , -descriptor- -accessory-;rare) OR(; and -accessory-;unique) +OR(;-heshe- has a;rare) OR(;-basicbitchdescriptor-;normal) -accessory- \ No newline at end of file diff --git a/csvfiles/special_lists/buildface_less_verbose.csv b/csvfiles/special_lists/buildface_less_verbose.csv index a4675ef..c600b7e 100644 --- a/csvfiles/special_lists/buildface_less_verbose.csv +++ b/csvfiles/special_lists/buildface_less_verbose.csv @@ -2,4 +2,6 @@ combination of OR(-nonfictional-;-fictional-;legendary) OR(;, OR(-nonfictional-; -facepart- of OR(-nonfictional-;-fictional-;legendary), -facepart- of OR(-nonfictional-;-fictional-;legendary) OR(;very;legendary) -buildfacepart- OR(; OR(,;and) -buildfacepart-;normal) OR(; and -buildfacepart-;legendary) OR(;very;legendary) -humandescriptor- -facepart- OR(; and -humandescriptor- -facepart-;uncommon) --facepart- of OR(-conceptsuffix-;-basicbitchdescriptor-;uncommon) OR(; and -facepart- of OR(-conceptsuffix-;-basicbitchdescriptor-;uncommon);uncommon) \ No newline at end of file +-facepart- of OR(-conceptsuffix-;-basicbitchdescriptor-;uncommon) OR(; and -facepart- of OR(-conceptsuffix-;-basicbitchdescriptor-;uncommon);uncommon) +-buildfacepart-, -buildfacepart- +-buildfacepart- \ No newline at end of file diff --git a/csvfiles/special_lists/buildhair_less_verbose.csv b/csvfiles/special_lists/buildhair_less_verbose.csv index e941070..27024a6 100644 --- a/csvfiles/special_lists/buildhair_less_verbose.csv +++ b/csvfiles/special_lists/buildhair_less_verbose.csv @@ -1,2 +1,3 @@ -OR(-haircolor-;-hairdescriptor-;-culture-;uncommon) hair OR(styled as -hairstyle-;, ;rare) -OR(-haircolor-; -hairstyle-) OR(hairstyle;hair) \ No newline at end of file +OR(-haircolor-;-hairdescriptor-;-culture-;uncommon) hair +OR(-haircolor-; -hairstyle-) OR(hairstyle;hair) +-hairstyle- \ No newline at end of file diff --git a/csvfiles/special_lists/buildoutfit_less_verbose.csv b/csvfiles/special_lists/buildoutfit_less_verbose.csv index 775c213..61ba277 100644 --- a/csvfiles/special_lists/buildoutfit_less_verbose.csv +++ b/csvfiles/special_lists/buildoutfit_less_verbose.csv @@ -2,12 +2,12 @@ , OR(;-outfitdescriptor-;normal) OR(;-outfitdescriptor-;uncommon) OR(;-color-;uncommon) -outfit- OR(;from the OR(-age-;the -agecalculator-);rare) , OR(;-outfitdescriptor-;normal) OR(;-outfitdescriptor-;uncommon) OR(;-color-;uncommon) -outfit- OR(; and OR(;-outfitdescriptor-;uncommon) OR(;-color-;uncommon) -outfit-;rare) , OR(-job-;-rpgclass-;-season-;-animal--style) OR(-minioutfit-;-outfit-;rare) -, OR(;-outfitdescriptor-;uncommon) OR(-minioutfit-;-outfit-;rare) OR(;OR(designed;made;inspired;forged) by OR(-brand-;-fashiondesigner-);legendary) +, OR(;-outfitdescriptor-;uncommon) OR(-minioutfit-;-outfit-;rare) , OR(-material-;-color-;-element-;uncommon) -overrideoutfit- , OR(;-outfitdescriptor-;-material-;-color-;uncommon) OR(-outfit-;-minioutfit-;rare), OR(-pattern-;-outfitprinttotal-;-material-;rare) -print-, , OR(;-outfitdescriptor-;normal) -outfit-, OR(-outfitdescriptor-;-color-), OR(-pattern-;-outfitprinttotal-;-material-;uncommon) -print- OR(;-material-;rare) , -culture- -outfit-, OR(;OR(-outfitdescriptor-;-color-),;normal) -, OR(;-outfitdescriptor-;normal) OR(;-color-;uncommon) OR(;-culture-;uncommon) OR(;-material-;rare) -outfit- OR(that was OR(designed;made;inspired;forged) by -brand-;rare) +, OR(;-outfitdescriptor-;normal) OR(;-color-;uncommon) OR(;-culture-;uncommon) OR(;-material-;rare) -outfit- , OR(;-outfitdescriptor-;normal) OR(-minioutfit-;-outfit-;uncommon), -outfitvomit- , OR(;-outfitdescriptor-;normal) -outfit-, OR(;OR(is tailored by -fashiondesigner- OR(; and -fashiondesigner-;uncommon);-charactertype- OR(;and -charactertype-;rare));rare) , OR(;-outfitdescriptor-;normal) -artmovement- fashion style -outfit- diff --git a/csvfiles/vomit.csv b/csvfiles/vomit.csv index ad40658..5426c36 100644 --- a/csvfiles/vomit.csv +++ b/csvfiles/vomit.csv @@ -54,6 +54,8 @@ dripping -color- and -color- dripping with -color- Dufaycolor Photograph dynamic composition +drop shadow +emphasis lines Ebru Elegant Embossing @@ -65,6 +67,7 @@ expressive brush strokes fae folkore fairy tale Film grain +foreshortening Floral motifs Folded -material- full of -color- diff --git a/prompttester.py b/prompttester.py index 0d566e1..f7f0fd1 100644 --- a/prompttester.py +++ b/prompttester.py @@ -111,11 +111,11 @@ def generateprompts(amount = 1,insanitylevel="5",subject="all", artist="all", im if __name__ == "__main__": generateprompts(10,5 ,"all" # subject - ,"all" # artists - ,"all" # image type "only other types", "only templates mode", "art blaster mode", "quality vomit mode", "color cannon mode", "unique art mode", "massive madness mode", "photo fantasy mode", "subject only mode", "fixed styles mode", "dynamic templates mode", "artify mode" + ,"none" # artists + ,"all" # image type "only other types", "only templates mode", "all - anime", "art blaster mode", "quality vomit mode", "color cannon mode", "unique art mode", "massive madness mode", "photo fantasy mode", "subject only mode", "fixed styles mode", "dynamic templates mode", "artify mode" , False # only artists ,"","" - ,"" #prefix prompt + ,"masterpiece, best quality, very aesthetic, absurdres" #prefix prompt ,"" #suffix prompt ,"",1,"" ,"" # subject override @@ -130,7 +130,7 @@ if __name__ == "__main__": , -1 # seed , "" #outfit override , False #prompt_g_and_l - , "SD1.5" #base model + , "Anime Model" #base model , "" #preset "All (random)..." , "" # superprompter ) \ No newline at end of file diff --git a/scripts/onebuttonprompt.py b/scripts/onebuttonprompt.py index 6f46957..e005ec5 100644 --- a/scripts/onebuttonprompt.py +++ b/scripts/onebuttonprompt.py @@ -18,14 +18,14 @@ from csv_reader import * from one_button_presets import OneButtonPresets OBPresets = OneButtonPresets() -basemodelslist = ["SD1.5", "SDXL", "Stable Cascade"] +basemodelslist = ["SD1.5", "SDXL", "Stable Cascade", "Anime Model"] #subjects = ["all","object","animal","humanoid", "landscape", "concept"] subjects =["------ all"] subjectsubtypesobject = ["all"] subjectsubtypeshumanoid = ["all"] subjectsubtypesconcept = ["all"] artists = ["all", "all (wild)", "none", "popular", "greg mode", "3D", "abstract", "angular", "anime" ,"architecture", "art nouveau", "art deco", "baroque", "bauhaus", "cartoon", "character", "children's illustration", "cityscape", "cinema", "clean", "cloudscape", "collage", "colorful", "comics", "cubism", "dark", "detailed", "digital", "expressionism", "fantasy", "fashion", "fauvism", "figurativism", "gore", "graffiti", "graphic design", "high contrast", "horror", "impressionism", "installation", "landscape", "light", "line drawing", "low contrast", "luminism", "magical realism", "manga", "melanin", "messy", "monochromatic", "nature", "nudity", "photography", "pop art", "portrait", "primitivism", "psychedelic", "realism", "renaissance", "romanticism", "scene", "sci-fi", "sculpture", "seascape", "space", "stained glass", "still life", "storybook realism", "street art", "streetscape", "surrealism", "symbolism", "textile", "ukiyo-e", "vibrant", "watercolor", "whimsical"] -imagetypes = ["all", "all - force multiple", "none", "photograph", "octane render","digital art","concept art", "painting", "portrait", "anime key visual", "only other types", "only templates mode", "dynamic templates mode", "art blaster mode", "quality vomit mode", "color cannon mode", "unique art mode", "massive madness mode", "photo fantasy mode", "subject only mode", "fixed styles mode", "the tokinator"] +imagetypes = ["all", "all - force multiple", "all - anime", "none", "photograph", "octane render","digital art","concept art", "painting", "portrait", "anime", "only other types", "only templates mode", "dynamic templates mode", "art blaster mode", "quality vomit mode", "color cannon mode", "unique art mode", "massive madness mode", "photo fantasy mode", "subject only mode", "fixed styles mode", "the tokinator"] promptmode = ["at the back", "in the front"] promptcompounder = ["1", "2", "3", "4", "5"] ANDtogglemode = ["none", "automatic", "prefix AND prompt + suffix", "prefix + prefix + prompt + suffix"]