@Override
  @SideOnly(Side.CLIENT)
  public boolean onClick(
      GuiEnderCompendium gui,
      int x,
      int y,
      int mouseX,
      int mouseY,
      int buttonId,
      boolean isUnlocked) {
    if (!isUnlocked) return false;

    for (int a = 0, xx = x, yy = y; a < 6; a++) {
      ItemStack is = a == 5 ? charm : runes[a];

      if (is != null
          && mouseX >= xx + 1
          && mouseX <= xx + 18
          && mouseY >= yy + 1
          && mouseY <= yy + 18) {
        KnowledgeObject<? extends IKnowledgeObjectInstance<?>> obj =
            KnowledgeUtils.tryGetFromItemStack(is);
        if (obj == null) return false;

        gui.showObject(obj);
        gui.moveToCurrentObject(true);
        return true;
      }

      if (a == 4) xx = x + 98;
      else xx += 19;
    }

    return false;
  }
  @Override
  @SideOnly(Side.CLIENT)
  public void onRender(
      GuiEnderCompendium gui, int x, int y, int mouseX, int mouseY, boolean isUnlocked) {
    GL11.glColor4f(1F, 1F, 1F, 1F);
    gui.mc.getTextureManager().bindTexture(GuiEnderCompendium.texFragments);
    gui.drawTexturedModalRect(x, y, 89, 0, 96, 20);

    for (int a = 0, xx = x, yy = y; a < 6; a++) {
      ItemStack is =
          isUnlocked ? (a == 5 ? charm : runes[a]) : KnowledgeFragmentCrafting.lockedItem;

      if (is != null) {
        GuiItemRenderHelper.renderItemIntoGUI(gui.mc.getTextureManager(), is, xx + 2, yy + 2);

        if (isUnlocked
            && mouseX >= xx + 1
            && mouseX <= xx + 18
            && mouseY >= yy + 1
            && mouseY <= yy + 18) {
          GuiItemRenderHelper.setupTooltip(
              mouseX,
              mouseY,
              Joiner.on('\n').join(KnowledgeUtils.getCompendiumTooltip(is, gui.mc.thePlayer)));
        }
      }

      if (a == 4) xx = x + 98;
      else xx += 19;
    }
  }
 public static final <T extends IObjectHolder<?>> KnowledgeObject<T> fromObject(ItemStack is) {
   if (!KnowledgeUtils.isItemStackViable(is)) return null;
   return (KnowledgeObject<T>)
       getAllObjects()
           .stream()
           .filter(knowledgeObj -> knowledgeObj.holder.checkEquality(is))
           .findAny()
           .orElse(null);
 }