text:
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="ChangeListManager">
    <list default="true" id="9f8b5cb0-f886-4607-8704-1607b59e9c91" name="Default" comment="" />
    <ignored path="Matricpro.iws" />
    <ignored path=".idea/workspace.xml" />
    <ignored path=".idea/dataSources.local.xml" />
    <option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
    <option name="TRACKING_ENABLED" value="true" />
    <option name="SHOW_DIALOG" value="false" />
    <option name="HIGHLIGHT_CONFLICTS" value="true" />
    <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
    <option name="LAST_RESOLUTION" value="IGNORE" />
  </component>
  <component name="ChangesViewManager" flattened_view="true" show_ignored="false" />
  <component name="CreatePatchCommitExecutor">
    <option name="PATCH_PATH" value="" />
  </component>
  <component name="DaemonCodeAnalyzer">
    <disable_hints />
  </component>
  <component name="ExecutionTargetManager" SELECTED_TARGET="default_target" />
  <component name="FavoritesManager">
    <favorites_list name="Matricpro" />
  </component>
  <component name="FileEditorManager">
    <leaf>
      <file leaf-file-name="carrera.php" pinned="false" current-in-tab="false">
        <entry file="file://$PROJECT_DIR$/application/controllers/carrera.php">
          <provider selected="true" editor-type-id="text-editor">
            <state vertical-scroll-proportion="-23.923077" vertical-offset="891" max-vertical-offset="1615">
              <caret line="89" column="1" selection-start-line="0" selection-start-column="0" selection-end-line="89" selection-end-column="1" />
              <folding />
            </state>
          </provider>
        </entry>
      </file>
      <file leaf-file-name="estudiante.php" pinned="false" current-in-tab="false">
        <entry file="file://$PROJECT_DIR$/application/controllers/estudiante.php">
          <provider selected="true" editor-type-id="text-editor">
            <state vertical-scroll-proportion="19.23077" vertical-offset="1061" max-vertical-offset="1717">
              <caret line="33" column="40" selection-start-line="33" selection-start-column="40" selection-end-line="33" selection-end-column="40" />
              <folding />
            </state>
          </provider>
        </entry>
      </file>
      <file leaf-file-name=".htaccess" pinned="false" current-in-tab="false">
        <entry file="file://$PROJECT_DIR$/application/.htaccess">
          <provider selected="true" editor-type-id="text-editor">
            <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="187">
              <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
              <folding />
            </state>
          </provider>
        </entry>
      </file>
      <file leaf-file-name=".htaccess" pinned="false" current-in-tab="false">
        <entry file="file://$PROJECT_DIR$/.htaccess">
          <provider selected="true" editor-type-id="text-editor">
            <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="306">
              <caret line="12" column="11" selection-start-line="12" selection-start-column="11" selection-end-line="12" selection-end-column="11" />
              <folding />
            </state>
          </provider>
        </entry>
      </file>
      <file leaf-file-name="menuAdministrador.php" pinned="false" current-in-tab="true">
        <entry file="file://$PROJECT_DIR$/application/views/layout/default/menuAdministrador.php">
          <provider selected="true" editor-type-id="text-editor">
            <state vertical-scroll-proportion="0.5960366" vertical-offset="0" max-vertical-offset="656">
              <caret line="23" column="0" selection-start-line="23" selection-start-column="0" selection-end-line="23" selection-end-column="0" />
              <folding>
                <element signature="n#style#0;n#div#0;n#div#0;n#nav#0;n#div#0;n#body#0;n#!!top" expanded="true" />
                <element signature="n#style#0;n#ul#0;n#div#0;n#div#0;n#nav#0;n#div#0;n#body#0;n#!!top" expanded="true" />
              </folding>
            </state>
          </provider>
        </entry>
      </file>
      <file leaf-file-name="index.php" pinned="false" current-in-tab="false">
        <entry file="file://$PROJECT_DIR$/application/views/estudiante/index.php">
          <provider selected="true" editor-type-id="text-editor">
            <state vertical-scroll-proportion="-0.0" vertical-offset="0" max-vertical-offset="782">
              <caret line="0" column="25" selection-start-line="0" selection-start-column="25" selection-end-line="0" selection-end-column="25" />
              <folding>
                <element signature="n#style#0;n#div#0;n#body#0;n#html#0;n#!!top" expanded="true" />
              </folding>
            </state>
          </provider>
        </entry>
      </file>
      <file leaf-file-name="index.php" pinned="false" current-in-tab="false">
        <entry file="file://$PROJECT_DIR$/application/views/carrera/index.php">
          <provider selected="true" editor-type-id="text-editor">
            <state vertical-scroll-proportion="-23.923077" vertical-offset="58" max-vertical-offset="782">
              <caret line="40" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="40" selection-end-column="0" />
              <folding>
                <element signature="n#style#0;n#div#0;n#body#0;n#html#0;n#!!top" expanded="true" />
              </folding>
            </state>
          </provider>
        </entry>
      </file>
      <file leaf-file-name="footer.php" pinned="false" current-in-tab="false">
        <entry file="file://$PROJECT_DIR$/application/views/layout/default/footer.php">
          <provider selected="true" editor-type-id="text-editor">
            <state vertical-scroll-proportion="-1.3076923" vertical-offset="0" max-vertical-offset="221">
              <caret line="2" column="13" selection-start-line="2" selection-start-column="13" selection-end-line="2" selection-end-column="13" />
              <folding />
            </state>
          </provider>
        </entry>
      </file>
      <file leaf-file-name="examples.php" pinned="false" current-in-tab="false">
        <entry file="file://$PROJECT_DIR$/application/controllers/examples.php">
          <provider selected="true" editor-type-id="text-editor">
            <state vertical-scroll-proportion="-10.461538" vertical-offset="0" max-vertical-offset="4318">
              <caret line="16" column="19" selection-start-line="16" selection-start-column="19" selection-end-line="16" selection-end-column="19" />
              <folding />
            </state>
          </provider>
        </entry>
      </file>
      <file leaf-file-name="example.php" pinned="false" current-in-tab="false">
        <entry file="file://$PROJECT_DIR$/application/views/example.php">
          <provider selected="true" editor-type-id="text-editor">
            <state vertical-scroll-proportion="9.153846" vertical-offset="238" max-vertical-offset="884">
              <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
              <folding />
            </state>
          </provider>
        </entry>
      </file>
    </leaf>
  </component>
  <component name="FindManager">
    <FindUsagesManager>
      <setting name="OPEN_NEW_TAB" value="true" />
    </FindUsagesManager>
  </component>
  <component name="Git.Settings">
    <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
  </component>
  <component name="IdeDocumentHistory">
    <option name="changedFiles">
      <list>
        <option value="$PROJECT_DIR$/application/config/autoload.php" />
        <option value="$PROJECT_DIR$/application/config/config.php" />
        <option value="$PROJECT_DIR$/application/config/database.php" />
        <option value="$PROJECT_DIR$/application/views/welcome_message.php" />
        <option value="$PROJECT_DIR$/application/views/layout/default/header.php" />
        <option value="$PROJECT_DIR$/application/controllers/Welcome.php" />
        <option value="$PROJECT_DIR$/application/views/layout/default/footer.php" />
        <option value="$PROJECT_DIR$/application/views/carrera/index.php" />
        <option value="$PROJECT_DIR$/application/controllers/carrera.php" />
        <option value="$PROJECT_DIR$/application/views/estudiante/index.php" />
        <option value="$PROJECT_DIR$/application/controllers/estudiante.php" />
        <option value="$PROJECT_DIR$/application/views/layout/default/menuAdministrador.php" />
      </list>
    </option>
  </component>
  <component name="PhpWorkspaceProjectConfiguration" backward_compatibility_performed="true" />
  <component name="ProjectFrameBounds">
    <option name="x" value="-8" />
    <option name="y" value="-8" />
    <option name="width" value="1552" />
    <option name="height" value="842" />
  </component>
  <component name="ProjectLevelVcsManager" settingsEditedManually="false">
    <OptionsSetting value="true" id="Add" />
    <OptionsSetting value="true" id="Remove" />
    <OptionsSetting value="true" id="Checkout" />
    <OptionsSetting value="true" id="Update" />
    <OptionsSetting value="true" id="Status" />
    <OptionsSetting value="true" id="Edit" />
    <ConfirmationsSetting value="0" id="Add" />
    <ConfirmationsSetting value="0" id="Remove" />
  </component>
  <component name="ProjectReloadState">
    <option name="STATE" value="0" />
  </component>
  <component name="ProjectView">
    <navigator currentView="ProjectPane" proportions="" version="1">
      <flattenPackages />
      <showMembers />
      <showModules />
      <showLibraryContents />
      <hideEmptyPackages />
      <abbreviatePackageNames />
      <autoscrollToSource />
      <autoscrollFromSource />
      <sortByType />
    </navigator>
    <panes>
      <pane id="Scope" />
      <pane id="ProjectPane">
        <subPane>
          <PATH>
            <PATH_ELEMENT>
              <option name="myItemId" value="Matricpro" />
              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
            </PATH_ELEMENT>
          </PATH>
          <PATH>
            <PATH_ELEMENT>
              <option name="myItemId" value="Matricpro" />
              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
            </PATH_ELEMENT>
            <PATH_ELEMENT>
              <option name="myItemId" value="Matricpro" />
              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
            </PATH_ELEMENT>
          </PATH>
          <PATH>
            <PATH_ELEMENT>
              <option name="myItemId" value="Matricpro" />
              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
            </PATH_ELEMENT>
            <PATH_ELEMENT>
              <option name="myItemId" value="Matricpro" />
              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
            </PATH_ELEMENT>
            <PATH_ELEMENT>
              <option name="myItemId" value="application" />
              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
            </PATH_ELEMENT>
          </PATH>
          <PATH>
            <PATH_ELEMENT>
              <option name="myItemId" value="Matricpro" />
              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
            </PATH_ELEMENT>
            <PATH_ELEMENT>
              <option name="myItemId" value="Matricpro" />
              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
            </PATH_ELEMENT>
            <PATH_ELEMENT>
              <option name="myItemId" value="application" />
              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
            </PATH_ELEMENT>
            <PATH_ELEMENT>
              <option name="myItemId" value="views" />
              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
            </PATH_ELEMENT>
          </PATH>
          <PATH>
            <PATH_ELEMENT>
              <option name="myItemId" value="Matricpro" />
              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
            </PATH_ELEMENT>
            <PATH_ELEMENT>
              <option name="myItemId" value="Matricpro" />
              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
            </PATH_ELEMENT>
            <PATH_ELEMENT>
              <option name="myItemId" value="application" />
              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
            </PATH_ELEMENT>
            <PATH_ELEMENT>
              <option name="myItemId" value="views" />
              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
            </PATH_ELEMENT>
            <PATH_ELEMENT>
              <option name="myItemId" value="layout" />
              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
            </PATH_ELEMENT>
            <PATH_ELEMENT>
              <option name="myItemId" value="default" />
              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
            </PATH_ELEMENT>
          </PATH>
          <PATH>
            <PATH_ELEMENT>
              <option name="myItemId" value="Matricpro" />
              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
            </PATH_ELEMENT>
            <PATH_ELEMENT>
              <option name="myItemId" value="Matricpro" />
              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
            </PATH_ELEMENT>
            <PATH_ELEMENT>
              <option name="myItemId" value="application" />
              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
            </PATH_ELEMENT>
            <PATH_ELEMENT>
              <option name="myItemId" value="controllers" />
              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
            </PATH_ELEMENT>
          </PATH>
        </subPane>
      </pane>
    </panes>
  </component>
  <component name="PropertiesComponent">
    <property name="last_opened_file_path" value="$PROJECT_DIR$" />
    <property name="WebServerToolWindowFactoryState" value="false" />
  </component>
  <component name="RunManager">
    <configuration default="true" type="PHPUnitRunConfigurationType" factoryName="PHPUnit">
      <TestRunner />
      <method />
    </configuration>
    <configuration default="true" type="PhpLocalRunConfigurationType" factoryName="PHP Console">
      <method />
    </configuration>
    <configuration default="true" type="JavascriptDebugType" factoryName="JavaScript Debug">
      <method />
    </configuration>
    <configuration default="true" type="PhpBehatConfigurationType" factoryName="Behat">
      <BehatRunner />
      <method />
    </configuration>
    <configuration default="true" type="PhpUnitRemoteRunConfigurationType" factoryName="PHPUnit on Server">
      <method />
    </configuration>
    <configuration default="true" type="js.build_tools.gulp" factoryName="Gulp.js">
      <method />
    </configuration>
    <list size="0" />
  </component>
  <component name="ShelveChangesManager" show_recycled="false" />
  <component name="TaskManager">
    <task active="true" id="Default" summary="Default task">
      <changelist id="9f8b5cb0-f886-4607-8704-1607b59e9c91" name="Default" comment="" />
      <created>1433721188171</created>
      <option name="number" value="Default" />
      <updated>1433721188171</updated>
    </task>
    <servers />
  </component>
  <component name="ToolWindowManager">
    <frame x="-8" y="-8" width="1552" height="842" extended-state="6" />
    <editor active="true" />
    <layout>
      <window_info id="Changes" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
      <window_info id="Terminal" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
      <window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
      <window_info id="Database" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
      <window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
      <window_info id="Application Servers" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
      <window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.17578125" sideWeight="0.5" order="0" side_tool="false" content_ui="combo" />
      <window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="-1" side_tool="true" content_ui="tabs" />
      <window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="-1" side_tool="true" content_ui="tabs" />
      <window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
      <window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
      <window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
      <window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
      <window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
      <window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="SLIDING" type="SLIDING" visible="false" weight="0.4" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
      <window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
      <window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="2" side_tool="false" content_ui="combo" />
      <window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
      <window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
    </layout>
  </component>
  <component name="Vcs.Log.UiProperties">
    <option name="RECENTLY_FILTERED_USER_GROUPS">
      <collection />
    </option>
    <option name="RECENTLY_FILTERED_BRANCH_GROUPS">
      <collection />
    </option>
  </component>
  <component name="VcsContentAnnotationSettings">
    <option name="myLimit" value="2678400000" />
  </component>
  <component name="VcsManagerConfiguration">
    <option name="myTodoPanelSettings">
      <TodoPanelSettings />
    </option>
  </component>
  <component name="XDebuggerManager">
    <breakpoint-manager />
    <watches-manager />
  </component>
  <component name="editorHistoryManager">
    <entry file="file://$PROJECT_DIR$/application/config/autoload.php">
      <provider selected="true" editor-type-id="text-editor">
        <state vertical-scroll-proportion="-64.07692" vertical-offset="0" max-vertical-offset="2482">
          <caret line="98" column="1" selection-start-line="98" selection-start-column="1" selection-end-line="98" selection-end-column="1" />
          <folding />
        </state>
      </provider>
    </entry>
    <entry file="file://$PROJECT_DIR$/application/config/config.php">
      <provider selected="true" editor-type-id="text-editor">
        <state vertical-scroll-proportion="-7.1923075" vertical-offset="0" max-vertical-offset="8602">
          <caret line="11" column="1" selection-start-line="11" selection-start-column="1" selection-end-line="11" selection-end-column="1" />
          <folding />
        </state>
      </provider>
    </entry>
    <entry file="file://$PROJECT_DIR$/application/config/database.php">
      <provider selected="true" editor-type-id="text-editor">
        <state vertical-scroll-proportion="-12.423077" vertical-offset="816" max-vertical-offset="1547">
          <caret line="67" column="23" selection-start-line="67" selection-start-column="23" selection-end-line="67" selection-end-column="23" />
          <folding />
        </state>
      </provider>
    </entry>
    <entry file="file://$PROJECT_DIR$/application/config/routes.php">
      <provider selected="true" editor-type-id="text-editor">
        <state vertical-scroll-proportion="-13.653846" vertical-offset="393" max-vertical-offset="1020">
          <caret line="44" column="19" selection-start-line="44" selection-start-column="19" selection-end-line="44" selection-end-column="19" />
          <folding />
        </state>
      </provider>
    </entry>
    <entry file="file://$PROJECT_DIR$/application/views/welcome_message.php">
      <provider selected="true" editor-type-id="text-editor">
        <state vertical-scroll-proportion="-14.307693" vertical-offset="733" max-vertical-offset="1360">
          <caret line="65" column="12" selection-start-line="65" selection-start-column="12" selection-end-line="65" selection-end-column="12" />
          <folding />
        </state>
      </provider>
    </entry>
    <entry file="file://$PROJECT_DIR$/application/views/layout/default/header.php">
      <provider selected="true" editor-type-id="text-editor">
        <state vertical-scroll-proportion="-4.576923" vertical-offset="0" max-vertical-offset="221">
          <caret line="7" column="0" selection-start-line="7" selection-start-column="0" selection-end-line="7" selection-end-column="0" />
          <folding>
            <marker date="1433722749670" expanded="true" signature="-1:-1" placeholder="..." />
          </folding>
        </state>
      </provider>
    </entry>
    <entry file="file://$PROJECT_DIR$/application/controllers/Welcome.php">
      <provider selected="true" editor-type-id="text-editor">
        <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="595">
          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="29" selection-end-column="0" />
          <folding />
        </state>
      </provider>
    </entry>
    <entry file="file://$PROJECT_DIR$/application/views/layout/default/footer.php">
      <provider selected="true" editor-type-id="text-editor">
        <state vertical-scroll-proportion="-1.3076923" vertical-offset="0" max-vertical-offset="221">
          <caret line="2" column="13" selection-start-line="2" selection-start-column="13" selection-end-line="2" selection-end-column="13" />
          <folding />
        </state>
      </provider>
    </entry>
    <entry file="file://$PROJECT_DIR$/application/views/example.php">
      <provider selected="true" editor-type-id="text-editor">
        <state vertical-scroll-proportion="9.153846" vertical-offset="238" max-vertical-offset="884">
          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
          <folding />
        </state>
      </provider>
    </entry>
    <entry file="file://$PROJECT_DIR$/application/controllers/examples.php">
      <provider selected="true" editor-type-id="text-editor">
        <state vertical-scroll-proportion="-10.461538" vertical-offset="0" max-vertical-offset="4318">
          <caret line="16" column="19" selection-start-line="16" selection-start-column="19" selection-end-line="16" selection-end-column="19" />
          <folding />
        </state>
      </provider>
    </entry>
    <entry file="file://$PROJECT_DIR$/application/controllers/carrera.php">
      <provider selected="true" editor-type-id="text-editor">
        <state vertical-scroll-proportion="-23.923077" vertical-offset="891" max-vertical-offset="1615">
          <caret line="89" column="1" selection-start-line="0" selection-start-column="0" selection-end-line="89" selection-end-column="1" />
          <folding />
        </state>
      </provider>
    </entry>
    <entry file="file://$PROJECT_DIR$/application/views/carrera/index.php">
      <provider selected="true" editor-type-id="text-editor">
        <state vertical-scroll-proportion="-23.923077" vertical-offset="58" max-vertical-offset="782">
          <caret line="40" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="40" selection-end-column="0" />
          <folding>
            <element signature="n#style#0;n#div#0;n#body#0;n#html#0;n#!!top" expanded="true" />
          </folding>
        </state>
      </provider>
    </entry>
    <entry file="file://$PROJECT_DIR$/application/views/estudiante/index.php">
      <provider selected="true" editor-type-id="text-editor">
        <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="782">
          <caret line="0" column="25" selection-start-line="0" selection-start-column="25" selection-end-line="0" selection-end-column="25" />
          <folding>
            <element signature="n#style#0;n#div#0;n#body#0;n#html#0;n#!!top" expanded="true" />
          </folding>
        </state>
      </provider>
    </entry>
    <entry file="file://$PROJECT_DIR$/application/controllers/estudiante.php">
      <provider selected="true" editor-type-id="text-editor">
        <state vertical-scroll-proportion="19.23077" vertical-offset="1061" max-vertical-offset="1717">
          <caret line="33" column="40" selection-start-line="33" selection-start-column="40" selection-end-line="33" selection-end-column="40" />
          <folding />
        </state>
      </provider>
    </entry>
    <entry file="file://$PROJECT_DIR$/application/.htaccess">
      <provider selected="true" editor-type-id="text-editor">
        <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="682">
          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
          <folding />
        </state>
      </provider>
    </entry>
    <entry file="file://$PROJECT_DIR$/.htaccess">
      <provider selected="true" editor-type-id="text-editor">
        <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="306">
          <caret line="12" column="11" selection-start-line="12" selection-start-column="11" selection-end-line="12" selection-end-column="11" />
          <folding />
        </state>
      </provider>
    </entry>
    <entry file="file://$PROJECT_DIR$/application/views/layout/default/menuAdministrador.php">
      <provider selected="true" editor-type-id="text-editor">
        <state vertical-scroll-proportion="0.5960366" vertical-offset="0" max-vertical-offset="656">
          <caret line="23" column="0" selection-start-line="23" selection-start-column="0" selection-end-line="23" selection-end-column="0" />
          <folding>
            <element signature="n#style#0;n#div#0;n#div#0;n#nav#0;n#div#0;n#body#0;n#!!top" expanded="true" />
            <element signature="n#style#0;n#ul#0;n#div#0;n#div#0;n#nav#0;n#div#0;n#body#0;n#!!top" expanded="true" />
          </folding>
        </state>
      </provider>
    </entry>
  </component>
</project>


text:
<!DOCTYPE html>

  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  <title>在Chrome中将上传的文件夹数据转化为按树结构展示 - 飞狐的部落格</title>
  <meta name="renderer" content="webkit" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>

<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />

<meta name="theme-color" content="#f8f5ec" />
<meta name="msapplication-navbutton-color" content="#f8f5ec">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="#f8f5ec">

<meta name="author" content="Rosen Lu" /><meta name="description" content="简要叙述如何在Chrome中将上传的文件夹数据转化为按树结构展示" /><meta name="keywords" content="文件夹上传, 树结构" />

<meta name="generator" content="Hugo 0.100.2 with theme even" />

<link rel="canonical" href="https://lucumt.info/post/web/convert-folder-upload-data-to-tree-node-in-chrome/" />
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/manifest.json">
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">

<link href="/sass/main.min.42582d13b483cd0f7dec049cf819eefca048379b10708ab4de86a139d1b963a1.css" rel="stylesheet">
<link href="/lib/fancybox/jquery.fancybox-3.1.20.min.css" rel="stylesheet">

<meta property="og:title" content="在Chrome中将上传的文件夹数据转化为按树结构展示" />
<meta property="og:description" content="简要叙述如何在Chrome中将上传的文件夹数据转化为按树结构展示" />
<meta property="og:type" content="article" />
<meta property="og:url" content="https://lucumt.info/post/web/convert-folder-upload-data-to-tree-node-in-chrome/" /><meta property="article:section" content="post" />
<meta property="article:published_time" content="2022-02-20T20:38:18+08:00" />
<meta property="article:modified_time" content="2022-08-20T20:38:18+08:00" />

<meta itemprop="name" content="在Chrome中将上传的文件夹数据转化为按树结构展示">
<meta itemprop="description" content="简要叙述如何在Chrome中将上传的文件夹数据转化为按树结构展示"><meta itemprop="datePublished" content="2022-02-20T20:38:18+08:00" />
<meta itemprop="dateModified" content="2022-08-20T20:38:18+08:00" />
<meta itemprop="wordCount" content="2809">
<meta itemprop="keywords" content="html5,JavaScript," /><meta name="twitter:card" content="summary"/>
<meta name="twitter:title" content="在Chrome中将上传的文件夹数据转化为按树结构展示"/>
<meta name="twitter:description" content="简要叙述如何在Chrome中将上传的文件夹数据转化为按树结构展示"/>

    Rosen's World

主页

归档

标签

分类

关于我

  Rosen's World

        主页

        归档

        标签

        分类

        关于我

在Chrome中将上传的文件夹数据转化为按树结构展示

         2022-02-20

             web编程

文章目录

结构分析

修改思路

逐层处理

处理重复

代码实现

Java版本实现

项目中有个模块支持按文件夹选中批量上传,用户希望在真正上传之前能够在浏览器中实时预览选中的文件夹层级结构,本文基于Chrome浏览器为例,简要说明这一实现。

若要Chrome浏览器中支持批量上传文件夹,需要在input控件中添加webkitdirectory属性,如下图所示

1
2
3

<body>
  上传文件夹 <input type="file" webkitdirectory onchange="getfolder(event)">
</body>

以一个典型的Maven功能做为测试目录,其文件结构如下,用户希望选中SpringTest文件夹后在前端上传之前就能够在网页上展示出类似的结构

当基于前述的HTML代码选中上面的工程目录上传时,Chrome浏览器会提示如下警告框,此警告框是浏览器出于安全原因提示1,可不用理会。

结构分析

在getfolder方法中分析event变量时,可发现event.target.files属性下包含我们所上传的全部文件,将其打印输出的结果如下:

进一步观察可发现其中的webkitRelativePath中包含文件的完整路径,类似SpringTest/target/classes/com/lucumt/bean/User.class,这个路径虽然包含了上传文件的完整路径,但其为一个字符串,无法直接用于展示层级结构,进一步分析event变量的其它属性也没有找到有用的信息,看来只能从webkitRelativePath着手更改。

修改思路

为了展示层级结构,首先需要定义一个如下所示的Node结构,其中path用于存储对应的文件名(不含父路径),children在为文件夹时存储子文件(文件夹)的信息:

1
2
3
4

function Node(path){
    this.path = path;
    this.children = [];
}

最终的结果都是基于Node进行组合处理。

逐层处理

如上图所示,由于通过JavaScript获取的都是节点的完整路径,从简化实现的角度考虑,系统按照文件夹层级自底向上逐级解析,解析到根目录时则停止。在此过程中,获取到的文件路径不断缩小,直至处理到根节点,以SpringTest/target/test-classes/com/lucumt/TestGetBean.class为例,其解析过程说明如下:

初始路径为SpringTest/target/test-classes/com/lucumt/TestGetBean.class

将前述路径拆分为TestGetBean.class(为其创建节点node1)和SpringTest/target/test-classes/com/lucumt(为其创建节点node2),node2的子节点包含node1

将node2的路径拆分为lucumt(更新node2节点的路径)和SpringTest/target/test-classes/com(为其创建node3节点),node3节点的子节点包含node2

将node3节点的路径拆分为com(更新node3节点的路径)和SpringTest/target/test-classes(为其创建节点node4)

将node4节点的路径拆分为test-classes(更新node4节点的路径)和SpringTest/target(为其创建节点node5)

将node5节点的路径拆分为target(更新node5节点路径)和SpringTest(为其创建节点node6)

节点node6已经是根节点,整个过程完毕,至此从node6基于children属性可一直往下招到node1文件节点。

处理重复

基于上述实现方案时有一个问题待解决,如SpringTest/target/test-classes/com/lucumt/TestGetBean.class和SpringTest/target/classes/com/lucumt/TestApplication.class在拆分到第2层级时,都会识别到lucumt文件夹,若都去创建该文件夹节点数据则会导致重复。

回顾前面的逐层处理实现方案可知,当处理SpringTest/target/classes/com/lucumt/TestApplication.class时,SpringTest/target/test-classes/com/lucumt/TestGetBean.class已经被处理完比,在这一过程中会给我们创建好lucumt目录,在接下来处理SpringTest/target/test-classes/com/lucumt/TestGetBean.class时我们只需要找到lucumt对应的父节点,然后检查父节点下有没有该目录即可。

基于上述分析,要在逐级遍历的过程中添加如下处理:

遍历到当前文件或文件夹节点时,需要查找其父节点,若父节点不存在则创建,同时将当前节点加入到父节点的子节点集合中去

若当前节点的父节点存在,则需要获取其所有的子节点,并与当前节点进行避免,判断当前节点是否存在,若存在则不需要重复创建

为了记录当前节点的父节点,可在JavaScript中采用Map数据结构,其中key为节点的路径,value为Node节点自身。

代码实现

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

function getfolder(event) {
    let files = event.target.files;
    let map = {};
    var rootPath = files[0].webkitRelativePath.split('/')[0];
    // 循环遍历,检测所有的文件路径
    for (var i in files) {
        var node = files[i];
        var path = node.webkitRelativePath;
        if (!path) {
            continue;
        }
        while (true) {
            // 处理到最顶层文件夹时,就不用往上继续处理
            if (!path || path.indexOf("/") == -1) {
                break;
            }
            var index = path.lastIndexOf("/");
            var parentPath = path.substring(0, index);
            var file = path.substring(index + 1);
            var node;
            if (!map[path]) {
                node = new Node(file);
                map[path] = node;
            } else {
                node = map[path];
            }

            // 父节点没有则创建
            if (!map[parentPath]) {
                var parentFile = parentPath.substring(parentPath.lastIndexOf("/") + 1)
                var pNode = new Node(parentFile);

                // 动态的更新父节点的子节点,为后续检查重复节点做准备
                pNode.children.push(node);

                map[parentPath] = pNode;
            } else {
                var pNode = map[parentPath];
                var children = pNode.children;
                var addNode = true;

                // 通过检查父节点下的子节点来避免重复创建
                for (var k in children) {
                    if (children[k].path == file) {
                        addNode = false;
                        break;
                    }
                }
                if (addNode) {
                    pNode.children.push(node);
                }
            }
            // 逐级缩短父节点的路径,直到回到最顶层
            path = parentPath;
        }
    }
    console.log(map[rootPath]);

}

执行上述代码后在Chrome控制台的输出如下,可见root中已能够正确的输出层级结构,进行到这一步后续在页面上展示就很容易了,此处不再叙述。

Java版本实现

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104

public class TestFilePathConvert {

    public static void main(String[] args) {
        String[] paths = {
                "a/b1/c1/d1.txt",
                "a/b1/c1/d2.txt",
                "a/b1/c1/d2/e1/f.txt",
                "a/b2/c2/d1",
                "a/b3/c1",
                "a/b4/c1/d1/e1/f1",
                "a/b4/c1/d1/e1/f2/g1.png",
                "a/b5/c1"
        };
        convertPathToTreeNode(paths);
    }

    public static void convertPathToTreeNode(String[] paths) {

        Map<String, Node> map = new HashMap<>();
        for (String path : paths) {
            while (true) {
                Node node, pNode;
                String nodeName;
                if (map.containsKey(path)) {
                    node = map.get(path);
                    nodeName = node.getName();
                } else {
                    int index = path.lastIndexOf("/");
                    nodeName = path.substring(index + 1);
                    node = new Node(nodeName);
                    map.put(path, node);
                }

                String parentPath = StringUtils.substringBeforeLast(path, "/");
                if (path.equals(parentPath)) {
                    break;
                }

                // 处理父节点
                if (map.containsKey(parentPath)) {
                    pNode = map.get(parentPath);
                } else {
                    int index = parentPath.lastIndexOf("/");
                    String pName = parentPath.substring(index + 1);
                    pNode = new Node(pName);
                    map.put(parentPath, pNode);
                }
                //检查当前节点是否存在
                boolean add = true;
                for (Node n : pNode.getChildren()) {
                    if (nodeName.equals(n.getName())) {
                        add = false;
                        break;
                    }
                }
                // 避免当前节点的重复添加
                if (add) {
                    pNode.getChildren().add(node);
                }
                path = parentPath;
            }
        }
        String root = StringUtils.substringBefore(paths[0], "/");
        Node rootNode = map.get(root);
        Gson gson = new Gson();
        System.out.println(gson.toJson(rootNode));
    }

    static class Node {
        private String name;

        private List<Node> children = new ArrayList<>();

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public List<Node> getChildren() {
            return children;
        }

        public void setChildren(List<Node> children) {
            this.children = children;
        }

        public Node(String name) {
            this.name = name;
        }

        @Override
        public String toString() {
            return "Node{" +
                    "name='" + name + '\'' +
                    ", children=" + children.size() +
                    '}';
        }
    }
}

https://stackoverflow.com/questions/50225019/how-to-remove-warning-message-in-chrome-when-uploading-a-directory ↩

          html5
          JavaScript

            5.[译]同线程系统
            上一篇

            Spring中BeanFactory和FactoryBean的区别以及使用场景
            下一篇

    Please enable JavaScript to view the comments powered by giscus.

    由 Hugo 强力驱动

  |

    主题 -
    Even

    ©
    2016 -
    2022Rosen Lu

redpajama_set_name: RedPajamaGithub


text: Insert Issue Here


text:
(function() {
  var LightbotInstruction, actions, colors,
    __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };

  actions = ['forward', 'right', 'left', 'jump', 'bulb', 'p1', 'p2', 'return'];

  colors = ['green', 'red'];

  module.exports = LightbotInstruction = (function() {
    function LightbotInstruction(action, color) {
      var _ref, _ref1;
      this.action = action;
      this.color = color != null ? color : null;
      if (_ref = this.action, __indexOf.call(actions, _ref) < 0) {
        throw new Error("invalid action: " + this.action);
      }
      if ((this.color != null) && (_ref1 = !this.color, __indexOf.call(colors, _ref1) >= 0)) {
        throw new Error("invalid color: " + this.color);
      }
    }

    LightbotInstruction.prototype.draw = function() {
      var line;
      line = this.action;
      if (this.color) {
        line = "[" + (this.color === 'red' ? 31 : 32) + "m" + line + "";
      }
      return console.log(line);
    };

    return LightbotInstruction;

  })();

}).call(this);


text:
import numpy as np
from scipy.ndimage import zoom
from keras.models import Model
from keras.applications.resnet50 import preprocess_input
from keras.preprocessing.image import load_img, img_to_array

class CAMExplainer:
    """CAM (Class Activation Map) Explainer"""

    def __init__(self, model, target_size=(224, 224)):
        self.model = model
        self.target_size = target_size

        self.class_weights_ = None
        self.resnet50_cam_layers_ = None

    def fit(self, img_path):
        if self.class_weights_ is None:
            self.resnet50_cam_layers_, self.class_weights_ = self._get_resnet50_cam_info()

        self.img_, keras_img = self._read_and_process_img(img_path)
        self.cam_, self.predicted_class_ = self._create_cam(keras_img)
        return self

    def plot(self):
        import matplotlib.pyplot as plt
        fig, ax = plt.subplots()

        ax.imshow(self.img_, alpha=0.5)
        ax.imshow(self.cam_, cmap='jet', alpha=0.5)
        plt.show()

    def _create_cam(self, img):
        # before_gap_output will be of shape [1, 7, 7, 2048] for resnet50
        before_gap_output, prediction = self.resnet50_cam_layers_.predict(img)
        img_width = before_gap_output.shape[1]
        img_height = before_gap_output.shape[2]
        n_activation = before_gap_output.shape[3]

        predicted_class = np.argmax(prediction)
        dominate_class_weight = self.class_weights_[:, predicted_class]

        # we resize the shape of the activation so we can perform a dot product with
        # the dominated class weight
        before_gap_output = np.squeeze(before_gap_output).reshape((-1, n_activation))
        cam = np.dot(before_gap_output, dominate_class_weight).reshape((img_width, img_height))

        # we reshape it back to the target image size
        # so we can overlay the class activation map on top of our image later
        # order 1 = bi-linear interpolation was fast enough for this use-case
        width_scale_ratio = self.target_size[0] // img_width
        height_scale_ratio = self.target_size[1] // img_height
        cam = zoom(cam, (width_scale_ratio, height_scale_ratio), order=1)
        return cam, predicted_class

    def _read_and_process_img(self, img_path):
        """
        Reads in a single image, resize it to the specified target size
        and performs the same preprocessing on the image as the original
        pre-trained model.
        """
        img = load_img(img_path, target_size=self.target_size)
        img_arr = img_to_array(img)

        # keras works with batches of images, since we only have 1 image
        # here, we need to add an additional dimension to turn it into
        # shape [samples, size1, size2, channels]
        keras_img = np.expand_dims(img_arr, axis=0)

        # different pre-trained model preprocess the images differently
        # we also preprocess our images the same way to be consistent
        keras_img = preprocess_input(keras_img)
        return img, keras_img

    def _get_resnet50_cam_info(self):
        # we need the output of the activation layer right before the
        # global average pooling (gap) layer and the last dense/softmax
        # layer that generates the class prediction
        before_gap_layer = self.model.layers[-4]
        class_pred_layer = self.model.layers[-1]

        outputs = before_gap_layer.output, class_pred_layer.output
        resnet50_cam_layers = Model(inputs=self.model.input, outputs=outputs)

        # only access the first element of weights, we won't be needing the bias term here
        class_weights = class_pred_layer.get_weights()[0]
        return resnet50_cam_layers, class_weights


text:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="digital_text_size">50dp</dimen>
    <dimen name="digital_text_size_round">50dp</dimen>
    <dimen name="digital_am_pm_size">25dp</dimen>
    <dimen name="digital_am_pm_size_round">30dp</dimen>
    <dimen name="digital_x_offset">60dp</dimen>
    <dimen name="digital_x_offset_round">60dp</dimen> <!--25-->
    <dimen name="digital_y_offset">140dp</dimen>
    <dimen name="digital_config_color_picker_item_margin">32dp</dimen>
    <dimen name="content_padding_start">12dp</dimen>
</resources>


text:
module RansackAdvancedPlus
  class Service

    attr_accessor :klass, :ransack_object, :form

    def initialize(model)
      @model_name = model
      @klass = model.classify.constantize
      @ransack_object = @klass.send :ransack
      @form = nil
      @view_context
    end

    def build_form_context(view_context)
      @view_context = view_context
      @view_context.search_form_for(@ransack_object){|frm| @form = frm}
    end

    #REQUIRE CALL build_form_context BEFORE USE THIS
    def builder_by_type(type, group_index=0, condition_index=0)
      if type=='condition'
        builder_grouping(group_index)
      elsif type=='value'
        builder_condition(group_index, condition_index)
      else
        @form
      end
    end

    #REQUIRE CALL build_form_context BEFORE USE THIS
    def builder_grouping(group_index=0)
      if @form.grouping_fields.present?
        @form.grouping_fields
      else
        @form.send("grouping_fields", @form.object.send("build_grouping"), child_index: group_index){|g| @g=g}
        @g
      end
    end

    #REQUIRE CALL build_form_context BEFORE USE THIS
    def builder_condition(group_index=0, condition_index=0)
      if @form.condition_fields.present?
        @form.condition_fields
      else
        @form.send("grouping_fields", @form.object.send("build_grouping"), child_index: group_index){|g| @g=g}
        @g.send("condition_fields", @g.object.send("build_condition"), child_index: condition_index){|c| @c=c}
        @c
      end
    end

    def attributes(attribute=nil)
      bases = [''] + @klass.ransackable_associations
      fields_type = Hash.new
      bases.each do |model|
        model_name = model.present? ? "#{model}_" : ""
        @ransack_object.context.traverse(model).columns_hash.each do |field, attributes|
          attr_name = "#{model_name}#{field}"
          next if attribute.present? && attr_name!=attribute.to_s
          fields_type[attr_name] = attributes.type
        end
      end
      fields_type
    end

    def attribute_type(attribute)
      if attribute_is_collection?(attribute)
        :collection
      else
        attributes(attribute).values.first
      end
    end

    def attribute_operators(attribute)
      operators_by_type(attribute_type(attribute))
    end

    def association_klass_from_attribute(attribute)
      klass = nil
      attribute_name = nil
      @klass.ransackable_associations.each do |association|
        if attribute =~ /^#{association}_/
          klass = association.classify.constantize
          attribute_name = attribute.gsub("#{association}_",'')
        end
      end
      return klass, attribute_name
    end

    def attribute_is_collection?(attribute)
      association_klass, attribute_name = association_klass_from_attribute(attribute)
      (association_klass && association_klass.respond_to?("#{attribute_name}_collection"))
    end

    def operators_by_type(type)
      case type.to_sym
        when :string
          [:eq, :not_eq, :matches, :does_not_match]
        when :integer, :float
          [:eq, :not_eq, :lt, :lteq, :gt, :gteq, :in, :not_in]
        when :date, :time, :datetime
          [:eq, :not_eq, :lt, :lteq, :gt, :gteq]
        when :boolean
          [:eq, :not_eq]
        else
          [:eq, :not_eq]
      end
    end

    def filter_associations(associations_by_user=nil)
      if associations_by_user.present?
        if associations_by_user.is_a?(Hash)
          associations_by_user.keys.reject{|m| @model_name==m}
        else
          associations_by_user
        end
      else
        @klass.ransackable_associations
      end
    end

    def filter_attributes(associations_by_user=nil)
      attributes = []
      if associations_by_user.present?
        associations_by_user.map do |m, attrs|
          attrs.map do |a|
            attributes << {"#{m.to_s}_#{(a.is_a?(Hash) ? a.keys.first : a)}" => (a.is_a?(Hash) ? a.values.first : nil)}
          end
        end
      end
      attributes.flatten.inject(:merge)
    end

    def build_associations(associations_by_user=nil)
      @klass = @ransack_object.context.klass
      associations_by_user = @klass.ransackable_associations unless associations_by_user.present?
      new_associations = []
      if associations_by_user.is_a?(Array)
        associations = [''] + associations_by_user
        associations.each do |model_name|
          new_associations << build_attributes_from_model(model_name)
        end
      elsif associations_by_user.is_a?(Hash)
        associations = associations_by_user.keys
        associations.each do |model_name|
          new_associations << build_attributes_from_model(model_name.to_s, associations_by_user[model_name.to_sym])
        end
      end
      new_associations.flatten.inject(:merge)
    end

    def build_attributes_from_model(model_name, default_attributes={})
      new_attributes = []
      ransack_model_name = model_name.to_s==@model_name ? '' : model_name
      default_attributes = attribute_array_to_hash(default_attributes)
      @ransack_object.context.traverse(ransack_model_name).columns_hash.each do |field, attributes|
        next if default_attributes.present? && !default_attributes.key?(field.to_sym)
        default = default_attributes.present? ? default_attributes[field.to_sym] : attributes.default
        limit = attributes.cast_type.present? ? attributes.cast_type.limit : nil
        type = default.is_a?(Array) || default =~ URI::regexp ? 'collection' : attributes.type
        new_attributes << {"#{model_name}_#{field}" => {type: type, limit: limit, default: default}}
      end
      {"#{model_name}" => new_attributes}
    end

    def attribute_array_to_hash(attributes)
      attributes.reduce(Hash.new){|a, h| a.merge( h.is_a?(Hash) ? {h.keys.first.to_sym => h.values.first} : {h.to_sym => nil} ) }
    end

  end
end


text:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Xml.Linq;

namespace _046_053_LINQ___Set_Operators
{
    public class LinqSamples
    {
        private List<Product> productList;
        private List<Customer> customerList;

        [Category("Set Operators")]
        [Description("This sample uses Distinct to remove duplicate elements in a sequence of " +
                    "factors of 300.")]
        public void Linq46()
        {
            int[] factorsOf300 = { 2, 2, 3, 5, 5 };

            var uniqueFactors = factorsOf300.Distinct();

            Console.WriteLine("Prime factors of 300:");
            foreach (var f in uniqueFactors)
            {
                Console.WriteLine(f);
            }
        }

        [Category("Set Operators")]
        [Description("This sample uses Distinct to find the unique Category names.")]
        public void Linq47()
        {
            List<Product> products = GetProductList();

            var categoryNames = (
                from prod in products
                select prod.Category)
                .Distinct();

            Console.WriteLine("Category names:");
            foreach (var n in categoryNames)
            {
                Console.WriteLine(n);
            }
        }

        [Category("Set Operators")]
        [Description("This sample uses Union to create one sequence that contains the unique values " +
                     "from both arrays.")]
        public void Linq48()
        {
            int[] numbersA = { 0, 2, 4, 5, 6, 8, 9 };
            int[] numbersB = { 1, 3, 5, 7, 8 };

            var uniqueNumbers = numbersA.Union(numbersB);

            Console.WriteLine("Unique numbers from both arrays:");
            foreach (var n in uniqueNumbers)
            {
                Console.WriteLine(n);
            }
        }

        [Category("Set Operators")]
        [Description("This sample uses the Union method to create one sequence that contains the unique first letter " +
                     "from both product and customer names. Union is only available through method syntax.")]
        public void Linq49()
        {
            List<Product> products = GetProductList();
            List<Customer> customers = GetCustomerList();

            var productFirstChars =
                from prod in products
                select prod.ProductName[0];
            var customerFirstChars =
                from cust in customers
                select cust.CompanyName[0];

            var uniqueFirstChars = productFirstChars.Union(customerFirstChars);

            Console.WriteLine("Unique first letters from Product names and Customer names:");
            foreach (var ch in uniqueFirstChars)
            {
                Console.WriteLine(ch);
            }
        }

        [Category("Set Operators")]
        [Description("This sample uses Intersect to create one sequence that contains the common values " +
                    "shared by both arrays.")]
        public void Linq50()
        {
            int[] numbersA = { 0, 2, 4, 5, 6, 8, 9 };
            int[] numbersB = { 1, 3, 5, 7, 8 };

            var commonNumbers = numbersA.Intersect(numbersB);

            Console.WriteLine("Common numbers shared by both arrays:");
            foreach (var n in commonNumbers)
            {
                Console.WriteLine(n);
            }
        }

        [Category("Set Operators")]
        [Description("This sample uses Intersect to create one sequence that contains the common first letter " +
                     "from both product and customer names.")]
        public void Linq51()
        {
            List<Product> products = GetProductList();
            List<Customer> customers = GetCustomerList();

            var productFirstChars =
                from prod in products
                select prod.ProductName[0];
            var customerFirstChars =
                from cust in customers
                select cust.CompanyName[0];

            var commonFirstChars = productFirstChars.Intersect(customerFirstChars);

            Console.WriteLine("Common first letters from Product names and Customer names:");
            foreach (var ch in commonFirstChars)
            {
                Console.WriteLine(ch);
            }
        }

        [Category("Set Operators")]
        [Description("This sample uses Except to create a sequence that contains the values from numbersA" +
                     "that are not also in numbersB.")]
        public void Linq52()
        {
            int[] numbersA = { 0, 2, 4, 5, 6, 8, 9 };
            int[] numbersB = { 1, 3, 5, 7, 8 };

            IEnumerable<int> aOnlyNumbers = numbersA.Except(numbersB);

            Console.WriteLine("Numbers in first array but not second array:");
            foreach (var n in aOnlyNumbers)
            {
                Console.WriteLine(n);
            }
        }

        [Category("Set Operators")]
        [Description("This sample uses Except to create one sequence that contains the first letters " +
                     "of product names that are not also first letters of customer names.")]
        public void Linq53()
        {
            List<Product> products = GetProductList();
            List<Customer> customers = GetCustomerList();

            var productFirstChars =
                from prod in products
                select prod.ProductName[0];
            var customerFirstChars =
                from cust in customers
                select cust.CompanyName[0];

            var productOnlyFirstChars = productFirstChars.Except(customerFirstChars);

            Console.WriteLine("First letters from Product names, but not from Customer names:");
            foreach (var ch in productOnlyFirstChars)
            {
                Console.WriteLine(ch);
            }
        }

        public List<Product> GetProductList()
        {
            if (productList == null)
                createLists();

            return productList;
        }

        public List<Customer> GetCustomerList()
        {
            if (customerList == null)
                createLists();

            return customerList;
        }

        private void createLists()
        {
            // Product data created in-memory using collection initializer:
            productList =
                new List<Product> {
                    new Product { ProductID = 1, ProductName = "Chai", Category = "Beverages", UnitPrice = 18.0000M, UnitsInStock = 39 },
                    new Product { ProductID = 2, ProductName = "Chang", Category = "Beverages", UnitPrice = 19.0000M, UnitsInStock = 17 },
                    new Product { ProductID = 3, ProductName = "Aniseed Syrup", Category = "Condiments", UnitPrice = 10.0000M, UnitsInStock = 13 },
                    new Product { ProductID = 4, ProductName = "Chef Anton's Cajun Seasoning", Category = "Condiments", UnitPrice = 22.0000M, UnitsInStock = 53 },
                    new Product { ProductID = 5, ProductName = "Chef Anton's Gumbo Mix", Category = "Condiments", UnitPrice = 21.3500M, UnitsInStock = 0 },
                    new Product { ProductID = 6, ProductName = "Grandma's Boysenberry Spread", Category = "Condiments", UnitPrice = 25.0000M, UnitsInStock = 120 },
                    new Product { ProductID = 7, ProductName = "Uncle Bob's Organic Dried Pears", Category = "Produce", UnitPrice = 30.0000M, UnitsInStock = 15 },
                    new Product { ProductID = 8, ProductName = "Northwoods Cranberry Sauce", Category = "Condiments", UnitPrice = 40.0000M, UnitsInStock = 6 },
                    new Product { ProductID = 9, ProductName = "Mishi Kobe Niku", Category = "Meat/Poultry", UnitPrice = 97.0000M, UnitsInStock = 29 },
                    new Product { ProductID = 10, ProductName = "Ikura", Category = "Seafood", UnitPrice = 31.0000M, UnitsInStock = 31 },
                    new Product { ProductID = 11, ProductName = "Queso Cabrales", Category = "Dairy Products", UnitPrice = 21.0000M, UnitsInStock = 22 },
                    new Product { ProductID = 12, ProductName = "Queso Manchego La Pastora", Category = "Dairy Products", UnitPrice = 38.0000M, UnitsInStock = 86 },
                    new Product { ProductID = 13, ProductName = "Konbu", Category = "Seafood", UnitPrice = 6.0000M, UnitsInStock = 24 },
                    new Product { ProductID = 14, ProductName = "Tofu", Category = "Produce", UnitPrice = 23.2500M, UnitsInStock = 35 },
                    new Product { ProductID = 15, ProductName = "Genen Shouyu", Category = "Condiments", UnitPrice = 15.5000M, UnitsInStock = 39 },
                    new Product { ProductID = 16, ProductName = "Pavlova", Category = "Confections", UnitPrice = 17.4500M, UnitsInStock = 29 },
                    new Product { ProductID = 17, ProductName = "Alice Mutton", Category = "Meat/Poultry", UnitPrice = 39.0000M, UnitsInStock = 0 },
                    new Product { ProductID = 18, ProductName = "Carnarvon Tigers", Category = "Seafood", UnitPrice = 62.5000M, UnitsInStock = 42 },
                    new Product { ProductID = 19, ProductName = "Teatime Chocolate Biscuits", Category = "Confections", UnitPrice = 9.2000M, UnitsInStock = 25 },
                    new Product { ProductID = 20, ProductName = "Sir Rodney's Marmalade", Category = "Confections", UnitPrice = 81.0000M, UnitsInStock = 40 },
                    new Product { ProductID = 21, ProductName = "Sir Rodney's Scones", Category = "Confections", UnitPrice = 10.0000M, UnitsInStock = 3 },
                    new Product { ProductID = 22, ProductName = "Gustaf's Knäckebröd", Category = "Grains/Cereals", UnitPrice = 21.0000M, UnitsInStock = 104 },
                    new Product { ProductID = 23, ProductName = "Tunnbröd", Category = "Grains/Cereals", UnitPrice = 9.0000M, UnitsInStock = 61 },
                    new Product { ProductID = 24, ProductName = "Guaraná Fantástica", Category = "Beverages", UnitPrice = 4.5000M, UnitsInStock = 20 },
                    new Product { ProductID = 25, ProductName = "NuNuCa Nuß-Nougat-Creme", Category = "Confections", UnitPrice = 14.0000M, UnitsInStock = 76 },
                    new Product { ProductID = 26, ProductName = "Gumbär Gummibärchen", Category = "Confections", UnitPrice = 31.2300M, UnitsInStock = 15 },
                    new Product { ProductID = 27, ProductName = "Schoggi Schokolade", Category = "Confections", UnitPrice = 43.9000M, UnitsInStock = 49 },
                    new Product { ProductID = 28, ProductName = "Rössle Sauerkraut", Category = "Produce", UnitPrice = 45.6000M, UnitsInStock = 26 },
                    new Product { ProductID = 29, ProductName = "Thüringer Rostbratwurst", Category = "Meat/Poultry", UnitPrice = 123.7900M, UnitsInStock = 0 },
                    new Product { ProductID = 30, ProductName = "Nord-Ost Matjeshering", Category = "Seafood", UnitPrice = 25.8900M, UnitsInStock = 10 },
                    new Product { ProductID = 31, ProductName = "Gorgonzola Telino", Category = "Dairy Products", UnitPrice = 12.5000M, UnitsInStock = 0 },
                    new Product { ProductID = 32, ProductName = "Mascarpone Fabioli", Category = "Dairy Products", UnitPrice = 32.0000M, UnitsInStock = 9 },
                    new Product { ProductID = 33, ProductName = "Geitost", Category = "Dairy Products", UnitPrice = 2.5000M, UnitsInStock = 112 },
                    new Product { ProductID = 34, ProductName = "Sasquatch Ale", Category = "Beverages", UnitPrice = 14.0000M, UnitsInStock = 111 },
                    new Product { ProductID = 35, ProductName = "Steeleye Stout", Category = "Beverages", UnitPrice = 18.0000M, UnitsInStock = 20 },
                    new Product { ProductID = 36, ProductName = "Inlagd Sill", Category = "Seafood", UnitPrice = 19.0000M, UnitsInStock = 112 },
                    new Product { ProductID = 37, ProductName = "Gravad lax", Category = "Seafood", UnitPrice = 26.0000M, UnitsInStock = 11 },
                    new Product { ProductID = 38, ProductName = "Côte de Blaye", Category = "Beverages", UnitPrice = 263.5000M, UnitsInStock = 17 },
                    new Product { ProductID = 39, ProductName = "Chartreuse verte", Category = "Beverages", UnitPrice = 18.0000M, UnitsInStock = 69 },
                    new Product { ProductID = 40, ProductName = "Boston Crab Meat", Category = "Seafood", UnitPrice = 18.4000M, UnitsInStock = 123 },
                    new Product { ProductID = 41, ProductName = "Jack's New England Clam Chowder", Category = "Seafood", UnitPrice = 9.6500M, UnitsInStock = 85 },
                    new Product { ProductID = 42, ProductName = "Singaporean Hokkien Fried Mee", Category = "Grains/Cereals", UnitPrice = 14.0000M, UnitsInStock = 26 },
                    new Product { ProductID = 43, ProductName = "Ipoh Coffee", Category = "Beverages", UnitPrice = 46.0000M, UnitsInStock = 17 },
                    new Product { ProductID = 44, ProductName = "Gula Malacca", Category = "Condiments", UnitPrice = 19.4500M, UnitsInStock = 27 },
                    new Product { ProductID = 45, ProductName = "Rogede sild", Category = "Seafood", UnitPrice = 9.5000M, UnitsInStock = 5 },
                    new Product { ProductID = 46, ProductName = "Spegesild", Category = "Seafood", UnitPrice = 12.0000M, UnitsInStock = 95 },
                    new Product { ProductID = 47, ProductName = "Zaanse koeken", Category = "Confections", UnitPrice = 9.5000M, UnitsInStock = 36 },
                    new Product { ProductID = 48, ProductName = "Chocolade", Category = "Confections", UnitPrice = 12.7500M, UnitsInStock = 15 },
                    new Product { ProductID = 49, ProductName = "Maxilaku", Category = "Confections", UnitPrice = 20.0000M, UnitsInStock = 10 },
                    new Product { ProductID = 50, ProductName = "Valkoinen suklaa", Category = "Confections", UnitPrice = 16.2500M, UnitsInStock = 65 },
                    new Product { ProductID = 51, ProductName = "Manjimup Dried Apples", Category = "Produce", UnitPrice = 53.0000M, UnitsInStock = 20 },
                    new Product { ProductID = 52, ProductName = "Filo Mix", Category = "Grains/Cereals", UnitPrice = 7.0000M, UnitsInStock = 38 },
                    new Product { ProductID = 53, ProductName = "Perth Pasties", Category = "Meat/Poultry", UnitPrice = 32.8000M, UnitsInStock = 0 },
                    new Product { ProductID = 54, ProductName = "Tourtière", Category = "Meat/Poultry", UnitPrice = 7.4500M, UnitsInStock = 21 },
                    new Product { ProductID = 55, ProductName = "Pâté chinois", Category = "Meat/Poultry", UnitPrice = 24.0000M, UnitsInStock = 115 },
                    new Product { ProductID = 56, ProductName = "Gnocchi di nonna Alice", Category = "Grains/Cereals", UnitPrice = 38.0000M, UnitsInStock = 21 },
                    new Product { ProductID = 57, ProductName = "Ravioli Angelo", Category = "Grains/Cereals", UnitPrice = 19.5000M, UnitsInStock = 36 },
                    new Product { ProductID = 58, ProductName = "Escargots de Bourgogne", Category = "Seafood", UnitPrice = 13.2500M, UnitsInStock = 62 },
                    new Product { ProductID = 59, ProductName = "Raclette Courdavault", Category = "Dairy Products", UnitPrice = 55.0000M, UnitsInStock = 79 },
                    new Product { ProductID = 60, ProductName = "Camembert Pierrot", Category = "Dairy Products", UnitPrice = 34.0000M, UnitsInStock = 19 },
                    new Product { ProductID = 61, ProductName = "Sirop d'érable", Category = "Condiments", UnitPrice = 28.5000M, UnitsInStock = 113 },
                    new Product { ProductID = 62, ProductName = "Tarte au sucre", Category = "Confections", UnitPrice = 49.3000M, UnitsInStock = 17 },
                    new Product { ProductID = 63, ProductName = "Vegie-spread", Category = "Condiments", UnitPrice = 43.9000M, UnitsInStock = 24 },
                    new Product { ProductID = 64, ProductName = "Wimmers gute Semmelknödel", Category = "Grains/Cereals", UnitPrice = 33.2500M, UnitsInStock = 22 },
                    new Product { ProductID = 65, ProductName = "Louisiana Fiery Hot Pepper Sauce", Category = "Condiments", UnitPrice = 21.0500M, UnitsInStock = 76 },
                    new Product { ProductID = 66, ProductName = "Louisiana Hot Spiced Okra", Category = "Condiments", UnitPrice = 17.0000M, UnitsInStock = 4 },
                    new Product { ProductID = 67, ProductName = "Laughing Lumberjack Lager", Category = "Beverages", UnitPrice = 14.0000M, UnitsInStock = 52 },
                    new Product { ProductID = 68, ProductName = "Scottish Longbreads", Category = "Confections", UnitPrice = 12.5000M, UnitsInStock = 6 },
                    new Product { ProductID = 69, ProductName = "Gudbrandsdalsost", Category = "Dairy Products", UnitPrice = 36.0000M, UnitsInStock = 26 },
                    new Product { ProductID = 70, ProductName = "Outback Lager", Category = "Beverages", UnitPrice = 15.0000M, UnitsInStock = 15 },
                    new Product { ProductID = 71, ProductName = "Flotemysost", Category = "Dairy Products", UnitPrice = 21.5000M, UnitsInStock = 26 },
                    new Product { ProductID = 72, ProductName = "Mozzarella di Giovanni", Category = "Dairy Products", UnitPrice = 34.8000M, UnitsInStock = 14 },
                    new Product { ProductID = 73, ProductName = "Röd Kaviar", Category = "Seafood", UnitPrice = 15.0000M, UnitsInStock = 101 },
                    new Product { ProductID = 74, ProductName = "Longlife Tofu", Category = "Produce", UnitPrice = 10.0000M, UnitsInStock = 4 },
                    new Product { ProductID = 75, ProductName = "Rhönbräu Klosterbier", Category = "Beverages", UnitPrice = 7.7500M, UnitsInStock = 125 },
                    new Product { ProductID = 76, ProductName = "Lakkalikööri", Category = "Beverages", UnitPrice = 18.0000M, UnitsInStock = 57 },
                    new Product { ProductID = 77, ProductName = "Original Frankfurter grüne Soße", Category = "Condiments", UnitPrice = 13.0000M, UnitsInStock = 32 }
            };

            // Customer/Order data read into memory from XML file using XLinq:
            customerList = (
                from e in XDocument.Load("Customers.xml").
                          Root.Elements("customer")
                select new Customer
                {
                    CustomerID = (string)e.Element("id"),
                    CompanyName = (string)e.Element("name"),
                    Address = (string)e.Element("address"),
                    City = (string)e.Element("city"),
                    Region = (string)e.Element("region"),
                    PostalCode = (string)e.Element("postalcode"),
                    Country = (string)e.Element("country"),
                    Phone = (string)e.Element("phone"),
                    Fax = (string)e.Element("fax"),
                    Orders = (
                        from o in e.Elements("orders").Elements("order")
                        select new Order
                        {
                            OrderID = (int)o.Element("id"),
                            OrderDate = (DateTime)o.Element("orderdate"),
                            Total = (decimal)o.Element("total")
                        })
                        .ToArray()
                })
                .ToList();
        }
    }
}


text:
{-# LANGUAGE CPP, DeriveDataTypeable #-}
-----------------------------------------------------------------------------
-- |
-- Module      : Language.Py.Token
-- Copyright   : (c) 2009 Bernie Pope
-- License     : BSD-style
-- Maintainer  : bjpop@csse.unimelb.edu.au
-- Stability   : experimental
-- Portability : ghc
--
-- Lexical tokens for the Python lexer. Contains the superset of tokens from
-- version 2 and version 3 of Python (they are mostly the same).
-----------------------------------------------------------------------------

module Language.Py.Token
  -- * The tokens
  ( Token (..)
  -- * String conversion
  , debugTokenString
  , tokenString
  -- * Classification
  , hasLiteral
  , TokenClass (..)
  , classifyToken
  ) where

import Language.Py.Pretty
import Language.Py.SrcLocation (SrcSpan (..), SrcLocation (..), Span(getSpan))
import Data.Data

-- | Lexical tokens.
data Token
  -- Whitespace
  = IndentToken { tokenSpan :: !SrcSpan }                       -- ^ Indentation: increase.
  | DedentToken { tokenSpan :: !SrcSpan }                       -- ^ Indentation: decrease.
  | NewlineToken { tokenSpan :: !SrcSpan }                      -- ^ Newline.
  | LineJoinToken { tokenSpan :: !SrcSpan }                     -- ^ Line join (backslash at end of line).

  -- Comment
  | CommentToken { tokenSpan :: !SrcSpan, tokenLiteral :: !String } -- ^ Single line comment.

  -- Identifiers
  | IdentifierToken { tokenSpan :: !SrcSpan, tokenLiteral :: !String }            -- ^ Identifier.

  -- Literals
  | StringToken { tokenSpan :: !SrcSpan, tokenLiteral :: !String }                   -- ^ Literal: string.
  | ByteStringToken { tokenSpan :: !SrcSpan, tokenLiteral :: !String }    -- ^ Literal: byte string.
  | UnicodeStringToken { tokenSpan :: !SrcSpan, tokenLiteral :: !String } -- ^ Literal: unicode string, version 2 only.
  | IntegerToken { tokenSpan :: !SrcSpan, tokenLiteral :: !String, tokenInteger :: !Integer }                 -- ^ Literal: integer.
  | LongIntegerToken { tokenSpan :: !SrcSpan, tokenLiteral :: !String, tokenInteger :: !Integer }             -- ^ Literal: long integer. /Version 2 only/.
  | FloatToken { tokenSpan :: !SrcSpan, tokenLiteral :: !String, tokenDouble :: !Double }                     -- ^ Literal: floating point.
  | ImaginaryToken { tokenSpan :: !SrcSpan, tokenLiteral :: !String, tokenDouble :: !Double }                 -- ^ Literal: imaginary number.

  -- Keywords
  | DefToken { tokenSpan :: !SrcSpan }                          -- ^ Keyword: \'def\'.
  | WhileToken { tokenSpan :: !SrcSpan }                        -- ^ Keyword: \'while\'.
  | IfToken { tokenSpan :: !SrcSpan }                           -- ^ Keyword: \'if\'.
  | TrueToken { tokenSpan :: !SrcSpan }                         -- ^ Keyword: \'True\'.
  | FalseToken { tokenSpan :: !SrcSpan }                        -- ^ Keyword: \'False\'.
  | ReturnToken { tokenSpan :: !SrcSpan }                       -- ^ Keyword: \'Return\'.
  | TryToken { tokenSpan :: !SrcSpan }                          -- ^ Keyword: \'try\'.
  | ExceptToken { tokenSpan :: !SrcSpan }                       -- ^ Keyword: \'except\'.
  | RaiseToken { tokenSpan :: !SrcSpan }                        -- ^ Keyword: \'raise\'.
  | InToken { tokenSpan :: !SrcSpan }                           -- ^ Keyword: \'in\'.
  | IsToken { tokenSpan :: !SrcSpan }                           -- ^ Keyword: \'is\'.
  | LambdaToken { tokenSpan :: !SrcSpan }                       -- ^ Keyword: \'lambda\'.
  | ClassToken { tokenSpan :: !SrcSpan }                        -- ^ Keyword: \'class\'.
  | FinallyToken { tokenSpan :: !SrcSpan }                      -- ^ Keyword: \'finally\'.
  | NoneToken { tokenSpan :: !SrcSpan }                         -- ^ Keyword: \'None\'.
  | ForToken { tokenSpan :: !SrcSpan }                          -- ^ Keyword: \'for\'.
  | FromToken { tokenSpan :: !SrcSpan }                         -- ^ Keyword: \'from\'.
  | GlobalToken { tokenSpan :: !SrcSpan }                       -- ^ Keyword: \'global\'.
  | WithToken { tokenSpan :: !SrcSpan }                         -- ^ Keyword: \'with\'.
  | AsToken { tokenSpan :: !SrcSpan }                           -- ^ Keyword: \'as\'.
  | ElifToken { tokenSpan :: !SrcSpan }                         -- ^ Keyword: \'elif\'.
  | YieldToken { tokenSpan :: !SrcSpan }                        -- ^ Keyword: \'yield\'.
  | AssertToken { tokenSpan :: !SrcSpan }                       -- ^ Keyword: \'assert\'.
  | ImportToken { tokenSpan :: !SrcSpan }                       -- ^ Keyword: \'import\'.
  | PassToken { tokenSpan :: !SrcSpan }                         -- ^ Keyword: \'pass\'.
  | BreakToken { tokenSpan :: !SrcSpan }                        -- ^ Keyword: \'break\'.
  | ContinueToken { tokenSpan :: !SrcSpan }                     -- ^ Keyword: \'continue\'.
  | DeleteToken { tokenSpan :: !SrcSpan }                       -- ^ Keyword: \'del\'.
  | ElseToken { tokenSpan :: !SrcSpan }                         -- ^ Keyword: \'else\'.
  | NotToken { tokenSpan :: !SrcSpan }                          -- ^ Keyword: \'not\'.
  | AndToken { tokenSpan :: !SrcSpan }                          -- ^ Keyword: boolean conjunction \'and\'.
  | OrToken { tokenSpan :: !SrcSpan }                           -- ^ Keyword: boolean disjunction \'or\'.
  -- Version 3.x only:
  | NonLocalToken { tokenSpan :: !SrcSpan }                     -- ^ Keyword: \'nonlocal\' (Python 3.x only)
  -- Version 2.x only:
  | PrintToken { tokenSpan :: !SrcSpan }                        -- ^ Keyword: \'print\'. (Python 2.x only)
  | ExecToken { tokenSpan :: !SrcSpan }                         -- ^ Keyword: \'exec\'. (Python 2.x only)

  -- Delimiters
  | AtToken { tokenSpan :: !SrcSpan }                           -- ^ Delimiter: at sign \'\@\'.
  | LeftRoundBracketToken { tokenSpan :: !SrcSpan }             -- ^ Delimiter: left round bracket \'(\'.
  | RightRoundBracketToken { tokenSpan :: !SrcSpan }            -- ^ Delimiter: right round bracket \')\'.
  | LeftSquareBracketToken { tokenSpan :: !SrcSpan }            -- ^ Delimiter: left square bracket \'[\'.
  | RightSquareBracketToken { tokenSpan :: !SrcSpan }           -- ^ Delimiter: right square bracket \']\'.
  | LeftBraceToken { tokenSpan :: !SrcSpan }                    -- ^ Delimiter: left curly bracket \'{\'.
  | RightBraceToken { tokenSpan :: !SrcSpan }                   -- ^ Delimiter: right curly bracket \'}\'.
  | DotToken { tokenSpan :: !SrcSpan }                          -- ^ Delimiter: dot (full stop) \'.\'.
  | CommaToken { tokenSpan :: !SrcSpan }                        -- ^ Delimiter: comma \',\'.
  | SemiColonToken { tokenSpan :: !SrcSpan }                    -- ^ Delimiter: semicolon \';\'.
  | ColonToken { tokenSpan :: !SrcSpan }                        -- ^ Delimiter: colon \':\'.
  | EllipsisToken { tokenSpan :: !SrcSpan }                     -- ^ Delimiter: ellipses (three dots) \'...\'.
  | RightArrowToken { tokenSpan :: !SrcSpan }                   -- ^ Delimiter: right facing arrow \'->\'.
  | AssignToken { tokenSpan :: !SrcSpan }                       -- ^ Delimiter: assignment \'=\'.
  | PlusAssignToken { tokenSpan :: !SrcSpan }                   -- ^ Delimiter: plus assignment \'+=\'.
  | MinusAssignToken { tokenSpan :: !SrcSpan }                  -- ^ Delimiter: minus assignment \'-=\'.
  | MultAssignToken { tokenSpan :: !SrcSpan }                   -- ^ Delimiter: multiply assignment \'*=\'
  | DivAssignToken { tokenSpan :: !SrcSpan }                    -- ^ Delimiter: divide assignment \'/=\'.
  | ModAssignToken { tokenSpan :: !SrcSpan }                    -- ^ Delimiter: modulus assignment \'%=\'.
  | PowAssignToken { tokenSpan :: !SrcSpan }                    -- ^ Delimiter: power assignment \'**=\'.
  | BinAndAssignToken { tokenSpan :: !SrcSpan }                 -- ^ Delimiter: binary-and assignment \'&=\'.
  | BinOrAssignToken { tokenSpan :: !SrcSpan }                  -- ^ Delimiter: binary-or assignment \'|=\'.
  | BinXorAssignToken { tokenSpan :: !SrcSpan }                 -- ^ Delimiter: binary-xor assignment \'^=\'.
  | LeftShiftAssignToken { tokenSpan :: !SrcSpan }              -- ^ Delimiter: binary-left-shift assignment \'<<=\'.
  | RightShiftAssignToken { tokenSpan :: !SrcSpan }             -- ^ Delimiter: binary-right-shift assignment \'>>=\'.
  | FloorDivAssignToken { tokenSpan :: !SrcSpan }               -- ^ Delimiter: floor-divide assignment \'//=\'.
  | BackQuoteToken { tokenSpan :: !SrcSpan }                    -- ^ Delimiter: back quote character \'`\'.

  -- Operators
  | PlusToken { tokenSpan :: !SrcSpan }                         -- ^ Operator: plus \'+\'.
  | MinusToken { tokenSpan :: !SrcSpan }                        -- ^ Operator: minus: \'-\'.
  | MultToken { tokenSpan :: !SrcSpan }                         -- ^ Operator: multiply \'*\'.
  | DivToken { tokenSpan :: !SrcSpan }                          -- ^ Operator: divide \'/\'.
  | GreaterThanToken { tokenSpan :: !SrcSpan }                  -- ^ Operator: greater-than \'>\'.
  | LessThanToken { tokenSpan :: !SrcSpan }                     -- ^ Operator: less-than \'<\'.
  | EqualityToken { tokenSpan :: !SrcSpan }                     -- ^ Operator: equals \'==\'.
  | GreaterThanEqualsToken { tokenSpan :: !SrcSpan }            -- ^ Operator: greater-than-or-equals \'>=\'.
  | LessThanEqualsToken { tokenSpan :: !SrcSpan }               -- ^ Operator: less-than-or-equals \'<=\'.
  | ExponentToken { tokenSpan :: !SrcSpan }                     -- ^ Operator: exponential \'**\'.
  | BinaryOrToken { tokenSpan :: !SrcSpan }                     -- ^ Operator: binary-or \'|\'.
  | XorToken { tokenSpan :: !SrcSpan }                          -- ^ Operator: binary-xor \'^\'.
  | BinaryAndToken { tokenSpan :: !SrcSpan }                    -- ^ Operator: binary-and \'&\'.
  | ShiftLeftToken { tokenSpan :: !SrcSpan }                    -- ^ Operator: binary-shift-left \'<<\'.
  | ShiftRightToken { tokenSpan :: !SrcSpan }                   -- ^ Operator: binary-shift-right \'>>\'.
  | ModuloToken { tokenSpan :: !SrcSpan }                       -- ^ Operator: modulus \'%\'.
  | FloorDivToken { tokenSpan :: !SrcSpan }                     -- ^ Operator: floor-divide \'//\'.
  | TildeToken { tokenSpan :: !SrcSpan }                        -- ^ Operator: tilde \'~\'.
  | NotEqualsToken { tokenSpan :: !SrcSpan }                    -- ^ Operator: not-equals \'!=\'.
  | NotEqualsV2Token { tokenSpan :: !SrcSpan }                  -- ^ Operator: not-equals \'<>\'. Version 2 only.

  -- Special cases
  | EOFToken { tokenSpan :: !SrcSpan }                          -- ^ End of file
  deriving (Eq, Ord, Show, Typeable, Data)

instance Span Token where
  getSpan = tokenSpan

-- | Produce a string from a token containing detailed information. Mainly intended for debugging.
debugTokenString :: Token -> String
debugTokenString token
  = render (text (show $ toConstr token) <+> pretty (tokenSpan token) <+>
    if hasLiteral token then text (tokenLiteral token) else empty)

-- | Test if a token contains its literal source text.
hasLiteral :: Token -> Bool
hasLiteral token
  = case token of
      CommentToken {}     -> True
      IdentifierToken {}  -> True
      StringToken {}      -> True
      ByteStringToken {}  -> True
      IntegerToken {}     -> True
      LongIntegerToken {} -> True
      FloatToken {}       -> True
      ImaginaryToken  {}  -> True
      other               -> False

-- | Classification of tokens
data TokenClass
  = Comment
  | Number
  | Identifier
  | Punctuation
  | Bracket
  | Layout
  | Keyword
  | String
  | Operator
  | Assignment
  deriving (Show, Eq, Ord)

classifyToken :: Token -> TokenClass
classifyToken token =
  case token of
    IndentToken {} -> Layout
    DedentToken {} -> Layout
    NewlineToken {} -> Layout
    CommentToken {} -> Comment
    IdentifierToken {} -> Identifier
    StringToken {} -> String
    ByteStringToken {} -> String
    IntegerToken {} -> Number
    LongIntegerToken {} -> Number
    FloatToken {} -> Number
    ImaginaryToken {} -> Number
    DefToken {} -> Keyword
    WhileToken {} -> Keyword
    IfToken {} ->  Keyword
    TrueToken {} -> Keyword
    FalseToken {} -> Keyword
    ReturnToken {} -> Keyword
    TryToken {} -> Keyword
    ExceptToken {} -> Keyword
    RaiseToken {} -> Keyword
    InToken {} -> Keyword
    IsToken {} -> Keyword
    LambdaToken {} -> Keyword
    ClassToken {} -> Keyword
    FinallyToken {} -> Keyword
    NoneToken {} -> Keyword
    ForToken {} -> Keyword
    FromToken {} -> Keyword
    GlobalToken {} -> Keyword
    WithToken {} -> Keyword
    AsToken {} -> Keyword
    ElifToken {} -> Keyword
    YieldToken {} -> Keyword
    AssertToken {} -> Keyword
    ImportToken {} -> Keyword
    PassToken {} -> Keyword
    BreakToken {} -> Keyword
    ContinueToken {} -> Keyword
    DeleteToken {} -> Keyword
    ElseToken {} -> Keyword
    NotToken {} -> Keyword
    AndToken {} -> Keyword
    OrToken {} -> Keyword
    NonLocalToken {} -> Keyword
    PrintToken {} -> Keyword
    ExecToken {} -> Keyword
    AtToken {} -> Keyword
    LeftRoundBracketToken {} -> Bracket
    RightRoundBracketToken {} -> Bracket
    LeftSquareBracketToken {} -> Bracket
    RightSquareBracketToken {} -> Bracket
    LeftBraceToken {} -> Bracket
    RightBraceToken {} -> Bracket
    DotToken {} -> Operator
    CommaToken {} -> Punctuation
    SemiColonToken {} -> Punctuation
    ColonToken {} -> Punctuation
    EllipsisToken {} -> Keyword  -- What kind of thing is an ellipsis?
    RightArrowToken {} -> Punctuation
    AssignToken {} -> Assignment
    PlusAssignToken {} -> Assignment
    MinusAssignToken {} -> Assignment
    MultAssignToken {} -> Assignment
    DivAssignToken {} -> Assignment
    ModAssignToken {} -> Assignment
    PowAssignToken {} -> Assignment
    BinAndAssignToken {} -> Assignment
    BinOrAssignToken {} -> Assignment
    BinXorAssignToken {} -> Assignment
    LeftShiftAssignToken {} -> Assignment
    RightShiftAssignToken {} -> Assignment
    FloorDivAssignToken {} -> Assignment
    BackQuoteToken {} -> Punctuation
    PlusToken {} -> Operator
    MinusToken {} -> Operator
    MultToken {} -> Operator
    DivToken {} -> Operator
    GreaterThanToken {} -> Operator
    LessThanToken {} -> Operator
    EqualityToken {} -> Operator
    GreaterThanEqualsToken {} -> Operator
    LessThanEqualsToken {} -> Operator
    ExponentToken {} -> Operator
    BinaryOrToken {} -> Operator
    XorToken {} -> Operator
    BinaryAndToken {} -> Operator
    ShiftLeftToken {} -> Operator
    ShiftRightToken {} -> Operator
    ModuloToken {} -> Operator
    FloorDivToken {} -> Operator
    TildeToken {} -> Operator
    NotEqualsToken {} -> Operator
    NotEqualsV2Token {} -> Operator
    LineJoinToken {} -> Layout
    EOFToken {} -> Layout  -- maybe a spurious classification.

-- | Produce a string from a token which is suitable for printing as Python concrete syntax.
-- /Invisible/ tokens yield an empty string.
tokenString :: Token -> String
tokenString token
  = case token of
      IndentToken {} -> ""
      DedentToken {} -> ""
      NewlineToken {} -> ""
      CommentToken {} -> tokenLiteral token
      IdentifierToken {} -> tokenLiteral token
      StringToken {} -> tokenLiteral token
      ByteStringToken {} -> tokenLiteral token
      IntegerToken {} -> tokenLiteral token
      LongIntegerToken {} -> tokenLiteral token
      FloatToken {} -> tokenLiteral token
      ImaginaryToken {} -> tokenLiteral token
      DefToken {} -> "def"
      WhileToken {} -> "while"
      IfToken {} -> "if"
      TrueToken {} -> "True"
      FalseToken {} -> "False"
      ReturnToken {} -> "return"
      TryToken {} -> "try"
      ExceptToken {} -> "except"
      RaiseToken {} -> "raise"
      InToken {} -> "in"
      IsToken {} -> "is"
      LambdaToken {} -> "lambda"
      ClassToken {} -> "class"
      FinallyToken {} -> "finally"
      NoneToken {} -> "None"
      ForToken {} -> "for"
      FromToken {} -> "from"
      GlobalToken {} -> "global"
      WithToken {} -> "with"
      AsToken {} -> "as"
      ElifToken {} -> "elif"
      YieldToken {} -> "yield"
      AssertToken {} -> "assert"
      ImportToken {} -> "import"
      PassToken {} -> "pass"
      BreakToken {} -> "break"
      ContinueToken {} -> "continue"
      DeleteToken {} -> "delete"
      ElseToken {} -> "else"
      NotToken {} -> "not"
      AndToken {} -> "and"
      OrToken {} -> "or"
      NonLocalToken {} -> "nonlocal"
      PrintToken {} -> "print"
      ExecToken {} -> "exec"
      AtToken {} -> "at"
      LeftRoundBracketToken {} -> "("
      RightRoundBracketToken {} -> ")"
      LeftSquareBracketToken {} -> "["
      RightSquareBracketToken {} -> "]"
      LeftBraceToken {} -> "{"
      RightBraceToken {} -> "}"
      DotToken {} -> "."
      CommaToken {} -> ","
      SemiColonToken {} -> ";"
      ColonToken {} -> ":"
      EllipsisToken {} -> "..."
      RightArrowToken {} -> "->"
      AssignToken {} -> "="
      PlusAssignToken {} -> "+="
      MinusAssignToken {} -> "-="
      MultAssignToken {} -> "*="
      DivAssignToken {} -> "/="
      ModAssignToken {} -> "%="
      PowAssignToken {} -> "**="
      BinAndAssignToken {} -> "&="
      BinOrAssignToken {} -> "|="
      BinXorAssignToken {} -> "^="
      LeftShiftAssignToken {} -> "<<="
      RightShiftAssignToken {} -> ">>="
      FloorDivAssignToken {} -> "//="
      BackQuoteToken {} -> "`"
      PlusToken {} -> "+"
      MinusToken {} -> "-"
      MultToken {} -> "*"
      DivToken {} -> "/"
      GreaterThanToken {} -> ">"
      LessThanToken {} -> "<"
      EqualityToken {} -> "=="
      GreaterThanEqualsToken {} -> ">="
      LessThanEqualsToken {} -> "<="
      ExponentToken {} -> "**"
      BinaryOrToken {} -> "|"
      XorToken {} -> "^"
      BinaryAndToken {} -> "&"
      ShiftLeftToken {} -> "<<"
      ShiftRightToken {} -> ">>"
      ModuloToken {} -> "%"
      FloorDivToken {} -> "//"
      TildeToken {} -> "~"
      NotEqualsToken {} -> "!="
      NotEqualsV2Token {} -> "<>"
      LineJoinToken {} -> "\\"
      EOFToken {} -> ""


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DuoCode.SimpleInjector.InvokeStrategies
{
    internal static class OpenGenericTypes
    {
        private static readonly Type enumerableType = typeof(IEnumerable<>);
        private static readonly Type funcType = typeof(Func<>);

        public static bool IsEnumerable(Type type)
        {
            return type.IsGenericType && type.GetGenericTypeDefinition().IsAssignableFrom(enumerableType);
        }

        public static bool IsFunc(Type type)
        {
            return type.IsGenericType && type.GetGenericTypeDefinition().IsAssignableFrom(funcType);
        }

        public static bool IsUnknownOpenType(Type type)
        {
            if (!type.IsGenericType) return false;

            return !IsEnumerable(type) && !IsFunc(type);
        }
    }
}


text:
module BodyClasses
  extend ActiveSupport::Concern

  included do
    before_action do
      full_controller_name = controller_path.gsub('/', '-')

      @body_classes = ["#{full_controller_name}--common", "#{full_controller_name}-#{action_name}"]
    end
  end
end


text:
<?xml version='1.0' encoding='UTF-8'?>
<project>
  <actions/>
  <description></description>
  <logRotator class="hudson.tasks.LogRotator">
    <daysToKeep>21</daysToKeep>
    <numToKeep>-1</numToKeep>
    <artifactDaysToKeep>14</artifactDaysToKeep>
    <artifactNumToKeep>25</artifactNumToKeep>
  </logRotator>
  <keepDependencies>false</keepDependencies>
  <properties>
    <com.sonyericsson.jenkins.plugins.bfa.model.ScannerJobProperty plugin="build-failure-analyzer@1.13.0">
      <doNotScan>false</doNotScan>
    </com.sonyericsson.jenkins.plugins.bfa.model.ScannerJobProperty>
    <com.coravy.hudson.plugins.github.GithubProjectProperty plugin="github@1.11.3">
      <projectUrl>https://github.com/dotnet/roslyn/</projectUrl>
    </com.coravy.hudson.plugins.github.GithubProjectProperty>
  </properties>
  <scm class="hudson.plugins.git.GitSCM" plugin="git@2.3.5">
    <configVersion>2</configVersion>
    <userRemoteConfigs>
      <hudson.plugins.git.UserRemoteConfig>
        <url>git://github.com/dotnet/roslyn.git</url>
      </hudson.plugins.git.UserRemoteConfig>
    </userRemoteConfigs>
    <branches>
      <hudson.plugins.git.BranchSpec>
        <name>*/master</name>
      </hudson.plugins.git.BranchSpec>
    </branches>
    <doGenerateSubmoduleConfigurations>false</doGenerateSubmoduleConfigurations>
    <submoduleCfg class="list"/>
    <extensions>
      <hudson.plugins.git.extensions.impl.WipeWorkspace/>
      <hudson.plugins.git.extensions.impl.CloneOption>
        <shallow>true</shallow>
        <reference></reference>
      </hudson.plugins.git.extensions.impl.CloneOption>
    </extensions>
  </scm>
  <assignedNode>mac-roslyn</assignedNode>
  <canRoam>false</canRoam>
  <disabled>false</disabled>
  <blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
  <blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
  <triggers/>
  <concurrentBuild>true</concurrentBuild>
  <builders>
    <hudson.tasks.Shell>
      <command>./cibuild.sh --mono-path ~/builds/mono/bin --os Darwin</command>
    </hudson.tasks.Shell>
  </builders>
  <publishers>
    <xunit plugin="xunit@1.96">
      <types>
        <XUnitDotNetTestType>
          <pattern>**/*TestResults.xml</pattern>
          <skipNoTestFiles>false</skipNoTestFiles>
          <failIfNotNew>true</failIfNotNew>
          <deleteOutputFiles>true</deleteOutputFiles>
          <stopProcessingIfError>true</stopProcessingIfError>
        </XUnitDotNetTestType>
      </types>
      <thresholds>
        <org.jenkinsci.plugins.xunit.threshold.FailedThreshold>
          <unstableThreshold></unstableThreshold>
          <unstableNewThreshold></unstableNewThreshold>
          <failureThreshold></failureThreshold>
          <failureNewThreshold></failureNewThreshold>
        </org.jenkinsci.plugins.xunit.threshold.FailedThreshold>
        <org.jenkinsci.plugins.xunit.threshold.SkippedThreshold>
          <unstableThreshold></unstableThreshold>
          <unstableNewThreshold></unstableNewThreshold>
          <failureThreshold></failureThreshold>
          <failureNewThreshold></failureNewThreshold>
        </org.jenkinsci.plugins.xunit.threshold.SkippedThreshold>
      </thresholds>
      <thresholdMode>1</thresholdMode>
      <extraConfiguration>
        <testTimeMargin>3000</testTimeMargin>
      </extraConfiguration>
    </xunit>
  </publishers>
  <buildWrappers>
    <hudson.plugins.build__timeout.BuildTimeoutWrapper plugin="build-timeout@1.14.1">
      <strategy class="hudson.plugins.build_timeout.impl.AbsoluteTimeOutStrategy">
        <timeoutMinutes>120</timeoutMinutes>
      </strategy>
      <operationList/>
    </hudson.plugins.build__timeout.BuildTimeoutWrapper>
  </buildWrappers>
</project>


text:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:baselineAligned="false"
    android:divider="?android:attr/dividerHorizontal"
    android:orientation="vertical"
    android:padding="16dp"
    android:showDividers="middle"
    tools:context=".MusicDetailFragment" >

    <TextView
        android:id="@+id/music_title"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/dummy_text"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/music_artist"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="@string/dummy_text" />

        <TextView
            android:id="@+id/music_license"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="@string/dummy_text" />

        <TextView
            android:id="@+id/music_size"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/dummy_text" />

        <FrameLayout
            android:id="@+id/fragment_player"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>

</LinearLayout>


text:
package com.howtodoinjava.demo.binding;

public class ContactInfo {
	private String tel;
	private String address;

	public String getTel() {
		return tel;
	}

	public void setTel(String tel) {
		this.tel = tel;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	public String toString() {
		return String.format("ContactInfo[tel:%s, address:%s]", tel, address);
	}
}


text:
namespace PokeD.BattleEngine.Attack.Calculation
{
    public enum AttackT
    {
        Normal,
        Special,
        NormaSpecial,
        SpecialNormal
    }

    public static class DamageCalculation
    {
    }
}


text:
package org.kie.bc.client.perspectives.standalone;

import javax.enterprise.context.ApplicationScoped;

import org.uberfire.client.workbench.WorkbenchCustomStandalonePerspectiveDefinition;

@ApplicationScoped
public class WorkbenchCustomStandalonePerspectiveDefinitionImpl implements WorkbenchCustomStandalonePerspectiveDefinition {

    @Override
    public String getStandalonePerspectiveIdentifier() {
        return AuthoringPerspective.IDENTIFIER;
    }

    @Override
    public boolean openPathAutomatically() {
        return false;
    }
}


text:
package org.batfish.representation.juniper;

import java.util.List;
import org.batfish.common.Warnings;
import org.batfish.datamodel.Configuration;
import org.batfish.datamodel.ospf.OspfMetricType;
import org.batfish.datamodel.routing_policy.statement.SetOspfMetricType;
import org.batfish.datamodel.routing_policy.statement.Statement;

/** A {@link Statement} that sets the OSPF external metric type on a route. */
public final class PsThenExternal extends PsThen {

  private final OspfMetricType _type;

  public PsThenExternal(OspfMetricType type) {
    _type = type;
  }

  @Override
  public void applyTo(
      List<Statement> statements,
      JuniperConfiguration juniperVendorConfiguration,
      Configuration c,
      Warnings warnings) {
    statements.add(new SetOspfMetricType(_type));
  }

  public OspfMetricType getType() {
    return _type;
  }
}


text:
<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * DemonstrativoResultadosItens
 *
 * @ORM\Table(name="demonstrativo_resultados_itens")
 * @ORM\Entity
 */
class DemonstrativoResultadosItens
{
    /**
     * @var string
     *
     * @ORM\Column(name="descricao", type="string", length=300, nullable=true)
     */
    private $descricao;

    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * Set descricao
     *
     * @param string $descricao
     *
     * @return DemonstrativoResultadosItens
     */
    public function setDescricao($descricao)
    {
        $this->descricao = $descricao;

        return $this;
    }

    /**
     * Get descricao
     *
     * @return string
     */
    public function getDescricao()
    {
        return $this->descricao;
    }

    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }
}