Fix European trip return heuristic for weekend location tracking
Adjust European short trip heuristic from >3 days to >1 day to correctly detect when user has returned home from European trips. This fixes the April 29-30, 2023 case where the location incorrectly showed "Sankt Georg, Hamburg" instead of "Bristol" when the user was free (no events scheduled) after the foss-north trip ended on April 27. The previous logic required more than 3 days to pass before assuming return home from European countries, but for short European trips by rail/ferry, users typically return within 1-2 days. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
663dc479c2
commit
ea4980a5d7
6407 changed files with 1072847 additions and 18 deletions
99
node_modules/ajv-formats/src/limit.ts
generated
vendored
Normal file
99
node_modules/ajv-formats/src/limit.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
import type Ajv from "ajv"
|
||||
import type {
|
||||
Plugin,
|
||||
CodeKeywordDefinition,
|
||||
KeywordErrorDefinition,
|
||||
Code,
|
||||
Name,
|
||||
ErrorObject,
|
||||
} from "ajv"
|
||||
import type {AddedFormat} from "ajv/dist/types"
|
||||
import type {Rule} from "ajv/dist/compile/rules"
|
||||
import {KeywordCxt} from "ajv"
|
||||
import {_, str, or, getProperty, operators} from "ajv/dist/compile/codegen"
|
||||
|
||||
type Kwd = "formatMaximum" | "formatMinimum" | "formatExclusiveMaximum" | "formatExclusiveMinimum"
|
||||
|
||||
type Comparison = "<=" | ">=" | "<" | ">"
|
||||
|
||||
const ops = operators
|
||||
|
||||
const KWDs: {[K in Kwd]: {okStr: Comparison; ok: Code; fail: Code}} = {
|
||||
formatMaximum: {okStr: "<=", ok: ops.LTE, fail: ops.GT},
|
||||
formatMinimum: {okStr: ">=", ok: ops.GTE, fail: ops.LT},
|
||||
formatExclusiveMaximum: {okStr: "<", ok: ops.LT, fail: ops.GTE},
|
||||
formatExclusiveMinimum: {okStr: ">", ok: ops.GT, fail: ops.LTE},
|
||||
}
|
||||
|
||||
export type LimitFormatError = ErrorObject<Kwd, {limit: string; comparison: Comparison}>
|
||||
|
||||
const error: KeywordErrorDefinition = {
|
||||
message: ({keyword, schemaCode}) => str`should be ${KWDs[keyword as Kwd].okStr} ${schemaCode}`,
|
||||
params: ({keyword, schemaCode}) =>
|
||||
_`{comparison: ${KWDs[keyword as Kwd].okStr}, limit: ${schemaCode}}`,
|
||||
}
|
||||
|
||||
export const formatLimitDefinition: CodeKeywordDefinition = {
|
||||
keyword: Object.keys(KWDs),
|
||||
type: "string",
|
||||
schemaType: "string",
|
||||
$data: true,
|
||||
error,
|
||||
code(cxt) {
|
||||
const {gen, data, schemaCode, keyword, it} = cxt
|
||||
const {opts, self} = it
|
||||
if (!opts.validateFormats) return
|
||||
|
||||
const fCxt = new KeywordCxt(it, (self.RULES.all.format as Rule).definition, "format")
|
||||
if (fCxt.$data) validate$DataFormat()
|
||||
else validateFormat()
|
||||
|
||||
function validate$DataFormat(): void {
|
||||
const fmts = gen.scopeValue("formats", {
|
||||
ref: self.formats,
|
||||
code: opts.code.formats,
|
||||
})
|
||||
const fmt = gen.const("fmt", _`${fmts}[${fCxt.schemaCode}]`)
|
||||
cxt.fail$data(
|
||||
or(
|
||||
_`typeof ${fmt} != "object"`,
|
||||
_`${fmt} instanceof RegExp`,
|
||||
_`typeof ${fmt}.compare != "function"`,
|
||||
compareCode(fmt)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
function validateFormat(): void {
|
||||
const format = fCxt.schema as string
|
||||
const fmtDef: AddedFormat | undefined = self.formats[format]
|
||||
if (!fmtDef || fmtDef === true) return
|
||||
if (
|
||||
typeof fmtDef != "object" ||
|
||||
fmtDef instanceof RegExp ||
|
||||
typeof fmtDef.compare != "function"
|
||||
) {
|
||||
throw new Error(`"${keyword}": format "${format}" does not define "compare" function`)
|
||||
}
|
||||
const fmt = gen.scopeValue("formats", {
|
||||
key: format,
|
||||
ref: fmtDef,
|
||||
code: opts.code.formats ? _`${opts.code.formats}${getProperty(format)}` : undefined,
|
||||
})
|
||||
|
||||
cxt.fail$data(compareCode(fmt))
|
||||
}
|
||||
|
||||
function compareCode(fmt: Name): Code {
|
||||
return _`${fmt}.compare(${data}, ${schemaCode}) ${KWDs[keyword as Kwd].fail} 0`
|
||||
}
|
||||
},
|
||||
dependencies: ["format"],
|
||||
}
|
||||
|
||||
const formatLimitPlugin: Plugin<undefined> = (ajv: Ajv): Ajv => {
|
||||
ajv.addKeyword(formatLimitDefinition)
|
||||
return ajv
|
||||
}
|
||||
|
||||
export default formatLimitPlugin
|
||||
Loading…
Add table
Add a link
Reference in a new issue