diff --git a/2025-restaurants.json b/2025-restaurants.json index b3228fb..6dd683f 100644 --- a/2025-restaurants.json +++ b/2025-restaurants.json @@ -14,15 +14,45 @@ "courses": { "First Course": [ { - "name": "Quesadilla", - "desc": "Braised short rib, pepperjack cheese, black bean corn salsa, chipotle crema, queso fresco, pico de gallo" + "name": "Short Rib", + "desc": "Quesadilla Braised short rib, pepperjack cheese, black bean corn salsa, chipotle crema, queso fresco, pico de gallo" + }, + { + "name": "Ahi Tuna Crudo", + "desc": "Cucumber mignonette, shallots, garlic oil, wonton crisps, watermelon radishes" + }, + { + "name": "Kale and Brussels Sprouts Salad", + "desc": "Chopped kale, shredded Brussels sprouts, grated" } ], "Second Course": [ - + { + "name": "Southwestern Sirloin", + "desc": "Marinated top sirloin, sweet potato hash, chimichurri, fried sweet potato crisps, asparagus GF" + }, + { + "name": "Mediterranean Chicken", + "desc": "Pan-seared French cut chicken breast, saffron rice, squash medley, lemon garlic aioli, tomato-shallot relish, balsamic glaze" + }, + { + "name": "Cajun Jambalaya Pasta", + "desc": "Chicken, andouille sausage, creamy Cajun sauce, okra, penne, garlic bread" + } ], "Third Course": [ - + { + "name": "Strawberry Bliss", + "desc": "Yellow cake stacked with strawberry compote, vanilla custard, basil strawberry coulis, vanilla anglaise" + }, + { + "name": "Chocolate Peanut Butter Cake", + "desc": "Chocolate and peanut butter layer cake, Irish cream chocolate ganache" + }, + { + "name": "Crème Brulée", + "desc": "House-made crème brulée, fresh mixed berries GF" + } ] } } @@ -505,16 +535,49 @@ "url": "https://inlanderrestaurantweek.com/project/bardenay/", "menu": { "hours": "Menu served Sun-Thu, 5-9 pm; Fri-Sat, 5-10 pm", - "phone": "", + "phone": "(208) 765-1540", "courses": { "First Course": [ - + { + "name": "Corn Panna Cotta", + "desc": "Savory roasted corn custard, cornbread, popcorn, avocado crema, tajin, cotija, and chives V" + }, + { + "name": "Steak \u0026 Potato Canapés", + "desc": "Charbroiled beef tenderloin, Boursin cheese spread, arugula, pickled red onion, and balsamic glaze on roasted Yukon gold potato medallions GF" + }, + { + "name": "Smoked Trout Dip", + "desc": "Local Idaho red trout cream cheese spread, beet-marinated deviled eggs, capers, candied bacon, lemon zest, and everything bagel crisps" + } ], "Second Course": [ - + { + "name": "Massaman Curry Lamb Shank", + "desc": "Braised spiced lamb shank, carrots, and potatoes in a coconut milk curry over saffron basmati rice GF DF" + }, + { + "name": "Miso Red Snapper", + "desc": "Charbroiled Atlantic red snapper fillet, sweet miso-tamari glaze, chilled soba noodle salad with edamame, water chestnuts, peppers, onions, and sesame seeds DF" + }, + { + "name": "Mushroom Spanakopita", + "desc": "Wild mushroom medley, spinach, fresh herbs, and feta baked in puff pastry with roasted carrot and chickpea Greek salad and tzatziki V" + } ], "Third Course": [ - + { + "name": "Wasabi Mojito Cheesecake", + "desc": "Minty-lime cheesecake with a hint of wasabi, Bardenay rum mojito sauce, whipped cream, and frosted lime zest GF" + }, + { + "name": "Elvis Cake", + "desc": "Peanut butter mousse in a cookie crust with brûléed banana, caramel, candied bacon, whipped cream, and shaved chocolate GF" + }, + { + "name": "Root Beer Float", + "desc": "Not Your Father’s Root Beer over house-spun espresso-cinnamon ice cream. Must be 21 to order" + } ] } } @@ -530,16 +593,49 @@ "url": "https://inlanderrestaurantweek.com/project/barkrescuepub/", "menu": { "hours": "Menu served Sun-Thur, 4-9 pm; Fri-Sat, 4-10 pm", - "phone": "", + "phone": "(509) 418-2551", "courses": { "First Course": [ - + { + "name": "Korean Spam Dog", + "desc": "Two spam and mozzarella-stuffed Korean dogs served with a side of kimchi slaw and sriracha aioli" + }, + { + "name": "Crispy Brussels", + "desc": "Crispy Brussels sprouts with parmesan and lemon basil dipping sauce GF V" + }, + { + "name": "Thai Mozzarella Egg Rolls", + "desc": "Mozzarella and Thai peanut sauce egg rolls served with a sriracha dipping sauce" + } ], "Second Course": [ - + { + "name": "Garlic Steak Bites", + "desc": "Garlic parmesan steak bites on top of a potato mash and served with a chimichurri sauce GF" + }, + { + "name": "Tamale with Rojo Pork", + "desc": "Green chili and cheese tamale topped with rojo braised pork GF" + }, + { + "name": "Tofu Schnitzel Sandwich", + "desc": "Ultra-crispy tofu schnitzel sandwich with garlic, mayo, arugula, tomato and a fried egg on a brioche bun V" + } ], "Third Course": [ - + { + "name": "Oreo Icebox Cake", + "desc": "Oreo Icebox Cake V+" + }, + { + "name": "Apple Compote Hand Pie", + "desc": "Apple Compote Hand Pie" + }, + { + "name": "Roasted Pineapple Angel Food Cake", + "desc": "Angel food cake with brown sugar roasted pineapple and a buttercream glaze" + } ] } } @@ -1257,13 +1353,46 @@ "phone": "", "courses": { "First Course": [ - + { + "name": "Signature Salad", + "desc": "Organic baby spinach, brie, bacon, apple and candied walnuts, dressed with pomegranate vinaigrette" + }, + { + "name": "Mac n Cheese", + "desc": "Rich four-cheese sauce, stuffed with cream cheese and topped with gruyere cheese sauce V" + }, + { + "name": "Ahi Poke", + "desc": "Yellow fin tuna, green onion, avocado, crispy tortilla, seaweed and cucumber, topped with tamari sauce" + } ], "Second Course": [ - + { + "name": "Halibut Filet", + "desc": "Tender halibut in a buerre blanc sauce on parmesan risotto with seasonal vegetables and Asian cucumbers GF" + }, + { + "name": "Rack of Lamb", + "desc": "Topped with a huckleberry glaze and goat cheese, served with roasted local potatoes and seasonal vegetables GF" + }, + { + "name": "Surf n Turf Burger", + "desc": "Beef filet topped with butter poached lobster and bearnaise sauce, served on a brioche bun with garlic fries and a lemon aioli" + } ], "Third Course": [ - + { + "name": "Blueberry Cobbler", + "desc": "Local blueberries, crispy topping with blueberry sauce, whipped cream and vanilla bean ice cream V" + }, + { + "name": "Flourless Chocolate Cake", + "desc": "Served with a huckleberry glaze and whipped cream GF V" + }, + { + "name": "New York Cheesecake", + "desc": "Creamy classic cheesecake topped with strawberry sauce and whipped cream" + } ] } } @@ -1573,13 +1702,46 @@ "phone": "", "courses": { "First Course": [ - + { + "name": "Burrata Naan", + "desc": "Burrata cheese, baby arugula, spinach pesto, marinara sauce on our house-made naan GFA V" + }, + { + "name": "Whipped Feta and Pita", + "desc": "Creamy whipped feta, pickled garlic, sweet and spicy honey drizzle GFA V" + }, + { + "name": "Scallops and Arugula Salad", + "desc": "Pan-seared scallops, baby arugula, shaved parmesan, pickled shallots, sunflower seeds, microgreens, tossed with a gin vinaigrette GF" + } ], "Second Course": [ - + { + "name": "Bourbon Butter Raviolis", + "desc": "Bourbon butter, shallots, garlic, white wine, heavy cream, wild mushroom stuffed raviolis garnished with parsley and parmesan cheese V" + }, + { + "name": "Cajun Trout", + "desc": "Blackened steelhead trout, sautéed spinach, over garlic Yukon gold mashed potatoes" + }, + { + "name": "Birria Beef Over Polenta", + "desc": "Birria-braised beef in a consommé, chipotle sauce, cojita cheese, cilantro and tomato" + } ], "Third Course": [ - + { + "name": "Waffles and Cream", + "desc": "Sugar pearl waffles stuffed with French vanilla bean ice cream, salted bourbon caramel" + }, + { + "name": "Tiramisu", + "desc": "Layers of coffee-soaked ladyfingers, creamy mascarpone, cocoa dusting" + }, + { + "name": "Apple and Cherry Crisp", + "desc": "Gingered apple, sour cherry, cinnamon crumble" + } ] } } @@ -1598,13 +1760,46 @@ "phone": "(509) 863-9501", "courses": { "First Course": [ - + { + "name": "Grilled Octopus Salad", + "desc": "Fire grilled octopus, fresh spinach, organic heirloom tomato, cucumber, green onion, pepitas, sweet and tangy citrus vinaigrette GF" + }, + { + "name": "Acorn Squash Arancini", + "desc": "Risotto, acorn squash, herb seasoned bread crumbs, Parmesan Reggiano, smokey tomato jam, green garnish V" + }, + { + "name": "Braised Beet and Fugi Apple Salad", + "desc": "Crisp Fugi apple, braised red and golden beets, herbed ricotta cheese, horseradish vinaigrette, fresh herbs, candied pecans GF V" + } ], "Second Course": [ - + { + "name": "Bison Meatloaf", + "desc": "Savory bison, ground and mixed with traditional breadcrumbs, egg and fresh herbs, sweet and spicy mixed berry glaze, whipped then baked Parmesan Duchess potatoes, garlic roasted green beans" + }, + { + "name": "Smoked Pork Ribs", + "desc": "Smoked then pan-finished tender pork ribs, tangy smokey chipotle barbecue sauce, crispy broiled sunchokes, sweet corn pureé, house-fried chicharrones GF" + }, + { + "name": "Crab and Butternut Squash Pasta", + "desc": "Lump Alaskan Crab meat, spiraled butternut squash, buttery white wine sauce, smoked artichoke hearts, heirloom cherry tomatoes, Parmesan Reggiano, green onion curls Vegetarian upon request GF V" + } ], "Third Course": [ - + { + "name": "Yuzu and Blonde Chocolate Choux Buns", + "desc": "French Choux pastry baked with a sugary craquelin top, citrusy yuzu pastry cream, white chocolate caramel mousse rosette V" + }, + { + "name": "Pot de Creme au Chocolat", + "desc": "Velvety rich chocolate custard, dulce de leche whipped with heavy cream, candied orange GF V" + }, + { + "name": "French Chocolate Cheesecake", + "desc": "Creamy, chocolatey cheesecake, sweet walnut crust, boozy caramel sauce, Chantilly cream V" + } ] } } @@ -2088,13 +2283,46 @@ "phone": "(509) 315-4613", "courses": { "First Course": [ - + { + "name": "Winter Salad", + "desc": "citrus. hazelnut. goat cheese." + }, + { + "name": "Smoked Steelhead", + "desc": "amaranth. roe. almond." + }, + { + "name": "Pork Rillettes", + "desc": "Gander \u0026 Ryegrass bread. olive. caper and raisin chutney." + } ], "Second Course": [ - + { + "name": "Casarecce", + "desc": "pork shoulder ragout. parmesan." + }, + { + "name": "Campanelle", + "desc": "squash. pork belly. pepitas." + }, + { + "name": "Spaghetti", + "desc": "red beef sauce. parmesan." + } ], "Third Course": [ - + { + "name": "Pork Tenderloin", + "desc": "carrot. chicory. hazelnut." + }, + { + "name": "Scallop", + "desc": "cauliflower. mushroom. citrus." + }, + { + "name": "Shortrib", + "desc": "potatoes. kale. root vegetables." + } ] } } @@ -2492,28 +2720,44 @@ "courses": { "First Course": [ { - "name": "GF V", + "name": "Subudana Pakore", "desc": "Subudana (tapioca), potatoes, cumin, and finely chopped fresh herbs, fried as a pakore (fritter) GF V" }, { - "name": "GF V", + "name": "Moong Dal Chaat", "desc": "Moong dal (green lentil) pakore (fritter), served chaat-style (street food snack) topped with sweetened yogurt and chutneys GF V" }, { - "name": "GF V", + "name": "Singhara Aloo Tikki", "desc": "Water chestnut flour, potatoes, cilantro, green chiles, ginger, fresh herbs and spices. Crispy on the outside and deliciously soft inside GF V" } ], "Second Course": [ { - "name": "GF DFA", + "name": "Chicken Methi Mali", + "desc": "Chicken and fenugreek leaves cooked with Indian aromas. Freshly chopped ginger, garlic and fresh yogurt make a thick, creamy sauce. Served with rice and naan GF V+A" + }, + { + "name": "Saag with Goat", "desc": "Goat marinated with yogurt, fresh herbs and Indian aromas. Cooked in creamy saag (spinach sauce), served with rice and naan GF DFA" + }, + { + "name": "Methi Matter Mali", + "desc": "Methi (fenugreek) and green peas cooked with fragrant and creamy gravy with spices. Served with rice and naan GF – Coconut milk option / vegetarian option" } ], "Third Course": [ { - "name": "GF V+", + "name": "Carrot Cake Halwa", + "desc": "Fresh carrots roasted in butter, pistachios, cashews, golden raisins, and plenty of ground cardamom" + }, + { + "name": "Paan Ice Cream", "desc": "This refreshing paan (betel leaves) ice cream has all the flavors: rose petal jam, candied fennel, dates, and coconut GF V+" + }, + { + "name": "Gulabjamun with Rabdi", + "desc": "Indian donuts served with delicious, creamy, and rich rabdi (pistachio and cashew sauce) V" } ] } @@ -2766,28 +3010,44 @@ "courses": { "First Course": [ { - "name": "GF V", + "name": "Subudana Pakore", "desc": "Subudana (tapioca), potatoes, cumin, and finely chopped fresh herbs, fried as a pakore (fritter) GF V" }, { - "name": "GF V", + "name": "Moong Dal Chaat", "desc": "Moong dal (green lentil) pakore (fritter), served chaat-style (street food snack) topped with sweetened yogurt and chutneys GF V" }, { - "name": "GF V", + "name": "Singhara Aloo Tikki", "desc": "Water chestnut flour, potatoes, cilantro, green chiles, ginger, fresh herbs and spices. Crispy on the outside and deliciously soft inside GF V" } ], "Second Course": [ { - "name": "GF DFA", + "name": "Chicken Methi Mali", + "desc": "Chicken and fenugreek leaves cooked with Indian aromas. Freshly chopped ginger, garlic and fresh yogurt make a thick, creamy sauce. Served with rice and naan GF V+A" + }, + { + "name": "Saag with Goat", "desc": "Goat marinated with yogurt, fresh herbs and Indian aromas. Cooked in creamy saag (spinach sauce), served with rice and naan GF DFA" + }, + { + "name": "Methi Matter Mali", + "desc": "Methi (fenugreek) and green peas cooked with fragrant and creamy gravy with spices. Served with rice and naan GF – Coconut milk option / vegetarian option" } ], "Third Course": [ { - "name": "GF V+", + "name": "Carrot Cake Halwa", + "desc": "Fresh carrots roasted in butter, pistachios, cashews, golden raisins, and plenty of ground cardamom" + }, + { + "name": "Paan Ice Cream", "desc": "This refreshing paan (betel leaves) ice cream has all the flavors: rose petal jam, candied fennel, dates, and coconut GF V+" + }, + { + "name": "Gulabjamun with Rabdi", + "desc": "Indian donuts served with delicious, creamy, and rich rabdi (pistachio and cashew sauce) V" } ] } @@ -3007,31 +3267,43 @@ "courses": { "First Course": [ { - "name": "GFA V V+", + "name": "Hummus Dip with Pita", "desc": "Slow-cooked garbanzo beans blended with tahini, lemon and garlic, topped with extra virgin olive oil and served with pita GFA V V+ – Add beef shawarma meat $14" }, { - "name": "GFA V", + "name": "Tzatziki Dip with Pita", "desc": "Fresh Greek yogurt, cucumber, fresh dill, mint and garlic, served with pita GFA V – Add lamb kofta skewer $9" }, { - "name": "GF V V+", + "name": "Vegetarian Grape Leaves with Tzatziki", "desc": "Six handmade rolls stuffed with seasoned rice and vegetables, slow-cooked in tomato broth and olive oil, served with tzatziki sauce GF V V+ – Add gyro meat $12" } ], "Second Course": [ { - "name": "GF V V+", + "name": "Chicken Shish Kebab Platter", + "desc": "Two skewers of marinated tenderloin chunks grilled on an open flame, served over saffron turmeric basmati rice with a side of Mediterranean salad and garlic sauce GF – Upgrade side to tabouleh $6" + }, + { + "name": "Falafel Dinner Platter", "desc": "Deep fried falafel patties served over saffron turmeric basmati rice with a side of Mediterranean salad and our tahini sauce GF V V+ – Upgrade side to lentil soup $8" + }, + { + "name": "Gyros Greek Platter", + "desc": "Grilled beef and lamb strips served over saffron turmeric basmati rice with a side of Mediterranean salad and our tahini sauce DF – Upgrade side to Greek salad $6" } ], "Third Course": [ { - "name": "GF V", + "name": "Lebanese Rice Pudding", "desc": "Creamy rice pudding flavored with orange blossom and rose water GF V – Add ice cream scoop $5" }, { - "name": "GF V V+", + "name": "Namoura (Semolina Cake)", + "desc": "Popular classic Middle Eastern dessert made with semolina flour and topped with a sweet sugar syrup – Add nuts and honey $5" + }, + { + "name": "Halva", "desc": "A Middle Eastern treat made from tahini GF V V+ – Add pita $2" } ] @@ -3628,13 +3900,46 @@ "phone": "", "courses": { "First Course": [ - + { + "name": "EFESTĒ Feral Sauvignon Blanc", + "desc": "White peach, lime leaf, flint" + }, + { + "name": "No-Li Porch Glow Amber", + "desc": "Crisp and refreshing with a hint of chocolate malt" + }, + { + "name": "Maple New Fashioned", + "desc": "Browne Family whiskey, barrel-aged maple syrup, Amarena cherry juice, Peychaud’s bitters" + } ], "Second Course": [ - + { + "name": "Double Smash Burger", + "desc": "Two quarter-pound Prime beef patties, American cheese, caramelized onion, aioli and Thousand Island on a brioche bun, served with french fries" + }, + { + "name": "8 oz. New York", + "desc": "Russet purée, seasonal vegetable, brandy peppercorn demi-glace" + }, + { + "name": "Pan-Seared Salmon", + "desc": "Champagne vinaigrette orzo, Brussels sprouts, bacon, mustard beurre blanc" + } ], "Third Course": [ - + { + "name": "Crème Brûlée", + "desc": "Baked coconut vanilla custard, caramelized sugar" + }, + { + "name": "Cranberry Orange Chiffon", + "desc": "White chocolate chiffon cake, orange white chocolate mousse, cranberry gelée" + }, + { + "name": "Strawberry Rhubarb Sorbet", + "desc": "Fresh berries, mint" + } ] } } @@ -3944,13 +4249,46 @@ "phone": "(509) 323-2578", "courses": { "First Course": [ - + { + "name": "Burrata Caprese", + "desc": "Heirloom tomato, red pesto, basil, grilled baguette V" + }, + { + "name": "Roasted Beet Salad", + "desc": "Roasted beets and watercress, pancetta, chevre, lemon vinaigrette GF" + }, + { + "name": "Baby Kale Caesar", + "desc": "Baby kale, garlic crouton, aged Parmesan Add chicken $5 or shrimp $8" + } ], "Second Course": [ - + { + "name": "Risotto with Roasted Butternut Squash", + "desc": "Risotto, roasted butternut squash, sage, smoked gouda and mascarpone" + }, + { + "name": "Carleton Farms Pork Loin", + "desc": "Pork loin brined and lightly smoked, baby kale, garlic chips, gruyere mashed potato, honey-apricot gastrique" + }, + { + "name": "Flatiron Steak Frites Wild Mushrooms", + "desc": "Flatiron steak frites wild mushrooms, roasted leeks, 10-year aged balsamic, truffle fries" + } ], "Third Course": [ - + { + "name": "Peach Bread Pudding", + "desc": "Fig jam, vanilla crème anglaise" + }, + { + "name": "Coconut Panna Cotta", + "desc": "Coconut panna cotta, raspberries, lemon curd, Chantilly cream" + }, + { + "name": "Crème Brulee", + "desc": "" + } ] } } @@ -4085,15 +4423,45 @@ "phone": "(509) 934-1979", "courses": { "First Course": [ - + { + "name": "Steak Bites", + "desc": "Steak bites marinated in house-made signature steak sauce. Served with cheesy garlic bread" + }, + { + "name": "Caesar Salad", + "desc": "Romaine, house-made Caesar dressing, croutons and grated parmesan cheese GFA – Add chicken $6" + }, + { + "name": "Garlic Cheese Curds", + "desc": "Garlic breaded Wisconsin white cheddar cheese curds with Ponderosa boom-boom dipping sauce V" + } ], "Second Course": [ - + { + "name": "Chicken Fried Steak", + "desc": "12 oz. chicken fried steak served with vegetable medley and choice of potatoes" + }, + { + "name": "Bleu Cheese \u0026 Pecan Salmon", + "desc": "Pecan and bleu cheese crusted grilled salmon. Served with white rice and vegetable medley GFA" + }, + { + "name": "Bourbon Chicken", + "desc": "Grilled chicken breast topped with mushroom and onion bourbon sauce. Served with mashed potatoes and vegetable medley" + } ], "Third Course": [ { - "name": "GFA V", + "name": "Brownie Skillet", + "desc": "Warm brownie in a cast iron skillet topped with vanilla ice cream V" + }, + { + "name": "Creme Brulee", "desc": "House-made creme brulee GFA V" + }, + { + "name": "Lemon Cookie Sandwich", + "desc": "Lemon and white chocolate chip cookie filled with vanilla ice cream and house-made bourbon caramel sauce V" } ] } @@ -4735,13 +5103,46 @@ "phone": "(509) 326-7251", "courses": { "First Course": [ - + { + "name": "Celtic Caesar Salad", + "desc": "Chopped romaine, baby kale, shaved Parmesan, house-made croutons" + }, + { + "name": "Donegal Bay Clam Chowder", + "desc": "Creamy clam chowder, chopped red pepper, cabbage, onion, potato" + }, + { + "name": "Boxty Cakes", + "desc": "Two breaded potato cakes with corned beef and Dubliner cheese, deep fried" + } ], "Second Course": [ - + { + "name": "Corned Beef and Cabbage", + "desc": "Our signature dish! Slow-cooked, tender corned beef, braised cabbage, colcannon potatoes, creamy horseradish" + }, + { + "name": "Guinness Beef Stew", + "desc": "Guinness-braised Kobe beef cubes, rustic-cut carrots, parsnips, celery, pearl onions with Colcannon-style mashed potatoes on top" + }, + { + "name": "Fish and Chips", + "desc": "Two pieces of wild-caught, sustainable Pacific Cod, hand-breaded in crispy panko and seasonings. Comes with French fries and scratch-made tartar sauce" + } ], "Third Course": [ - + { + "name": "Irish Bread Pudding", + "desc": "Scratch-made and topped with a buttered rum sauce and currants" + }, + { + "name": "Bailey’s Creme Brulee", + "desc": "Bailey’s custard with a caramelized sugar topping and a shortbread shamrock cookie" + }, + { + "name": "Danny Boy’s Chocolate Brownie", + "desc": "Scratch-made chocolate brownie topped with candied pecans and Andes mint crumbles" + } ] } } @@ -5343,13 +5744,46 @@ "phone": "(509) 598-4300", "courses": { "First Course": [ - + { + "name": "Burrata Cheese and Local Beets", + "desc": "Arugula, heirloom tomatoes, aged balsamic reduction GF, V" + }, + { + "name": "Grapefruit Salad", + "desc": "Bibb lettuce, goat cheese, avocado, mandarin oranges, mint-lime vinaigrette GF, V" + }, + { + "name": "Smoky Butternut Squash Bisque", + "desc": "Chipotle pepitas, cilantro GF, V" + } ], "Second Course": [ - + { + "name": "Grilled Bone-In Pork Chop", + "desc": "Smoked apple puree, mashed potatoes, local vegetables GF" + }, + { + "name": "Blueberry Duck Breast", + "desc": "Blueberry gastrique, fingerling potatoes, local vegetables GF" + }, + { + "name": "Pan Seared Sea Scallops", + "desc": "Lemon-tarragon risotto, brown butter, local vegetables GF" + } ], "Third Course": [ - + { + "name": "Rolo Dome", + "desc": "Chocolate mousse, salted caramel GF, V" + }, + { + "name": "Blood Orange Cheesecake", + "desc": "Vanilla cheesecake, blood orange gelee V" + }, + { + "name": "Crème Brûlée", + "desc": "Housemade vanilla custard GF, V" + } ] } } @@ -5415,13 +5849,46 @@ "phone": "(208) 758-0111", "courses": { "First Course": [ - + { + "name": "Tequila Clams", + "desc": "Reposado tequila, Argentinian chorizo, clams, herbs, lime, grilled sourdough GFA Double portion size \u0026#8211; $8" + }, + { + "name": "Half Salad", + "desc": "Half size portion of any salad: Quinoa Greens V+ , Jicama Citrus V , Warmed Spinach, Roasted Beet V , Cezar GFA Add your choice of protein \u0026#8211; $6, Full size salad \u0026#8211; $6" + }, + { + "name": "Elote Cakes", + "desc": "Roasted corn, masa, queso fresco, cilantro, crema, pickled Fresno chilis GF V" + } ], "Second Course": [ - + { + "name": "Churrasco Steak", + "desc": "Argentinian-style grilled skirt steak, chimichurri, mashed sweet potatoes with coconut milk GF Add grilled shrimp \u0026#8211; $8" + }, + { + "name": "Arroz con Gandules", + "desc": "Honduran-style rice dish with pork, pigeon peas, vegetables and spices GF" + }, + { + "name": "Chicken or Vegetable Tamale", + "desc": "Slow cooked pulled chicken or spiced roasted vegetable blend (V), stuffed inside our banana leaf-wrapped Oaxacan style tamales. Gallo pinto and dressed jicama slaw GF Add a second Tamale \u0026#8211; $10" + } ], "Third Course": [ - + { + "name": "Arroz con Leche Flan", + "desc": "Latin-style spiced rice pudding composed within a velvety custard of a flan GF V" + }, + { + "name": "Chocolate Torte", + "desc": "Flourless chocolate torte, pink peppercorn goat’s milk panna cotta, burnt candied orange peel, masa crumble GF V" + }, + { + "name": "Alfajores y Cafe", + "desc": "Latin shortbread cookies served with our signature coffee blend from Coeur d’Alene Coffee Company V Add rum (to your coffee) $8" + } ] } } @@ -6108,13 +6575,46 @@ "phone": "", "courses": { "First Course": [ - + { + "name": "Boudin Balls", + "desc": "Louisiana’s version of a snacking sausage. Served with a jalapeño remoulade" + }, + { + "name": "Whipped Honey Cornbread", + "desc": "Cast-iron seared, whipped honey butter, scallions V" + }, + { + "name": "Louisiana Garlic Soup", + "desc": "Creamy roasted garlic soup. A Louisiana tradition!" + } ], "Second Course": [ - + { + "name": "Duck Gumbo", + "desc": "Duck and Andouille sausage gumbo" + }, + { + "name": "Trout Meuniere", + "desc": "Steelhead trout with a brown butter sauce" + }, + { + "name": "Pork Grillades", + "desc": "Slow-roasted pork shoulder served with our stone-ground cheesy grits GF" + } ], "Third Course": [ - + { + "name": "King Cake", + "desc": "Who will find the baby?! V" + }, + { + "name": "Beignets", + "desc": "A traditional French doughnut V \u0026#8211; Make it an affogato! $7" + }, + { + "name": "Pear \u0026 Almond Tart", + "desc": "Almond frangipane pastry with poached pear topping V" + } ] } } @@ -6193,13 +6693,46 @@ "phone": "", "courses": { "First Course": [ - + { + "name": "Roasted Beet Salad", + "desc": "Organic spring greens tossed in a balsamic white truffle vinaigrette, topped with roasted beets, toasted hazelnuts and chèvre GF V – Vegan available by request" + }, + { + "name": "Jalapeño Cheddar Chicken Soup", + "desc": "Chicken stock base, jalapeños, sharp cheddar cheese, shredded chicken, fresh herbs, and a touch of cream. A must try! GF" + }, + { + "name": "Classic Caesar Salad", + "desc": "Crisp romaine hearts tossed with a classic creamy Caesar dressing, house croutons and Parmigiano-Reggiano cheese. Served with lemon GFA" + } ], "Second Course": [ - + { + "name": "Yellow Curry Prawns or Tofu", + "desc": "House-made yellow curry with just the right amount of kick, with your choice of tofu or prawns. Served with a coconut rice cake, sweet peas, heirloom carrots, roasted red peppers, and micro pea shoots GF – Vegetarian and vegan option available" + }, + { + "name": "Braised Beef Short Ribs", + "desc": "Boneless beef short ribs roasted for 16 hours with rosemary and thyme, served with a green peppercorn red wine pan sauce and “everything” Yukon potatoes GF" + }, + { + "name": "Hunter’s Chicken", + "desc": "Chicken leg and thigh quarter, cured and braised until falling off the bone served with a rich hunter’s sauce full of vegetables, herbs and chicken stock and “everything” Yukon potatoes GF" + } ], "Third Course": [ - + { + "name": "Mini Margarita Pie", + "desc": "Frozen key lime pie with graham cracker crust. Special ingredient: tequila! Topped with whipped cream and red sea salt V" + }, + { + "name": "Wiley’s Bourbon Creme Brûlée", + "desc": "Delicious brûléed custard with vanilla bean and orange peel topped with bourbon-nutmeg caramel and whipped cream GF V" + }, + { + "name": "Chocolate Pot de Creme", + "desc": "A decadent dessert featuring coconut cream, chocolate and a hint of spice. Topped with raspberry puree and candied pecan GF V – Vegan available by request" + } ] } } diff --git a/fix-2025.ps1 b/fix-2025.ps1 deleted file mode 100644 index dbb748f..0000000 --- a/fix-2025.ps1 +++ /dev/null @@ -1,121 +0,0 @@ -# fix-2025.ps1 - Post-process the scraped 2025 restaurant JSON -# Fixes: HTML entities in names/descs, wrong prices, re-fetches 0-course restaurants - -$projectDir = Split-Path -Parent $MyInvocation.MyCommand.Definition -$jsonPath = Join-Path $projectDir '2025-restaurants.json' - -$data = Get-Content $jsonPath -Raw -Encoding UTF8 | ConvertFrom-Json - -function Decode-Html($str) { - if (-not $str) { return $str } - $s = $str - $s = $s -replace '&', '&' - $s = $s -replace ''', "'" - $s = $s -replace '"', '"' - $s = $s -replace '<', '<' - $s = $s -replace '>', '>' - $s = $s -replace ' ', ' ' - $s = $s -replace '\s+', ' ' - $s.Trim() -} - -# ---- Report issues ---- -Write-Host "=== Data Quality Report ===" -Write-Host "Total restaurants: $($data.Count)" -Write-Host "" - -Write-Host "Wrong prices (not 25/35/45):" -$data | Where-Object { $_.price -notin @(25,35,45) } | ForEach-Object { - Write-Host " $($_.slug): price=$($_.price)" -} - -Write-Host "" -Write-Host "Zero-course restaurants (all 3 empty):" -$data | Where-Object { - $_.menu.courses.'First Course'.Count -eq 0 -and - $_.menu.courses.'Second Course'.Count -eq 0 -and - $_.menu.courses.'Third Course'.Count -eq 0 -} | ForEach-Object { Write-Host " $($_.slug) [price=$($_.price)] name=$($_.name)" } - -Write-Host "" -Write-Host "Partial courses (any course != 3):" -$data | Where-Object { - $_.menu.courses.'First Course'.Count -ne 3 -or - $_.menu.courses.'Second Course'.Count -ne 3 -or - $_.menu.courses.'Third Course'.Count -ne 3 -} | Where-Object { - # Exclude totally empty ones (already reported above) - -not ( - $_.menu.courses.'First Course'.Count -eq 0 -and - $_.menu.courses.'Second Course'.Count -eq 0 -and - $_.menu.courses.'Third Course'.Count -eq 0 - ) -} | ForEach-Object { - $c1 = $_.menu.courses.'First Course'.Count - $c2 = $_.menu.courses.'Second Course'.Count - $c3 = $_.menu.courses.'Third Course'.Count - Write-Host " $($_.slug): $c1/$c2/$c3" -} - -Write-Host "" -Write-Host "=== Applying Fixes ===" - -# ---- Fix HTML entities in all string fields ---- -foreach ($r in $data) { - $r.name = Decode-Html $r.name - $r.cuisine = Decode-Html $r.cuisine - - foreach ($course in @('First Course', 'Second Course', 'Third Course')) { - $items = $r.menu.courses.$course - if ($items) { - foreach ($item in $items) { - $item.name = Decode-Html $item.name - $item.desc = Decode-Html $item.desc - } - } - } -} - -# ---- Fix wrong prices using the Wayback Machine price page ---- -# The price page listed restaurants under $25, $35, $45 sections. -# We'll re-fetch pages for wrong-price restaurants using a tighter regex. - -$wrongPrice = $data | Where-Object { $_.price -notin @(25,35,45) } -if ($wrongPrice.Count -gt 0) { - Write-Host "Re-fetching $($wrongPrice.Count) restaurants with wrong prices..." - - foreach ($r in $wrongPrice) { - Write-Host " $($r.slug)..." -NoNewline - try { - $url = "https://web.archive.org/web/20250306132630/https://inlanderrestaurantweek.com/project/$($r.slug)/" - $resp = Invoke-WebRequest -Uri $url -UseBasicParsing -TimeoutSec 60 -ErrorAction Stop - $html = $resp.Content - - # Look specifically for h1 containing a 2-digit price at a tier - $priceM = [regex]::Match($html, '
]*>(.*?)
', $opts)) { + $pc = $pm.Groups[1].Value + if ($pc -notmatch '|') { continue } + $d = Get-Dish $pc + if ($d -and $d.name) { $null = $dishes.Add($d) } + } + return ,$dishes +} + +function Get-CourseBlock($html, $label, $nextLabel) { + $opts = [System.Text.RegularExpressions.RegexOptions]::Singleline + if ($nextLabel) { + $m = [regex]::Match($html, ([regex]::Escape($label) + '(.+?)(?=' + [regex]::Escape($nextLabel) + ')'), $opts) + if ($m.Success) { return $m.Groups[1].Value } + } + $idx = $html.IndexOf($label) + if ($idx -ge 0) { + $sub = $html.Substring($idx, [Math]::Min(8000, $html.Length - $idx)) + $sameDivM = [regex]::Match($sub, '(?s)\s*((?! Dish Name Dish Name 2 Dish Name Dish Name 2 Dish Name Dish Name Dish Name Dish Name First PartSecond Part Description Dish Name Dish Name Part1Part2 Description ]*>(.*?) ]*>(.*?) ]*>(.*?) ]*>(.*?)First Course
Description
Description 2Second Course
First Course
+
Description
Description 2Second Course
+ ...
+
Description text here
With space before br
` inside (India House, Lebanon, Karma, ponderosa)
+```html
+
Description text
Description without span
` is INSIDE the `` tag.
+
+### Style 3 — `` + `` combo (1898 restaurant)
+```html
+$45
+```
+Regex: `\$(\d+)`
+PROBLEM: Some pages show drink prices like $22 that match before the real price.
+SOLUTION: Always build an authoritative slug→price map from the price listing page.
+
+### Price Listing Page — Authoritative Prices
+URL: `https://inlanderrestaurantweek.com/price/` (or Wayback archived version)
+```html
+
Description text
` before ``
+```html
+
Description text
+ $bWithBrM = [regex]::Match($pContent, '(?s)(.*?)
', $opts)
+ if ($bWithBrM.Success) {
+ $name = Get-CleanText $bWithBrM.Groups[1].Value
+ if (Test-ValidDishName $name) {
+ $desc = Get-CleanText ($pContent.Substring($bWithBrM.Index + $bWithBrM.Length))
+ return [PSCustomObject]@{ name = $name; desc = $desc }
+ }
+ }
+
+ # Style 3: Part1...Part2
+ $bM = [regex]::Match($pContent, '(?s)(.*?)', $opts)
+ if ($bM.Success) {
+ $namePart = Get-CleanText $bM.Groups[1].Value
+ if (Test-ValidDishName $namePart) {
+ $afterB = $pContent.Substring($bM.Index + $bM.Length)
+ $sM2 = [regex]::Match($afterB, '(?s)^[^<]*(.*?)(.*)', $opts)
+ if ($sM2.Success) {
+ $p2 = Get-CleanText $sM2.Groups[1].Value
+ if (-not (Test-DietaryTag $p2) -and $p2.Length -ge 2) {
+ return [PSCustomObject]@{ name = "$namePart $p2".Trim(); desc = Get-CleanText $sM2.Groups[2].Value }
+ }
+ }
+ return [PSCustomObject]@{ name = $namePart; desc = Get-CleanText $afterB }
+ }
+ }
+
+ # Style 1: Name
+ $sM = [regex]::Match($pContent, '(?s)(.*?)', $opts)
+ if ($sM.Success) {
+ $name = Get-CleanText $sM.Groups[1].Value
+ if (-not (Test-ValidDishName $name)) { return $null }
+ $afterBr = ''
+ if ($pContent -match '(?s)
(.*?)$') { $afterBr = $matches[1] }
+ else { $am = [regex]::Match($pContent, '(?s)(.*?)$', $opts); if ($am.Success) { $afterBr = $am.Groups[1].Value } }
+ return [PSCustomObject]@{ name = $name; desc = Get-CleanText $afterBr }
+ }
+ return $null
+}
+
+function Test-ValidDishName($name) {
+ $name.Length -ge 3 -and $name.Length -le 80 -and
+ $name -notmatch '^(GF|GFA|V\+?|DF|DFA|V:|2025|Drink|V\+A)$' -and
+ $name -notmatch '^[A-Z]{1,3}:'
+}
+
+function Test-DietaryTag($str) {
+ $str -match '^(GF|GFA|V\+?|DF|DFA|V:|2025|Drink|V\+A)$'
+}
+```
+
+### HTML Cleanup
+```powershell
+function Get-CleanText($rawHtml) {
+ $t = $rawHtml -replace '<[^>]+>', ' '
+ $t = $t -replace '&', '&' -replace ''', "'" -replace '"', '"'
+ $t = $t -replace '<', '<' -replace '>', '>' -replace ' ', ' '
+ $t = $t -replace '–', '-' -replace '—', '-'
+ ($t -replace '\s+', ' ').Trim()
+}
+```
+
+---
+
+## Step 4: Fix Prices
+
+After scraping, apply authoritative prices from the price listing page:
+- Parse `project_category_(25|35|45)` CSS class from portfolio items
+- Match slug from adjacent `href` attribute
+- Build a hashtable and apply to all entries
+
+Common gotcha: Restaurant pages may show $22 (wine), $33 (lunch) — these are NOT the event price.
+
+---
+
+## Step 5: Recover Missing Restaurants
+
+If a restaurant has 0/0/0 courses:
+1. Try alternate Wayback timestamps: `20250401000000`, `20250415000000`, `20250501000000`, `20250601000000`
+2. Check if page uses Layout B (same-block) — add Strategy 2 to course block extractor
+3. Check if page uses `` tags instead of `` for dish names
+
+**Known JS-only restaurants** (no static cache recoverable for 2025):
+heritage, kismet, littlenoodle, macdaddys, purgatory, redtail, republickitchen, republicpi, vicinopizza
+
+---
+
+## Step 6: Output and Validation
+
+```powershell
+# Save as UTF-8 (important — special characters in restaurant names)
+$json = $data | ConvertTo-Json -Depth 10
+[System.IO.File]::WriteAllText($outPath, $json, [System.Text.Encoding]::UTF8)
+
+# Validate: list any restaurant not at 3/3/3
+$data | Where-Object {
+ $_.menu.courses.'First Course'.Count -ne 3 -or
+ $_.menu.courses.'Second Course'.Count -ne 3 -or
+ $_.menu.courses.'Third Course'.Count -ne 3
+} | ForEach-Object {
+ "$($_.slug): $($_.menu.courses.'First Course'.Count)/$($_.menu.courses.'Second Course'.Count)/$($_.menu.courses.'Third Course'.Count)"
+}
+```
+
+---
+
+## PowerShell Script Execution Pattern (REQUIRED)
+
+```bash
+# Write script to project dir (via Write tool or Edit)
+# Then in bash:
+cp "//WinServ-20-3.chns.local/Profiles/derekc/Documents/Coding Projects/.../script.ps1" \
+ "/c/Users/derekc.CHNSLocal/AppData/Local/Temp/script.ps1"
+powershell.exe -ExecutionPolicy Bypass -File "C:\Users\derekc.CHNSLocal\AppData\Local\Temp\script.ps1"
+```
+
+**Never** use `powershell -Command "..."` for multi-line scripts — escaping is unreliable.
+**Never** try to run `.ps1` directly from `\\WinServ-20-3...` UNC path — execution policy blocks it.
+
+---
+
+## PowerShell Gotchas
+- `"$slug: text"` fails if `:` follows var — use `"${slug}: text"`
+- Function names like `Is-X`, `Decode-X`, `Parse-X` get PSScriptAnalyzer warnings (unapproved verbs) but work fine
+- `return ,$array` (comma prefix) forces PowerShell to return an array, not unroll it
+- `[System.IO.File]::WriteAllText(path, json, UTF8)` — use this, not `Out-File`, to avoid BOM/encoding issues
diff --git a/rescrape-missing.ps1 b/rescrape-missing.ps1
deleted file mode 100644
index af521c4..0000000
--- a/rescrape-missing.ps1
+++ /dev/null
@@ -1,179 +0,0 @@
-# rescrape-missing.ps1 - Re-fetches 0-course and partial restaurants
-# using CDX API to find best available Wayback Machine snapshot
-
-$projectDir = Split-Path -Parent $MyInvocation.MyCommand.Definition
-$jsonPath = Join-Path $projectDir '2025-restaurants.json'
-
-$data = Get-Content $jsonPath -Raw -Encoding UTF8 | ConvertFrom-Json
-
-function Decode-Html($str) {
- if (-not $str) { return $str }
- $s = $str -replace '&','&' -replace ''',"'" -replace '"','"' -replace '<','<' -replace '>','>' -replace ' ',' ' -replace '\s+',' '
- $s.Trim()
-}
-
-function Get-CleanText($rawHtml) {
- $t = $rawHtml -replace '<[^>]+>', ' '
- $t = Decode-Html $t
- $t.Trim()
-}
-
-function Invoke-Dishes($courseHtml) {
- $dishes = [System.Collections.ArrayList]@()
- $opts = [System.Text.RegularExpressions.RegexOptions]::Singleline
-
- $pMatches = [regex]::Matches($courseHtml, '
(.*?)$') { $afterBr = $matches[1] }
- else {
- $afterStrong = [regex]::Match($pContent, '(?s)(.*?)$', $opts)
- if ($afterStrong.Success) { $afterBr = $afterStrong.Groups[1].Value }
- }
- $desc = Get-CleanText $afterBr
- $null = $dishes.Add([PSCustomObject]@{ name = $name; desc = $desc })
- }
- return ,$dishes
-}
-
-function Invoke-CourseBlock($html, $courseLabel, $nextLabel) {
- $opts = [System.Text.RegularExpressions.RegexOptions]::Singleline
- if ($nextLabel) {
- $pattern = [regex]::Escape($courseLabel) + '(.+?)(?=' + [regex]::Escape($nextLabel) + ')'
- $m = [regex]::Match($html, $pattern, $opts)
- if ($m.Success) { return $m.Groups[1].Value }
- }
- $idx = $html.IndexOf($courseLabel)
- if ($idx -ge 0) {
- $sub = $html.Substring($idx, [Math]::Min(6000, $html.Length - $idx))
- $innerM = [regex]::Match($sub, '(?s)et_pb_text_inner">(?!
(.*?)$') { $afterBr = $matches[1] }
- else {
- $am = [regex]::Match($pContent, '(?s)(.*?)$', $opts)
- if ($am.Success) { $afterBr = $am.Groups[1].Value }
- }
- $desc = Get-CleanText $afterBr
- $null = $dishes.Add([PSCustomObject]@{ name = $name; desc = $desc })
- }
- return ,$dishes
-}
-
-function Invoke-CourseBlock($html, $courseLabel, $nextLabel) {
- $opts = [System.Text.RegularExpressions.RegexOptions]::Singleline
- if ($nextLabel) {
- $m = [regex]::Match($html, ([regex]::Escape($courseLabel) + '(.+?)(?=' + [regex]::Escape($nextLabel) + ')'), $opts)
- if ($m.Success) { return $m.Groups[1].Value }
- }
- $idx = $html.IndexOf($courseLabel)
- if ($idx -ge 0) {
- $sub = $html.Substring($idx, [Math]::Min(6000, $html.Length - $idx))
- $im = [regex]::Match($sub, '(?s)et_pb_text_inner">(?!
- $afterBr = ''
- if ($pContent -match '(?s)
(.*?)$') {
- $afterBr = $matches[1]
- } else {
- $afterStrong = [regex]::Match($pContent, '(?s)(.*?)$', $opts)
- if ($afterStrong.Success) { $afterBr = $afterStrong.Groups[1].Value }
- }
-
- $desc = Get-CleanText $afterBr
- $null = $dishes.Add([PSCustomObject]@{ name = $name; desc = $desc })
- }
-
- return ,$dishes
-}
-
-function Extract-CourseBlock($html, $courseLabel, $nextLabel) {
- $opts = [System.Text.RegularExpressions.RegexOptions]::Singleline
-
- # Strategy 1: find content in et_pb_text_inner after course label, before next label
- if ($nextLabel) {
- $pattern = [regex]::Escape($courseLabel) + '(.+?)(?=' + [regex]::Escape($nextLabel) + ')'
- $m = [regex]::Match($html, $pattern, $opts)
- if ($m.Success) { return $m.Groups[1].Value }
- }
-
- # Strategy 2: find the et_pb_text_inner block immediately following the course label
- $idx = $html.IndexOf($courseLabel)
- if ($idx -ge 0) {
- $sub = $html.Substring($idx, [Math]::Min(6000, $html.Length - $idx))
- # Skip past the heading block and find the next text_inner content
- $innerM = [regex]::Match($sub, '(?s)et_pb_text_inner">(?!
(.*?)$') {
- $afterBr = $matches[1]
- } else {
- $afterStrong = [regex]::Match($pContent, '(.*?)$', $opts)
- if ($afterStrong.Success) { $afterBr = $afterStrong.Groups[1].Value }
- }
-
- $desc = Get-CleanText $afterBr
- $null = $dishes.Add([PSCustomObject]@{ name = $name; desc = $desc })
- }
-
- return ,$dishes
-}
-
-function Extract-CourseBlock($html, $courseLabel) {
- $opts = [System.Text.RegularExpressions.RegexOptions]::Singleline
- $pattern = [regex]::Escape($courseLabel) + '.{0,300}?et_pb_text_inner">(.+?)(?=