(
    ----------------------------------------------------------------
    -- 1. シーン設定とヘルパー配置
    ----------------------------------------------------------------
    delete objects
    local spacing = 20.0, zHeight = 0.0, helperSize = 10.0, targetDist = 20.0
    
    local posArr = #(
        [0, spacing, zHeight], [spacing, spacing, zHeight], [spacing * 2, spacing, zHeight],
        [0, 0, zHeight], [spacing, 0, zHeight], [spacing * 2, 0, zHeight]
    )

    local hpA1 = Point name:"Helper_A1" pos:posArr[1] size:helperSize wirecolor:red
    local hpA2 = Point name:"Helper_A2" pos:posArr[2] size:helperSize wirecolor:green
    local hpA3 = Point name:"Helper_A3" pos:posArr[3] size:helperSize wirecolor:blue
    local hpB1 = Point name:"Helper_B1" pos:posArr[4] size:helperSize wirecolor:yellow
    local hpB2 = Point name:"Helper_B2" pos:posArr[5] size:helperSize wirecolor:orange
    local hpB3 = Point name:"Helper_B3" pos:posArr[6] size:helperSize wirecolor:white

    hpA2.parent = hpA1; hpA3.parent = hpA2
    hpB2.parent = hpB1; hpB3.parent = hpB2

    hpA1.isFrozen = true; hpB1.isFrozen = true

    format "Helpers created and linked.\n"

    ----------------------------------------------------------------
    -- 2. キー修復システム（ティーポット方式の導入）
    ----------------------------------------------------------------
    global isAdjusting = false
    global expectedKeyValues = #() -- 構造: #( #(Helper, Time, LocalPos), ... )

    -- 期待値データベース初期化関数
    fn initExpectedValues helpers = (
        expectedKeyValues = #()
        for h in helpers do (
            local ctrl = h.pos.controller
            if isKindOf ctrl Position_XYZ then (
                -- キーが存在する時間を探す (X, Y, Zどれかにあるはず)
                local times = #()
                join times (for k in ctrl.X_Position.controller.keys collect k.time)
                join times (for k in ctrl.Y_Position.controller.keys collect k.time)
                join times (for k in ctrl.Z_Position.controller.keys collect k.time)
                makeUniqueArray times
                
                for t in times do (
                    local localPos = at time t (in coordsys parent h.pos)
                    append expectedKeyValues #(h, t, localPos)
                )
            )
        )
    )

    -- キー修復関数（期待値データベースに基づいて全キーを再設定）
    fn repairKeys = (
        suspendEditing() -- キー設定によるイベント再発火を防ぐ
        try (
            for data in expectedKeyValues do (
                local h = data[1], t = data[2], localPos = data[3]
                local ctrl = h.pos.controller
                if isKindOf ctrl Position_XYZ then (
                    local ctrls = #(ctrl.X_Position.controller, ctrl.Y_Position.controller, ctrl.Z_Position.controller)
                    local vals = #(localPos.x, localPos.y, localPos.z)
                    
                    for i = 1 to 3 do (
                        local axisCtrl = ctrls[i]
                        local val = vals[i]
                        local keyIndex = getKeyIndex axisCtrl t
                        if keyIndex > 0 then (
                            axisCtrl.keys[keyIndex].value = val
                        ) else (
                            addNewKey axisCtrl t
                            axisCtrl.keys[(getKeyIndex axisCtrl t)].value = val
                        )
                    )
                )
            )
            format "キー修復完了 (Frame %t)\n" sliderTime
        ) catch (
            format "修復エラー: %\n" (getCurrentException())
        )
        resumeEditing()
    )

    -- 期待値更新関数（現在のフレームの位置をデータベースに反映）
    fn updateExpectedValues helpers currentFrame = (
        for h in helpers do (
            local localPos = in coordsys parent h.pos
            local found = false
            for i = 1 to expectedKeyValues.count do (
                if expectedKeyValues[i][1] == h and expectedKeyValues[i][2] == currentFrame then (
                    expectedKeyValues[i][3] = localPos
                    found = true
                    exit
                )
            )
            if not found then (
                append expectedKeyValues #(h, currentFrame, localPos)
            )
        )
    )

    ----------------------------------------------------------------
    -- 3. 移動イベントハンドラ
    ----------------------------------------------------------------
    
    -- A系列のヘルパーが動いた時の処理
    fn onASeriesMoved movedHelper =
    (
        if not isAdjusting then
        (
            isAdjusting = true
            local currentFrame = sliderTime
            local movedHelpers = #()
            
            -- 位置補正ロジック（元のスクリプト通り）
            case movedHelper of
            (
                hpA2: (
                    append movedHelpers hpA2; append movedHelpers hpB2; append movedHelpers hpB3
                    local offset = hpA2.pos - hpA1.pos
                    if length offset != spacing then hpA2.pos = hpA1.pos + normalize(offset) * spacing
                    
                    local dir = normalize(hpB2.pos - hpA2.pos)
                    hpB2.pos = hpA2.pos + dir * targetDist
                    
                    local offset3 = hpB3.pos - hpB2.pos
                    if length offset3 != spacing then hpB3.pos = hpB2.pos + normalize(offset3) * spacing
                )
                
                hpA3: (
                    append movedHelpers hpA2; append movedHelpers hpA3; append movedHelpers hpB2; append movedHelpers hpB3
                    local offset = hpA3.pos - hpA2.pos
                    local expectedOffset = normalize(offset) * spacing
                    if length offset != spacing then hpA2.pos = hpA3.pos - expectedOffset
                    
                    local offset2 = hpA2.pos - hpA1.pos
                    if length offset2 != spacing then (
                        hpA2.pos = hpA1.pos + normalize(offset2) * spacing
                        hpA3.pos = hpA2.pos + expectedOffset
                    )
                    
                    local dir2 = normalize(hpB2.pos - hpA2.pos)
                    hpB2.pos = hpA2.pos + dir2 * targetDist
                    
                    local dir3 = normalize(hpB3.pos - hpA3.pos)
                    hpB3.pos = hpA3.pos + dir3 * targetDist
                    
                    local offsetB3 = hpB3.pos - hpB2.pos
                    if length offsetB3 != spacing then hpB3.pos = hpB2.pos + normalize(offsetB3) * spacing
                )
            )
            
            -- キー設定と修復（ティーポット方式）
            updateExpectedValues movedHelpers currentFrame
            repairKeys()
            
            isAdjusting = false
        )
    )

    -- B系列のヘルパーが動いた時の処理（A系列と同様の構造）
    fn onBSeriesMoved movedHelper =
    (
        if not isAdjusting then
        (
            isAdjusting = true
            local currentFrame = sliderTime
            local movedHelpers = #()

            -- 位置補正ロジック（元のスクリプト通り）
            case movedHelper of
            (
                hpB2: (
                    append movedHelpers hpB2; append movedHelpers hpA2; append movedHelpers hpA3
                    local offset = hpB2.pos - hpB1.pos
                    if length offset != spacing then hpB2.pos = hpB1.pos + normalize(offset) * spacing
                    
                    local dir = normalize(hpA2.pos - hpB2.pos)
                    hpA2.pos = hpB2.pos + dir * targetDist
                    
                    local offset3 = hpA3.pos - hpA2.pos
                    if length offset3 != spacing then hpA3.pos = hpA2.pos + normalize(offset3) * spacing
                )
                
                hpB3: (
                    append movedHelpers hpB2; append movedHelpers hpB3; append movedHelpers hpA2; append movedHelpers hpA3
                    local offset = hpB3.pos - hpB2.pos
                    local expectedOffset = normalize(offset) * spacing
                    if length offset != spacing then hpB2.pos = hpB3.pos - expectedOffset
                    
                    local offset2 = hpB2.pos - hpB1.pos
                    if length offset2 != spacing then (
                        hpB2.pos = hpB1.pos + normalize(offset2) * spacing
                        hpB3.pos = hpB2.pos + expectedOffset
                    )
                    
                    local dir2 = normalize(hpA2.pos - hpB2.pos)
                    hpA2.pos = hpB2.pos + dir2 * targetDist
                    
                    local dir3 = normalize(hpA3.pos - hpB3.pos)
                    hpA3.pos = hpB3.pos + dir3 * targetDist
                    
                    local offsetA3 = hpA3.pos - hpA2.pos
                    if length offsetA3 != spacing then hpA3.pos = hpA2.pos + normalize(offsetA3) * spacing
                )
            )

            -- キー設定と修復（ティーポット方式）
            updateExpectedValues movedHelpers currentFrame
            repairKeys()

            isAdjusting = false
        )
    )

    -- 初期化とハンドラ登録
    initExpectedValues #(hpA1, hpA2, hpA3, hpB1, hpB2, hpB3)
    deleteAllChangeHandlers id:#HelperMoveMonitor

    when transform hpA2 changes id:#HelperMoveMonitor do onASeriesMoved hpA2
    when transform hpA3 changes id:#HelperMoveMonitor do onASeriesMoved hpA3
    when transform hpB2 changes id:#HelperMoveMonitor do onBSeriesMoved hpB2
    when transform hpB3 changes id:#HelperMoveMonitor do onBSeriesMoved hpB3

    format "\nSetup complete. Auto-keying and key repair active.\n"
)
このMAXSCRIPTだと、A3を動かしてもA1は動かない、このロジックを先のスクリプトに適用できない？