text:
#include "config.h"
#include "modules/accessibility/AXObject.h"

#include "core/editing/VisibleUnits.h"
#include "core/editing/htmlediting.h"
#include "core/frame/LocalFrame.h"
#include "core/frame/Settings.h"
#include "core/html/HTMLDialogElement.h"
#include "core/html/HTMLFrameOwnerElement.h"
#include "core/layout/LayoutListItem.h"
#include "core/layout/LayoutTheme.h"
#include "core/layout/LayoutView.h"
#include "modules/accessibility/AXObjectCacheImpl.h"
#include "platform/UserGestureIndicator.h"
#include "platform/text/PlatformLocale.h"
#include "wtf/HashSet.h"
#include "wtf/StdLibExtras.h"
#include "wtf/text/WTFString.h"

using blink::WebLocalizedString;

namespace blink {

using namespace HTMLNames;

namespace {
typedef HashMap<String, AccessibilityRole, CaseFoldingHash> ARIARoleMap;
typedef HashSet<String, CaseFoldingHash> ARIAWidgetSet;

struct RoleEntry {
    const char* ariaRole;
    AccessibilityRole webcoreRole;
};

const RoleEntry roles[] = {
    { "alert", AlertRole },
    { "alertdialog", AlertDialogRole },
    { "application", ApplicationRole },
    { "article", ArticleRole },
    { "banner", BannerRole },
    { "button", ButtonRole },
    { "checkbox", CheckBoxRole },
    { "columnheader", ColumnHeaderRole },
    { "combobox", ComboBoxRole },
    { "complementary", ComplementaryRole },
    { "contentinfo", ContentInfoRole },
    { "definition", DefinitionRole },
    { "dialog", DialogRole },
    { "directory", DirectoryRole },
    { "document", DocumentRole },
    { "form", FormRole },
    { "grid", GridRole },
    { "gridcell", CellRole },
    { "group", GroupRole },
    { "heading", HeadingRole },
    { "img", ImageRole },
    { "link", LinkRole },
    { "list", ListRole },
    { "listbox", ListBoxRole },
    { "listitem", ListItemRole },
    { "log", LogRole },
    { "main", MainRole },
    { "marquee", MarqueeRole },
    { "math", MathRole },
    { "menu", MenuRole },
    { "menubar", MenuBarRole },
    { "menuitem", MenuItemRole },
    { "menuitemcheckbox", MenuItemCheckBoxRole },
    { "menuitemradio", MenuItemRadioRole },
    { "navigation", NavigationRole },
    { "none", NoneRole },
    { "note", NoteRole },
    { "option", ListBoxOptionRole },
    { "presentation", PresentationalRole },
    { "progressbar", ProgressIndicatorRole },
    { "radio", RadioButtonRole },
    { "radiogroup", RadioGroupRole },
    { "region", RegionRole },
    { "row", RowRole },
    { "rowheader", RowHeaderRole },
    { "scrollbar", ScrollBarRole },
    { "search", SearchRole },
    { "searchbox", SearchBoxRole },
    { "separator", SplitterRole },
    { "slider", SliderRole },
    { "spinbutton", SpinButtonRole },
    { "status", StatusRole },
    { "switch", SwitchRole },
    { "tab", TabRole },
    { "tablist", TabListRole },
    { "tabpanel", TabPanelRole },
    { "text", StaticTextRole },
    { "textbox", TextFieldRole },
    { "timer", TimerRole },
    { "toolbar", ToolbarRole },
    { "tooltip", UserInterfaceTooltipRole },
    { "tree", TreeRole },
    { "treegrid", TreeGridRole },
    { "treeitem", TreeItemRole }
};

struct InternalRoleEntry {
    AccessibilityRole webcoreRole;
    const char* internalRoleName;
};

const InternalRoleEntry internalRoles[] = {
    { UnknownRole, "Unknown" },
    { AlertDialogRole, "AlertDialog" },
    { AlertRole, "Alert" },
    { AnnotationRole, "Annotation" },
    { ApplicationRole, "Application" },
    { ArticleRole, "Article" },
    { BannerRole, "Banner" },
    { BlockquoteRole, "Blockquote" },
    { BusyIndicatorRole, "BusyIndicator" },
    { ButtonRole, "Button" },
    { CanvasRole, "Canvas" },
    { CaptionRole, "Caption" },
    { CellRole, "Cell" },
    { CheckBoxRole, "CheckBox" },
    { ColorWellRole, "ColorWell" },
    { ColumnHeaderRole, "ColumnHeader" },
    { ColumnRole, "Column" },
    { ComboBoxRole, "ComboBox" },
    { ComplementaryRole, "Complementary" },
    { ContentInfoRole, "ContentInfo" },
    { DateRole, "Date" },
    { DateTimeRole, "DateTime" },
    { DefinitionRole, "Definition" },
    { DescriptionListDetailRole, "DescriptionListDetail" },
    { DescriptionListRole, "DescriptionList" },
    { DescriptionListTermRole, "DescriptionListTerm" },
    { DetailsRole, "Details" },
    { DialogRole, "Dialog" },
    { DirectoryRole, "Directory" },
    { DisclosureTriangleRole, "DisclosureTriangle" },
    { DivRole, "Div" },
    { DocumentRole, "Document" },
    { EmbeddedObjectRole, "EmbeddedObject" },
    { FigcaptionRole, "Figcaption" },
    { FigureRole, "Figure" },
    { FooterRole, "Footer" },
    { FormRole, "Form" },
    { GridRole, "Grid" },
    { GroupRole, "Group" },
    { HeadingRole, "Heading" },
    { IframePresentationalRole, "IframePresentational" },
    { IframeRole, "Iframe" },
    { IgnoredRole, "Ignored" },
    { ImageMapLinkRole, "ImageMapLink" },
    { ImageMapRole, "ImageMap" },
    { ImageRole, "Image" },
    { InlineTextBoxRole, "InlineTextBox" },
    { LabelRole, "Label" },
    { LegendRole, "Legend" },
    { LinkRole, "Link" },
    { ListBoxOptionRole, "ListBoxOption" },
    { ListBoxRole, "ListBox" },
    { ListItemRole, "ListItem" },
    { ListMarkerRole, "ListMarker" },
    { ListRole, "List" },
    { LogRole, "Log" },
    { MainRole, "Main" },
    { MarqueeRole, "Marquee" },
    { MathRole, "Math" },
    { MenuBarRole, "MenuBar" },
    { MenuButtonRole, "MenuButton" },
    { MenuItemRole, "MenuItem" },
    { MenuItemCheckBoxRole, "MenuItemCheckBox" },
    { MenuItemRadioRole, "MenuItemRadio" },
    { MenuListOptionRole, "MenuListOption" },
    { MenuListPopupRole, "MenuListPopup" },
    { MenuRole, "Menu" },
    { MeterRole, "Meter" },
    { NavigationRole, "Navigation" },
    { NoneRole, "None" },
    { NoteRole, "Note" },
    { OutlineRole, "Outline" },
    { ParagraphRole, "Paragraph" },
    { PopUpButtonRole, "PopUpButton" },
    { PreRole, "Pre" },
    { PresentationalRole, "Presentational" },
    { ProgressIndicatorRole, "ProgressIndicator" },
    { RadioButtonRole, "RadioButton" },
    { RadioGroupRole, "RadioGroup" },
    { RegionRole, "Region" },
    { RootWebAreaRole, "RootWebArea" },
    { RowHeaderRole, "RowHeader" },
    { RowRole, "Row" },
    { RubyRole, "Ruby" },
    { RulerRole, "Ruler" },
    { SVGRootRole, "SVGRoot" },
    { ScrollAreaRole, "ScrollArea" },
    { ScrollBarRole, "ScrollBar" },
    { SeamlessWebAreaRole, "SeamlessWebArea" },
    { SearchRole, "Search" },
    { SearchBoxRole, "SearchBox" },
    { SliderRole, "Slider" },
    { SliderThumbRole, "SliderThumb" },
    { SpinButtonPartRole, "SpinButtonPart" },
    { SpinButtonRole, "SpinButton" },
    { SplitterRole, "Splitter" },
    { StaticTextRole, "StaticText" },
    { StatusRole, "Status" },
    { SwitchRole, "Switch" },
    { TabGroupRole, "TabGroup" },
    { TabListRole, "TabList" },
    { TabPanelRole, "TabPanel" },
    { TabRole, "Tab" },
    { TableHeaderContainerRole, "TableHeaderContainer" },
    { TableRole, "Table" },
    { TextFieldRole, "TextField" },
    { TimeRole, "Time" },
    { TimerRole, "Timer" },
    { ToggleButtonRole, "ToggleButton" },
    { ToolbarRole, "Toolbar" },
    { TreeGridRole, "TreeGrid" },
    { TreeItemRole, "TreeItem" },
    { TreeRole, "Tree" },
    { UserInterfaceTooltipRole, "UserInterfaceTooltip" },
    { WebAreaRole, "WebArea" },
    { LineBreakRole, "LineBreak" },
    { WindowRole, "Window" }
};

static_assert(WTF_ARRAY_LENGTH(internalRoles) == NumRoles, "Not all internal roles have an entry in internalRoles array");

// Roles which we need to map in the other direction
const RoleEntry reverseRoles[] = {
    { "button", ToggleButtonRole },
    { "combobox", PopUpButtonRole },
    { "contentinfo", FooterRole },
    { "menuitem", MenuButtonRole },
    { "menuitem", MenuListOptionRole },
    { "progressbar", MeterRole },
    { "textbox", TextFieldRole }
};

static ARIARoleMap* createARIARoleMap()
{
    ARIARoleMap* roleMap = new ARIARoleMap;

    for (size_t i = 0; i < WTF_ARRAY_LENGTH(roles); ++i)
        roleMap->set(roles[i].ariaRole, roles[i].webcoreRole);
    return roleMap;
}

static Vector<AtomicString>* createRoleNameVector()
{
    Vector<AtomicString>* roleNameVector = new Vector<AtomicString>(NumRoles);
    for (int i = 0; i < NumRoles; i++)
        (*roleNameVector)[i] = nullAtom;

    for (size_t i = 0; i < WTF_ARRAY_LENGTH(roles); ++i)
        (*roleNameVector)[roles[i].webcoreRole] = AtomicString(roles[i].ariaRole);

    for (size_t i = 0; i < WTF_ARRAY_LENGTH(reverseRoles); ++i)
        (*roleNameVector)[reverseRoles[i].webcoreRole] = AtomicString(reverseRoles[i].ariaRole);

    return roleNameVector;
}

static Vector<AtomicString>* createInternalRoleNameVector()
{
    Vector<AtomicString>* internalRoleNameVector = new Vector<AtomicString>(NumRoles);
    for (size_t i = 0; i < WTF_ARRAY_LENGTH(internalRoles); i++)
        (*internalRoleNameVector)[internalRoles[i].webcoreRole] = AtomicString(internalRoles[i].internalRoleName);

    return internalRoleNameVector;
}

const char* ariaWidgets[] = {
    // From http://www.w3.org/TR/wai-aria/roles#widget_roles
    "alert",
    "alertdialog",
    "button",
    "checkbox",
    "dialog",
    "gridcell",
    "link",
    "log",
    "marquee",
    "menuitem",
    "menuitemcheckbox",
    "menuitemradio",
    "option",
    "progressbar",
    "radio",
    "scrollbar",
    "slider",
    "spinbutton",
    "status",
    "tab",
    "tabpanel",
    "textbox",
    "timer",
    "tooltip",
    "treeitem",
    // Composite user interface widgets.  This list is also from w3.org site refrerenced above.
    "combobox",
    "grid",
    "listbox",
    "menu",
    "menubar",
    "radiogroup",
    "tablist",
    "tree",
    "treegrid"
};

static ARIAWidgetSet* createARIARoleWidgetSet()
{
    ARIAWidgetSet* widgetSet = new HashSet<String, CaseFoldingHash>();
    for (size_t i = 0; i < WTF_ARRAY_LENGTH(ariaWidgets); ++i)
        widgetSet->add(String(ariaWidgets[i]));
    return widgetSet;
}

const char* ariaInteractiveWidgetAttributes[] = {
    // These attributes implicitly indicate the given widget is interactive.
    // From http://www.w3.org/TR/wai-aria/states_and_properties#attrs_widgets
    "aria-activedescendant",
    "aria-checked",
    "aria-controls",
    "aria-disabled", // If it's disabled, it can be made interactive.
    "aria-expanded",
    "aria-haspopup",
    "aria-multiselectable",
    "aria-pressed",
    "aria-required",
    "aria-selected"
};

HTMLDialogElement* getActiveDialogElement(Node* node)
{
    return node->document().activeModalDialog();
}

} // namespace

AXObject::AXObject(AXObjectCacheImpl* axObjectCache)
    : m_id(0)
    , m_haveChildren(false)
    , m_role(UnknownRole)
    , m_lastKnownIsIgnoredValue(DefaultBehavior)
    , m_detached(false)
    , m_parent(0)
    , m_lastModificationCount(-1)
    , m_cachedIsIgnored(false)
    , m_cachedIsInertOrAriaHidden(false)
    , m_cachedIsDescendantOfLeafNode(false)
    , m_cachedIsDescendantOfDisabledNode(false)
    , m_cachedHasInheritedPresentationalRole(false)
    , m_cachedIsPresentationalChild(false)
    , m_cachedLiveRegionRoot(0)
    , m_axObjectCache(axObjectCache)
{
}

AXObject::~AXObject()
{
    ASSERT(isDetached());
}

void AXObject::detach()
{
    // Clear any children and call detachFromParent on them so that
    // no children are left with dangling pointers to their parent.
    clearChildren();

    m_detached = true;
}

bool AXObject::isDetached() const
{
    return m_detached;
}

bool AXObject::isARIATextControl() const
{
    return ariaRoleAttribute() == TextFieldRole || ariaRoleAttribute() == SearchBoxRole;
}

bool AXObject::isButton() const
{
    AccessibilityRole role = roleValue();

    return role == ButtonRole || role == PopUpButtonRole || role == ToggleButtonRole;
}

bool AXObject::isLandmarkRelated() const
{
    switch (roleValue()) {
    case ApplicationRole:
    case ArticleRole:
    case BannerRole:
    case ComplementaryRole:
    case ContentInfoRole:
    case FooterRole:
    case FormRole:
    case MainRole:
    case NavigationRole:
    case RegionRole:
    case SearchRole:
        return true;
    default:
        return false;
    }
}

bool AXObject::isMenuRelated() const
{
    switch (roleValue()) {
    case MenuRole:
    case MenuBarRole:
    case MenuButtonRole:
    case MenuItemRole:
    case MenuItemCheckBoxRole:
    case MenuItemRadioRole:
        return true;
    default:
        return false;
    }
}

bool AXObject::isPasswordFieldAndShouldHideValue() const
{
    Settings* settings = document()->settings();
    if (!settings || settings->accessibilityPasswordValuesEnabled())
        return false;

    return isPasswordField();
}

bool AXObject::isClickable() const
{
    switch (roleValue()) {
    case ButtonRole:
    case CheckBoxRole:
    case ColorWellRole:
    case ComboBoxRole:
    case ImageMapLinkRole:
    case LinkRole:
    case ListBoxOptionRole:
    case MenuButtonRole:
    case PopUpButtonRole:
    case RadioButtonRole:
    case SpinButtonRole:
    case TabRole:
    case TextFieldRole:
    case ToggleButtonRole:
        return true;
    default:
        return false;
    }
}

bool AXObject::accessibilityIsIgnored() const
{
    updateCachedAttributeValuesIfNeeded();
    return m_cachedIsIgnored;
}

void AXObject::updateCachedAttributeValuesIfNeeded() const
{
    AXObjectCacheImpl* cache = axObjectCache();
    if (!cache)
        return;

    if (cache->modificationCount() == m_lastModificationCount)
        return;

    m_lastModificationCount = cache->modificationCount();
    m_cachedIsInertOrAriaHidden = computeIsInertOrAriaHidden();
    m_cachedIsDescendantOfLeafNode = (leafNodeAncestor() != 0);
    m_cachedIsDescendantOfDisabledNode = (disabledAncestor() != 0);
    m_cachedHasInheritedPresentationalRole = (inheritsPresentationalRoleFrom() != 0);
    m_cachedIsPresentationalChild = (ancestorForWhichThisIsAPresentationalChild() != 0);
    m_cachedIsIgnored = computeAccessibilityIsIgnored();
    m_cachedLiveRegionRoot = isLiveRegion() ?
        this :
        (parentObjectIfExists() ? parentObjectIfExists()->liveRegionRoot() : 0);
}

bool AXObject::accessibilityIsIgnoredByDefault(IgnoredReasons* ignoredReasons) const
{
    return defaultObjectInclusion(ignoredReasons) == IgnoreObject;
}

AXObjectInclusion AXObject::accessibilityPlatformIncludesObject() const
{
    if (isMenuListPopup() || isMenuListOption())
        return IncludeObject;

    return DefaultBehavior;
}

AXObjectInclusion AXObject::defaultObjectInclusion(IgnoredReasons* ignoredReasons) const
{
    if (isInertOrAriaHidden()) {
        if (ignoredReasons)
            computeIsInertOrAriaHidden(ignoredReasons);
        return IgnoreObject;
    }

    if (isPresentationalChild()) {
        if (ignoredReasons) {
            AXObject* ancestor = ancestorForWhichThisIsAPresentationalChild();
            ignoredReasons->append(IgnoredReason(AXAncestorDisallowsChild, ancestor));
        }
        return IgnoreObject;
    }

    return accessibilityPlatformIncludesObject();
}

bool AXObject::isInertOrAriaHidden() const
{
    updateCachedAttributeValuesIfNeeded();
    return m_cachedIsInertOrAriaHidden;
}

bool AXObject::computeIsInertOrAriaHidden(IgnoredReasons* ignoredReasons) const
{
    if (node()) {
        if (node()->isInert()) {
            if (ignoredReasons) {
                HTMLDialogElement* dialog = getActiveDialogElement(node());
                if (dialog) {
                    AXObject* dialogObject = axObjectCache()->getOrCreate(dialog);
                    if (dialogObject)
                        ignoredReasons->append(IgnoredReason(AXActiveModalDialog, dialogObject));
                    else
                        ignoredReasons->append(IgnoredReason(AXInert));
                } else {
                    // TODO(aboxhall): handle inert attribute if it eventuates
                    ignoredReasons->append(IgnoredReason(AXInert));
                }
            }
            return true;
        }
    } else {
        AXObject* parent = parentObject();
        if (parent && parent->isInertOrAriaHidden()) {
            if (ignoredReasons)
                parent->computeIsInertOrAriaHidden(ignoredReasons);
            return true;
        }
    }

    const AXObject* hiddenRoot = ariaHiddenRoot();
    if (hiddenRoot) {
        if (ignoredReasons) {
            if (hiddenRoot == this)
                ignoredReasons->append(IgnoredReason(AXAriaHidden));
            else
                ignoredReasons->append(IgnoredReason(AXAriaHiddenRoot, hiddenRoot));
        }
        return true;
    }

    return false;
}

bool AXObject::isDescendantOfLeafNode() const
{
    updateCachedAttributeValuesIfNeeded();
    return m_cachedIsDescendantOfLeafNode;
}

AXObject* AXObject::leafNodeAncestor() const
{
    if (AXObject* parent = parentObject()) {
        if (!parent->canHaveChildren())
            return parent;

        return parent->leafNodeAncestor();
    }

    return 0;
}

const AXObject* AXObject::ariaHiddenRoot() const
{
    for (const AXObject* object = this; object; object = object->parentObject()) {
        if (equalIgnoringCase(object->getAttribute(aria_hiddenAttr), "true"))
            return object;
    }

    return 0;
}

bool AXObject::isDescendantOfDisabledNode() const
{
    updateCachedAttributeValuesIfNeeded();
    return m_cachedIsDescendantOfDisabledNode;
}

const AXObject* AXObject::disabledAncestor() const
{
    const AtomicString& disabled = getAttribute(aria_disabledAttr);
    if (equalIgnoringCase(disabled, "true"))
        return this;
    if (equalIgnoringCase(disabled, "false"))
        return 0;

    if (AXObject* parent = parentObject())
        return parent->disabledAncestor();

    return 0;
}

bool AXObject::lastKnownIsIgnoredValue()
{
    if (m_lastKnownIsIgnoredValue == DefaultBehavior)
        m_lastKnownIsIgnoredValue = accessibilityIsIgnored() ? IgnoreObject : IncludeObject;

    return m_lastKnownIsIgnoredValue == IgnoreObject;
}

void AXObject::setLastKnownIsIgnoredValue(bool isIgnored)
{
    m_lastKnownIsIgnoredValue = isIgnored ? IgnoreObject : IncludeObject;
}

bool AXObject::hasInheritedPresentationalRole() const
{
    updateCachedAttributeValuesIfNeeded();
    return m_cachedHasInheritedPresentationalRole;
}

bool AXObject::isPresentationalChild() const
{
    updateCachedAttributeValuesIfNeeded();
    return m_cachedIsPresentationalChild;
}

String AXObject::name(AXNameFrom& nameFrom, Vector<AXObject*>& nameObjects)
{
    HashSet<AXObject*> visited;
    return textAlternative(false, false, visited, &nameFrom, &nameObjects);
}

// In ARIA 1.1, the default value for aria-orientation changed from horizontal to undefined.
AccessibilityOrientation AXObject::orientation() const
{
    return AccessibilityOrientationUndefined;
}

static String queryString(WebLocalizedString::Name name)
{
    return Locale::defaultLocale().queryString(name);
}

String AXObject::actionVerb() const
{
    // FIXME: Need to add verbs for select elements.

    switch (roleValue()) {
    case ButtonRole:
    case ToggleButtonRole:
        return queryString(WebLocalizedString::AXButtonActionVerb);
    case TextFieldRole:
        return queryString(WebLocalizedString::AXTextFieldActionVerb);
    case RadioButtonRole:
        return queryString(WebLocalizedString::AXRadioButtonActionVerb);
    case CheckBoxRole:
    case SwitchRole:
        return queryString(isChecked() ? WebLocalizedString::AXCheckedCheckBoxActionVerb : WebLocalizedString::AXUncheckedCheckBoxActionVerb);
    case LinkRole:
        return queryString(WebLocalizedString::AXLinkActionVerb);
    case PopUpButtonRole:
        // FIXME: Implement.
        return String();
    case MenuListPopupRole:
        // FIXME: Implement.
        return String();
    default:
        return emptyString();
    }
}

AccessibilityButtonState AXObject::checkboxOrRadioValue() const
{
    // If this is a real checkbox or radio button, AXLayoutObject will handle.
    // If it's an ARIA checkbox or radio, the aria-checked attribute should be used.

    const AtomicString& result = getAttribute(aria_checkedAttr);
    if (equalIgnoringCase(result, "true"))
        return ButtonStateOn;
    if (equalIgnoringCase(result, "mixed")) {
        AccessibilityRole role = ariaRoleAttribute();
        if (role == RadioButtonRole || role == MenuItemRadioRole || role == SwitchRole)
            return ButtonStateOff;
        return ButtonStateMixed;
    }

    return ButtonStateOff;
}

bool AXObject::isMultiline() const
{
    Node* node = this->node();
    if (!node)
        return false;

    if (isHTMLTextAreaElement(*node))
        return true;

    if (node->hasEditableStyle())
        return true;

    if (!isNativeTextControl() && !isNonNativeTextControl())
        return false;

    return equalIgnoringCase(getAttribute(aria_multilineAttr), "true");
}

bool AXObject::ariaPressedIsPresent() const
{
    return !getAttribute(aria_pressedAttr).isEmpty();
}

bool AXObject::supportsARIAAttributes() const
{
    return isLiveRegion()
        || supportsARIADragging()
        || supportsARIADropping()
        || supportsARIAFlowTo()
        || supportsARIAOwns()
        || hasAttribute(aria_labelAttr);
}

bool AXObject::supportsRangeValue() const
{
    return isProgressIndicator()
        || isMeter()
        || isSlider()
        || isScrollbar()
        || isSpinButton();
}

bool AXObject::supportsSetSizeAndPosInSet() const
{
    AXObject* parent = parentObject();
    if (!parent)
        return false;

    int role = roleValue();
    int parentRole = parent->roleValue();

    if ((role == ListBoxOptionRole && parentRole == ListBoxRole)
        || (role == ListItemRole && parentRole == ListRole)
        || (role == MenuItemRole && parentRole == MenuRole)
        || (role == RadioButtonRole && parentRole == RadioGroupRole)
        || (role == TabRole && parentRole == TabListRole)
        || (role == TreeItemRole && parentRole == TreeRole))
        return true;

    return false;
}

int AXObject::indexInParent() const
{
    if (!parentObject())
        return 0;

    const auto& siblings = parentObject()->children();
    int childCount = siblings.size();

    for (int index = 0; index < childCount; ++index) {
        if (siblings[index].get() == this) {
            return index;
        }
    }
    return 0;
}

void AXObject::ariaTreeRows(AccessibilityChildrenVector& result)
{
    for (const auto& child : children()) {
        // Add tree items as the rows.
        if (child->roleValue() == TreeItemRole)
            result.append(child);

        // Now see if this item also has rows hiding inside of it.
        child->ariaTreeRows(result);
    }
}

bool AXObject::isLiveRegion() const
{
    const AtomicString& liveRegion = liveRegionStatus();
    return equalIgnoringCase(liveRegion, "polite") || equalIgnoringCase(liveRegion, "assertive");
}

const AXObject* AXObject::liveRegionRoot() const
{
    updateCachedAttributeValuesIfNeeded();
    return m_cachedLiveRegionRoot;
}

const AtomicString& AXObject::containerLiveRegionStatus() const
{
    updateCachedAttributeValuesIfNeeded();
    return m_cachedLiveRegionRoot ? m_cachedLiveRegionRoot->liveRegionStatus() : nullAtom;
}

const AtomicString& AXObject::containerLiveRegionRelevant() const
{
    updateCachedAttributeValuesIfNeeded();
    return m_cachedLiveRegionRoot ? m_cachedLiveRegionRoot->liveRegionRelevant() : nullAtom;
}

bool AXObject::containerLiveRegionAtomic() const
{
    updateCachedAttributeValuesIfNeeded();
    return m_cachedLiveRegionRoot ? m_cachedLiveRegionRoot->liveRegionAtomic() : false;
}

bool AXObject::containerLiveRegionBusy() const
{
    updateCachedAttributeValuesIfNeeded();
    return m_cachedLiveRegionRoot ? m_cachedLiveRegionRoot->liveRegionBusy() : false;
}

void AXObject::markCachedElementRectDirty() const
{
    for (const auto& child : m_children)
        child->markCachedElementRectDirty();
}

IntPoint AXObject::clickPoint()
{
    LayoutRect rect = elementRect();
    return roundedIntPoint(LayoutPoint(rect.x() + rect.width() / 2, rect.y() + rect.height() / 2));
}

IntRect AXObject::boundingBoxForQuads(LayoutObject* obj, const Vector<FloatQuad>& quads)
{
    ASSERT(obj);
    if (!obj)
        return IntRect();

    size_t count = quads.size();
    if (!count)
        return IntRect();

    IntRect result;
    for (size_t i = 0; i < count; ++i) {
        IntRect r = quads[i].enclosingBoundingBox();
        if (!r.isEmpty()) {
            if (obj->style()->hasAppearance())
                LayoutTheme::theme().adjustPaintInvalidationRect(obj, r);
            result.unite(r);
        }
    }
    return result;
}

AXObject* AXObject::elementAccessibilityHitTest(const IntPoint& point) const
{
    // Send the hit test back into the sub-frame if necessary.
    if (isAttachment()) {
        Widget* widget = widgetForAttachmentView();
        // Normalize the point for the widget's bounds.
        if (widget && widget->isFrameView())
            return axObjectCache()->getOrCreate(widget)->accessibilityHitTest(IntPoint(point - widget->frameRect().location()));
    }

    // Check if there are any mock elements that need to be handled.
    for (const auto& child : m_children) {
        if (child->isMockObject() && child->elementRect().contains(point))
            return child->elementAccessibilityHitTest(point);
    }

    return const_cast<AXObject*>(this);
}

const AXObject::AccessibilityChildrenVector& AXObject::children()
{
    updateChildrenIfNecessary();

    return m_children;
}

AXObject* AXObject::parentObject() const
{
    if (m_detached)
        return 0;

    if (m_parent)
        return m_parent;

    return computeParent();
}

AXObject* AXObject::parentObjectIfExists() const
{
    if (m_detached)
        return 0;

    if (m_parent)
        return m_parent;

    return computeParentIfExists();
}

AXObject* AXObject::parentObjectUnignored() const
{
    AXObject* parent;
    for (parent = parentObject(); parent && parent->accessibilityIsIgnored(); parent = parent->parentObject()) {
    }

    return parent;
}

void AXObject::updateChildrenIfNecessary()
{
    if (!hasChildren())
        addChildren();
}

void AXObject::clearChildren()
{
    // Detach all weak pointers from objects to their parents.
    for (const auto& child : m_children)
        child->detachFromParent();

    m_children.clear();
    m_haveChildren = false;
}

AXObject* AXObject::focusedUIElement() const
{
    Document* doc = document();
    if (!doc)
        return 0;

    Page* page = doc->page();
    if (!page)
        return 0;

    return axObjectCache()->focusedUIElementForPage(page);
}

Document* AXObject::document() const
{
    FrameView* frameView = documentFrameView();
    if (!frameView)
        return 0;

    return frameView->frame().document();
}

FrameView* AXObject::documentFrameView() const
{
    const AXObject* object = this;
    while (object && !object->isAXLayoutObject())
        object = object->parentObject();

    if (!object)
        return 0;

    return object->documentFrameView();
}

String AXObject::language() const
{
    const AtomicString& lang = getAttribute(langAttr);
    if (!lang.isEmpty())
        return lang;

    AXObject* parent = parentObject();

    // as a last resort, fall back to the content language specified in the meta tag
    if (!parent) {
        Document* doc = document();
        if (doc)
            return doc->contentLanguage();
        return nullAtom;
    }

    return parent->language();
}

bool AXObject::hasAttribute(const QualifiedName& attribute) const
{
    Node* elementNode = node();
    if (!elementNode)
        return false;

    if (!elementNode->isElementNode())
        return false;

    Element* element = toElement(elementNode);
    return element->fastHasAttribute(attribute);
}

const AtomicString& AXObject::getAttribute(const QualifiedName& attribute) const
{
    Node* elementNode = node();
    if (!elementNode)
        return nullAtom;

    if (!elementNode->isElementNode())
        return nullAtom;

    Element* element = toElement(elementNode);
    return element->fastGetAttribute(attribute);
}

//
// Scrollable containers.
//

bool AXObject::isScrollableContainer() const
{
    return !!getScrollableAreaIfScrollable();
}

IntPoint AXObject::scrollOffset() const
{
    ScrollableArea* area = getScrollableAreaIfScrollable();
    if (!area)
        return IntPoint();

    return IntPoint(area->scrollPosition().x(), area->scrollPosition().y());
}

IntPoint AXObject::minimumScrollOffset() const
{
    ScrollableArea* area = getScrollableAreaIfScrollable();
    if (!area)
        return IntPoint();

    return IntPoint(area->minimumScrollPosition().x(), area->minimumScrollPosition().y());
}

IntPoint AXObject::maximumScrollOffset() const
{
    ScrollableArea* area = getScrollableAreaIfScrollable();
    if (!area)
        return IntPoint();

    return IntPoint(area->maximumScrollPosition().x(), area->maximumScrollPosition().y());
}

void AXObject::setScrollOffset(const IntPoint& offset) const
{
    ScrollableArea* area = getScrollableAreaIfScrollable();
    if (!area)
        return;

    area->setScrollPosition(DoublePoint(offset.x(), offset.y()));
}

//
// Modify or take an action on an object.
//

bool AXObject::press() const
{
    Element* actionElem = actionElement();
    if (!actionElem)
        return false;
    UserGestureIndicator gestureIndicator(DefinitelyProcessingNewUserGesture);
    actionElem->accessKeyAction(true);
    return true;
}

void AXObject::scrollToMakeVisible() const
{
    IntRect objectRect = pixelSnappedIntRect(elementRect());
    objectRect.setLocation(IntPoint());
    scrollToMakeVisibleWithSubFocus(objectRect);
}

// This is a 1-dimensional scroll offset helper function that's applied
// separately in the horizontal and vertical directions, because the
// logic is the same. The goal is to compute the best scroll offset
// in order to make an object visible within a viewport.
//
// If the object is already fully visible, returns the same scroll
// offset.
//
// In case the whole object cannot fit, you can specify a
// subfocus - a smaller region within the object that should
// be prioritized. If the whole object can fit, the subfocus is
// ignored.
//
// If possible, the object and subfocus are centered within the
// viewport.
//
// Example 1: the object is already visible, so nothing happens.
//   +----------Viewport---------+
//                 +---Object---+
//                 +--SubFocus--+
//
// Example 2: the object is not fully visible, so it's centered
// within the viewport.
//   Before:
//   +----------Viewport---------+
//                         +---Object---+
//                         +--SubFocus--+
//
//   After:
//                 +----------Viewport---------+
//                         +---Object---+
//                         +--SubFocus--+
//
// Example 3: the object is larger than the viewport, so the
// viewport moves to show as much of the object as possible,
// while also trying to center the subfocus.
//   Before:
//   +----------Viewport---------+
//     +---------------Object--------------+
//                         +-SubFocus-+
//
//   After:
//             +----------Viewport---------+
//     +---------------Object--------------+
//                         +-SubFocus-+
//
// When constraints cannot be fully satisfied, the min
// (left/top) position takes precedence over the max (right/bottom).
//
// Note that the return value represents the ideal new scroll offset.
// This may be out of range - the calling function should clip this
// to the available range.
static int computeBestScrollOffset(int currentScrollOffset, int subfocusMin, int subfocusMax, int objectMin, int objectMax, int viewportMin, int viewportMax)
{
    int viewportSize = viewportMax - viewportMin;

    // If the object size is larger than the viewport size, consider
    // only a portion that's as large as the viewport, centering on
    // the subfocus as much as possible.
    if (objectMax - objectMin > viewportSize) {
        // Since it's impossible to fit the whole object in the
        // viewport, exit now if the subfocus is already within the viewport.
        if (subfocusMin - currentScrollOffset >= viewportMin
            && subfocusMax - currentScrollOffset <= viewportMax)
            return currentScrollOffset;

        // Subfocus must be within focus.
        subfocusMin = std::max(subfocusMin, objectMin);
        subfocusMax = std::min(subfocusMax, objectMax);

        // Subfocus must be no larger than the viewport size; favor top/left.
        if (subfocusMax - subfocusMin > viewportSize)
            subfocusMax = subfocusMin + viewportSize;

        // Compute the size of an object centered on the subfocus, the size of the viewport.
        int centeredObjectMin = (subfocusMin + subfocusMax - viewportSize) / 2;
        int centeredObjectMax = centeredObjectMin + viewportSize;

        objectMin = std::max(objectMin, centeredObjectMin);
        objectMax = std::min(objectMax, centeredObjectMax);
    }

    // Exit now if the focus is already within the viewport.
    if (objectMin - currentScrollOffset >= viewportMin
        && objectMax - currentScrollOffset <= viewportMax)
        return currentScrollOffset;

    // Center the object in the viewport.
    return (objectMin + objectMax - viewportMin - viewportMax) / 2;
}

void AXObject::scrollToMakeVisibleWithSubFocus(const IntRect& subfocus) const
{
    // Search up the parent chain until we find the first one that's scrollable.
    AXObject* scrollParent = parentObject();
    ScrollableArea* scrollableArea = 0;
    while (scrollParent) {
        scrollableArea = scrollParent->getScrollableAreaIfScrollable();
        if (scrollableArea && !scrollParent->isAXScrollView())
            break;
        scrollParent = scrollParent->parentObject();
    }
    if (!scrollParent || !scrollableArea)
        return;

    IntRect objectRect = pixelSnappedIntRect(elementRect());
    IntPoint scrollPosition = scrollableArea->scrollPosition();
    IntRect scrollVisibleRect = scrollableArea->visibleContentRect();

    // Convert the object rect into local coordinates.
    if (!scrollParent->isWebArea()) {
        objectRect.moveBy(scrollPosition);
        objectRect.moveBy(-pixelSnappedIntRect(scrollParent->elementRect()).location());
    }

    int desiredX = computeBestScrollOffset(
        scrollPosition.x(),
        objectRect.x() + subfocus.x(), objectRect.x() + subfocus.maxX(),
        objectRect.x(), objectRect.maxX(),
        0, scrollVisibleRect.width());
    int desiredY = computeBestScrollOffset(
        scrollPosition.y(),
        objectRect.y() + subfocus.y(), objectRect.y() + subfocus.maxY(),
        objectRect.y(), objectRect.maxY(),
        0, scrollVisibleRect.height());

    scrollParent->setScrollOffset(IntPoint(desiredX, desiredY));

    // Convert the subfocus into the coordinates of the scroll parent.
    IntRect newSubfocus = subfocus;
    IntRect newElementRect = pixelSnappedIntRect(elementRect());
    IntRect scrollParentRect = pixelSnappedIntRect(scrollParent->elementRect());
    newSubfocus.move(newElementRect.x(), newElementRect.y());
    newSubfocus.move(-scrollParentRect.x(), -scrollParentRect.y());

    // Recursively make sure the scroll parent itself is visible.
    if (scrollParent->parentObject())
        scrollParent->scrollToMakeVisibleWithSubFocus(newSubfocus);
}

void AXObject::scrollToGlobalPoint(const IntPoint& globalPoint) const
{
    // Search up the parent chain and create a vector of all scrollable parent objects
    // and ending with this object itself.
    Vector<const AXObject*> objects;
    AXObject* parentObject;
    for (parentObject = this->parentObject(); parentObject; parentObject = parentObject->parentObject()) {
        if (parentObject->getScrollableAreaIfScrollable() && !parentObject->isAXScrollView())
            objects.prepend(parentObject);
    }
    objects.append(this);

    // Start with the outermost scrollable (the main window) and try to scroll the
    // next innermost object to the given point.
    int offsetX = 0, offsetY = 0;
    IntPoint point = globalPoint;
    size_t levels = objects.size() - 1;
    for (size_t i = 0; i < levels; i++) {
        const AXObject* outer = objects[i];
        const AXObject* inner = objects[i + 1];
        ScrollableArea* scrollableArea = outer->getScrollableAreaIfScrollable();

        IntRect innerRect = inner->isWebArea() ? pixelSnappedIntRect(inner->parentObject()->elementRect()) : pixelSnappedIntRect(inner->elementRect());
        IntRect objectRect = innerRect;
        IntPoint scrollPosition = scrollableArea->scrollPosition();

        // Convert the object rect into local coordinates.
        objectRect.move(offsetX, offsetY);
        if (!outer->isWebArea())
            objectRect.move(scrollPosition.x(), scrollPosition.y());

        int desiredX = computeBestScrollOffset(
            0,
            objectRect.x(), objectRect.maxX(),
            objectRect.x(), objectRect.maxX(),
            point.x(), point.x());
        int desiredY = computeBestScrollOffset(
            0,
            objectRect.y(), objectRect.maxY(),
            objectRect.y(), objectRect.maxY(),
            point.y(), point.y());
        outer->setScrollOffset(IntPoint(desiredX, desiredY));

        if (outer->isWebArea() && !inner->isWebArea()) {
            // If outer object we just scrolled is a web area (frame) but the inner object
            // is not, keep track of the coordinate transformation to apply to
            // future nested calculations.
            scrollPosition = scrollableArea->scrollPosition();
            offsetX -= (scrollPosition.x() + point.x());
            offsetY -= (scrollPosition.y() + point.y());
            point.move(scrollPosition.x() - innerRect.x(), scrollPosition.y() - innerRect.y());
        } else if (inner->isWebArea()) {
            // Otherwise, if the inner object is a web area, reset the coordinate transformation.
            offsetX = 0;
            offsetY = 0;
        }
    }
}

void AXObject::notifyIfIgnoredValueChanged()
{
    bool isIgnored = accessibilityIsIgnored();
    if (lastKnownIsIgnoredValue() != isIgnored) {
        axObjectCache()->childrenChanged(parentObject());
        setLastKnownIsIgnoredValue(isIgnored);
    }
}

void AXObject::selectionChanged()
{
    if (AXObject* parent = parentObjectIfExists())
        parent->selectionChanged();
}

int AXObject::lineForPosition(const VisiblePosition& visiblePos) const
{
    if (visiblePos.isNull() || !node())
        return -1;

    // If the position is not in the same editable region as this AX object, return -1.
    Node* containerNode = visiblePos.deepEquivalent().containerNode();
    if (!containerNode->containsIncludingShadowDOM(node()) && !node()->containsIncludingShadowDOM(containerNode))
        return -1;

    int lineCount = -1;
    VisiblePosition currentVisiblePos = visiblePos;
    VisiblePosition savedVisiblePos;

    // move up until we get to the top
    // FIXME: This only takes us to the top of the rootEditableElement, not the top of the
    // top document.
    do {
        savedVisiblePos = currentVisiblePos;
        VisiblePosition prevVisiblePos = previousLinePosition(currentVisiblePos, 0, HasEditableAXRole);
        currentVisiblePos = prevVisiblePos;
        ++lineCount;
    } while (currentVisiblePos.isNotNull() && !(inSameLine(currentVisiblePos, savedVisiblePos)));

    return lineCount;
}

bool AXObject::isARIAControl(AccessibilityRole ariaRole)
{
    return isARIAInput(ariaRole) || ariaRole == ButtonRole
        || ariaRole == ComboBoxRole || ariaRole == SliderRole;
}

bool AXObject::isARIAInput(AccessibilityRole ariaRole)
{
    return ariaRole == RadioButtonRole || ariaRole == CheckBoxRole || ariaRole == TextFieldRole || ariaRole == SwitchRole || ariaRole ==  SearchBoxRole;
}

AccessibilityRole AXObject::ariaRoleToWebCoreRole(const String& value)
{
    ASSERT(!value.isEmpty());

    static const ARIARoleMap* roleMap = createARIARoleMap();

    Vector<String> roleVector;
    value.split(' ', roleVector);
    AccessibilityRole role = UnknownRole;
    for (const auto& child : roleVector) {
        role = roleMap->get(child);
        if (role)
            return role;
    }

    return role;
}

bool AXObject::isInsideFocusableElementOrARIAWidget(const Node& node)
{
    const Node* curNode = &node;
    do {
        if (curNode->isElementNode()) {
            const Element* element = toElement(curNode);
            if (element->isFocusable())
                return true;
            String role = element->getAttribute("role");
            if (!role.isEmpty() && AXObject::includesARIAWidgetRole(role))
                return true;
            if (hasInteractiveARIAAttribute(*element))
                return true;
        }
        curNode = curNode->parentNode();
    } while (curNode && !isHTMLBodyElement(node));
    return false;
}

bool AXObject::hasInteractiveARIAAttribute(const Element& element)
{
    for (size_t i = 0; i < WTF_ARRAY_LENGTH(ariaInteractiveWidgetAttributes); ++i) {
        const char* attribute = ariaInteractiveWidgetAttributes[i];
        if (element.hasAttribute(attribute)) {
            return true;
        }
    }
    return false;
}

bool AXObject::includesARIAWidgetRole(const String& role)
{
    static const HashSet<String, CaseFoldingHash>* roleSet = createARIARoleWidgetSet();

    Vector<String> roleVector;
    role.split(' ', roleVector);
    for (const auto& child : roleVector) {
        if (roleSet->contains(child))
            return true;
    }
    return false;
}

bool AXObject::nameFromContents() const
{
    switch (roleValue()) {
    case ButtonRole:
    case CheckBoxRole:
    case CellRole:
    case ColumnHeaderRole:
    case DirectoryRole:
    case LinkRole:
    case ListItemRole:
    case MenuItemRole:
    case MenuItemCheckBoxRole:
    case MenuItemRadioRole:
    case MenuListOptionRole:
    case RadioButtonRole:
    case RowHeaderRole:
    case StaticTextRole:
    case StatusRole:
    case SwitchRole:
    case TreeItemRole:
        return true;
    default:
        return false;
    }
}

AccessibilityRole AXObject::buttonRoleType() const
{
    // If aria-pressed is present, then it should be exposed as a toggle button.
    // http://www.w3.org/TR/wai-aria/states_and_properties#aria-pressed
    if (ariaPressedIsPresent())
        return ToggleButtonRole;
    if (ariaHasPopup())
        return PopUpButtonRole;
    // We don't contemplate RadioButtonRole, as it depends on the input
    // type.

    return ButtonRole;
}

const AtomicString& AXObject::roleName(AccessibilityRole role)
{
    static const Vector<AtomicString>* roleNameVector = createRoleNameVector();

    return roleNameVector->at(role);
}

const AtomicString& AXObject::internalRoleName(AccessibilityRole role)
{
    static const Vector<AtomicString>* internalRoleNameVector = createInternalRoleNameVector();

    return internalRoleNameVector->at(role);
}

} // namespace blink


text:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/btn_horizontal_list"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:text="@string/btn_label_horizontal_list" />

    <Button
        android:id="@+id/btn_vertical_list"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:text="@string/btn_label_vertical_list" />

    <Button
        android:id="@+id/btn_grid_list"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:text="@string/btn_label_grid_list" />

    <Button
        android:id="@+id/btn_staggered_grid_list"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:text="@string/btn_label_staggered_grid_list" />
</LinearLayout>

redpajama_set_name: RedPajamaGithub


text:
using System.Dynamic;
using System.Web.Mvc;

namespace Bandage
{
    public class DynamicViewModel : DynamicObject
    {
        public DynamicViewModel()
        {
            viewData = new ViewDataDictionary();
        }

        public DynamicViewModel(ViewDataDictionary viewData)
        {
            this.viewData = viewData;
        }

        readonly ViewDataDictionary viewData;
        readonly DynamicPropertyProvider dynamicProperties = new DynamicPropertyProvider();

        public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            if (!(value is IWrapper))
                value = Wrapper.Create(value, dynamicProperties);

            viewData[binder.Name] = value;
            return true;
        }

        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            if (viewData.TryGetValue(binder.Name, out result))
            {
                if (!(result is IWrapper))
                {
                    result = Wrapper.Create(result, dynamicProperties);
                }
                return true;
            }

            result = null;
            return false;
        }

        public void Add(DynamicProperty dynamicProperty)
        {
            dynamicProperties.Add(dynamicProperty);
        }

        public static implicit operator ViewDataDictionary(DynamicViewModel dvm)
        {
            return dvm.viewData;
        }
    }
}


text:
using LibGit2Sharp;

namespace GitTools.Testing;

/// <summary>
/// Creates a repo with a develop branch off main which is a single commit ahead of main
/// </summary>
public class BaseGitFlowRepositoryFixture : EmptyRepositoryFixture
{
    /// <summary>
    /// Creates a repo with a develop branch off main which is a single commit ahead of main
    ///
    /// Main will be tagged with the initial version before branching develop
    /// </summary>
    public BaseGitFlowRepositoryFixture(string initialVersion) : this(initialVersion, "main")
    {
    }

    /// <summary>
    /// Creates a repo with a develop branch off main which is a single commit ahead of main
    ///
    /// Main will be tagged with the initial version before branching develop
    /// </summary>
    public BaseGitFlowRepositoryFixture(string initialVersion, string branchName) :
        this(r => r.MakeATaggedCommit(initialVersion), branchName)
    {
    }

    /// <summary>
    /// Creates a repo with a develop branch off main which is a single commit ahead of main
    ///
    /// The initial setup actions will be performed before branching develop
    /// </summary>
    public BaseGitFlowRepositoryFixture(Action<IRepository> initialMainAction) : this(initialMainAction, "main")
    {
    }

    /// <summary>
    /// Creates a repo with a develop branch off main which is a single commit ahead of main
    ///
    /// The initial setup actions will be performed before branching develop
    /// </summary>
    public BaseGitFlowRepositoryFixture(Action<IRepository> initialMainAction, string branchName) :
        base(branchName) => SetupRepo(initialMainAction);

    private void SetupRepo(Action<IRepository> initialMainAction)
    {
        var randomFile = Path.Combine(Repository.Info.WorkingDirectory, Guid.NewGuid().ToString());
        File.WriteAllText(randomFile, string.Empty);
        Commands.Stage(Repository, randomFile);

        initialMainAction(Repository);

        Commands.Checkout(Repository, Repository.CreateBranch("develop"));
        Repository.MakeACommit();
    }
}


text:
require 'xcodeproj'
require 'json'

def add_files_to_project(path, json_path)
    production = File.basename(path).start_with?('Pod')
    json = JSON.parse File.read(json_path)
    project = Xcodeproj::Project.open(path)
    target = get_target(project, production)

    group_path = get_group_name(production)
    uikit_group = project.main_group.find_subpath(group_path, true)
    uikit_group.clear
    uikit_group.set_source_tree('SOURCE_ROOT')
    clear_target(target)

    file_refs = []
    json.each do |f|
        unless uikit_group.find_file_by_path(f)
            file_ref = uikit_group.new_reference(f)
            file_refs << file_ref
        end
    end

    target.add_file_references(file_refs)

    project.save
end

def get_target(project, production)
    if production
        project.targets.reduce(project.targets.first) do |init, t|
            puts "[Find] Find target #{t}"
            if t.to_s.include? 'DKNightVersion'
                init = t
            end
        end
    else
        project.targets.first
    end
end

def get_group_name(production)
    if production
        'Pods/DKNightVersion/UIKit'
    else
        'DKNightVersion/Pod/Classes/UIKit'
    end
end

def should_remove(file_name)
    return false if file_name.match('UIButton') or file_name.match('UIImageView')
    /UI[a-zA-Z]+\+(?:[a-zA-Z]+?|Night)\.[hm]/.match(file_name)
end

def clear_target(target)
    target.source_build_phase.files_references.each do |file_ref|
        if file_ref != nil && should_remove(file_ref.name)
            target.source_build_phase.remove_file_reference(file_ref)
        end
    end
    target.headers_build_phase.files_references.each do |file_ref|
        if file_ref != nil && should_remove(file_ref.name)
            target.headers_build_phase.remove_file_reference(file_ref)
        end
    end
end


text:
module ActivitiesHelper
  def destroy_link(record)
    return '' unless record.members.empty?
    (link_to t('common.delete'), activity_path(record),
  method: :delete, data: { confirm: t('activities.confirm_destroy') }).html_safe
  end
end


text:
import pkg_resources
import logging

import yardstick.ssh as ssh
from yardstick.benchmark.scenarios import base

LOG = logging.getLogger(__name__)

class Ping(base.Scenario):
    """Execute ping between two hosts

  Parameters
    packetsize - number of data bytes to send
        type:    int
        unit:    bytes
        default: 56
    """

    __scenario_type__ = "Ping"

    TARGET_SCRIPT = 'ping_benchmark.bash'

    def __init__(self, scenario_cfg, context_cfg):
        self.scenario_cfg = scenario_cfg
        self.context_cfg = context_cfg
        self.target_script = pkg_resources.resource_filename(
            'yardstick.benchmark.scenarios.networking', Ping.TARGET_SCRIPT)
        host = self.context_cfg['host']
        user = host.get('user', 'ubuntu')
        ip = host.get('ip', None)
        key_filename = host.get('key_filename', '/root/.ssh/id_rsa')
        password = host.get('password', None)

        if password is not None:
            LOG.info("Log in via pw, user:%s, host:%s, pw:%s",
                     user, ip, password)
            self.connection = ssh.SSH(user, ip, password=password)
        else:
            LOG.info("Log in via key, user:%s, host:%s, key_filename:%s",
                     user, ip, key_filename)
            self.connection = ssh.SSH(user, ip, key_filename=key_filename)

        self.connection.wait()

    def run(self, result):
        """execute the benchmark"""

        if "options" in self.scenario_cfg:
            options = "-s %s" % \
                self.scenario_cfg['options'].get("packetsize", '56')
        else:
            options = ""

        destination = self.context_cfg['target'].get('ipaddr', '127.0.0.1')
        dest_list = [s.strip() for s in destination.split(',')]

        result["rtt"] = {}
        rtt_result = result["rtt"]

        for pos, dest in enumerate(dest_list):
            if 'targets' in self.scenario_cfg:
                target_vm = self.scenario_cfg['targets'][pos]
            else:
                target_vm = self.scenario_cfg['target']

            LOG.debug("ping '%s' '%s'", options, dest)
            exit_status, stdout, stderr = self.connection.execute(
                "/bin/sh -s {0} {1}".format(dest, options),
                stdin=open(self.target_script, "r"))

            if exit_status != 0:
                raise RuntimeError(stderr)

            if stdout:
                target_vm_name = target_vm.split('.')[0]
                rtt_result[target_vm_name] = float(stdout)
                if "sla" in self.scenario_cfg:
                    sla_max_rtt = int(self.scenario_cfg["sla"]["max_rtt"])
                    assert rtt_result[target_vm_name] <= sla_max_rtt,\
                        "rtt %f > sla: max_rtt(%f); " % \
                        (rtt_result[target_vm_name], sla_max_rtt)
            else:
                LOG.error("ping '%s' '%s' timeout", options, target_vm)

def _test():    # pragma: no cover
    '''internal test function'''
    key_filename = pkg_resources.resource_filename("yardstick.resources",
                                                   "files/yardstick_key")
    ctx = {
        "host": {
            "ip": "10.229.47.137",
            "user": "root",
            "key_filename": key_filename
        },
        "target": {
            "ipaddr": "10.229.17.105",
        }
    }

    logger = logging.getLogger("yardstick")
    logger.setLevel(logging.DEBUG)

    args = {}
    result = {}

    p = Ping(args, ctx)
    p.run(result)
    print result

if __name__ == '__main__':    # pragma: no cover
    _test()


text:
#include <tommath.h>
#ifdef BN_FAST_S_MP_MUL_DIGS_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
 *
 * LibTomMath is a library that provides multiple-precision
 * integer arithmetic as well as number theoretic functionality.
 *
 * The library was designed directly after the MPI library by
 * Michael Fromberger but has been written from scratch with
 * additional optimizations in place.
 *
 * The library is free for all purposes without any express
 * guarantee it works.
 *
 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
 */

/* Fast (comba) multiplier
 *
 * This is the fast column-array [comba] multiplier.  It is
 * designed to compute the columns of the product first
 * then handle the carries afterwards.  This has the effect
 * of making the nested loops that compute the columns very
 * simple and schedulable on super-scalar processors.
 *
 * This has been modified to produce a variable number of
 * digits of output so if say only a half-product is required
 * you don't have to compute the upper half (a feature
 * required for fast Barrett reduction).
 *
 * Based on Algorithm 14.12 on pp.595 of HAC.
 *
 */
int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
{
  int     olduse, res, pa, ix, iz;
  mp_digit W[MP_WARRAY];
  register mp_word  _W;

  /* grow the destination as required */
  if (c->alloc < digs) {
    if ((res = mp_grow (c, digs)) != MP_OKAY) {
      return res;
    }
  }

  /* number of output digits to produce */
  pa = MIN(digs, a->used + b->used);

  /* clear the carry */
  _W = 0;
  for (ix = 0; ix < pa; ix++) {
      int      tx, ty;
      int      iy;
      mp_digit *tmpx, *tmpy;

      /* get offsets into the two bignums */
      ty = MIN(b->used-1, ix);
      tx = ix - ty;

      /* setup temp aliases */
      tmpx = a->dp + tx;
      tmpy = b->dp + ty;

      /* this is the number of times the loop will iterrate, essentially
         while (tx++ < a->used && ty-- >= 0) { ... }
       */
      iy = MIN(a->used-tx, ty+1);

      /* execute loop */
      for (iz = 0; iz < iy; ++iz) {
         _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);

      }

      /* store term */
      W[ix] = ((mp_digit)_W) & MP_MASK;

      /* make next carry */
      _W = _W >> ((mp_word)DIGIT_BIT);
 }

  /* setup dest */
  olduse  = c->used;
  c->used = pa;

  {
    register mp_digit *tmpc;
    tmpc = c->dp;
    for (ix = 0; ix < pa+1; ix++) {
      /* now extract the previous digit [below the carry] */
      *tmpc++ = W[ix];
    }

    /* clear unused digits [that existed in the old copy of c] */
    for (; ix < olduse; ix++) {
      *tmpc++ = 0;
    }
  }
  mp_clamp (c);
  return MP_OKAY;
}
#endif

/* $Source$ */
/* $Revision$ */
/* $Date$ */


text:
import redis

try:
    from django.utils.encoding import force_unicode
except ImportError:  # Python 3.*
    from django.utils.encoding import force_text as force_unicode
from django.contrib.sessions.backends.base import SessionBase, CreateError
from redis_sessions import settings

# Avoid new redis connection on each request

if settings.SESSION_REDIS_SENTINEL_LIST is not None:
    from redis.sentinel import Sentinel

    redis_server = Sentinel(settings.SESSION_REDIS_SENTINEL_LIST, socket_timeout=0.1) \
                    .master_for(settings.SESSION_REDIS_SENTINEL_MASTER_ALIAS,
                                socket_timeout=0.1,
                                db=getattr(settings, 'SESSION_REDIS_DB', 0))

elif settings.SESSION_REDIS_URL is not None:

    redis_server = redis.StrictRedis.from_url(settings.SESSION_REDIS_URL)
elif settings.SESSION_REDIS_UNIX_DOMAIN_SOCKET_PATH is None:

    redis_server = redis.StrictRedis(
        host=settings.SESSION_REDIS_HOST,
        port=settings.SESSION_REDIS_PORT,
        db=settings.SESSION_REDIS_DB,
        password=settings.SESSION_REDIS_PASSWORD
    )
else:

    redis_server = redis.StrictRedis(
        unix_socket_path=settings.SESSION_REDIS_UNIX_DOMAIN_SOCKET_PATH,
        db=settings.SESSION_REDIS_DB,
        password=settings.SESSION_REDIS_PASSWORD,
    )

if settings.SESSION_REDIS_WRAPPER is not None:
    redis_server = settings.SESSION_REDIS_WRAPPER(redis_server)

class SessionStore(SessionBase):
    """
    Implements Redis database session store.
    """
    def __init__(self, session_key=None):
        super(SessionStore, self).__init__(session_key)

        self.server = redis_server

    def load(self):
        try:
            session_data = self.server.get(
                self.get_real_stored_key(self._get_or_create_session_key())
            )
            return self.decode(force_unicode(session_data))
        except:
            self._session_key = None
            return {}

    def exists(self, session_key):
        return self.server.exists(self.get_real_stored_key(session_key))

    def create(self):
        while True:
            self._session_key = self._get_new_session_key()

            try:
                self.save(must_create=True)
            except CreateError:
                # Key wasn't unique. Try again.
                continue
            self.modified = True
            return

    def save(self, must_create=False):
        if self.session_key is None:
            return self.create()
        if must_create and self.exists(self._get_or_create_session_key()):
            raise CreateError
        data = self.encode(self._get_session(no_load=must_create))
        if redis.VERSION[0] >= 2:
            self.server.setex(
                self.get_real_stored_key(self._get_or_create_session_key()),
                self.get_expiry_age(),
                data
            )
        else:
            self.server.set(
                self.get_real_stored_key(self._get_or_create_session_key()),
                data
            )
            self.server.expire(
                self.get_real_stored_key(self._get_or_create_session_key()),
                self.get_expiry_age()
            )

    def delete(self, session_key=None):
        if session_key is None:
            if self.session_key is None:
                return
            session_key = self.session_key
        try:
            self.server.delete(self.get_real_stored_key(session_key))
        except:
            pass

    def get_real_stored_key(self, session_key):
        """Return the real key name in redis storage
        @return string
        """
        prefix = settings.SESSION_REDIS_PREFIX
        if not prefix:
            return session_key
        return ':'.join([prefix, session_key])


text:
title: "Pragmatic Lessons from Converting to React Hooks"
date: 2019-02-07
author: Daniel Lemay
tags:
  - react
  - react hooks
image: "./images/hooks-diff.jpg"
showImageInArticle: true
canonicalLink: "https://www.dslemay.com/blog/2019/02/06/pragmatic-lessons-from-converting-to-react-hooks"
---

Last week I decided to install the React 16.8 alpha on a branch and experiment with React Hooks in preparation for their release on February 6, 2018. The site utilized a [render prop](https://reactjs.org/docs/render-props.html) based Slideshow component in several places as well as a handful of other class based components. Through this process, I was able to consolidate the application code and eliminate all class based components from the site's code base. The React team does not recommend refactoring your entire codebase to Hooks on their release. I did this primarily as a means to engage with the Hooks API in a relatively small codebase. You can find the code conversion to Hooks discussed in this post at the [related PR](https://github.com/dslemay/Portfolio-Site/pull/10).

## Converting to Hooks and lessons learned

The [Hooks documentation](https://reactjs.org/docs/hooks-intro.html) is well presented and an excellent resource to getting started with hooks. I previously championed the render props pattern for reusable logic and composability. However, the extra syntax often comes with tradeoffs in clarity. These concerns include: "wrapper hell" and more mental overhead to parse nested JSX structure within the component. Adding a second render prop component or ternary operator further compounds these concerns. These additional wrappers also display in the React devTools and can get out of hand. The possibility of cleaning up this syntax and providing clearer code is alluring.

```javascript
export const PureRandomQuote = ({
  data: {
    contentfulSlideshow: { slides },
  },
}) => (
  <Slideshow slides={slides}>
    {({ slideData: quote }) => (
      <div className={gridStyles} data-testid="random-quote">
        <QuoteCard>
          <div>{quote.quote}</div>
          <div className={attribution}>{`~${quote.attribution}`}</div>
        </QuoteCard>
      </div>
    )}
  </Slideshow>
)
```

Several components on the site used a Slideshow render prop component. This exposed functionality to play/pause, pass down the current index, go to the previous/next slide, or go to a specific slide in the array. This component accepted an array of slides as a prop and provided an object as the argument in the returned function. Children components used these fields for data rendering or functionality. This is a common approach to the render prop pattern.

This previous implementation had several downsides. The component tracked the timer's ID as an instance variable to clear the timeout. The slide updater function accepted a second argument, to determine if it should clear the stored timeout and create a new one. This resolves the issue of stacking timeouts. A further source of additional code was the need for a state updater function. This is a requirement when accessing the current state in the setState call to ensure that the [updates are applied correctly](https://reactjs.org/docs/react-component.html#setstate). This particular function was complex enough that it was pulled out into it's own side-loaded module. Migrating to a custom hook alleviated these concerns and others.

```javascript
// Can result in state batching issues and is an anti-pattern
const updateStateBad = () => this.setState({ count: this.state.count + 1 })

// Preferred way to reference current state in setState call
const updateStateGood = () =>
  this.setState(state => ({ count: state.count + 1 }))
```

The custom `useSlideshow` hook utilizes two different hooks to replace the functionality of the render props component: `useState` and `useEffect`. The current index and playing states are both set with their own calls to useState. The `useEffect` hook checks if the isPlaying state is true and then sets the timeout to advance the slide to the next index. It resets to the first slide after it reaches the last index. The hook clears the timeout when the current index or isPlaying state changes. The hook includes a function to update the the slide. The necessary state and functions are return in an object.

```javascript
function useSlideshow(slides, { timerLength = 5000 } = {}) {
  const [isPlaying, setIsPlaying] = useState(true)
  const [currIndex, setCurrIndex] = useState(0)

  useEffect(() => {
    if (isPlaying) {
      const timer = setTimeout(
        () => setCurrIndex((currIndex + 1) % slides.length),
        timerLength
      )

      return () => clearTimeout(timer)
    }
  }, [currIndex, isPlaying])

  const updateSlide = (direction: Direction) => {
    if (typeof direction === "number") {
      return setCurrIndex(direction)
    }

    if (direction === "next") {
      return setCurrIndex((currIndex + 1) % slides.length)
    }

    return setCurrIndex((currIndex - 1 + slides.length) % slides.length)
  }

  return {
    currIndex,
    isPlaying,
    setIsPlaying,
    updateSlide,
  }
}
```

The benefits of this structural change go beyond aesthetic cleanup. One major benefit is the cleanup and re-running of useEffect when specific properties change. This eliminates the need of storing the timeout id as a static property. It also eliminates imperative prop comparisons in `componentDidUpdate`. Instead, the function declares the data that will trigger a re-run of this side effect. If `currIndex` or `isPlaying` change, the effect will re-run. First the function will run the cleanup function to clear the timeout, and then will run the effect again. This compounds when a component requires many side effects.

The `useEffect` hook brings more clarity and organization to the side effects in your components. Class based components force you to provide your set up and tear down across three separate life cycle methods: `componentDidMount`, `componentDidUpdate`, and `componentWillUnmount`. This often results in duplication of code. A component may use many side effects which are all placed in these same lifecycle methods. The `useEffect` Hook shifts this paradigm by isolating the functionality of a given side effect in one function. Clean up for the effect is set as a return function. This colocation allows for easier mental parsing and grouping functions by their area of concern.

An extra benefit of `useState` is the ability to reference the current state without additional syntax. With Hooks you can call `setCurrIndex((currIndex + 1) % slides.length)` rather than passing a function which returns the partial state object to update. This results in cleaner code, and eliminated the need for the side-loaded function for the Slideshow component. Converting the Slideshow from a render prop component to a custom Hook resulted in a net reduction of 76 lines of code. Other components within the site utilized class components to manage a single piece of state. Hooks allow you to reduce the boilerplate of a class based component in these circumstances. Functional components connect to state with one line of code.

## Structuring Hooks in Gatsby

Currently I am structuring all my custom hooks in a top level folder so that other components can import them from a central location. Pulling the React dependencies out of Gatsby in version 2 allows for using Hooks immediately. To begin using Hooks today, update React and React-DOM to 16.8.0. There are considerations to take with the `useEffect Hook`. If it references the window object, you need to check that window is defined to avoid Gatsby build errors. These effects would normally live in `componentDidMount` where the component hydrates in the DOM. Hooks are called in the build process. The Gatsby docs have great resources for [debugging HTML builds](docs/debugging-html-builds/) if you encounter this issue.

```javascript
function useMediaQuery() {
  const [isMobile, setIsMobile] = useState(false)

  const handleSizeChange = ({ matches }) => setIsMobile(matches)

  useEffect(() => {
    // Window does not exist on SSR
    if (typeof window !== "undefined") {
      const mql = window.matchMedia("(max-width: 650px)")
      mql.addListener(handleSizeChange)
      setIsMobile(mql.matches) // Set initial state in DOM

      return () => mql.removeListener(handleSizeChange)
    }
  }, [])

  return { isMobile }
}
```

Hooks bring many benefits to React functional components. Specific benefits include:

- Abstracting logic with custom Hooks over render props for reduced syntax and elements in devTools
- Improved ability to share logic across components
- Ability to call `useState` without the need for state updater functions if referencing the current version of state
- Encapsulating side effects into their own function by area of concern
- Provide clean up logic for side effects in a central location compared to across three lifecycle methods

Hooks may not be the death of class based components, but they do encourage critical thought before reaching for a class component. I believe that Hooks are a meaningful shift in the way we approach React development. I can't wait to see what you will build with Hooks.


text:
<!DOCTYPE html>

    <link rel="stylesheet" href="style.css" type="text/css" />

Models

Create Person

        Name: <input id="name" value="Bob Smith" />
        Age: <input id="age" value="20" />
        <button id="add">Add</button>

Change Ages

        Age: <input id="change_age" value="20" />
        <button id="change_ages">Change</button>

People

People Aged 20


text:
import switcher3

window = switcher3.Window(None,"- GVIM", "gvim")
window.activate_app()
#window.debug()
#return


text:
package tgt;

public class StaticCaller003 {
	public String run3() {
		return Integer.toString(SimpleClass003.getMe42());
	}
}


text:
import getSize from './get-size';
import getMarginBox from './get-margin-box';

/**
 * Returns the size (width or height) of a list of elements, including margins.
 * @param {HTMLElement[]} elements An array of child elements (not a NodeList).
 * @param {string} dimension `'width'` or `'height'`.
 * @return {number}
 */
export default function getElementsSize(elements, dimension) {
  return elements.reduce((memo, el) => {
    const outerSize = getSize(el)[dimension];
    const margins = getMarginBox(el);
    const marginSize = dimension === 'height' ?
      margins.top + margins.bottom :
      margins.left + margins.right;

    return memo + outerSize + marginSize;
  }, 0);
}


text:
layout: post
title: Transmission on Raspberry Pi
tags:
- raspberrypi
- pickup.local
---

Prerequisites
=============

- [Headless Raspberry Pi setup]({% post_url 2013-09-17-headless_raspberrypi_setup %})

Install
=======

    $ sudo apt-get install transmission-daemon

    $ sudo mkdir /mnt/usbdrive/torrents
    $ sudo mkdir /mnt/usbdrive/torrents/completed
    $ sudo chmod a+w /mnt/usbdrive/torrents/completed
    $ sudo mkdir /mnt/usbdrive/torrents/downloading
    $ sudo chmod a+w /mnt/usbdrive/torrents/downloading

Fix conf:

    $ sudo emacs /etc/transmission-daemon/settings.json

Set:

    "download-dir": "/mnt/usbdrive/torrents/completed",
    "incomplete-dir": "/mnt/usbdrive/torrents/downloading",
    "incomplete-dir-enabled": true,
    "rpc-whitelist": "127.0.0.1,192.168.0.*",
    "rpc-port": [PORT],

Reload conf:

    $ sudo invoke-rc.d transmission-daemon reload

Visit <http://pickup.local:[PORT]> with transmission/transmission credentials


text:
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Data;

namespace Shapefile
{
    /// <summary>
    /// Base Shapefile shape - contains only the shape type and metadata plus helper methods.
    /// An instance of Shape is the Null ShapeType. If the Type field is not ShapeType.Null then
    /// cast to the more specific shape (i.e. ShapePolygon).
    /// </summary>
    public class Shape
    {
        internal ShapeType _type;
        private int _recordNumber;
        private StringDictionary _metadata;
        private IDataRecord _dataRecord;

        /// <summary>
        /// Base Shapefile shape - contains only the shape type and metadata plus helper methods.
        /// An instance of Shape is the Null ShapeType. If the Type field is not ShapeType.Null then
        /// cast to the more specific shape (i.e. ShapePolygon).
        /// </summary>
        /// <param name="shapeType">The ShapeType of the shape</param>
        /// <param name="recordNumber">The record number in the Shapefile</param>
        /// <param name="metadata">Metadata about the shape (optional)</param>
        /// <param name="dataRecord">IDataRecord associated with the shape</param>
        protected internal Shape(ShapeType shapeType, int recordNumber, StringDictionary metadata, IDataRecord dataRecord)
        {
            _type = shapeType;
            _metadata = metadata;
            _recordNumber = recordNumber;
            _dataRecord = dataRecord;
        }

        /// <summary>
        /// Gets the metadata (as a string) for a given name (key). Valid names
        /// for this shape can be retrieved by calling GetMetadataNames().
        /// </summary>
        /// <param name="name">The name to retreieve</param>
        /// <returns>The metadata string, or null if the requested name does not exist</returns>
        public string GetMetadata(string name)
        {
            if ((_metadata != null) && (_metadata.ContainsKey(name)))
            {
                return _metadata[name];
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// Gets an array of valid metadata names (keys) for this shape. Returns
        /// null if not metadata exists.
        /// </summary>
        /// <returns>Array of metadata names, or null of no metadata exists</returns>
        public string[] GetMetadataNames()
        {
            if ((_metadata != null) && (_metadata.Keys.Count > 0))
            {
                List<string> names = new List<string>(_metadata.Keys.Count);
                foreach (string key in _metadata.Keys)
                {
                    names.Add(key);
                }
                return names.ToArray();
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// Returns the IDataRecord associated with the shape metadata
        /// </summary>
        public IDataRecord DataRecord
        {
            get { return _dataRecord; }
        }

        /// <summary>
        /// Gets the record number associated with this shape
        /// </summary>
        public int RecordNumber
        {
            get { return _recordNumber; }
        }

        /// <summary>
        /// Get the ShapeType of this shape
        /// </summary>
        public ShapeType Type
        {
            get { return _type; }
        }

        /// <summary>
        /// Extracts a double precision rectangle (RectangleD) from a byte array - assumes that
        /// the called has validated that there is enough space in the byte array for four
        /// doubles (32 bytes)
        /// </summary>
        /// <param name="value">byte array</param>
        /// <param name="startIndex">start index in the array</param>
        /// <param name="order">byte order of the doubles to be extracted</param>
        /// <returns>The RectangleD</returns>
        protected RectangleD ParseBoundingBox(byte[] value, int startIndex, ProvidedOrder order)
        {
            return new RectangleD(EndianBitConverter.ToDouble(value, startIndex, order),
                EndianBitConverter.ToDouble(value, startIndex + 8, order),
                EndianBitConverter.ToDouble(value, startIndex + 16, order),
                EndianBitConverter.ToDouble(value, startIndex + 24, order));
        }

        /// <summary>
        /// The PolyLine and Polygon shapes share the same structure, this method parses the bounding box
        /// and list of parts for both
        /// </summary>
        /// <param name="shapeData">The shape record as a byte array</param>
        /// <param name="boundingBox">Returns the bounding box</param>
        /// <param name="parts">Returns the list of parts</param>
        protected void ParsePolyLineOrPolygon(byte[] shapeData, out RectangleD boundingBox, out List<PointD[]> parts)
        {
            boundingBox = new RectangleD();
            parts = null;

            // metadata is validated by the base class
            if (shapeData == null)
            {
                throw new ArgumentNullException("shapeData");
            }

            // Note, shapeData includes an 8 byte header so positions below are +8
            // Position     Field       Value       Type        Number      Order
            // Byte 0       Shape Type  3 or 5      Integer     1           Little
            // Byte 4       Box         Box         Double      4           Little
            // Byte 36      NumParts    NumParts    Integer     1           Little
            // Byte 40      NumPoints   NumPoints   Integer     1           Little
            // Byte 44      Parts       Parts       Integer     NumParts    Little
            // Byte X       Points      Points      Point       NumPoints   Little
            //
            // Note: X = 44 + 4 * NumParts

            // validation step 1 - must have at least 8 + 4 + (4*8) + 4 + 4 bytes = 52
            if (shapeData.Length < 44)
            {
                throw new InvalidOperationException("Invalid shape data");
            }

            // extract bounding box, number of parts and number of points
            boundingBox = ParseBoundingBox(shapeData, 12, ProvidedOrder.Little);
            int numParts = EndianBitConverter.ToInt32(shapeData, 44, ProvidedOrder.Little);
            int numPoints = EndianBitConverter.ToInt32(shapeData, 48, ProvidedOrder.Little);

            // validation step 2 - we're expecting 4 * numParts + 16 * numPoints + 52 bytes total
            if (shapeData.Length != 52 + (4 * numParts) + (16 * numPoints))
            {
                throw new InvalidOperationException("Invalid shape data");
            }

            // now extract the parts
            int partsOffset = 52 + (4 * numParts);
            parts = new List<PointD[]>(numParts);
            for (int part = 0; part < numParts; part++)
            {
                // this is the index of the start of the part in the points array
                int startPart = (EndianBitConverter.ToInt32(shapeData, 52 + (4 * part), ProvidedOrder.Little) * 16) + partsOffset;

                int numBytes;
                if (part == numParts - 1)
                {
                    // it's the last part so we go to the end of the point array
                    numBytes = shapeData.Length - startPart;
                }
                else
                {
                    // we need to get the next part
                    int nextPart = (EndianBitConverter.ToInt32(shapeData, 52 + (4 * (part + 1)), ProvidedOrder.Little) * 16) + partsOffset;
                    numBytes = nextPart - startPart;
                }

                // the number of 16-byte points to read for this segment
                int numPointsInPart = numBytes / 16;

                PointD[] points = new PointD[numPointsInPart];
                for (int point = 0; point < numPointsInPart; point++)
                {
                    points[point] = new PointD(EndianBitConverter.ToDouble(shapeData, startPart + (16 * point), ProvidedOrder.Little),
                        EndianBitConverter.ToDouble(shapeData, startPart + 8 + (16 * point), ProvidedOrder.Little));
                }

                parts.Add(points);
            }
        }

        /// <summary>
        /// The PolygonZ shape share the same structure, this method parses the bounding box
        /// and list of parts for both
        /// </summary>
        /// <param name="shapeData">The shape record as a byte array</param>
        /// <param name="boundingBox">Returns the bounding box</param>
        /// <param name="parts">Returns the list of parts</param>
        protected void ParsePolygonZ(byte[] shapeData, out RectangleD boundingBox, out List<PointD[]> parts)
        {
            boundingBox = new RectangleD();
            parts = null;

            // metadata is validated by the base class
            if (shapeData == null)
            {
                throw new ArgumentNullException("shapeData");
            }

            // Note, shapeData includes an 8 byte header so positions below are +8
            // Position     Field       Value       Type        Number      Order
            // Byte 0       Shape Type  25          Integer     1           Little
            // Byte 4       Box         Box         Double      4           Little
            // Byte 36      NumParts    NumParts    Integer     1           Little
            // Byte 40      NumPoints   NumPoints   Integer     1           Little
            // Byte 44      Parts       Parts       Integer     NumParts    Little
            // Byte X       Points      Points      Point       NumPoints   Little
            // Byte Y       Zmin        Zmin        Double      1           Little
            // Byte Y+8     Zmax        Zmax        Double      1           Little
            // Byte Y+16    Zarray      Zarray      Double      NumPoints   Little
            // Byte Z*      Mmin        Mmin        Double      1           Little
            // Byte Z+8*    Mmax        Mmax        Double      1           Little
            // Byte Z+16*   Marray      Marray      Double      NumPoints   Little
            // Byte M*      Mmin        Mmin        Double      1           Little
            // Byte Z+8*    Mmax        Mmax        Double      1           Little
            // Byte Z+16*   Marray      Marray      Double      NumPoints   Little
            //
            // Note: X = 44 + (4 * NumParts), Y = X + (16 * NumPoints), Z = Y + 16 + (8 * NumPoints)
            // * optional

            // validation step 1 - must have at least 8 + 4 + (4*8) + 4 + 4 bytes = 52
            if (shapeData.Length < 44)
            {
                throw new InvalidOperationException("Invalid shape data");
            }

            // extract bounding box, number of parts and number of points
            boundingBox = ParseBoundingBox(shapeData, 12, ProvidedOrder.Little);
            int numParts = EndianBitConverter.ToInt32(shapeData, 44, ProvidedOrder.Little);
            int numPoints = EndianBitConverter.ToInt32(shapeData, 48, ProvidedOrder.Little);

            // validation step 2 - we're expecting 4 * numParts + 16 * numPoints + 52 bytes total
            if (shapeData.Length != 52 + (4 * numParts) + (16 * numPoints) &&
                shapeData.Length != 52 + (4 * numParts) + (16 * numPoints) + 16 + (8 * numPoints) &&
                shapeData.Length != 52 + (4 * numParts) + (16 * numPoints) + 16 + (8 * numPoints) + 16 + (8 * numPoints))
            {
                throw new InvalidOperationException("Invalid shape data");
            }

            // now extract the parts
            int partsOffset = 52 + (4 * numParts);
            parts = new List<PointD[]>(numParts);
            for (var part = 0; part < numParts; part++)
            {
                // this is the index of the start of the part in the points array
                var startPart = (EndianBitConverter.ToInt32(shapeData, 52 + (4 * part), ProvidedOrder.Little) * 16) + partsOffset;

                int numBytes;
                if (part == numParts - 1)
                {
                    // it's the last part so we go to the end of the point array
                    numBytes = shapeData.Length - startPart;
                }
                else
                {
                    // we need to get the next part
                    var nextPart = (EndianBitConverter.ToInt32(shapeData, 52 + (4 * (part + 1)), ProvidedOrder.Little) * 16) + partsOffset;
                    numBytes = nextPart - startPart;
                }

                // the number of 16-byte points to read for this segment
                var numPointsInPart = Math.Min(numBytes / 16, numPoints);

                var points = new PointD[numPointsInPart];
                for (var point = 0; point < numPointsInPart; point++)
                {
                    points[point] = new PointD(EndianBitConverter.ToDouble(shapeData, startPart + (16 * point), ProvidedOrder.Little),
                        EndianBitConverter.ToDouble(shapeData, startPart + 8 + (16 * point), ProvidedOrder.Little));
                }

                parts.Add(points);
            }
        }

    }
}


text:
from __future__ import print_function
import os.path
import yaml
import json
import msgpack
from pynanomsg import Domain, AF_SP, REP, PUB, SOL_SOCKET, RCVTIMEO

CONFIG = 'config.yaml'

mtime = os.path.getmtime(CONFIG)
with open(CONFIG, 'rt') as f:
    data = yaml.load(f)

dom = Domain(AF_SP)
rsock = dom.socket(REP)
rsock.bind('ipc:///tmp/ns.sock')
rsock.setsockopt(SOL_SOCKET, RCVTIMEO, 1000)

usock = dom.socket(PUB)
usock.bind('ipc:///tmp/nsup.sock')
usock.setsockopt(SOL_SOCKET, RCVTIMEO, 1000)
print('Name service is listening at "ipc:///tmp/ns.sock"')
print('Run nanomsg/nanoconfig apps with:')
print('    NN_CONFIG_SERVICE=ipc:///tmp/ns.sock '
          'NN_CONFIG_UPDATES=ipc:///tmp/nsup.sock app ...')

while True:
    try:
        req = rsock.recv(4096)
    except AssertionError:  # crappy pynanomsg
        # We're timed out, probably need to recheck config for updates
        nmtime = os.path.getmtime(CONFIG)
        if nmtime != mtime:

            with open(CONFIG, 'rt') as f:
                ndata = yaml.load(f)

            topics = set()
            for req, resp in ndata.items():
                if(req in data  # there was address
                    and data[req] != resp  # it was different
                    and len(data[req]) >= 3):  # and there is a subscription
                    #  Add subscriptions to set of updates
                    topics.update(data[req][3])
            # Send updates to everybody
            # Some topics might target more sockets than needed
            # but we don't care little inefficiency here
            for i in topics:
                print("UPDATE TO", i)
                usock.send(i.encode('ascii'))

            data = ndata
            mtime = nmtime

    else:
        print("REQUEST", req)
        if req in data:
            resp = data[req]
        else:
            resp = [0, 404, "Not found"]
        print("RESPONSE", json.dumps(resp))
        rsock.send(msgpack.dumps(resp))


text:
ACCEPTED

#### According to
The Catalogue of Life, 3rd January 2011

#### Published in
Monograph of Clavaria and allied Genera (Annals of Botany Memoirs No. 1) 311 (1950)

#### Original name
Clavaria cirrhata Berk., 1856

### Remarks
null


text:
typedef struct {
    unsigned char alpha;
    unsigned char red;
    unsigned char green;
    unsigned char blue;
}VTARGB8PointValue;

@interface VTARGB8 : NSObject

//取值按照argb取
+ (VTARGB8PointValue)pointValueFromData:(NSData *)imageData
                      pointIndex:(CGPoint)pointIndex
                       imageSize:(CGSize)imageSize;

//取值按照argb取
+ (VTARGB8PointValue)pointValueFromData:(NSData *)imageData
                           index:(NSInteger)index
                       imageSize:(CGSize)imageSize;
@end


text:
using namespace clang;
using namespace llvm::opt;

namespace {
template <typename IntTy>
IntTy getLastArgIntValueImpl(const ArgList &Args, OptSpecifier Id,
                             IntTy Default, DiagnosticsEngine *Diags,
                             unsigned Base) {
  IntTy Res = Default;
  if (Arg *A = Args.getLastArg(Id)) {
    if (StringRef(A->getValue()).getAsInteger(Base, Res)) {
      if (Diags)
        Diags->Report(diag::err_drv_invalid_int_value)
            << A->getAsString(Args) << A->getValue();
    }
  }
  return Res;
}
} // namespace

namespace clang {

int getLastArgIntValue(const ArgList &Args, OptSpecifier Id, int Default,
                       DiagnosticsEngine *Diags, unsigned Base) {
  return getLastArgIntValueImpl<int>(Args, Id, Default, Diags, Base);
}

uint64_t getLastArgUInt64Value(const ArgList &Args, OptSpecifier Id,
                               uint64_t Default, DiagnosticsEngine *Diags,
                               unsigned Base) {
  return getLastArgIntValueImpl<uint64_t>(Args, Id, Default, Diags, Base);
}

} // namespace clang


text:
require 'rails_helper'

RSpec.describe ResponsesController, type: :controller do

end