Can You Kill Salmonella in Eggs Without Cooking Them? I Tried It
With advice from infectious disease experts, I tested a low-effort way to pasteurize eggs at home.
找到 2766 篇相关文章
With advice from infectious disease experts, I tested a low-effort way to pasteurize eggs at home.
Salmonella outbreaks are seemingly everywhere right now. A good temperature probe is the last and best line of defense.
We are pleased to announce the latest major version of the NgRx framework, featuring exciting new features, bug fixes, and other updates. Resource Extensions 🧩 Angular's resource and httpResource APIs cover a large part of async state management, but two very common requirements are not configurable at the resource level: Value on loading: when a resource reloads, value() resets to undefined until the new data arrives. Value on error: when a resource enters the error state, reading value() throws. The new @ngrx/signals/resource entry point addresses both cases with resource extensions : a set of utilities for customizing the behavior of a Resource in a composable, reusable way. They wrap an existing resource and patch only the parts of its behavior that should change, while fully preserving the original resource type. The extendResource function accepts the resource as the first argument, followed by the extensions to apply: import { Component } from ' @angular/core ' ; import { httpResource } from ' @angular/common/http ' ; import { extendResource , withPreviousValueOnLoading , withValueOnError , } from ' @ngrx/signals/resource ' ; @ Component ({ /* ... */ }) export class TodoList { // type: HttpResourceRef<Todo[] | undefined> readonly todosResource = extendResource ( httpResource < Todo [] > (() => ' /api/todos ' ), withPreviousValueOnLoading (), withValueOnError ( undefined ) ); } The returned resource is still the exact resource that was passed in, so no access is lost to the APIs of more specific resource types, such as WritableResource . Only value() behaves differently: it keeps the previously loaded todos while a reload is in flight, and returns undefined instead of throwing when the request fails. Built-in Extensions There are four built-in extensions: withPreviousValueOnLoading keeps the last resolved value while the resource is reloading, which is exactly what paginated and filtered lists need to avoid flickering. withValueOnLoading returns a specific fal
Proteger datos que deben seguir siendo secretos dentro de diez años es un problema de hoy : un adversario puede capturar tu tráfico cifrado ahora y descifrarlo cuando exista la capacidad cuántica ( harvest now, decrypt later ). Quipu es una librería libre de cifrado híbrido post-cuántico para datos en reposo: combina criptografía clásica probada con la nueva, de modo que solo se rompe si ambas caen a la vez. Rust puro, y por qué Quipu nació apuntando a varios lenguajes: un núcleo en Rust con una C ABI encima y bindings para Python, Node y Go. Funcionaba, pero la lección fue clara: mantener una interfaz de C estable más cuatro bindings, cada uno con su empaquetado y sus pruebas de interoperabilidad, era complejidad que no pagaba para el objetivo real —proteger datos en reposo— y ampliaba la superficie de ataque con unsafe que no queríamos. Hoy Quipu es Rust puro : memoria segura, sin garbage collector , sin unsafe de primera parte . Y para quien no programa en Rust, se distribuye como rueda nativa de Python (vía PyO3) — que es la superficie que el cliente que no es de Rust de verdad necesita. Una sola base de código, una sola cosa que auditar. Es la misma filosofía que guía el resto: donde hay buena criptografía, se reutiliza; la simplicidad es una decisión de seguridad, no una comodidad. Instalación cargo add quipu # Rust pip install quipu-crypto # Python (rueda nativa, PyO3) Cifrar y descifrar en Python import quipu # Simétrico con contraseña blob = quipu . encrypt_stream ( b " datos sensibles " , " mi-passphrase " ) assert quipu . decrypt_stream ( blob , " mi-passphrase " ) == b " datos sensibles " # Post-cuántico para un destinatario pub , sec = quipu . generate_keypair () # X25519 + ML-KEM-1024 c = quipu . encode_to_recipient ( b " secreto " , pub ) assert quipu . decode_as_recipient ( c , sec ) == b " secreto " Qué hay debajo Cifrado: XChaCha20-Poly1305 (AEAD autenticado). Derivación de claves: Argon2id (resistente a fuerza bruta) + HKDF. Post-cuántico: X25519
The FTC and Zillow have announced a settlement that ends the case alleging that a 2025 "partnership" between Zillow and Redfin violated antitrust laws. The FTC had alleged Zillow agreed to pay Redfin to syndicate its listings, while Redfin would end its own advertising contracts and promise not to compete with Zillow for multifamily listings. […]
"Mummified remains sold online exhibit signs of biodeterioration, yet sellers provide no safety guidance."
We open-sourced 449 real equipment financing quotes so nobody has to trust our math Commercial equipment financing sites are almost always a black box: you land on a page, see a monthly payment, and have no way to check how that number was actually derived. The APR is picked out of thin air, the "starting at" price is aspirational, and the amortization math is never shown. We built Equipment Capital Index to do the opposite — every page shows the real per-machine price, the actual amortization schedule, and now we've published the whole underlying dataset so anyone can verify or build on it. What's actually in the dataset equipment-financing-rate-data is a CC BY 4.0 dataset of aggregate financing benchmarks computed from 449 individually priced, real machines — construction equipment, ag machinery, trucking fleet, power equipment, and material handling gear. No survey estimates, no fabricated averages. Current live snapshot: Category Machines tracked Avg APR Avg est. monthly payment Heavy Construction 222 8.25% $3,272 Agriculture 84 7.75% $4,411 Trucking Fleet 63 8.00% $2,501 Power Equipment 44 8.50% $957 Material Handling 36 8.50% $825 Site-wide average: 8.17% APR , $2,954/mo across all 449 machines. Why this exists A couple of principles drove the design: Every number traces back to a real machine. Each of the 449 rows has a sourced price (dealer listing, MSRP, or a documented class-typical estimate — and it's disclosed which one) and a real amortization calculation, not a rounded guess. The math is reproducible, not just displayed. The same aggregation logic that powers the /press page on the site also generates this dataset — one source of truth computed twice, so the numbers can't silently drift apart. It shouldn't require scraping a webpage. The data has three independent, permanent homes: A live JSON API: /api/rate-report.json ( OpenAPI spec ) A self-updating GitHub repo (regenerates from live data every 3 days via GitHub Actions) A permanent, versioned DOI o
Capacity will rise by a record 45GW this year, according to S&P Global Energy.
In one crash, the driver of a 2024 Blazer EV said they had to "deliberately steer the vehicle into a concrete curb" to slow it down and avoid a "catastrophic intersection collision."
Microsoft has outlined an AI governance architecture spanning nine governance domains and four functions: policy, control, visibility, and proof. The approach connects policies with runtime enforcement, continuous evaluation, observability, identity, security, and audit evidence to help organizations verify governance requirements as AI applications and agents operate in production. By Leela Kumili
Berry Street founder Noah Kotlove and Healthify founder Tushar Vashisht will act as co-CEOs of the new entity.
Many newer vehicles can be accessed from the owner's phone, if they've set it up. There are some things to consider before adding your key.
There is a layer in my database called 1 . Somebody created it, presumably by accident, and it sat there for months looking harmless. It was the only layer in the system that never served a single tile, and nobody noticed, because it was empty anyway. That layer turned out to be a symptom of a SQL injection vulnerability. This post is about the design that produced it — which I still think is a good design — and the four things I got wrong inside it. The setup A web GIS with about 2.7 million features: 1.8 million points, 697,000 lines, 172,000 polygons. Users create layers through the UI, upload data into them, edit geometry, and expect to see it on a map. The features do not live in a table per layer. They live in three tables — one for points, one for lines, one for polygons — with a layer_id foreign key and a JSON column for attributes: project_pointfeature 1,820,288 rows project_linefeature 697,009 rows project_polygonfeature 171,830 rows That's a deliberate trade. A table per layer means DDL every time a user clicks "new layer", a migration story that never ends, and a schema that drifts. Three generic tables mean one schema, one set of indexes, and layers that are just rows in a metadata table. The cost lands on the tile server. The pattern Martin serves vector tiles from PostGIS. Point it at a database and it discovers spatial tables and views and publishes each as an MVT endpoint. It can be told to publish views but not tables: postgres : auto_publish : from_schemas : [ public ] publish_tables : false reload_interval : 5s So: give every layer its own view. A Django post_save signal on the Layer model creates it: CREATE OR REPLACE VIEW t19_saobracajni_znakovi AS SELECT f . id , f . feature_attrs , f . geom , f . layer_id , l . name AS layer_name , lg . name AS layer_group_name , p . title AS project_title FROM project_pointfeature f JOIN project_layer l ON f . layer_id = l . id JOIN project_layergroup lg ON l . layer_group_id = lg . id JOIN project_project p
GrapheneOS, an open source version of Android that prioritizes security and privacy, has detailed its plans for supporting Motorola smartphones. Official support is set to arrive next year, starting with traditional flagships, before rolling out to Motorola's foldable phones and perhaps cheaper models, eventually. In a Mastodon thread, the GrapheneOS Foundation announced that it will […]
Asgaut Mjølne Söderbom and Ola Hast discuss the evolution of their software engineering practices past continuous deployment and pair engineering. The conversation continues where it left off in the previous episode and focuses on the experiments in adopting Claude Code and the reasons why they consider it good for everything else, but not coding. By Asgaut Mjølne Söderbom, Ola Hast
Shift-left and DevOps have impacted how we flow changes from inception to production, but at the cost of increased cognitive load and duplication of effort across testing, security, and maintenance. This article explores the real-world challenges of rightsizing developer platforms and finding a cultural match for engineering teams who use them to reduce cognitive load and deliver change faster. By John Keates
Tethered display glasses are truly practical face computers. They trade bulky spatial computing for simplicity: Plug in, recline, and get a massive screen right in front of your nose.
How to get a photo below a strict KB limit Many government portals, job forms, school applications, and support websites reject an otherwise valid photo because it is larger than a fixed limit such as 100 KB or 200 KB. Standard gallery apps usually offer cropping or a quality percentage, but they do not tell you whether the final file will meet a specific upload limit. That is the problem I built FormFit to solve on Android. Why exact-KB compression is tricky File size depends on more than width and height. Image detail, color variation, output format, and compression quality all affect the result. A quality setting that works for one photo may leave another photo far above the required size. FormFit works toward a maximum KB target and adjusts the generated copy for you. The practical goal is to create a file at or below the limit while keeping it as clear as possible. Compress a photo on Android Install FormFit from Google Play . Open the photo-compression tool and select the image you need to upload. Enter the maximum file size required by the website or form. Optionally resize the image dimensions or choose JPG, PNG, or WebP for the generated copy. Run the compression, review the result, and save or share the new file. The original photo is not replaced. FormFit creates a separate output copy, so you can compare the result before uploading it. Remove metadata from generated copies Photos can contain metadata such as device or capture information. When you only need to submit the visible image, FormFit can remove metadata from the generated copy. This does not change the original file. Turn several photos into one PDF Some forms ask for a single PDF instead of multiple image files. FormFit can combine up to 20 selected photos into one PDF directly on the phone. This is useful for receipts, scanned notes, application documents, and other small document sets. On-device processing The selected photos and PDFs are processed on the Android device. FormFit does not req
People have been talking to each other for at least 100,000 years, as best we can tell. And in all that time, there has been only one thing in the world that could learn a human language to perfect fluency: a human child. Now there are two. Four short years after the release of ChatGPT,…
📚 This is part 2 of a series. Part 1: The Origin Story Part 2: [Current Article] Part 3: Coming soon... Let me tell you about the day my crash reporting UI crashed. The Grey Screen One afternoon, my Android app's crash screen rendered all-grey. No content. No report button. Just a blank slate where the app's last line of defense should have been. The root cause? A stale file from Gradle's build cache after a major refactor. The compiled resource IDs no longer matched the packaged resource table. ViewBinding inflated the wrong layout, and a silent NullPointerException killed the crash screen itself. It was invisible in CI. It only appeared in specific rebuild scenarios. And it took hours to trace. That bug taught me something important: The fix isn't done when the patch ships. It's done when the lesson becomes automated. So I wrote a build-time task that reads the compiled class files directly, compares them against the final packaged resources, and verifies every constant matches. It runs automatically after every packaging step. You never have to remember to invoke it. That was the first of many incident-driven tools I built. The FAB That Disappeared A few weeks later, a developer tools Floating Action Button vanished from consumer apps. Debug menus inaccessible. Secure screens incorrectly enabled. Turns out, my shared library's BuildConfigUtils was reading the library's own BuildConfig —which is baked as "release" at publish time. An AAR can never know the consumer's build type. 25 files across 34 call sites were silently broken. I built a Gradle plugin that generates a SskBuildConfig object per consumer module, per variant, using AGP's onVariants callback. It registers generated source via KotlinCompile.source() —not reflection, which broke across AGP versions. It detects Android plugins by extension type, not hardcoded IDs, so it works with com.android.application , com.android.library , com.android.dynamic-feature , and any future Google plugin. Same package as